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/client/episodic | |
| 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/client/episodic')
| -rw-r--r-- | mp/src/game/client/episodic/c_npc_advisor.cpp | 502 | ||||
| -rw-r--r-- | mp/src/game/client/episodic/c_npc_puppet.cpp | 334 | ||||
| -rw-r--r-- | mp/src/game/client/episodic/c_prop_coreball.cpp | 282 | ||||
| -rw-r--r-- | mp/src/game/client/episodic/c_prop_scalable.cpp | 392 | ||||
| -rw-r--r-- | mp/src/game/client/episodic/c_vehicle_jeep_episodic.cpp | 266 | ||||
| -rw-r--r-- | mp/src/game/client/episodic/c_vort_charge_token.cpp | 1200 | ||||
| -rw-r--r-- | mp/src/game/client/episodic/c_weapon_hopwire.cpp | 842 | ||||
| -rw-r--r-- | mp/src/game/client/episodic/episodic_screenspaceeffects.cpp | 928 | ||||
| -rw-r--r-- | mp/src/game/client/episodic/episodic_screenspaceeffects.h | 238 | ||||
| -rw-r--r-- | mp/src/game/client/episodic/flesh_internal_material_proxy.cpp | 450 |
10 files changed, 2717 insertions, 2717 deletions
diff --git a/mp/src/game/client/episodic/c_npc_advisor.cpp b/mp/src/game/client/episodic/c_npc_advisor.cpp index 94cd047b..4aba115d 100644 --- a/mp/src/game/client/episodic/c_npc_advisor.cpp +++ b/mp/src/game/client/episodic/c_npc_advisor.cpp @@ -1,251 +1,251 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Definition for client-side advisor.
-//
-//=====================================================================================//
-
-
-
-#include "cbase.h"
-// this file contains the definitions for the message ID constants (eg ADVISOR_MSG_START_BEAM etc)
-#include "npc_advisor_shared.h"
-
-#if NPC_ADVISOR_HAS_BEHAVIOR
-
-#include "particles_simple.h"
-#include "citadel_effects_shared.h"
-#include "particles_attractor.h"
-#include "clienteffectprecachesystem.h"
-#include "c_te_effect_dispatch.h"
-
-#include "c_ai_basenpc.h"
-#include "dlight.h"
-#include "iefx.h"
-
-
-//-----------------------------------------------------------------------------
-// Purpose: unpack a networked entity index into a basehandle.
-//-----------------------------------------------------------------------------
-inline C_BaseEntity *IndexToEntity( int eindex )
-{
- return ClientEntityList().GetBaseEntityFromHandle(ClientEntityList().EntIndexToHandle(eindex));
-}
-
-
-
-#define ADVISOR_ELIGHT_CVARS 1 // enable/disable tuning advisor elight with console variables
-
-#if ADVISOR_ELIGHT_CVARS
-ConVar advisor_elight_e("advisor_elight_e","3");
-ConVar advisor_elight_rfeet("advisor_elight_rfeet","52");
-#endif
-
-
-/*! Client-side reflection of the advisor class.
- */
-class C_NPC_Advisor : public C_AI_BaseNPC
-{
- DECLARE_CLASS( C_NPC_Advisor, C_AI_BaseNPC );
- DECLARE_CLIENTCLASS();
-
-public:
- // Server to client message received
- virtual void ReceiveMessage( int classID, bf_read &msg );
- virtual void ClientThink( void );
-
-private:
- /*
- // broken into its own function so I can move it if necesasry
- void Initialize();
- */
-
- // start/stop beam particle effect from me to a pelting object
- void StartBeamFX( C_BaseEntity *pOnEntity );
- void StopBeamFX( C_BaseEntity *pOnEntity );
-
- void StartElight();
- void StopElight();
-
- int m_ElightKey; // test using an elight to make the escape sequence more visible. 0 is invalid.
-
-};
-
-IMPLEMENT_CLIENTCLASS_DT( C_NPC_Advisor, DT_NPC_Advisor, CNPC_Advisor )
-
-END_RECV_TABLE()
-
-// Server to client message received
-void C_NPC_Advisor::ReceiveMessage( int classID, bf_read &msg )
-{
- if ( classID != GetClientClass()->m_ClassID )
- {
- // message is for subclass
- BaseClass::ReceiveMessage( classID, msg );
- return;
- }
-
- int messageType = msg.ReadByte();
- switch( messageType )
- {
- case ADVISOR_MSG_START_BEAM:
- {
- int eindex = msg.ReadLong();
- StartBeamFX(IndexToEntity(eindex));
- }
- break;
-
- case ADVISOR_MSG_STOP_BEAM:
- {
- int eindex = msg.ReadLong();
- StopBeamFX(IndexToEntity(eindex));
-
- }
- break;
-
- case ADVISOR_MSG_STOP_ALL_BEAMS:
- {
- ParticleProp()->StopEmission();
- }
- break;
- case ADVISOR_MSG_START_ELIGHT:
- {
- StartElight();
- }
- break;
- case ADVISOR_MSG_STOP_ELIGHT:
- {
- StopElight();
- }
- break;
-
- default:
- AssertMsg1( false, "Received unknown message %d", messageType);
- }
-}
-
-/// only use of the clientthink on the advisor is to update the elight
-void C_NPC_Advisor::ClientThink( void )
-{
- // if the elight has gone away, bail out
- if (m_ElightKey == 0)
- {
- SetNextClientThink( CLIENT_THINK_NEVER );
- return;
- }
-
- // get the elight
- dlight_t * el = effects->GetElightByKey(m_ElightKey);
- if (!el)
- {
- // the elight has been invalidated. bail out.
- m_ElightKey = 0;
-
- SetNextClientThink( CLIENT_THINK_NEVER );
- return;
- }
- else
- {
- el->origin = WorldSpaceCenter();
-
-#if ADVISOR_ELIGHT_CVARS
- el->color.exponent = advisor_elight_e.GetFloat();
- el->radius = advisor_elight_rfeet.GetFloat() * 12.0f;
-#endif
- }
-}
-
-//-----------------------------------------------------------------------------
-// Create a telekinetic beam effect from my head to an object
-// TODO: use a point attachment.
-//-----------------------------------------------------------------------------
-void C_NPC_Advisor::StartBeamFX( C_BaseEntity *pOnEntity )
-{
- Assert(pOnEntity);
- if (!pOnEntity)
- return;
-
- CNewParticleEffect *pEffect = ParticleProp()->Create( "Advisor_Psychic_Beam", PATTACH_ABSORIGIN_FOLLOW );
-
- Assert(pEffect);
- if (!pEffect) return;
-
- ParticleProp()->AddControlPoint( pEffect, 1, pOnEntity, PATTACH_ABSORIGIN_FOLLOW );
-}
-
-
-//-----------------------------------------------------------------------------
-// terminate a telekinetic beam effect from my head to an object
-//-----------------------------------------------------------------------------
-void C_NPC_Advisor::StopBeamFX( C_BaseEntity *pOnEntity )
-{
- Assert(pOnEntity);
- if (!pOnEntity)
- return;
-
- ParticleProp()->StopParticlesInvolving( pOnEntity );
-}
-
-
-
-
-
-
-void C_NPC_Advisor::StartElight()
-{
- AssertMsg(m_ElightKey == 0 , "Advisor trying to create new elight on top of old one!");
- if ( m_ElightKey != 0 )
- {
- Warning("Advisor tried to start his elight when it was already one.\n");
- }
- else
- {
- m_ElightKey = LIGHT_INDEX_TE_DYNAMIC + this->entindex();
- dlight_t * el = effects->CL_AllocElight( m_ElightKey );
-
- if ( el )
- {
- // create an elight on top of me
- el->origin = this->WorldSpaceCenter();
-
- el->color.r = 235;
- el->color.g = 255;
- el->color.b = 255;
- el->color.exponent = 3;
-
- el->radius = 52*12;
- el->decay = 0.0f;
- el->die = gpGlobals->curtime + 2000.0f; // 1000 just means " a long time "
-
- SetNextClientThink( CLIENT_THINK_ALWAYS );
- }
- else
- { // null out the light value
- m_ElightKey = 0;
- }
- }
-}
-
-void C_NPC_Advisor::StopElight()
-{
- AssertMsg( m_ElightKey != 0, "Advisor tried to stop elight when none existed!");
- dlight_t * el;
- // note: the following conditional sets el if not short-circuited
- if ( m_ElightKey == 0 || (el = effects->GetElightByKey(m_ElightKey)) == NULL )
- {
- Warning("Advisor tried to stop its elight when it had none.\n");
- }
- else
- {
- // kill the elight by setting the die value to now
- el->die = gpGlobals->curtime;
- }
-}
-
-
-#endif
-
-/******************************************************
- * Tenser, said the Tensor. *
- * Tenser, said the Tensor. *
- * Tension, apprehension and dissension have begun. *
- ******************************************************/
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Definition for client-side advisor. +// +//=====================================================================================// + + + +#include "cbase.h" +// this file contains the definitions for the message ID constants (eg ADVISOR_MSG_START_BEAM etc) +#include "npc_advisor_shared.h" + +#if NPC_ADVISOR_HAS_BEHAVIOR + +#include "particles_simple.h" +#include "citadel_effects_shared.h" +#include "particles_attractor.h" +#include "clienteffectprecachesystem.h" +#include "c_te_effect_dispatch.h" + +#include "c_ai_basenpc.h" +#include "dlight.h" +#include "iefx.h" + + +//----------------------------------------------------------------------------- +// Purpose: unpack a networked entity index into a basehandle. +//----------------------------------------------------------------------------- +inline C_BaseEntity *IndexToEntity( int eindex ) +{ + return ClientEntityList().GetBaseEntityFromHandle(ClientEntityList().EntIndexToHandle(eindex)); +} + + + +#define ADVISOR_ELIGHT_CVARS 1 // enable/disable tuning advisor elight with console variables + +#if ADVISOR_ELIGHT_CVARS +ConVar advisor_elight_e("advisor_elight_e","3"); +ConVar advisor_elight_rfeet("advisor_elight_rfeet","52"); +#endif + + +/*! Client-side reflection of the advisor class. + */ +class C_NPC_Advisor : public C_AI_BaseNPC +{ + DECLARE_CLASS( C_NPC_Advisor, C_AI_BaseNPC ); + DECLARE_CLIENTCLASS(); + +public: + // Server to client message received + virtual void ReceiveMessage( int classID, bf_read &msg ); + virtual void ClientThink( void ); + +private: + /* + // broken into its own function so I can move it if necesasry + void Initialize(); + */ + + // start/stop beam particle effect from me to a pelting object + void StartBeamFX( C_BaseEntity *pOnEntity ); + void StopBeamFX( C_BaseEntity *pOnEntity ); + + void StartElight(); + void StopElight(); + + int m_ElightKey; // test using an elight to make the escape sequence more visible. 0 is invalid. + +}; + +IMPLEMENT_CLIENTCLASS_DT( C_NPC_Advisor, DT_NPC_Advisor, CNPC_Advisor ) + +END_RECV_TABLE() + +// Server to client message received +void C_NPC_Advisor::ReceiveMessage( int classID, bf_read &msg ) +{ + if ( classID != GetClientClass()->m_ClassID ) + { + // message is for subclass + BaseClass::ReceiveMessage( classID, msg ); + return; + } + + int messageType = msg.ReadByte(); + switch( messageType ) + { + case ADVISOR_MSG_START_BEAM: + { + int eindex = msg.ReadLong(); + StartBeamFX(IndexToEntity(eindex)); + } + break; + + case ADVISOR_MSG_STOP_BEAM: + { + int eindex = msg.ReadLong(); + StopBeamFX(IndexToEntity(eindex)); + + } + break; + + case ADVISOR_MSG_STOP_ALL_BEAMS: + { + ParticleProp()->StopEmission(); + } + break; + case ADVISOR_MSG_START_ELIGHT: + { + StartElight(); + } + break; + case ADVISOR_MSG_STOP_ELIGHT: + { + StopElight(); + } + break; + + default: + AssertMsg1( false, "Received unknown message %d", messageType); + } +} + +/// only use of the clientthink on the advisor is to update the elight +void C_NPC_Advisor::ClientThink( void ) +{ + // if the elight has gone away, bail out + if (m_ElightKey == 0) + { + SetNextClientThink( CLIENT_THINK_NEVER ); + return; + } + + // get the elight + dlight_t * el = effects->GetElightByKey(m_ElightKey); + if (!el) + { + // the elight has been invalidated. bail out. + m_ElightKey = 0; + + SetNextClientThink( CLIENT_THINK_NEVER ); + return; + } + else + { + el->origin = WorldSpaceCenter(); + +#if ADVISOR_ELIGHT_CVARS + el->color.exponent = advisor_elight_e.GetFloat(); + el->radius = advisor_elight_rfeet.GetFloat() * 12.0f; +#endif + } +} + +//----------------------------------------------------------------------------- +// Create a telekinetic beam effect from my head to an object +// TODO: use a point attachment. +//----------------------------------------------------------------------------- +void C_NPC_Advisor::StartBeamFX( C_BaseEntity *pOnEntity ) +{ + Assert(pOnEntity); + if (!pOnEntity) + return; + + CNewParticleEffect *pEffect = ParticleProp()->Create( "Advisor_Psychic_Beam", PATTACH_ABSORIGIN_FOLLOW ); + + Assert(pEffect); + if (!pEffect) return; + + ParticleProp()->AddControlPoint( pEffect, 1, pOnEntity, PATTACH_ABSORIGIN_FOLLOW ); +} + + +//----------------------------------------------------------------------------- +// terminate a telekinetic beam effect from my head to an object +//----------------------------------------------------------------------------- +void C_NPC_Advisor::StopBeamFX( C_BaseEntity *pOnEntity ) +{ + Assert(pOnEntity); + if (!pOnEntity) + return; + + ParticleProp()->StopParticlesInvolving( pOnEntity ); +} + + + + + + +void C_NPC_Advisor::StartElight() +{ + AssertMsg(m_ElightKey == 0 , "Advisor trying to create new elight on top of old one!"); + if ( m_ElightKey != 0 ) + { + Warning("Advisor tried to start his elight when it was already one.\n"); + } + else + { + m_ElightKey = LIGHT_INDEX_TE_DYNAMIC + this->entindex(); + dlight_t * el = effects->CL_AllocElight( m_ElightKey ); + + if ( el ) + { + // create an elight on top of me + el->origin = this->WorldSpaceCenter(); + + el->color.r = 235; + el->color.g = 255; + el->color.b = 255; + el->color.exponent = 3; + + el->radius = 52*12; + el->decay = 0.0f; + el->die = gpGlobals->curtime + 2000.0f; // 1000 just means " a long time " + + SetNextClientThink( CLIENT_THINK_ALWAYS ); + } + else + { // null out the light value + m_ElightKey = 0; + } + } +} + +void C_NPC_Advisor::StopElight() +{ + AssertMsg( m_ElightKey != 0, "Advisor tried to stop elight when none existed!"); + dlight_t * el; + // note: the following conditional sets el if not short-circuited + if ( m_ElightKey == 0 || (el = effects->GetElightByKey(m_ElightKey)) == NULL ) + { + Warning("Advisor tried to stop its elight when it had none.\n"); + } + else + { + // kill the elight by setting the die value to now + el->die = gpGlobals->curtime; + } +} + + +#endif + +/****************************************************** + * Tenser, said the Tensor. * + * Tenser, said the Tensor. * + * Tension, apprehension and dissension have begun. * + ******************************************************/ diff --git a/mp/src/game/client/episodic/c_npc_puppet.cpp b/mp/src/game/client/episodic/c_npc_puppet.cpp index 4fa38ecd..193b1da2 100644 --- a/mp/src/game/client/episodic/c_npc_puppet.cpp +++ b/mp/src/game/client/episodic/c_npc_puppet.cpp @@ -1,167 +1,167 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================
-
-#include "cbase.h"
-#include "c_ai_basenpc.h"
-#include "bone_setup.h"
-
-// Must be the last file included
-#include "memdbgon.h"
-
-
-extern ConVar r_sequence_debug;
-
-class C_NPC_Puppet : public C_AI_BaseNPC
-{
- DECLARE_CLASS( C_NPC_Puppet, C_AI_BaseNPC );
-public:
-
- virtual void ClientThink( void );
- virtual void OnDataChanged( DataUpdateType_t updateType );
- virtual void BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed );
- virtual void AccumulateLayers( IBoneSetup &boneSetup, Vector pos[], Quaternion q[], float currentTime );
-
- EHANDLE m_hAnimationTarget;
- int m_nTargetAttachment;
-
- DECLARE_CLIENTCLASS();
-};
-
-IMPLEMENT_CLIENTCLASS_DT( C_NPC_Puppet, DT_NPC_Puppet, CNPC_Puppet )
- RecvPropEHandle( RECVINFO(m_hAnimationTarget) ),
- RecvPropInt( RECVINFO(m_nTargetAttachment) ),
-END_RECV_TABLE()
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_NPC_Puppet::OnDataChanged( DataUpdateType_t updateType )
-{
- BaseClass::OnDataChanged( updateType );
-
- if ( updateType == DATA_UPDATE_CREATED )
- {
- SetNextClientThink( CLIENT_THINK_ALWAYS );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: We need to slam our position!
-//-----------------------------------------------------------------------------
-void C_NPC_Puppet::BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed )
-{
- if ( m_hAnimationTarget && m_nTargetAttachment != -1 )
- {
- C_BaseAnimating *pTarget = m_hAnimationTarget->GetBaseAnimating();
- if ( pTarget )
- {
- matrix3x4_t matTarget;
- pTarget->GetAttachment( m_nTargetAttachment, matTarget );
-
- MatrixCopy( matTarget, GetBoneForWrite( 0 ) );
- boneComputed.ClearAll(); // FIXME: Why is this calculated already?
- boneComputed.MarkBone( 0 );
- }
- }
-
- // Call the baseclass
- BaseClass::BuildTransformations( pStudioHdr, pos, q, cameraTransform, boneMask, boneComputed );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_NPC_Puppet::ClientThink( void )
-{
- if ( m_hAnimationTarget == NULL )
- return;
-
- C_BaseAnimating *pTarget = m_hAnimationTarget->GetBaseAnimating();
- if ( pTarget == NULL )
- return;
-
- int nTargetSequence = pTarget->GetSequence();
- const char *pSequenceName = pTarget->GetSequenceName( nTargetSequence );
-
- int nSequence = LookupSequence( pSequenceName );
- if ( nSequence >= 0 )
- {
- if ( nSequence != GetSequence() )
- {
- SetSequence( nSequence );
- UpdateVisibility();
- }
-
- SetCycle( pTarget->GetCycle() );
- SetPlaybackRate( pTarget->GetPlaybackRate() );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_NPC_Puppet::AccumulateLayers( IBoneSetup &boneSetup, Vector pos[], Quaternion q[], float currentTime )
-{
- if ( m_hAnimationTarget == NULL )
- return;
-
- C_BaseAnimatingOverlay *pTarget = dynamic_cast<C_BaseAnimatingOverlay *>( m_hAnimationTarget->GetBaseAnimating() );
- if ( pTarget == NULL )
- return;
-
- // resort the layers
- int layer[MAX_OVERLAYS];
- int i;
- for (i = 0; i < MAX_OVERLAYS; i++)
- {
- layer[i] = MAX_OVERLAYS;
- }
- for (i = 0; i < pTarget->m_AnimOverlay.Count(); i++)
- {
- if (pTarget->m_AnimOverlay[i].m_nOrder < MAX_OVERLAYS)
- {
- layer[pTarget->m_AnimOverlay[i].m_nOrder] = i;
- }
- }
-
- int j;
- for (j = 0; j < MAX_OVERLAYS; j++)
- {
- i = layer[ j ];
- if (i < pTarget->m_AnimOverlay.Count())
- {
- float fWeight = pTarget->m_AnimOverlay[i].m_flWeight;
-
- if (fWeight > 0)
- {
- const char *pSequenceName = pTarget->GetSequenceName( pTarget->m_AnimOverlay[i].m_nSequence );
-
- int nSequence = LookupSequence( pSequenceName );
- if ( nSequence >= 0 )
- {
- float fCycle = pTarget->m_AnimOverlay[ i ].m_flCycle;
-
- fCycle = ClampCycle( fCycle, IsSequenceLooping( nSequence ) );
-
- if (fWeight > 1)
- fWeight = 1;
-
- boneSetup.AccumulatePose( pos, q, nSequence, fCycle, fWeight, currentTime, NULL );
-
-#if _DEBUG
- if (Q_stristr( boneSetup.GetStudioHdr()->pszName(), r_sequence_debug.GetString()) != NULL)
- {
- DevMsgRT( "%6.2f : %30s : %5.3f : %4.2f : %1d\n", currentTime, boneSetup.GetStudioHdr()->pSeqdesc( nSequence ).pszLabel(), fCycle, fWeight, i );
- }
-#endif
-
- }
- }
- }
- }
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "cbase.h" +#include "c_ai_basenpc.h" +#include "bone_setup.h" + +// Must be the last file included +#include "memdbgon.h" + + +extern ConVar r_sequence_debug; + +class C_NPC_Puppet : public C_AI_BaseNPC +{ + DECLARE_CLASS( C_NPC_Puppet, C_AI_BaseNPC ); +public: + + virtual void ClientThink( void ); + virtual void OnDataChanged( DataUpdateType_t updateType ); + virtual void BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed ); + virtual void AccumulateLayers( IBoneSetup &boneSetup, Vector pos[], Quaternion q[], float currentTime ); + + EHANDLE m_hAnimationTarget; + int m_nTargetAttachment; + + DECLARE_CLIENTCLASS(); +}; + +IMPLEMENT_CLIENTCLASS_DT( C_NPC_Puppet, DT_NPC_Puppet, CNPC_Puppet ) + RecvPropEHandle( RECVINFO(m_hAnimationTarget) ), + RecvPropInt( RECVINFO(m_nTargetAttachment) ), +END_RECV_TABLE() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_NPC_Puppet::OnDataChanged( DataUpdateType_t updateType ) +{ + BaseClass::OnDataChanged( updateType ); + + if ( updateType == DATA_UPDATE_CREATED ) + { + SetNextClientThink( CLIENT_THINK_ALWAYS ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: We need to slam our position! +//----------------------------------------------------------------------------- +void C_NPC_Puppet::BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed ) +{ + if ( m_hAnimationTarget && m_nTargetAttachment != -1 ) + { + C_BaseAnimating *pTarget = m_hAnimationTarget->GetBaseAnimating(); + if ( pTarget ) + { + matrix3x4_t matTarget; + pTarget->GetAttachment( m_nTargetAttachment, matTarget ); + + MatrixCopy( matTarget, GetBoneForWrite( 0 ) ); + boneComputed.ClearAll(); // FIXME: Why is this calculated already? + boneComputed.MarkBone( 0 ); + } + } + + // Call the baseclass + BaseClass::BuildTransformations( pStudioHdr, pos, q, cameraTransform, boneMask, boneComputed ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_NPC_Puppet::ClientThink( void ) +{ + if ( m_hAnimationTarget == NULL ) + return; + + C_BaseAnimating *pTarget = m_hAnimationTarget->GetBaseAnimating(); + if ( pTarget == NULL ) + return; + + int nTargetSequence = pTarget->GetSequence(); + const char *pSequenceName = pTarget->GetSequenceName( nTargetSequence ); + + int nSequence = LookupSequence( pSequenceName ); + if ( nSequence >= 0 ) + { + if ( nSequence != GetSequence() ) + { + SetSequence( nSequence ); + UpdateVisibility(); + } + + SetCycle( pTarget->GetCycle() ); + SetPlaybackRate( pTarget->GetPlaybackRate() ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_NPC_Puppet::AccumulateLayers( IBoneSetup &boneSetup, Vector pos[], Quaternion q[], float currentTime ) +{ + if ( m_hAnimationTarget == NULL ) + return; + + C_BaseAnimatingOverlay *pTarget = dynamic_cast<C_BaseAnimatingOverlay *>( m_hAnimationTarget->GetBaseAnimating() ); + if ( pTarget == NULL ) + return; + + // resort the layers + int layer[MAX_OVERLAYS]; + int i; + for (i = 0; i < MAX_OVERLAYS; i++) + { + layer[i] = MAX_OVERLAYS; + } + for (i = 0; i < pTarget->m_AnimOverlay.Count(); i++) + { + if (pTarget->m_AnimOverlay[i].m_nOrder < MAX_OVERLAYS) + { + layer[pTarget->m_AnimOverlay[i].m_nOrder] = i; + } + } + + int j; + for (j = 0; j < MAX_OVERLAYS; j++) + { + i = layer[ j ]; + if (i < pTarget->m_AnimOverlay.Count()) + { + float fWeight = pTarget->m_AnimOverlay[i].m_flWeight; + + if (fWeight > 0) + { + const char *pSequenceName = pTarget->GetSequenceName( pTarget->m_AnimOverlay[i].m_nSequence ); + + int nSequence = LookupSequence( pSequenceName ); + if ( nSequence >= 0 ) + { + float fCycle = pTarget->m_AnimOverlay[ i ].m_flCycle; + + fCycle = ClampCycle( fCycle, IsSequenceLooping( nSequence ) ); + + if (fWeight > 1) + fWeight = 1; + + boneSetup.AccumulatePose( pos, q, nSequence, fCycle, fWeight, currentTime, NULL ); + +#if _DEBUG + if (Q_stristr( boneSetup.GetStudioHdr()->pszName(), r_sequence_debug.GetString()) != NULL) + { + DevMsgRT( "%6.2f : %30s : %5.3f : %4.2f : %1d\n", currentTime, boneSetup.GetStudioHdr()->pSeqdesc( nSequence ).pszLabel(), fCycle, fWeight, i ); + } +#endif + + } + } + } + } +} + diff --git a/mp/src/game/client/episodic/c_prop_coreball.cpp b/mp/src/game/client/episodic/c_prop_coreball.cpp index 81a7a85a..a8ec7dc9 100644 --- a/mp/src/game/client/episodic/c_prop_coreball.cpp +++ b/mp/src/game/client/episodic/c_prop_coreball.cpp @@ -1,142 +1,142 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================
-
-#include "cbase.h"
-
-class C_PropCoreBall : public C_BaseAnimating
-{
- DECLARE_CLASS( C_PropCoreBall, C_BaseAnimating );
- DECLARE_CLIENTCLASS();
- DECLARE_DATADESC();
-
-public:
-
- C_PropCoreBall();
-
- void ApplyBoneMatrixTransform( matrix3x4_t& transform );
-
- float m_flScaleX;
- float m_flScaleY;
- float m_flScaleZ;
-
- float m_flLerpTimeX;
- float m_flLerpTimeY;
- float m_flLerpTimeZ;
-
- float m_flGoalTimeX;
- float m_flGoalTimeY;
- float m_flGoalTimeZ;
-
- float m_flCurrentScale[3];
- bool m_bRunningScale[3];
- float m_flTargetScale[3];
-
-private:
-
-};
-
-void RecvProxy_ScaleX( const CRecvProxyData *pData, void *pStruct, void *pOut )
-{
- C_PropCoreBall *pCoreData = (C_PropCoreBall *) pStruct;
-
- pCoreData->m_flScaleX = pData->m_Value.m_Float;
-
- if ( pCoreData->m_bRunningScale[0] == true )
- {
- pCoreData->m_flTargetScale[0] = pCoreData->m_flCurrentScale[0];
- }
-}
-
-void RecvProxy_ScaleY( const CRecvProxyData *pData, void *pStruct, void *pOut )
-{
- C_PropCoreBall *pCoreData = (C_PropCoreBall *) pStruct;
-
- pCoreData->m_flScaleY = pData->m_Value.m_Float;
-
- if ( pCoreData->m_bRunningScale[1] == true )
- {
- pCoreData->m_flTargetScale[1] = pCoreData->m_flCurrentScale[1];
- }
-}
-
-void RecvProxy_ScaleZ( const CRecvProxyData *pData, void *pStruct, void *pOut )
-{
- C_PropCoreBall *pCoreData = (C_PropCoreBall *) pStruct;
-
- pCoreData->m_flScaleZ = pData->m_Value.m_Float;
-
- if ( pCoreData->m_bRunningScale[2] == true )
- {
- pCoreData->m_flTargetScale[2] = pCoreData->m_flCurrentScale[2];
- }
-}
-
-IMPLEMENT_CLIENTCLASS_DT( C_PropCoreBall, DT_PropCoreBall, CPropCoreBall )
- RecvPropFloat( RECVINFO( m_flScaleX ), 0, RecvProxy_ScaleX ),
- RecvPropFloat( RECVINFO( m_flScaleY ), 0, RecvProxy_ScaleY ),
- RecvPropFloat( RECVINFO( m_flScaleZ ), 0, RecvProxy_ScaleZ ),
-
- RecvPropFloat( RECVINFO( m_flLerpTimeX ) ),
- RecvPropFloat( RECVINFO( m_flLerpTimeY ) ),
- RecvPropFloat( RECVINFO( m_flLerpTimeZ ) ),
-
- RecvPropFloat( RECVINFO( m_flGoalTimeX ) ),
- RecvPropFloat( RECVINFO( m_flGoalTimeY ) ),
- RecvPropFloat( RECVINFO( m_flGoalTimeZ ) ),
-END_RECV_TABLE()
-
-
-BEGIN_DATADESC( C_PropCoreBall )
- DEFINE_AUTO_ARRAY( m_flTargetScale, FIELD_FLOAT ),
- DEFINE_AUTO_ARRAY( m_bRunningScale, FIELD_BOOLEAN ),
-END_DATADESC()
-
-C_PropCoreBall::C_PropCoreBall( void )
-{
- m_flTargetScale[0] = 1.0f;
- m_flTargetScale[1] = 1.0f;
- m_flTargetScale[2] = 1.0f;
-
- m_bRunningScale[0] = false;
- m_bRunningScale[1] = false;
- m_bRunningScale[2] = false;
-}
-
-void C_PropCoreBall::ApplyBoneMatrixTransform( matrix3x4_t& transform )
-{
- BaseClass::ApplyBoneMatrixTransform( transform );
-
- float flVal[3] = { m_flTargetScale[0], m_flTargetScale[1], m_flTargetScale[2] };
- float *flTargetScale[3] = { &m_flTargetScale[0], &m_flTargetScale[1], &m_flTargetScale[2] };
- float flScale[3] = { m_flScaleX, m_flScaleY, m_flScaleZ };
- float flLerpTime[3] = { m_flLerpTimeX, m_flLerpTimeY, m_flLerpTimeZ };
- float flGoalTime[3] = { m_flGoalTimeX, m_flGoalTimeY, m_flGoalTimeZ };
- bool *bRunning[3] = { &m_bRunningScale[0], &m_bRunningScale[1], &m_bRunningScale[2] };
-
- for ( int i = 0; i < 3; i++ )
- {
- if ( *flTargetScale[i] != flScale[i] )
- {
- float deltaTime = (float)( gpGlobals->curtime - flGoalTime[i]) / flLerpTime[i];
- float flRemapVal = SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, *flTargetScale[i], flScale[i] );
-
- *bRunning[i] = true;
-
- if ( deltaTime >= 1.0f )
- {
- *flTargetScale[i] = flScale[i];
- *bRunning[i] = false;
- }
-
- flVal[i] = flRemapVal;
- m_flCurrentScale[i] = flVal[i];
- }
- }
-
- VectorScale( transform[0], flVal[0], transform[0] );
- VectorScale( transform[1], flVal[1], transform[1] );
- VectorScale( transform[2], flVal[2], transform[2] );
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "cbase.h" + +class C_PropCoreBall : public C_BaseAnimating +{ + DECLARE_CLASS( C_PropCoreBall, C_BaseAnimating ); + DECLARE_CLIENTCLASS(); + DECLARE_DATADESC(); + +public: + + C_PropCoreBall(); + + void ApplyBoneMatrixTransform( matrix3x4_t& transform ); + + float m_flScaleX; + float m_flScaleY; + float m_flScaleZ; + + float m_flLerpTimeX; + float m_flLerpTimeY; + float m_flLerpTimeZ; + + float m_flGoalTimeX; + float m_flGoalTimeY; + float m_flGoalTimeZ; + + float m_flCurrentScale[3]; + bool m_bRunningScale[3]; + float m_flTargetScale[3]; + +private: + +}; + +void RecvProxy_ScaleX( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + C_PropCoreBall *pCoreData = (C_PropCoreBall *) pStruct; + + pCoreData->m_flScaleX = pData->m_Value.m_Float; + + if ( pCoreData->m_bRunningScale[0] == true ) + { + pCoreData->m_flTargetScale[0] = pCoreData->m_flCurrentScale[0]; + } +} + +void RecvProxy_ScaleY( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + C_PropCoreBall *pCoreData = (C_PropCoreBall *) pStruct; + + pCoreData->m_flScaleY = pData->m_Value.m_Float; + + if ( pCoreData->m_bRunningScale[1] == true ) + { + pCoreData->m_flTargetScale[1] = pCoreData->m_flCurrentScale[1]; + } +} + +void RecvProxy_ScaleZ( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + C_PropCoreBall *pCoreData = (C_PropCoreBall *) pStruct; + + pCoreData->m_flScaleZ = pData->m_Value.m_Float; + + if ( pCoreData->m_bRunningScale[2] == true ) + { + pCoreData->m_flTargetScale[2] = pCoreData->m_flCurrentScale[2]; + } +} + +IMPLEMENT_CLIENTCLASS_DT( C_PropCoreBall, DT_PropCoreBall, CPropCoreBall ) + RecvPropFloat( RECVINFO( m_flScaleX ), 0, RecvProxy_ScaleX ), + RecvPropFloat( RECVINFO( m_flScaleY ), 0, RecvProxy_ScaleY ), + RecvPropFloat( RECVINFO( m_flScaleZ ), 0, RecvProxy_ScaleZ ), + + RecvPropFloat( RECVINFO( m_flLerpTimeX ) ), + RecvPropFloat( RECVINFO( m_flLerpTimeY ) ), + RecvPropFloat( RECVINFO( m_flLerpTimeZ ) ), + + RecvPropFloat( RECVINFO( m_flGoalTimeX ) ), + RecvPropFloat( RECVINFO( m_flGoalTimeY ) ), + RecvPropFloat( RECVINFO( m_flGoalTimeZ ) ), +END_RECV_TABLE() + + +BEGIN_DATADESC( C_PropCoreBall ) + DEFINE_AUTO_ARRAY( m_flTargetScale, FIELD_FLOAT ), + DEFINE_AUTO_ARRAY( m_bRunningScale, FIELD_BOOLEAN ), +END_DATADESC() + +C_PropCoreBall::C_PropCoreBall( void ) +{ + m_flTargetScale[0] = 1.0f; + m_flTargetScale[1] = 1.0f; + m_flTargetScale[2] = 1.0f; + + m_bRunningScale[0] = false; + m_bRunningScale[1] = false; + m_bRunningScale[2] = false; +} + +void C_PropCoreBall::ApplyBoneMatrixTransform( matrix3x4_t& transform ) +{ + BaseClass::ApplyBoneMatrixTransform( transform ); + + float flVal[3] = { m_flTargetScale[0], m_flTargetScale[1], m_flTargetScale[2] }; + float *flTargetScale[3] = { &m_flTargetScale[0], &m_flTargetScale[1], &m_flTargetScale[2] }; + float flScale[3] = { m_flScaleX, m_flScaleY, m_flScaleZ }; + float flLerpTime[3] = { m_flLerpTimeX, m_flLerpTimeY, m_flLerpTimeZ }; + float flGoalTime[3] = { m_flGoalTimeX, m_flGoalTimeY, m_flGoalTimeZ }; + bool *bRunning[3] = { &m_bRunningScale[0], &m_bRunningScale[1], &m_bRunningScale[2] }; + + for ( int i = 0; i < 3; i++ ) + { + if ( *flTargetScale[i] != flScale[i] ) + { + float deltaTime = (float)( gpGlobals->curtime - flGoalTime[i]) / flLerpTime[i]; + float flRemapVal = SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, *flTargetScale[i], flScale[i] ); + + *bRunning[i] = true; + + if ( deltaTime >= 1.0f ) + { + *flTargetScale[i] = flScale[i]; + *bRunning[i] = false; + } + + flVal[i] = flRemapVal; + m_flCurrentScale[i] = flVal[i]; + } + } + + VectorScale( transform[0], flVal[0], transform[0] ); + VectorScale( transform[1], flVal[1], transform[1] ); + VectorScale( transform[2], flVal[2], transform[2] ); }
\ No newline at end of file diff --git a/mp/src/game/client/episodic/c_prop_scalable.cpp b/mp/src/game/client/episodic/c_prop_scalable.cpp index 117d5aec..d3902db3 100644 --- a/mp/src/game/client/episodic/c_prop_scalable.cpp +++ b/mp/src/game/client/episodic/c_prop_scalable.cpp @@ -1,196 +1,196 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================
-
-#include "cbase.h"
-
-class C_PropScalable : public C_BaseAnimating
-{
- DECLARE_CLASS( C_PropScalable, C_BaseAnimating );
- DECLARE_CLIENTCLASS();
- DECLARE_DATADESC();
-
-public:
-
- C_PropScalable();
-
- virtual void ApplyBoneMatrixTransform( matrix3x4_t& transform );
- virtual void GetRenderBounds( Vector &theMins, Vector &theMaxs );
-
- // Must be available to proxy functions
- float m_flScaleX;
- float m_flScaleY;
- float m_flScaleZ;
-
- float m_flLerpTimeX;
- float m_flLerpTimeY;
- float m_flLerpTimeZ;
-
- float m_flGoalTimeX;
- float m_flGoalTimeY;
- float m_flGoalTimeZ;
-
- float m_flCurrentScale[3];
- bool m_bRunningScale[3];
- float m_flTargetScale[3];
-
-private:
-
- void CalculateScale( void );
- float m_nCalcFrame; // Frame the last calculation was made at
-};
-
-void RecvProxy_ScaleX( const CRecvProxyData *pData, void *pStruct, void *pOut )
-{
- C_PropScalable *pCoreData = (C_PropScalable *) pStruct;
-
- pCoreData->m_flScaleX = pData->m_Value.m_Float;
-
- if ( pCoreData->m_bRunningScale[0] == true )
- {
- pCoreData->m_flTargetScale[0] = pCoreData->m_flCurrentScale[0];
- }
-}
-
-void RecvProxy_ScaleY( const CRecvProxyData *pData, void *pStruct, void *pOut )
-{
- C_PropScalable *pCoreData = (C_PropScalable *) pStruct;
-
- pCoreData->m_flScaleY = pData->m_Value.m_Float;
-
- if ( pCoreData->m_bRunningScale[1] == true )
- {
- pCoreData->m_flTargetScale[1] = pCoreData->m_flCurrentScale[1];
- }
-}
-
-void RecvProxy_ScaleZ( const CRecvProxyData *pData, void *pStruct, void *pOut )
-{
- C_PropScalable *pCoreData = (C_PropScalable *) pStruct;
-
- pCoreData->m_flScaleZ = pData->m_Value.m_Float;
-
- if ( pCoreData->m_bRunningScale[2] == true )
- {
- pCoreData->m_flTargetScale[2] = pCoreData->m_flCurrentScale[2];
- }
-}
-
-IMPLEMENT_CLIENTCLASS_DT( C_PropScalable, DT_PropScalable, CPropScalable )
- RecvPropFloat( RECVINFO( m_flScaleX ), 0, RecvProxy_ScaleX ),
- RecvPropFloat( RECVINFO( m_flScaleY ), 0, RecvProxy_ScaleY ),
- RecvPropFloat( RECVINFO( m_flScaleZ ), 0, RecvProxy_ScaleZ ),
-
- RecvPropFloat( RECVINFO( m_flLerpTimeX ) ),
- RecvPropFloat( RECVINFO( m_flLerpTimeY ) ),
- RecvPropFloat( RECVINFO( m_flLerpTimeZ ) ),
-
- RecvPropFloat( RECVINFO( m_flGoalTimeX ) ),
- RecvPropFloat( RECVINFO( m_flGoalTimeY ) ),
- RecvPropFloat( RECVINFO( m_flGoalTimeZ ) ),
-END_RECV_TABLE()
-
-
-BEGIN_DATADESC( C_PropScalable )
- DEFINE_AUTO_ARRAY( m_flTargetScale, FIELD_FLOAT ),
- DEFINE_AUTO_ARRAY( m_bRunningScale, FIELD_BOOLEAN ),
-END_DATADESC()
-
-C_PropScalable::C_PropScalable( void )
-{
- m_flTargetScale[0] = 1.0f;
- m_flTargetScale[1] = 1.0f;
- m_flTargetScale[2] = 1.0f;
-
- m_bRunningScale[0] = false;
- m_bRunningScale[1] = false;
- m_bRunningScale[2] = false;
-
- m_nCalcFrame = 0;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Calculates the scake of the object once per frame
-//-----------------------------------------------------------------------------
-void C_PropScalable::CalculateScale( void )
-{
- // Don't bother to calculate this for a second time in the same frame
- if ( m_nCalcFrame == gpGlobals->framecount )
- return;
-
- // Mark that we cached this value for the frame
- m_nCalcFrame = gpGlobals->framecount;
-
- float flVal[3] = { m_flTargetScale[0], m_flTargetScale[1], m_flTargetScale[2] };
- float *flTargetScale[3] = { &m_flTargetScale[0], &m_flTargetScale[1], &m_flTargetScale[2] };
- float flScale[3] = { m_flScaleX, m_flScaleY, m_flScaleZ };
- float flLerpTime[3] = { m_flLerpTimeX, m_flLerpTimeY, m_flLerpTimeZ };
- float flGoalTime[3] = { m_flGoalTimeX, m_flGoalTimeY, m_flGoalTimeZ };
- bool *bRunning[3] = { &m_bRunningScale[0], &m_bRunningScale[1], &m_bRunningScale[2] };
-
- for ( int i = 0; i < 3; i++ )
- {
- if ( *flTargetScale[i] != flScale[i] )
- {
- float deltaTime = (float)( gpGlobals->curtime - flGoalTime[i]) / flLerpTime[i];
- float flRemapVal = SimpleSplineRemapValClamped( deltaTime, 0.0f, 1.0f, *flTargetScale[i], flScale[i] );
-
- *bRunning[i] = true;
-
- if ( deltaTime >= 1.0f )
- {
- *flTargetScale[i] = flScale[i];
- *bRunning[i] = false;
- }
-
- flVal[i] = flRemapVal;
- m_flCurrentScale[i] = flVal[i];
- }
- else
- {
- m_flCurrentScale[i] = m_flTargetScale[i];
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Scales the bones based on the current scales
-//-----------------------------------------------------------------------------
-void C_PropScalable::ApplyBoneMatrixTransform( matrix3x4_t& transform )
-{
- BaseClass::ApplyBoneMatrixTransform( transform );
-
- // Find the scale for this frame
- CalculateScale();
-
- VectorScale( transform[0], m_flCurrentScale[0], transform[0] );
- VectorScale( transform[1], m_flCurrentScale[1], transform[1] );
- VectorScale( transform[2], m_flCurrentScale[2], transform[2] );
-
- UpdateVisibility();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Ensures the render bounds match the scales
-//-----------------------------------------------------------------------------
-void C_PropScalable::GetRenderBounds( Vector &theMins, Vector &theMaxs )
-{
- BaseClass::GetRenderBounds( theMins, theMaxs );
-
- // Find the scale for this frame
- CalculateScale();
-
- // Extend our render bounds to encompass the scaled object
- theMins.x *= m_flCurrentScale[0];
- theMins.y *= m_flCurrentScale[1];
- theMins.z *= m_flCurrentScale[2];
-
- theMaxs.x *= m_flCurrentScale[0];
- theMaxs.y *= m_flCurrentScale[1];
- theMaxs.z *= m_flCurrentScale[2];
-
- Assert( theMins.IsValid() && theMaxs.IsValid() );
-
-}
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "cbase.h" + +class C_PropScalable : public C_BaseAnimating +{ + DECLARE_CLASS( C_PropScalable, C_BaseAnimating ); + DECLARE_CLIENTCLASS(); + DECLARE_DATADESC(); + +public: + + C_PropScalable(); + + virtual void ApplyBoneMatrixTransform( matrix3x4_t& transform ); + virtual void GetRenderBounds( Vector &theMins, Vector &theMaxs ); + + // Must be available to proxy functions + float m_flScaleX; + float m_flScaleY; + float m_flScaleZ; + + float m_flLerpTimeX; + float m_flLerpTimeY; + float m_flLerpTimeZ; + + float m_flGoalTimeX; + float m_flGoalTimeY; + float m_flGoalTimeZ; + + float m_flCurrentScale[3]; + bool m_bRunningScale[3]; + float m_flTargetScale[3]; + +private: + + void CalculateScale( void ); + float m_nCalcFrame; // Frame the last calculation was made at +}; + +void RecvProxy_ScaleX( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + C_PropScalable *pCoreData = (C_PropScalable *) pStruct; + + pCoreData->m_flScaleX = pData->m_Value.m_Float; + + if ( pCoreData->m_bRunningScale[0] == true ) + { + pCoreData->m_flTargetScale[0] = pCoreData->m_flCurrentScale[0]; + } +} + +void RecvProxy_ScaleY( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + C_PropScalable *pCoreData = (C_PropScalable *) pStruct; + + pCoreData->m_flScaleY = pData->m_Value.m_Float; + + if ( pCoreData->m_bRunningScale[1] == true ) + { + pCoreData->m_flTargetScale[1] = pCoreData->m_flCurrentScale[1]; + } +} + +void RecvProxy_ScaleZ( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + C_PropScalable *pCoreData = (C_PropScalable *) pStruct; + + pCoreData->m_flScaleZ = pData->m_Value.m_Float; + + if ( pCoreData->m_bRunningScale[2] == true ) + { + pCoreData->m_flTargetScale[2] = pCoreData->m_flCurrentScale[2]; + } +} + +IMPLEMENT_CLIENTCLASS_DT( C_PropScalable, DT_PropScalable, CPropScalable ) + RecvPropFloat( RECVINFO( m_flScaleX ), 0, RecvProxy_ScaleX ), + RecvPropFloat( RECVINFO( m_flScaleY ), 0, RecvProxy_ScaleY ), + RecvPropFloat( RECVINFO( m_flScaleZ ), 0, RecvProxy_ScaleZ ), + + RecvPropFloat( RECVINFO( m_flLerpTimeX ) ), + RecvPropFloat( RECVINFO( m_flLerpTimeY ) ), + RecvPropFloat( RECVINFO( m_flLerpTimeZ ) ), + + RecvPropFloat( RECVINFO( m_flGoalTimeX ) ), + RecvPropFloat( RECVINFO( m_flGoalTimeY ) ), + RecvPropFloat( RECVINFO( m_flGoalTimeZ ) ), +END_RECV_TABLE() + + +BEGIN_DATADESC( C_PropScalable ) + DEFINE_AUTO_ARRAY( m_flTargetScale, FIELD_FLOAT ), + DEFINE_AUTO_ARRAY( m_bRunningScale, FIELD_BOOLEAN ), +END_DATADESC() + +C_PropScalable::C_PropScalable( void ) +{ + m_flTargetScale[0] = 1.0f; + m_flTargetScale[1] = 1.0f; + m_flTargetScale[2] = 1.0f; + + m_bRunningScale[0] = false; + m_bRunningScale[1] = false; + m_bRunningScale[2] = false; + + m_nCalcFrame = 0; +} + +//----------------------------------------------------------------------------- +// Purpose: Calculates the scake of the object once per frame +//----------------------------------------------------------------------------- +void C_PropScalable::CalculateScale( void ) +{ + // Don't bother to calculate this for a second time in the same frame + if ( m_nCalcFrame == gpGlobals->framecount ) + return; + + // Mark that we cached this value for the frame + m_nCalcFrame = gpGlobals->framecount; + + float flVal[3] = { m_flTargetScale[0], m_flTargetScale[1], m_flTargetScale[2] }; + float *flTargetScale[3] = { &m_flTargetScale[0], &m_flTargetScale[1], &m_flTargetScale[2] }; + float flScale[3] = { m_flScaleX, m_flScaleY, m_flScaleZ }; + float flLerpTime[3] = { m_flLerpTimeX, m_flLerpTimeY, m_flLerpTimeZ }; + float flGoalTime[3] = { m_flGoalTimeX, m_flGoalTimeY, m_flGoalTimeZ }; + bool *bRunning[3] = { &m_bRunningScale[0], &m_bRunningScale[1], &m_bRunningScale[2] }; + + for ( int i = 0; i < 3; i++ ) + { + if ( *flTargetScale[i] != flScale[i] ) + { + float deltaTime = (float)( gpGlobals->curtime - flGoalTime[i]) / flLerpTime[i]; + float flRemapVal = SimpleSplineRemapValClamped( deltaTime, 0.0f, 1.0f, *flTargetScale[i], flScale[i] ); + + *bRunning[i] = true; + + if ( deltaTime >= 1.0f ) + { + *flTargetScale[i] = flScale[i]; + *bRunning[i] = false; + } + + flVal[i] = flRemapVal; + m_flCurrentScale[i] = flVal[i]; + } + else + { + m_flCurrentScale[i] = m_flTargetScale[i]; + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Scales the bones based on the current scales +//----------------------------------------------------------------------------- +void C_PropScalable::ApplyBoneMatrixTransform( matrix3x4_t& transform ) +{ + BaseClass::ApplyBoneMatrixTransform( transform ); + + // Find the scale for this frame + CalculateScale(); + + VectorScale( transform[0], m_flCurrentScale[0], transform[0] ); + VectorScale( transform[1], m_flCurrentScale[1], transform[1] ); + VectorScale( transform[2], m_flCurrentScale[2], transform[2] ); + + UpdateVisibility(); +} + +//----------------------------------------------------------------------------- +// Purpose: Ensures the render bounds match the scales +//----------------------------------------------------------------------------- +void C_PropScalable::GetRenderBounds( Vector &theMins, Vector &theMaxs ) +{ + BaseClass::GetRenderBounds( theMins, theMaxs ); + + // Find the scale for this frame + CalculateScale(); + + // Extend our render bounds to encompass the scaled object + theMins.x *= m_flCurrentScale[0]; + theMins.y *= m_flCurrentScale[1]; + theMins.z *= m_flCurrentScale[2]; + + theMaxs.x *= m_flCurrentScale[0]; + theMaxs.y *= m_flCurrentScale[1]; + theMaxs.z *= m_flCurrentScale[2]; + + Assert( theMins.IsValid() && theMaxs.IsValid() ); + +} diff --git a/mp/src/game/client/episodic/c_vehicle_jeep_episodic.cpp b/mp/src/game/client/episodic/c_vehicle_jeep_episodic.cpp index 4627bbfb..66beface 100644 --- a/mp/src/game/client/episodic/c_vehicle_jeep_episodic.cpp +++ b/mp/src/game/client/episodic/c_vehicle_jeep_episodic.cpp @@ -1,133 +1,133 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "c_prop_vehicle.h"
-#include "c_vehicle_jeep.h"
-#include "movevars_shared.h"
-#include "view.h"
-#include "flashlighteffect.h"
-#include "c_baseplayer.h"
-#include "c_te_effect_dispatch.h"
-#include "hl2_vehicle_radar.h"
-#include "usermessages.h"
-#include "hud_radar.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//=============================================================================
-//
-// Client-side Episodic Jeep (Jalopy) Class
-//
-class C_PropJeepEpisodic : public C_PropJeep
-{
-
- DECLARE_CLASS( C_PropJeepEpisodic, C_PropJeep );
-
-public:
- DECLARE_CLIENTCLASS();
-
-public:
- C_PropJeepEpisodic();
-
- void OnEnteredVehicle( C_BasePlayer *pPlayer );
- void Simulate( void );
-
-public:
- int m_iNumRadarContacts;
- Vector m_vecRadarContactPos[ RADAR_MAX_CONTACTS ];
- int m_iRadarContactType[ RADAR_MAX_CONTACTS ];
-};
-C_PropJeepEpisodic *g_pJalopy = NULL;
-
-IMPLEMENT_CLIENTCLASS_DT( C_PropJeepEpisodic, DT_CPropJeepEpisodic, CPropJeepEpisodic )
- //CNetworkVar( int, m_iNumRadarContacts );
- RecvPropInt( RECVINFO(m_iNumRadarContacts) ),
-
- //CNetworkArray( Vector, m_vecRadarContactPos, RADAR_MAX_CONTACTS );
- RecvPropArray( RecvPropVector(RECVINFO(m_vecRadarContactPos[0])), m_vecRadarContactPos ),
-
- //CNetworkArray( int, m_iRadarContactType, RADAR_MAX_CONTACTS );
- RecvPropArray( RecvPropInt( RECVINFO(m_iRadarContactType[0] ) ), m_iRadarContactType ),
-
-END_RECV_TABLE()
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void __MsgFunc_UpdateJalopyRadar(bf_read &msg)
-{
- // Radar code here!
- if( !GetHudRadar() )
- return;
-
- // Sometimes we update more quickly when we need to track something in high resolution.
- // Usually we do not, so default to false.
- GetHudRadar()->m_bUseFastUpdate = false;
-
- for( int i = 0 ; i < g_pJalopy->m_iNumRadarContacts ; i++ )
- {
- if( g_pJalopy->m_iRadarContactType[i] == RADAR_CONTACT_DOG )
- {
- GetHudRadar()->m_bUseFastUpdate = true;
- break;
- }
- }
-
- float flContactTimeToLive;
-
- if( GetHudRadar()->m_bUseFastUpdate )
- {
- flContactTimeToLive = RADAR_UPDATE_FREQUENCY_FAST;
- }
- else
- {
- flContactTimeToLive = RADAR_UPDATE_FREQUENCY;
- }
-
- for( int i = 0 ; i < g_pJalopy->m_iNumRadarContacts ; i++ )
- {
- GetHudRadar()->AddRadarContact( g_pJalopy->m_vecRadarContactPos[i], g_pJalopy->m_iRadarContactType[i], flContactTimeToLive );
- }
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-C_PropJeepEpisodic::C_PropJeepEpisodic()
-{
- if( g_pJalopy == NULL )
- {
- usermessages->HookMessage( "UpdateJalopyRadar", __MsgFunc_UpdateJalopyRadar );
- }
-
- g_pJalopy = this;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_PropJeepEpisodic::Simulate( void )
-{
- // Keep trying to hook to the radar.
- if( GetHudRadar() != NULL )
- {
- // This is not our ideal long-term solution. This will only work if you only have
- // one jalopy in a given level. The Jalopy and the Radar Screen are currently both
- // assumed to be singletons. This is appropriate for EP2, however. (sjb)
- GetHudRadar()->SetVehicle( this );
- }
-
- BaseClass::Simulate();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_PropJeepEpisodic::OnEnteredVehicle( C_BasePlayer *pPlayer )
-{
- BaseClass::OnEnteredVehicle( pPlayer );
-}
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" +#include "c_prop_vehicle.h" +#include "c_vehicle_jeep.h" +#include "movevars_shared.h" +#include "view.h" +#include "flashlighteffect.h" +#include "c_baseplayer.h" +#include "c_te_effect_dispatch.h" +#include "hl2_vehicle_radar.h" +#include "usermessages.h" +#include "hud_radar.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//============================================================================= +// +// Client-side Episodic Jeep (Jalopy) Class +// +class C_PropJeepEpisodic : public C_PropJeep +{ + + DECLARE_CLASS( C_PropJeepEpisodic, C_PropJeep ); + +public: + DECLARE_CLIENTCLASS(); + +public: + C_PropJeepEpisodic(); + + void OnEnteredVehicle( C_BasePlayer *pPlayer ); + void Simulate( void ); + +public: + int m_iNumRadarContacts; + Vector m_vecRadarContactPos[ RADAR_MAX_CONTACTS ]; + int m_iRadarContactType[ RADAR_MAX_CONTACTS ]; +}; +C_PropJeepEpisodic *g_pJalopy = NULL; + +IMPLEMENT_CLIENTCLASS_DT( C_PropJeepEpisodic, DT_CPropJeepEpisodic, CPropJeepEpisodic ) + //CNetworkVar( int, m_iNumRadarContacts ); + RecvPropInt( RECVINFO(m_iNumRadarContacts) ), + + //CNetworkArray( Vector, m_vecRadarContactPos, RADAR_MAX_CONTACTS ); + RecvPropArray( RecvPropVector(RECVINFO(m_vecRadarContactPos[0])), m_vecRadarContactPos ), + + //CNetworkArray( int, m_iRadarContactType, RADAR_MAX_CONTACTS ); + RecvPropArray( RecvPropInt( RECVINFO(m_iRadarContactType[0] ) ), m_iRadarContactType ), + +END_RECV_TABLE() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void __MsgFunc_UpdateJalopyRadar(bf_read &msg) +{ + // Radar code here! + if( !GetHudRadar() ) + return; + + // Sometimes we update more quickly when we need to track something in high resolution. + // Usually we do not, so default to false. + GetHudRadar()->m_bUseFastUpdate = false; + + for( int i = 0 ; i < g_pJalopy->m_iNumRadarContacts ; i++ ) + { + if( g_pJalopy->m_iRadarContactType[i] == RADAR_CONTACT_DOG ) + { + GetHudRadar()->m_bUseFastUpdate = true; + break; + } + } + + float flContactTimeToLive; + + if( GetHudRadar()->m_bUseFastUpdate ) + { + flContactTimeToLive = RADAR_UPDATE_FREQUENCY_FAST; + } + else + { + flContactTimeToLive = RADAR_UPDATE_FREQUENCY; + } + + for( int i = 0 ; i < g_pJalopy->m_iNumRadarContacts ; i++ ) + { + GetHudRadar()->AddRadarContact( g_pJalopy->m_vecRadarContactPos[i], g_pJalopy->m_iRadarContactType[i], flContactTimeToLive ); + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +C_PropJeepEpisodic::C_PropJeepEpisodic() +{ + if( g_pJalopy == NULL ) + { + usermessages->HookMessage( "UpdateJalopyRadar", __MsgFunc_UpdateJalopyRadar ); + } + + g_pJalopy = this; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_PropJeepEpisodic::Simulate( void ) +{ + // Keep trying to hook to the radar. + if( GetHudRadar() != NULL ) + { + // This is not our ideal long-term solution. This will only work if you only have + // one jalopy in a given level. The Jalopy and the Radar Screen are currently both + // assumed to be singletons. This is appropriate for EP2, however. (sjb) + GetHudRadar()->SetVehicle( this ); + } + + BaseClass::Simulate(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_PropJeepEpisodic::OnEnteredVehicle( C_BasePlayer *pPlayer ) +{ + BaseClass::OnEnteredVehicle( pPlayer ); +} diff --git a/mp/src/game/client/episodic/c_vort_charge_token.cpp b/mp/src/game/client/episodic/c_vort_charge_token.cpp index 6085ee6e..fa769fa0 100644 --- a/mp/src/game/client/episodic/c_vort_charge_token.cpp +++ b/mp/src/game/client/episodic/c_vort_charge_token.cpp @@ -1,600 +1,600 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=====================================================================================//
-
-#include "cbase.h"
-#include "particles_simple.h"
-#include "citadel_effects_shared.h"
-#include "particles_attractor.h"
-#include "iefx.h"
-#include "dlight.h"
-#include "clienteffectprecachesystem.h"
-#include "c_te_effect_dispatch.h"
-#include "fx_quad.h"
-
-#include "c_ai_basenpc.h"
-
-// For material proxy
-#include "proxyentity.h"
-#include "materialsystem/imaterial.h"
-#include "materialsystem/imaterialvar.h"
-
-#define NUM_INTERIOR_PARTICLES 8
-
-#define DLIGHT_RADIUS (150.0f)
-#define DLIGHT_MINLIGHT (40.0f/255.0f)
-
-class C_NPC_Vortigaunt : public C_AI_BaseNPC
-{
- DECLARE_CLASS( C_NPC_Vortigaunt, C_AI_BaseNPC );
- DECLARE_CLIENTCLASS();
-
-public:
- virtual void OnDataChanged( DataUpdateType_t updateType );
- virtual void ClientThink( void );
- virtual void ReceiveMessage( int classID, bf_read &msg );
-
-public:
- bool m_bIsBlue; ///< wants to fade to blue
- float m_flBlueEndFadeTime; ///< when to end fading from one skin to another
-
- bool m_bIsBlack; ///< wants to fade to black (networked)
- float m_flBlackFade; ///< [0.00 .. 1.00] where 1.00 is all black. Locally interpolated.
-};
-
-IMPLEMENT_CLIENTCLASS_DT( C_NPC_Vortigaunt, DT_NPC_Vortigaunt, CNPC_Vortigaunt )
- RecvPropTime( RECVINFO(m_flBlueEndFadeTime ) ),
- RecvPropBool( RECVINFO(m_bIsBlue) ),
- RecvPropBool( RECVINFO(m_bIsBlack) ),
-END_RECV_TABLE()
-
-
-#define VORTIGAUNT_BLUE_FADE_TIME 2.25f // takes this long to fade from green to blue or back
-#define VORT_BLACK_FADE_TIME 2.2f // time to interpolate up or down in fading to black
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : updateType -
-//-----------------------------------------------------------------------------
-void C_NPC_Vortigaunt::OnDataChanged( DataUpdateType_t updateType )
-{
- BaseClass::OnDataChanged( updateType );
-
- // start thinking if we need to fade.
- if ( m_flBlackFade != (m_bIsBlack ? 1.0f : 0.0f) )
- {
- SetNextClientThink( CLIENT_THINK_ALWAYS );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_NPC_Vortigaunt::ClientThink( void )
-{
- // Don't update if our frame hasn't moved forward (paused)
- if ( gpGlobals->frametime <= 0.0f )
- return;
-
- if ( m_bIsBlack )
- {
- // are we done?
- if ( m_flBlackFade >= 1.0f )
- {
- m_flBlackFade = 1.0f;
- SetNextClientThink( CLIENT_THINK_NEVER );
- }
- else // interpolate there
- {
- float lerpQuant = gpGlobals->frametime / VORT_BLACK_FADE_TIME;
- m_flBlackFade += lerpQuant;
- if ( m_flBlackFade > 1.0f )
- {
- m_flBlackFade = 1.0f;
- }
- }
- }
- else
- {
- // are we done?
- if ( m_flBlackFade <= 0.0f )
- {
- m_flBlackFade = 0.0f;
- SetNextClientThink( CLIENT_THINK_NEVER );
- }
- else // interpolate there
- {
- float lerpQuant = gpGlobals->frametime / VORT_BLACK_FADE_TIME;
- m_flBlackFade -= lerpQuant;
- if ( m_flBlackFade < 0.0f )
- {
- m_flBlackFade = 0.0f;
- }
- }
- }
-}
-
-// FIXME: Move to shared code!
-#define VORTFX_ZAPBEAM 0
-#define VORTFX_ARMBEAM 1
-
-//-----------------------------------------------------------------------------
-// Purpose: Receive messages from the server
-//-----------------------------------------------------------------------------
-void C_NPC_Vortigaunt::ReceiveMessage( int classID, bf_read &msg )
-{
- // Is the message for a sub-class?
- if ( classID != GetClientClass()->m_ClassID )
- {
- BaseClass::ReceiveMessage( classID, msg );
- return;
- }
-
- int messageType = msg.ReadByte();
- switch( messageType )
- {
- case VORTFX_ZAPBEAM:
- {
- // Find our attachment point
- unsigned char nAttachment = msg.ReadByte();
-
- // Get our attachment position
- Vector vecStart;
- QAngle vecAngles;
- GetAttachment( nAttachment, vecStart, vecAngles );
-
- // Get the final position we'll strike
- Vector vecEndPos;
- msg.ReadBitVec3Coord( vecEndPos );
-
- // Place a beam between the two points
- CNewParticleEffect *pEffect = ParticleProp()->Create( "vortigaunt_beam", PATTACH_POINT_FOLLOW, nAttachment );
- if ( pEffect )
- {
- pEffect->SetControlPoint( 0, vecStart );
- pEffect->SetControlPoint( 1, vecEndPos );
- }
- }
- break;
-
- case VORTFX_ARMBEAM:
- {
- int nIndex = msg.ReadLong();
- C_BaseEntity *pEnt = ClientEntityList().GetBaseEntityFromHandle( ClientEntityList().EntIndexToHandle( nIndex ) );
-
- if ( pEnt )
- {
- unsigned char nAttachment = msg.ReadByte();
- Vector vecEndPos;
- msg.ReadBitVec3Coord( vecEndPos );
-
- Vector vecNormal;
- msg.ReadBitVec3Normal( vecNormal );
-
- CNewParticleEffect *pEffect = pEnt->ParticleProp()->Create( "vortigaunt_beam_charge", PATTACH_POINT_FOLLOW, nAttachment );
- if ( pEffect )
- {
- // Set the control point's angles to be the surface normal we struct
- Vector vecRight, vecUp;
- VectorVectors( vecNormal, vecRight, vecUp );
- pEffect->SetControlPointOrientation( 1, vecNormal, vecRight, vecUp );
- pEffect->SetControlPoint( 1, vecEndPos );
- }
- }
- }
- break;
- default:
- AssertMsg1( false, "Received unknown message %d", messageType);
- }
-}
-
-class C_VortigauntChargeToken : public C_BaseEntity
-{
- DECLARE_CLASS( C_VortigauntChargeToken, C_BaseEntity );
- DECLARE_CLIENTCLASS();
-
-public:
- virtual void UpdateOnRemove( void );
- virtual void ClientThink( void );
- virtual void NotifyShouldTransmit( ShouldTransmitState_t state );
- virtual void OnDataChanged( DataUpdateType_t type );
-
- // For RecvProxy handlers
- float m_flFadeOutTime;
- float m_flFadeOutStart;
-
-private:
- bool SetupEmitters( void );
-
- bool m_bFadeOut;
- CNewParticleEffect *m_hEffect;
- dlight_t *m_pDLight;
-};
-
-void RecvProxy_FadeOutDuration( const CRecvProxyData *pData, void *pStruct, void *pOut )
-{
- C_VortigauntChargeToken *pVortToken = (C_VortigauntChargeToken *) pStruct;
- Assert( pOut == &pVortToken->m_flFadeOutTime );
-
- pVortToken->m_flFadeOutStart = gpGlobals->curtime;
- pVortToken->m_flFadeOutTime = ( pData->m_Value.m_Float - gpGlobals->curtime );
-}
-
-IMPLEMENT_CLIENTCLASS_DT( C_VortigauntChargeToken, DT_VortigauntChargeToken, CVortigauntChargeToken )
- RecvPropBool( RECVINFO( m_bFadeOut ) ),
-END_RECV_TABLE()
-
-void C_VortigauntChargeToken::UpdateOnRemove( void )
-{
- if ( m_hEffect )
- {
- m_hEffect->StopEmission();
- m_hEffect = NULL;
- }
-
- if ( m_pDLight != NULL )
- {
- m_pDLight->die = gpGlobals->curtime;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Change our transmission state
-//-----------------------------------------------------------------------------
-void C_VortigauntChargeToken::NotifyShouldTransmit( ShouldTransmitState_t state )
-{
- BaseClass::NotifyShouldTransmit( state );
-
- // Turn off
- if ( state == SHOULDTRANSMIT_END )
- {
- if ( m_hEffect )
- {
- m_hEffect->StopEmission();
- m_hEffect = NULL;
- }
- }
-
- // Turn on
- if ( state == SHOULDTRANSMIT_START )
- {
- m_hEffect = ParticleProp()->Create( "vortigaunt_charge_token", PATTACH_ABSORIGIN_FOLLOW );
- m_hEffect->SetControlPointEntity( 0, this );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_VortigauntChargeToken::OnDataChanged( DataUpdateType_t type )
-{
- if ( m_bFadeOut )
- {
- if ( m_hEffect )
- {
- m_hEffect->StopEmission();
- m_hEffect = NULL;
- }
- }
-
- BaseClass::OnDataChanged( type );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_VortigauntChargeToken::ClientThink( void )
-{
- //
- // -- DLight
- //
-
- if ( m_pDLight != NULL )
- {
- m_pDLight->origin = GetAbsOrigin();
- m_pDLight->radius = DLIGHT_RADIUS;
- }
-}
-
-//=============================================================================
-//
-// Dispel Effect
-//
-//=============================================================================
-
-class C_VortigauntEffectDispel : public C_BaseEntity
-{
- DECLARE_CLASS( C_VortigauntEffectDispel, C_BaseEntity );
- DECLARE_CLIENTCLASS();
-
-public:
- virtual void UpdateOnRemove( void );
- virtual void ClientThink( void );
- virtual void NotifyShouldTransmit( ShouldTransmitState_t state );
- virtual void OnDataChanged( DataUpdateType_t type );
-
- // For RecvProxy handlers
- float m_flFadeOutTime;
- float m_flFadeOutStart;
-
-private:
- bool SetupEmitters( void );
-
- CNewParticleEffect *m_hEffect;
- bool m_bFadeOut;
- dlight_t *m_pDLight;
-};
-
-void RecvProxy_DispelFadeOutDuration( const CRecvProxyData *pData, void *pStruct, void *pOut )
-{
- C_VortigauntEffectDispel *pVortToken = (C_VortigauntEffectDispel *) pStruct;
- Assert( pOut == &pVortToken->m_flFadeOutTime );
-
- pVortToken->m_flFadeOutStart = gpGlobals->curtime;
- pVortToken->m_flFadeOutTime = ( pData->m_Value.m_Float - gpGlobals->curtime );
-}
-
-IMPLEMENT_CLIENTCLASS_DT( C_VortigauntEffectDispel, DT_VortigauntEffectDispel, CVortigauntEffectDispel )
- RecvPropBool( RECVINFO( m_bFadeOut ) ),
-END_RECV_TABLE()
-
-void C_VortigauntEffectDispel::UpdateOnRemove( void )
-{
- if ( m_hEffect )
- {
- m_hEffect->StopEmission();
- m_hEffect = NULL;
- }
-
- if ( m_pDLight != NULL )
- {
- m_pDLight->die = gpGlobals->curtime;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_VortigauntEffectDispel::OnDataChanged( DataUpdateType_t type )
-{
- if ( m_bFadeOut )
- {
- if ( m_hEffect )
- {
- m_hEffect->StopEmission();
- m_hEffect = NULL;
- }
- }
-
- BaseClass::OnDataChanged( type );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_VortigauntEffectDispel::NotifyShouldTransmit( ShouldTransmitState_t state )
-{
- BaseClass::NotifyShouldTransmit( state );
-
- // Turn off
- if ( state == SHOULDTRANSMIT_END )
- {
- if ( m_hEffect )
- {
- m_hEffect->StopEmission();
- m_hEffect = NULL;
- }
- }
-
- // Turn on
- if ( state == SHOULDTRANSMIT_START )
- {
- m_hEffect = ParticleProp()->Create( "vortigaunt_hand_glow", PATTACH_ABSORIGIN_FOLLOW );
- m_hEffect->SetControlPointEntity( 0, this );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Create our emitter
-//-----------------------------------------------------------------------------
-bool C_VortigauntEffectDispel::SetupEmitters( void )
-{
- m_pDLight = NULL;
-
-#ifndef _X360
- m_pDLight = effects->CL_AllocDlight ( index );
- m_pDLight->origin = GetAbsOrigin();
- m_pDLight->color.r = 64;
- m_pDLight->color.g = 255;
- m_pDLight->color.b = 64;
- m_pDLight->radius = 0;
- m_pDLight->minlight = DLIGHT_MINLIGHT;
- m_pDLight->die = FLT_MAX;
-#endif // _X360
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_VortigauntEffectDispel::ClientThink( void )
-{
- if ( m_pDLight != NULL )
- {
- m_pDLight->origin = GetAbsOrigin();
- m_pDLight->radius = DLIGHT_RADIUS;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void DispelCallback( const CEffectData &data )
-{
- // Kaboom!
- Vector startPos = data.m_vOrigin + Vector(0,0,16);
- Vector endPos = data.m_vOrigin + Vector(0,0,-64);
-
- trace_t tr;
- UTIL_TraceLine( startPos, endPos, MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &tr );
-
- if ( tr.fraction < 1.0f )
- {
- //Add a ripple quad to the surface
- FX_AddQuad( tr.endpos + ( tr.plane.normal * 8.0f ),
- Vector( 0, 0, 1 ),
- 64.0f,
- 600.0f,
- 0.8f,
- 1.0f, // start alpha
- 0.0f, // end alpha
- 0.3f,
- random->RandomFloat( 0, 360 ),
- 0.0f,
- Vector( 0.5f, 1.0f, 0.5f ),
- 0.75f,
- "effects/ar2_altfire1b",
- (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA|FXQUAD_COLOR_FADE) );
-
- //Add a ripple quad to the surface
- FX_AddQuad( tr.endpos + ( tr.plane.normal * 8.0f ),
- Vector( 0, 0, 1 ),
- 16.0f,
- 300.0f,
- 0.9f,
- 1.0f, // start alpha
- 0.0f, // end alpha
- 0.9f,
- random->RandomFloat( 0, 360 ),
- 0.0f,
- Vector( 0.5f, 1.0f, 0.5f ),
- 1.25f,
- "effects/rollerglow",
- (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
- }
-}
-
-DECLARE_CLIENT_EFFECT( "VortDispel", DispelCallback );
-
-//-----------------------------------------------------------------------------
-// Purpose: Used for emissive lightning layer on vort
-//-----------------------------------------------------------------------------
-class CVortEmissiveProxy : public CEntityMaterialProxy
-{
-public:
- CVortEmissiveProxy( void );
- virtual ~CVortEmissiveProxy( void );
- virtual bool Init( IMaterial *pMaterial, KeyValues* pKeyValues );
- virtual void OnBind( C_BaseEntity *pC_BaseEntity );
- virtual IMaterial * GetMaterial();
-
-private:
-
- IMaterialVar *m_pMatEmissiveStrength;
- IMaterialVar *m_pMatDetailBlendStrength;
-};
-
-//-----------------------------------------------------------------------------
-CVortEmissiveProxy::CVortEmissiveProxy( void )
-{
- m_pMatEmissiveStrength = NULL;
- m_pMatDetailBlendStrength = NULL;
-}
-
-CVortEmissiveProxy::~CVortEmissiveProxy( void )
-{
- // Do nothing
-}
-
-//-----------------------------------------------------------------------------
-bool CVortEmissiveProxy::Init( IMaterial *pMaterial, KeyValues* pKeyValues )
-{
- Assert( pMaterial );
-
- // Need to get the material var
- bool bFound;
- m_pMatEmissiveStrength = pMaterial->FindVar( "$emissiveblendstrength", &bFound );
-
- if ( bFound )
- {
- // Optional
- bool bFound2;
- m_pMatDetailBlendStrength = pMaterial->FindVar( "$detailblendfactor", &bFound2 );
- }
-
- return bFound;
-}
-
-//-----------------------------------------------------------------------------
-void CVortEmissiveProxy::OnBind( C_BaseEntity *pEnt )
-{
- C_NPC_Vortigaunt *pVort = dynamic_cast<C_NPC_Vortigaunt *>(pEnt);
-
- float flBlendValue;
-
- if (pVort)
- {
- // do we need to crossfade?
- if (gpGlobals->curtime < pVort->m_flBlueEndFadeTime)
- {
- // will be 0 when fully faded and 1 when not faded at all:
- float fadeRatio = (pVort->m_flBlueEndFadeTime - gpGlobals->curtime) / VORTIGAUNT_BLUE_FADE_TIME;
- if (pVort->m_bIsBlue)
- {
- fadeRatio = 1.0f - fadeRatio;
- }
- flBlendValue = clamp( fadeRatio, 0.0f, 1.0f );
- }
- else // no crossfade
- {
- flBlendValue = pVort->m_bIsBlue ? 1.0f : 0.0f;
- }
-
- // ALEX VLACHOS:
- // The following variable varies on [0 .. 1]. 0.0 means the vort wants to be his normal
- // color. 1.0 means he wants to be all black. It is interpolated in the
- // C_NPC_Vortigaunt::ClientThink() function.
- //
- // pVort->m_flBlackFade
- }
- else
- { // if you bind this proxy to anything non-vort (eg a ragdoll) it's always green
- flBlendValue = 0.0f;
- }
-
-
- /*
- // !!! Change me !!! I'm using a clamped sin wave for debugging
- float flBlendValue = sinf( gpGlobals->curtime * 4.0f ) * 0.75f + 0.25f;
-
- // Clamp 0-1
- flBlendValue = ( flBlendValue < 0.0f ) ? 0.0f : ( flBlendValue > 1.0f ) ? 1.0f : flBlendValue;
- */
-
- if( m_pMatEmissiveStrength != NULL )
- {
- m_pMatEmissiveStrength->SetFloatValue( flBlendValue );
- }
-
- if( m_pMatDetailBlendStrength != NULL )
- {
- m_pMatDetailBlendStrength->SetFloatValue( flBlendValue );
- }
-}
-
-//-----------------------------------------------------------------------------
-IMaterial *CVortEmissiveProxy::GetMaterial()
-{
- if ( m_pMatEmissiveStrength != NULL )
- return m_pMatEmissiveStrength->GetOwningMaterial();
- else if ( m_pMatDetailBlendStrength != NULL )
- return m_pMatDetailBlendStrength->GetOwningMaterial();
- else
- return NULL;
-}
-
-EXPOSE_INTERFACE( CVortEmissiveProxy, IMaterialProxy, "VortEmissive" IMATERIAL_PROXY_INTERFACE_VERSION );
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=====================================================================================// + +#include "cbase.h" +#include "particles_simple.h" +#include "citadel_effects_shared.h" +#include "particles_attractor.h" +#include "iefx.h" +#include "dlight.h" +#include "clienteffectprecachesystem.h" +#include "c_te_effect_dispatch.h" +#include "fx_quad.h" + +#include "c_ai_basenpc.h" + +// For material proxy +#include "proxyentity.h" +#include "materialsystem/imaterial.h" +#include "materialsystem/imaterialvar.h" + +#define NUM_INTERIOR_PARTICLES 8 + +#define DLIGHT_RADIUS (150.0f) +#define DLIGHT_MINLIGHT (40.0f/255.0f) + +class C_NPC_Vortigaunt : public C_AI_BaseNPC +{ + DECLARE_CLASS( C_NPC_Vortigaunt, C_AI_BaseNPC ); + DECLARE_CLIENTCLASS(); + +public: + virtual void OnDataChanged( DataUpdateType_t updateType ); + virtual void ClientThink( void ); + virtual void ReceiveMessage( int classID, bf_read &msg ); + +public: + bool m_bIsBlue; ///< wants to fade to blue + float m_flBlueEndFadeTime; ///< when to end fading from one skin to another + + bool m_bIsBlack; ///< wants to fade to black (networked) + float m_flBlackFade; ///< [0.00 .. 1.00] where 1.00 is all black. Locally interpolated. +}; + +IMPLEMENT_CLIENTCLASS_DT( C_NPC_Vortigaunt, DT_NPC_Vortigaunt, CNPC_Vortigaunt ) + RecvPropTime( RECVINFO(m_flBlueEndFadeTime ) ), + RecvPropBool( RECVINFO(m_bIsBlue) ), + RecvPropBool( RECVINFO(m_bIsBlack) ), +END_RECV_TABLE() + + +#define VORTIGAUNT_BLUE_FADE_TIME 2.25f // takes this long to fade from green to blue or back +#define VORT_BLACK_FADE_TIME 2.2f // time to interpolate up or down in fading to black + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : updateType - +//----------------------------------------------------------------------------- +void C_NPC_Vortigaunt::OnDataChanged( DataUpdateType_t updateType ) +{ + BaseClass::OnDataChanged( updateType ); + + // start thinking if we need to fade. + if ( m_flBlackFade != (m_bIsBlack ? 1.0f : 0.0f) ) + { + SetNextClientThink( CLIENT_THINK_ALWAYS ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_NPC_Vortigaunt::ClientThink( void ) +{ + // Don't update if our frame hasn't moved forward (paused) + if ( gpGlobals->frametime <= 0.0f ) + return; + + if ( m_bIsBlack ) + { + // are we done? + if ( m_flBlackFade >= 1.0f ) + { + m_flBlackFade = 1.0f; + SetNextClientThink( CLIENT_THINK_NEVER ); + } + else // interpolate there + { + float lerpQuant = gpGlobals->frametime / VORT_BLACK_FADE_TIME; + m_flBlackFade += lerpQuant; + if ( m_flBlackFade > 1.0f ) + { + m_flBlackFade = 1.0f; + } + } + } + else + { + // are we done? + if ( m_flBlackFade <= 0.0f ) + { + m_flBlackFade = 0.0f; + SetNextClientThink( CLIENT_THINK_NEVER ); + } + else // interpolate there + { + float lerpQuant = gpGlobals->frametime / VORT_BLACK_FADE_TIME; + m_flBlackFade -= lerpQuant; + if ( m_flBlackFade < 0.0f ) + { + m_flBlackFade = 0.0f; + } + } + } +} + +// FIXME: Move to shared code! +#define VORTFX_ZAPBEAM 0 +#define VORTFX_ARMBEAM 1 + +//----------------------------------------------------------------------------- +// Purpose: Receive messages from the server +//----------------------------------------------------------------------------- +void C_NPC_Vortigaunt::ReceiveMessage( int classID, bf_read &msg ) +{ + // Is the message for a sub-class? + if ( classID != GetClientClass()->m_ClassID ) + { + BaseClass::ReceiveMessage( classID, msg ); + return; + } + + int messageType = msg.ReadByte(); + switch( messageType ) + { + case VORTFX_ZAPBEAM: + { + // Find our attachment point + unsigned char nAttachment = msg.ReadByte(); + + // Get our attachment position + Vector vecStart; + QAngle vecAngles; + GetAttachment( nAttachment, vecStart, vecAngles ); + + // Get the final position we'll strike + Vector vecEndPos; + msg.ReadBitVec3Coord( vecEndPos ); + + // Place a beam between the two points + CNewParticleEffect *pEffect = ParticleProp()->Create( "vortigaunt_beam", PATTACH_POINT_FOLLOW, nAttachment ); + if ( pEffect ) + { + pEffect->SetControlPoint( 0, vecStart ); + pEffect->SetControlPoint( 1, vecEndPos ); + } + } + break; + + case VORTFX_ARMBEAM: + { + int nIndex = msg.ReadLong(); + C_BaseEntity *pEnt = ClientEntityList().GetBaseEntityFromHandle( ClientEntityList().EntIndexToHandle( nIndex ) ); + + if ( pEnt ) + { + unsigned char nAttachment = msg.ReadByte(); + Vector vecEndPos; + msg.ReadBitVec3Coord( vecEndPos ); + + Vector vecNormal; + msg.ReadBitVec3Normal( vecNormal ); + + CNewParticleEffect *pEffect = pEnt->ParticleProp()->Create( "vortigaunt_beam_charge", PATTACH_POINT_FOLLOW, nAttachment ); + if ( pEffect ) + { + // Set the control point's angles to be the surface normal we struct + Vector vecRight, vecUp; + VectorVectors( vecNormal, vecRight, vecUp ); + pEffect->SetControlPointOrientation( 1, vecNormal, vecRight, vecUp ); + pEffect->SetControlPoint( 1, vecEndPos ); + } + } + } + break; + default: + AssertMsg1( false, "Received unknown message %d", messageType); + } +} + +class C_VortigauntChargeToken : public C_BaseEntity +{ + DECLARE_CLASS( C_VortigauntChargeToken, C_BaseEntity ); + DECLARE_CLIENTCLASS(); + +public: + virtual void UpdateOnRemove( void ); + virtual void ClientThink( void ); + virtual void NotifyShouldTransmit( ShouldTransmitState_t state ); + virtual void OnDataChanged( DataUpdateType_t type ); + + // For RecvProxy handlers + float m_flFadeOutTime; + float m_flFadeOutStart; + +private: + bool SetupEmitters( void ); + + bool m_bFadeOut; + CNewParticleEffect *m_hEffect; + dlight_t *m_pDLight; +}; + +void RecvProxy_FadeOutDuration( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + C_VortigauntChargeToken *pVortToken = (C_VortigauntChargeToken *) pStruct; + Assert( pOut == &pVortToken->m_flFadeOutTime ); + + pVortToken->m_flFadeOutStart = gpGlobals->curtime; + pVortToken->m_flFadeOutTime = ( pData->m_Value.m_Float - gpGlobals->curtime ); +} + +IMPLEMENT_CLIENTCLASS_DT( C_VortigauntChargeToken, DT_VortigauntChargeToken, CVortigauntChargeToken ) + RecvPropBool( RECVINFO( m_bFadeOut ) ), +END_RECV_TABLE() + +void C_VortigauntChargeToken::UpdateOnRemove( void ) +{ + if ( m_hEffect ) + { + m_hEffect->StopEmission(); + m_hEffect = NULL; + } + + if ( m_pDLight != NULL ) + { + m_pDLight->die = gpGlobals->curtime; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Change our transmission state +//----------------------------------------------------------------------------- +void C_VortigauntChargeToken::NotifyShouldTransmit( ShouldTransmitState_t state ) +{ + BaseClass::NotifyShouldTransmit( state ); + + // Turn off + if ( state == SHOULDTRANSMIT_END ) + { + if ( m_hEffect ) + { + m_hEffect->StopEmission(); + m_hEffect = NULL; + } + } + + // Turn on + if ( state == SHOULDTRANSMIT_START ) + { + m_hEffect = ParticleProp()->Create( "vortigaunt_charge_token", PATTACH_ABSORIGIN_FOLLOW ); + m_hEffect->SetControlPointEntity( 0, this ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_VortigauntChargeToken::OnDataChanged( DataUpdateType_t type ) +{ + if ( m_bFadeOut ) + { + if ( m_hEffect ) + { + m_hEffect->StopEmission(); + m_hEffect = NULL; + } + } + + BaseClass::OnDataChanged( type ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_VortigauntChargeToken::ClientThink( void ) +{ + // + // -- DLight + // + + if ( m_pDLight != NULL ) + { + m_pDLight->origin = GetAbsOrigin(); + m_pDLight->radius = DLIGHT_RADIUS; + } +} + +//============================================================================= +// +// Dispel Effect +// +//============================================================================= + +class C_VortigauntEffectDispel : public C_BaseEntity +{ + DECLARE_CLASS( C_VortigauntEffectDispel, C_BaseEntity ); + DECLARE_CLIENTCLASS(); + +public: + virtual void UpdateOnRemove( void ); + virtual void ClientThink( void ); + virtual void NotifyShouldTransmit( ShouldTransmitState_t state ); + virtual void OnDataChanged( DataUpdateType_t type ); + + // For RecvProxy handlers + float m_flFadeOutTime; + float m_flFadeOutStart; + +private: + bool SetupEmitters( void ); + + CNewParticleEffect *m_hEffect; + bool m_bFadeOut; + dlight_t *m_pDLight; +}; + +void RecvProxy_DispelFadeOutDuration( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + C_VortigauntEffectDispel *pVortToken = (C_VortigauntEffectDispel *) pStruct; + Assert( pOut == &pVortToken->m_flFadeOutTime ); + + pVortToken->m_flFadeOutStart = gpGlobals->curtime; + pVortToken->m_flFadeOutTime = ( pData->m_Value.m_Float - gpGlobals->curtime ); +} + +IMPLEMENT_CLIENTCLASS_DT( C_VortigauntEffectDispel, DT_VortigauntEffectDispel, CVortigauntEffectDispel ) + RecvPropBool( RECVINFO( m_bFadeOut ) ), +END_RECV_TABLE() + +void C_VortigauntEffectDispel::UpdateOnRemove( void ) +{ + if ( m_hEffect ) + { + m_hEffect->StopEmission(); + m_hEffect = NULL; + } + + if ( m_pDLight != NULL ) + { + m_pDLight->die = gpGlobals->curtime; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_VortigauntEffectDispel::OnDataChanged( DataUpdateType_t type ) +{ + if ( m_bFadeOut ) + { + if ( m_hEffect ) + { + m_hEffect->StopEmission(); + m_hEffect = NULL; + } + } + + BaseClass::OnDataChanged( type ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_VortigauntEffectDispel::NotifyShouldTransmit( ShouldTransmitState_t state ) +{ + BaseClass::NotifyShouldTransmit( state ); + + // Turn off + if ( state == SHOULDTRANSMIT_END ) + { + if ( m_hEffect ) + { + m_hEffect->StopEmission(); + m_hEffect = NULL; + } + } + + // Turn on + if ( state == SHOULDTRANSMIT_START ) + { + m_hEffect = ParticleProp()->Create( "vortigaunt_hand_glow", PATTACH_ABSORIGIN_FOLLOW ); + m_hEffect->SetControlPointEntity( 0, this ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Create our emitter +//----------------------------------------------------------------------------- +bool C_VortigauntEffectDispel::SetupEmitters( void ) +{ + m_pDLight = NULL; + +#ifndef _X360 + m_pDLight = effects->CL_AllocDlight ( index ); + m_pDLight->origin = GetAbsOrigin(); + m_pDLight->color.r = 64; + m_pDLight->color.g = 255; + m_pDLight->color.b = 64; + m_pDLight->radius = 0; + m_pDLight->minlight = DLIGHT_MINLIGHT; + m_pDLight->die = FLT_MAX; +#endif // _X360 + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_VortigauntEffectDispel::ClientThink( void ) +{ + if ( m_pDLight != NULL ) + { + m_pDLight->origin = GetAbsOrigin(); + m_pDLight->radius = DLIGHT_RADIUS; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void DispelCallback( const CEffectData &data ) +{ + // Kaboom! + Vector startPos = data.m_vOrigin + Vector(0,0,16); + Vector endPos = data.m_vOrigin + Vector(0,0,-64); + + trace_t tr; + UTIL_TraceLine( startPos, endPos, MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &tr ); + + if ( tr.fraction < 1.0f ) + { + //Add a ripple quad to the surface + FX_AddQuad( tr.endpos + ( tr.plane.normal * 8.0f ), + Vector( 0, 0, 1 ), + 64.0f, + 600.0f, + 0.8f, + 1.0f, // start alpha + 0.0f, // end alpha + 0.3f, + random->RandomFloat( 0, 360 ), + 0.0f, + Vector( 0.5f, 1.0f, 0.5f ), + 0.75f, + "effects/ar2_altfire1b", + (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA|FXQUAD_COLOR_FADE) ); + + //Add a ripple quad to the surface + FX_AddQuad( tr.endpos + ( tr.plane.normal * 8.0f ), + Vector( 0, 0, 1 ), + 16.0f, + 300.0f, + 0.9f, + 1.0f, // start alpha + 0.0f, // end alpha + 0.9f, + random->RandomFloat( 0, 360 ), + 0.0f, + Vector( 0.5f, 1.0f, 0.5f ), + 1.25f, + "effects/rollerglow", + (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) ); + } +} + +DECLARE_CLIENT_EFFECT( "VortDispel", DispelCallback ); + +//----------------------------------------------------------------------------- +// Purpose: Used for emissive lightning layer on vort +//----------------------------------------------------------------------------- +class CVortEmissiveProxy : public CEntityMaterialProxy +{ +public: + CVortEmissiveProxy( void ); + virtual ~CVortEmissiveProxy( void ); + virtual bool Init( IMaterial *pMaterial, KeyValues* pKeyValues ); + virtual void OnBind( C_BaseEntity *pC_BaseEntity ); + virtual IMaterial * GetMaterial(); + +private: + + IMaterialVar *m_pMatEmissiveStrength; + IMaterialVar *m_pMatDetailBlendStrength; +}; + +//----------------------------------------------------------------------------- +CVortEmissiveProxy::CVortEmissiveProxy( void ) +{ + m_pMatEmissiveStrength = NULL; + m_pMatDetailBlendStrength = NULL; +} + +CVortEmissiveProxy::~CVortEmissiveProxy( void ) +{ + // Do nothing +} + +//----------------------------------------------------------------------------- +bool CVortEmissiveProxy::Init( IMaterial *pMaterial, KeyValues* pKeyValues ) +{ + Assert( pMaterial ); + + // Need to get the material var + bool bFound; + m_pMatEmissiveStrength = pMaterial->FindVar( "$emissiveblendstrength", &bFound ); + + if ( bFound ) + { + // Optional + bool bFound2; + m_pMatDetailBlendStrength = pMaterial->FindVar( "$detailblendfactor", &bFound2 ); + } + + return bFound; +} + +//----------------------------------------------------------------------------- +void CVortEmissiveProxy::OnBind( C_BaseEntity *pEnt ) +{ + C_NPC_Vortigaunt *pVort = dynamic_cast<C_NPC_Vortigaunt *>(pEnt); + + float flBlendValue; + + if (pVort) + { + // do we need to crossfade? + if (gpGlobals->curtime < pVort->m_flBlueEndFadeTime) + { + // will be 0 when fully faded and 1 when not faded at all: + float fadeRatio = (pVort->m_flBlueEndFadeTime - gpGlobals->curtime) / VORTIGAUNT_BLUE_FADE_TIME; + if (pVort->m_bIsBlue) + { + fadeRatio = 1.0f - fadeRatio; + } + flBlendValue = clamp( fadeRatio, 0.0f, 1.0f ); + } + else // no crossfade + { + flBlendValue = pVort->m_bIsBlue ? 1.0f : 0.0f; + } + + // ALEX VLACHOS: + // The following variable varies on [0 .. 1]. 0.0 means the vort wants to be his normal + // color. 1.0 means he wants to be all black. It is interpolated in the + // C_NPC_Vortigaunt::ClientThink() function. + // + // pVort->m_flBlackFade + } + else + { // if you bind this proxy to anything non-vort (eg a ragdoll) it's always green + flBlendValue = 0.0f; + } + + + /* + // !!! Change me !!! I'm using a clamped sin wave for debugging + float flBlendValue = sinf( gpGlobals->curtime * 4.0f ) * 0.75f + 0.25f; + + // Clamp 0-1 + flBlendValue = ( flBlendValue < 0.0f ) ? 0.0f : ( flBlendValue > 1.0f ) ? 1.0f : flBlendValue; + */ + + if( m_pMatEmissiveStrength != NULL ) + { + m_pMatEmissiveStrength->SetFloatValue( flBlendValue ); + } + + if( m_pMatDetailBlendStrength != NULL ) + { + m_pMatDetailBlendStrength->SetFloatValue( flBlendValue ); + } +} + +//----------------------------------------------------------------------------- +IMaterial *CVortEmissiveProxy::GetMaterial() +{ + if ( m_pMatEmissiveStrength != NULL ) + return m_pMatEmissiveStrength->GetOwningMaterial(); + else if ( m_pMatDetailBlendStrength != NULL ) + return m_pMatDetailBlendStrength->GetOwningMaterial(); + else + return NULL; +} + +EXPOSE_INTERFACE( CVortEmissiveProxy, IMaterialProxy, "VortEmissive" IMATERIAL_PROXY_INTERFACE_VERSION ); diff --git a/mp/src/game/client/episodic/c_weapon_hopwire.cpp b/mp/src/game/client/episodic/c_weapon_hopwire.cpp index 807d46bc..942ef0c0 100644 --- a/mp/src/game/client/episodic/c_weapon_hopwire.cpp +++ b/mp/src/game/client/episodic/c_weapon_hopwire.cpp @@ -1,421 +1,421 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================
-
-#include "cbase.h"
-#include "basegrenade_shared.h"
-#include "fx_interpvalue.h"
-#include "fx_envelope.h"
-#include "materialsystem/imaterialvar.h"
-#include "particles_simple.h"
-#include "particles_attractor.h"
-
-// FIXME: Move out
-extern void DrawSpriteTangentSpace( const Vector &vecOrigin, float flWidth, float flHeight, color32 color );
-
-#define EXPLOSION_DURATION 3.0f
-
-//-----------------------------------------------------------------------------
-// Explosion effect for hopwire
-//-----------------------------------------------------------------------------
-
-class C_HopwireExplosion : public C_EnvelopeFX
-{
- typedef C_EnvelopeFX BaseClass;
-
-public:
- C_HopwireExplosion( void ) :
- m_hOwner( NULL )
- {
- m_FXCoreScale.SetAbsolute( 0.0f );
- m_FXCoreAlpha.SetAbsolute( 0.0f );
- }
-
- virtual void Update( void );
- virtual int DrawModel( int flags );
- virtual void GetRenderBounds( Vector& mins, Vector& maxs );
-
- bool SetupEmitters( void );
- void AddParticles( void );
- void SetOwner( C_BaseEntity *pOwner );
- void StartExplosion( void );
- void StopExplosion( void );
- void StartPreExplosion( void );
-
-private:
- CInterpolatedValue m_FXCoreScale;
- CInterpolatedValue m_FXCoreAlpha;
-
- CSmartPtr<CSimpleEmitter> m_pSimpleEmitter;
- CSmartPtr<CParticleAttractor> m_pAttractorEmitter;
-
- TimedEvent m_ParticleTimer;
-
- CHandle<C_BaseEntity> m_hOwner;
-};
-
-//-----------------------------------------------------------------------------
-// Purpose: Setup the emitters we'll be using
-//-----------------------------------------------------------------------------
-bool C_HopwireExplosion::SetupEmitters( void )
-{
- // Setup the basic core emitter
- if ( m_pSimpleEmitter.IsValid() == false )
- {
- m_pSimpleEmitter = CSimpleEmitter::Create( "hopwirecore" );
-
- if ( m_pSimpleEmitter.IsValid() == false )
- return false;
- }
-
- // Setup the attractor emitter
- if ( m_pAttractorEmitter.IsValid() == false )
- {
- m_pAttractorEmitter = CParticleAttractor::Create( GetRenderOrigin(), "hopwireattractor" );
-
- if ( m_pAttractorEmitter.IsValid() == false )
- return false;
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_HopwireExplosion::AddParticles( void )
-{
- // Make sure the emitters are setup properly
- if ( SetupEmitters() == false )
- return;
-
- float tempDelta = gpGlobals->frametime;
- while( m_ParticleTimer.NextEvent( tempDelta ) )
- {
- // ========================
- // Attracted dust particles
- // ========================
-
- // Update our attractor point
- m_pAttractorEmitter->SetAttractorOrigin( GetRenderOrigin() );
-
- Vector offset;
- SimpleParticle *sParticle;
-
- offset = GetRenderOrigin() + RandomVector( -256.0f, 256.0f );
-
- sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), g_Mat_Fleck_Cement[0], offset );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_vecVelocity = Vector(0,0,8);
- sParticle->m_flDieTime = 0.5f;
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
- sParticle->m_flRollDelta = 1.0f;
-
- float alpha = random->RandomFloat( 128.0f, 200.0f );
-
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = alpha;
-
- sParticle->m_uchStartSize = random->RandomInt( 1, 4 );
- sParticle->m_uchEndSize = 0;
-
- // ========================
- // Core effects
- // ========================
-
- // Reset our sort origin
- m_pSimpleEmitter->SetSortOrigin( GetRenderOrigin() );
-
- // Base of the core effect
- sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( "effects/strider_muzzle" ), GetRenderOrigin() );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_vecVelocity = vec3_origin;
- sParticle->m_flDieTime = 0.2f;
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
- sParticle->m_flRollDelta = 4.0f;
-
- alpha = random->RandomInt( 32, 200 );
-
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = 0;
- sParticle->m_uchEndAlpha = alpha;
-
- sParticle->m_uchStartSize = 255;
- sParticle->m_uchEndSize = 0;
-
- // Make sure we encompass the complete particle here!
- m_pSimpleEmitter->SetParticleCullRadius( sParticle->m_uchEndSize );
-
- // =========================
- // Dust ring effect
- // =========================
-
- if ( random->RandomInt( 0, 5 ) != 1 )
- return;
-
- Vector vecDustColor;
- vecDustColor.x = 0.35f;
- vecDustColor.y = 0.3f;
- vecDustColor.z = 0.25f;
-
- Vector color;
-
- int numRingSprites = 8;
- float yaw;
- Vector forward, vRight, vForward;
-
- vForward = Vector( 0, 1, 0 );
- vRight = Vector( 1, 0, 0 );
-
- float yawOfs = random->RandomFloat( 0, 359 );
-
- for ( int i = 0; i < numRingSprites; i++ )
- {
- yaw = ( (float) i / (float) numRingSprites ) * 360.0f;
- yaw += yawOfs;
-
- forward = ( vRight * sin( DEG2RAD( yaw) ) ) + ( vForward * cos( DEG2RAD( yaw ) ) );
- VectorNormalize( forward );
-
- trace_t tr;
-
- UTIL_TraceLine( GetRenderOrigin(), GetRenderOrigin()+(Vector(0, 0, -1024)), MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &tr );
-
- offset = ( RandomVector( -4.0f, 4.0f ) + tr.endpos ) + ( forward * 512.0f );
-
- sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), g_Mat_DustPuff[random->RandomInt(0,1)], offset );
-
- if ( sParticle != NULL )
- {
- sParticle->m_flLifetime = 0.0f;
- sParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f );
-
- sParticle->m_vecVelocity = forward * -random->RandomFloat( 1000, 1500 );
- sParticle->m_vecVelocity[2] += 128.0f;
-
- #if __EXPLOSION_DEBUG
- debugoverlay->AddLineOverlay( m_vecOrigin, m_vecOrigin + sParticle->m_vecVelocity, 255, 0, 0, false, 3 );
- #endif
-
- sParticle->m_uchColor[0] = vecDustColor.x * 255.0f;
- sParticle->m_uchColor[1] = vecDustColor.y * 255.0f;
- sParticle->m_uchColor[2] = vecDustColor.z * 255.0f;
-
- sParticle->m_uchStartSize = random->RandomInt( 32, 128 );
- sParticle->m_uchEndSize = 200;
-
- sParticle->m_uchStartAlpha = random->RandomFloat( 16, 64 );
- sParticle->m_uchEndAlpha = 0;
-
- sParticle->m_flRoll = random->RandomInt( 0, 360 );
- sParticle->m_flRollDelta = random->RandomFloat( -16.0f, 16.0f );
- }
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pOwner -
-//-----------------------------------------------------------------------------
-void C_HopwireExplosion::SetOwner( C_BaseEntity *pOwner )
-{
- m_hOwner = pOwner;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Updates the internal values for the effect
-//-----------------------------------------------------------------------------
-void C_HopwireExplosion::Update( void )
-{
- if ( m_hOwner )
- {
- SetRenderOrigin( m_hOwner->GetRenderOrigin() );
- }
-
- BaseClass::Update();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Updates and renders all effects
-//-----------------------------------------------------------------------------
-int C_HopwireExplosion::DrawModel( int flags )
-{
- AddParticles();
-
- CMatRenderContextPtr pRenderContext( materials );
- pRenderContext->Flush();
- UpdateRefractTexture();
-
- IMaterial *pMat = materials->FindMaterial( "effects/strider_pinch_dudv", TEXTURE_GROUP_CLIENT_EFFECTS );
-
- float refract = m_FXCoreAlpha.Interp( gpGlobals->curtime );
- float scale = m_FXCoreScale.Interp( gpGlobals->curtime );
-
- IMaterialVar *pVar = pMat->FindVar( "$refractamount", NULL );
- pVar->SetFloatValue( refract );
-
- pRenderContext->Bind( pMat, (IClientRenderable*)this );
-
- float sin1 = sinf( gpGlobals->curtime * 10 );
- float sin2 = sinf( gpGlobals->curtime );
-
- float scaleY = ( sin1 * sin2 ) * 32.0f;
- float scaleX = (sin2 * sin2) * 32.0f;
-
- // FIXME: The ball needs to sort properly at all times
- static color32 white = {255,255,255,255};
- DrawSpriteTangentSpace( GetRenderOrigin() + ( CurrentViewForward() * 128.0f ), scale+scaleX, scale+scaleY, white );
-
- return 1;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Returns the bounds relative to the origin (render bounds)
-//-----------------------------------------------------------------------------
-void C_HopwireExplosion::GetRenderBounds( Vector& mins, Vector& maxs )
-{
- float scale = m_FXCoreScale.Interp( gpGlobals->curtime );
-
- mins.Init( -scale, -scale, -scale );
- maxs.Init( scale, scale, scale );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_HopwireExplosion::StartExplosion( void )
-{
- m_FXCoreScale.Init( 300.0f, 500.0f, 2.0f, INTERP_SPLINE );
- m_FXCoreAlpha.Init( 0.0f, 0.1f, 1.5f, INTERP_SPLINE );
-
- // Particle timer
- m_ParticleTimer.Init( 60 );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_HopwireExplosion::StopExplosion( void )
-{
- m_FXCoreAlpha.InitFromCurrent( 0.0f, 1.0f, INTERP_SPLINE );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_HopwireExplosion::StartPreExplosion( void )
-{
-}
-
-//-----------------------------------------------------------------------------
-// Hopwire client class
-//-----------------------------------------------------------------------------
-
-class C_GrenadeHopwire : public C_BaseGrenade
-{
- DECLARE_CLASS( C_GrenadeHopwire, C_BaseGrenade );
- DECLARE_CLIENTCLASS();
-
-public:
- C_GrenadeHopwire( void );
-
- virtual int DrawModel( int flags );
-
- virtual void OnDataChanged( DataUpdateType_t updateType );
- virtual void ReceiveMessage( int classID, bf_read &msg );
-
-private:
-
- C_HopwireExplosion m_ExplosionEffect; // Explosion effect information and drawing
-};
-
-IMPLEMENT_CLIENTCLASS_DT( C_GrenadeHopwire, DT_GrenadeHopwire, CGrenadeHopwire )
-END_RECV_TABLE()
-
-#define HOPWIRE_START_EXPLOSION 0
-#define HOPWIRE_STOP_EXPLOSION 1
-#define HOPWIRE_START_PRE_EXPLOSION 2
-
-//-----------------------------------------------------------------------------
-// Constructor
-//-----------------------------------------------------------------------------
-C_GrenadeHopwire::C_GrenadeHopwire( void )
-{
- m_ExplosionEffect.SetActive( false );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Receive messages from the server
-// Input : classID - class to receive the message
-// &msg - message in question
-//-----------------------------------------------------------------------------
-void C_GrenadeHopwire::ReceiveMessage( int classID, bf_read &msg )
-{
- if ( classID != GetClientClass()->m_ClassID )
- {
- // Message is for subclass
- BaseClass::ReceiveMessage( classID, msg );
- return;
- }
-
- int messageType = msg.ReadByte();
- switch( messageType )
- {
- case HOPWIRE_START_EXPLOSION:
- {
- m_ExplosionEffect.SetActive();
- m_ExplosionEffect.SetOwner( this );
- m_ExplosionEffect.StartExplosion();
- }
- break;
- case HOPWIRE_STOP_EXPLOSION:
- {
- m_ExplosionEffect.StopExplosion();
- }
- break;
- default:
- break;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : updateType -
-//-----------------------------------------------------------------------------
-void C_GrenadeHopwire::OnDataChanged( DataUpdateType_t updateType )
-{
- BaseClass::OnDataChanged( updateType );
-
- m_ExplosionEffect.Update();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : flags -
-//-----------------------------------------------------------------------------
-int C_GrenadeHopwire::DrawModel( int flags )
-{
- if ( m_ExplosionEffect.IsActive() )
- return 1;
-
- return BaseClass::DrawModel( flags );
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "cbase.h" +#include "basegrenade_shared.h" +#include "fx_interpvalue.h" +#include "fx_envelope.h" +#include "materialsystem/imaterialvar.h" +#include "particles_simple.h" +#include "particles_attractor.h" + +// FIXME: Move out +extern void DrawSpriteTangentSpace( const Vector &vecOrigin, float flWidth, float flHeight, color32 color ); + +#define EXPLOSION_DURATION 3.0f + +//----------------------------------------------------------------------------- +// Explosion effect for hopwire +//----------------------------------------------------------------------------- + +class C_HopwireExplosion : public C_EnvelopeFX +{ + typedef C_EnvelopeFX BaseClass; + +public: + C_HopwireExplosion( void ) : + m_hOwner( NULL ) + { + m_FXCoreScale.SetAbsolute( 0.0f ); + m_FXCoreAlpha.SetAbsolute( 0.0f ); + } + + virtual void Update( void ); + virtual int DrawModel( int flags ); + virtual void GetRenderBounds( Vector& mins, Vector& maxs ); + + bool SetupEmitters( void ); + void AddParticles( void ); + void SetOwner( C_BaseEntity *pOwner ); + void StartExplosion( void ); + void StopExplosion( void ); + void StartPreExplosion( void ); + +private: + CInterpolatedValue m_FXCoreScale; + CInterpolatedValue m_FXCoreAlpha; + + CSmartPtr<CSimpleEmitter> m_pSimpleEmitter; + CSmartPtr<CParticleAttractor> m_pAttractorEmitter; + + TimedEvent m_ParticleTimer; + + CHandle<C_BaseEntity> m_hOwner; +}; + +//----------------------------------------------------------------------------- +// Purpose: Setup the emitters we'll be using +//----------------------------------------------------------------------------- +bool C_HopwireExplosion::SetupEmitters( void ) +{ + // Setup the basic core emitter + if ( m_pSimpleEmitter.IsValid() == false ) + { + m_pSimpleEmitter = CSimpleEmitter::Create( "hopwirecore" ); + + if ( m_pSimpleEmitter.IsValid() == false ) + return false; + } + + // Setup the attractor emitter + if ( m_pAttractorEmitter.IsValid() == false ) + { + m_pAttractorEmitter = CParticleAttractor::Create( GetRenderOrigin(), "hopwireattractor" ); + + if ( m_pAttractorEmitter.IsValid() == false ) + return false; + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_HopwireExplosion::AddParticles( void ) +{ + // Make sure the emitters are setup properly + if ( SetupEmitters() == false ) + return; + + float tempDelta = gpGlobals->frametime; + while( m_ParticleTimer.NextEvent( tempDelta ) ) + { + // ======================== + // Attracted dust particles + // ======================== + + // Update our attractor point + m_pAttractorEmitter->SetAttractorOrigin( GetRenderOrigin() ); + + Vector offset; + SimpleParticle *sParticle; + + offset = GetRenderOrigin() + RandomVector( -256.0f, 256.0f ); + + sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), g_Mat_Fleck_Cement[0], offset ); + + if ( sParticle == NULL ) + return; + + sParticle->m_vecVelocity = Vector(0,0,8); + sParticle->m_flDieTime = 0.5f; + sParticle->m_flLifetime = 0.0f; + + sParticle->m_flRoll = Helper_RandomInt( 0, 360 ); + sParticle->m_flRollDelta = 1.0f; + + float alpha = random->RandomFloat( 128.0f, 200.0f ); + + sParticle->m_uchColor[0] = alpha; + sParticle->m_uchColor[1] = alpha; + sParticle->m_uchColor[2] = alpha; + sParticle->m_uchStartAlpha = alpha; + sParticle->m_uchEndAlpha = alpha; + + sParticle->m_uchStartSize = random->RandomInt( 1, 4 ); + sParticle->m_uchEndSize = 0; + + // ======================== + // Core effects + // ======================== + + // Reset our sort origin + m_pSimpleEmitter->SetSortOrigin( GetRenderOrigin() ); + + // Base of the core effect + sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( "effects/strider_muzzle" ), GetRenderOrigin() ); + + if ( sParticle == NULL ) + return; + + sParticle->m_vecVelocity = vec3_origin; + sParticle->m_flDieTime = 0.2f; + sParticle->m_flLifetime = 0.0f; + + sParticle->m_flRoll = Helper_RandomInt( 0, 360 ); + sParticle->m_flRollDelta = 4.0f; + + alpha = random->RandomInt( 32, 200 ); + + sParticle->m_uchColor[0] = alpha; + sParticle->m_uchColor[1] = alpha; + sParticle->m_uchColor[2] = alpha; + sParticle->m_uchStartAlpha = 0; + sParticle->m_uchEndAlpha = alpha; + + sParticle->m_uchStartSize = 255; + sParticle->m_uchEndSize = 0; + + // Make sure we encompass the complete particle here! + m_pSimpleEmitter->SetParticleCullRadius( sParticle->m_uchEndSize ); + + // ========================= + // Dust ring effect + // ========================= + + if ( random->RandomInt( 0, 5 ) != 1 ) + return; + + Vector vecDustColor; + vecDustColor.x = 0.35f; + vecDustColor.y = 0.3f; + vecDustColor.z = 0.25f; + + Vector color; + + int numRingSprites = 8; + float yaw; + Vector forward, vRight, vForward; + + vForward = Vector( 0, 1, 0 ); + vRight = Vector( 1, 0, 0 ); + + float yawOfs = random->RandomFloat( 0, 359 ); + + for ( int i = 0; i < numRingSprites; i++ ) + { + yaw = ( (float) i / (float) numRingSprites ) * 360.0f; + yaw += yawOfs; + + forward = ( vRight * sin( DEG2RAD( yaw) ) ) + ( vForward * cos( DEG2RAD( yaw ) ) ); + VectorNormalize( forward ); + + trace_t tr; + + UTIL_TraceLine( GetRenderOrigin(), GetRenderOrigin()+(Vector(0, 0, -1024)), MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &tr ); + + offset = ( RandomVector( -4.0f, 4.0f ) + tr.endpos ) + ( forward * 512.0f ); + + sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), g_Mat_DustPuff[random->RandomInt(0,1)], offset ); + + if ( sParticle != NULL ) + { + sParticle->m_flLifetime = 0.0f; + sParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f ); + + sParticle->m_vecVelocity = forward * -random->RandomFloat( 1000, 1500 ); + sParticle->m_vecVelocity[2] += 128.0f; + + #if __EXPLOSION_DEBUG + debugoverlay->AddLineOverlay( m_vecOrigin, m_vecOrigin + sParticle->m_vecVelocity, 255, 0, 0, false, 3 ); + #endif + + sParticle->m_uchColor[0] = vecDustColor.x * 255.0f; + sParticle->m_uchColor[1] = vecDustColor.y * 255.0f; + sParticle->m_uchColor[2] = vecDustColor.z * 255.0f; + + sParticle->m_uchStartSize = random->RandomInt( 32, 128 ); + sParticle->m_uchEndSize = 200; + + sParticle->m_uchStartAlpha = random->RandomFloat( 16, 64 ); + sParticle->m_uchEndAlpha = 0; + + sParticle->m_flRoll = random->RandomInt( 0, 360 ); + sParticle->m_flRollDelta = random->RandomFloat( -16.0f, 16.0f ); + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pOwner - +//----------------------------------------------------------------------------- +void C_HopwireExplosion::SetOwner( C_BaseEntity *pOwner ) +{ + m_hOwner = pOwner; +} + +//----------------------------------------------------------------------------- +// Purpose: Updates the internal values for the effect +//----------------------------------------------------------------------------- +void C_HopwireExplosion::Update( void ) +{ + if ( m_hOwner ) + { + SetRenderOrigin( m_hOwner->GetRenderOrigin() ); + } + + BaseClass::Update(); +} + +//----------------------------------------------------------------------------- +// Purpose: Updates and renders all effects +//----------------------------------------------------------------------------- +int C_HopwireExplosion::DrawModel( int flags ) +{ + AddParticles(); + + CMatRenderContextPtr pRenderContext( materials ); + pRenderContext->Flush(); + UpdateRefractTexture(); + + IMaterial *pMat = materials->FindMaterial( "effects/strider_pinch_dudv", TEXTURE_GROUP_CLIENT_EFFECTS ); + + float refract = m_FXCoreAlpha.Interp( gpGlobals->curtime ); + float scale = m_FXCoreScale.Interp( gpGlobals->curtime ); + + IMaterialVar *pVar = pMat->FindVar( "$refractamount", NULL ); + pVar->SetFloatValue( refract ); + + pRenderContext->Bind( pMat, (IClientRenderable*)this ); + + float sin1 = sinf( gpGlobals->curtime * 10 ); + float sin2 = sinf( gpGlobals->curtime ); + + float scaleY = ( sin1 * sin2 ) * 32.0f; + float scaleX = (sin2 * sin2) * 32.0f; + + // FIXME: The ball needs to sort properly at all times + static color32 white = {255,255,255,255}; + DrawSpriteTangentSpace( GetRenderOrigin() + ( CurrentViewForward() * 128.0f ), scale+scaleX, scale+scaleY, white ); + + return 1; +} + +//----------------------------------------------------------------------------- +// Purpose: Returns the bounds relative to the origin (render bounds) +//----------------------------------------------------------------------------- +void C_HopwireExplosion::GetRenderBounds( Vector& mins, Vector& maxs ) +{ + float scale = m_FXCoreScale.Interp( gpGlobals->curtime ); + + mins.Init( -scale, -scale, -scale ); + maxs.Init( scale, scale, scale ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_HopwireExplosion::StartExplosion( void ) +{ + m_FXCoreScale.Init( 300.0f, 500.0f, 2.0f, INTERP_SPLINE ); + m_FXCoreAlpha.Init( 0.0f, 0.1f, 1.5f, INTERP_SPLINE ); + + // Particle timer + m_ParticleTimer.Init( 60 ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_HopwireExplosion::StopExplosion( void ) +{ + m_FXCoreAlpha.InitFromCurrent( 0.0f, 1.0f, INTERP_SPLINE ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_HopwireExplosion::StartPreExplosion( void ) +{ +} + +//----------------------------------------------------------------------------- +// Hopwire client class +//----------------------------------------------------------------------------- + +class C_GrenadeHopwire : public C_BaseGrenade +{ + DECLARE_CLASS( C_GrenadeHopwire, C_BaseGrenade ); + DECLARE_CLIENTCLASS(); + +public: + C_GrenadeHopwire( void ); + + virtual int DrawModel( int flags ); + + virtual void OnDataChanged( DataUpdateType_t updateType ); + virtual void ReceiveMessage( int classID, bf_read &msg ); + +private: + + C_HopwireExplosion m_ExplosionEffect; // Explosion effect information and drawing +}; + +IMPLEMENT_CLIENTCLASS_DT( C_GrenadeHopwire, DT_GrenadeHopwire, CGrenadeHopwire ) +END_RECV_TABLE() + +#define HOPWIRE_START_EXPLOSION 0 +#define HOPWIRE_STOP_EXPLOSION 1 +#define HOPWIRE_START_PRE_EXPLOSION 2 + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +C_GrenadeHopwire::C_GrenadeHopwire( void ) +{ + m_ExplosionEffect.SetActive( false ); +} + +//----------------------------------------------------------------------------- +// Purpose: Receive messages from the server +// Input : classID - class to receive the message +// &msg - message in question +//----------------------------------------------------------------------------- +void C_GrenadeHopwire::ReceiveMessage( int classID, bf_read &msg ) +{ + if ( classID != GetClientClass()->m_ClassID ) + { + // Message is for subclass + BaseClass::ReceiveMessage( classID, msg ); + return; + } + + int messageType = msg.ReadByte(); + switch( messageType ) + { + case HOPWIRE_START_EXPLOSION: + { + m_ExplosionEffect.SetActive(); + m_ExplosionEffect.SetOwner( this ); + m_ExplosionEffect.StartExplosion(); + } + break; + case HOPWIRE_STOP_EXPLOSION: + { + m_ExplosionEffect.StopExplosion(); + } + break; + default: + break; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : updateType - +//----------------------------------------------------------------------------- +void C_GrenadeHopwire::OnDataChanged( DataUpdateType_t updateType ) +{ + BaseClass::OnDataChanged( updateType ); + + m_ExplosionEffect.Update(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : flags - +//----------------------------------------------------------------------------- +int C_GrenadeHopwire::DrawModel( int flags ) +{ + if ( m_ExplosionEffect.IsActive() ) + return 1; + + return BaseClass::DrawModel( flags ); +} + diff --git a/mp/src/game/client/episodic/episodic_screenspaceeffects.cpp b/mp/src/game/client/episodic/episodic_screenspaceeffects.cpp index 220e750e..a2b59bbc 100644 --- a/mp/src/game/client/episodic/episodic_screenspaceeffects.cpp +++ b/mp/src/game/client/episodic/episodic_screenspaceeffects.cpp @@ -1,464 +1,464 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Episodic screen-space effects
-//
-
-#include "cbase.h"
-#include "ScreenSpaceEffects.h"
-#include "rendertexture.h"
-#include "materialsystem/imaterialsystemhardwareconfig.h"
-#include "materialsystem/imaterialsystem.h"
-#include "materialsystem/imaterialvar.h"
-#include "cdll_client_int.h"
-#include "materialsystem/itexture.h"
-#include "KeyValues.h"
-#include "clienteffectprecachesystem.h"
-
-#include "episodic_screenspaceeffects.h"
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-#ifdef _X360
-#define STUN_TEXTURE "_rt_FullFrameFB2"
-#else
-#define STUN_TEXTURE "_rt_WaterRefraction"
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CStunEffect::Init( void )
-{
- m_flDuration = 0.0f;
- m_flFinishTime = 0.0f;
- m_bUpdateView = true;
-
- KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" );
- pVMTKeyValues->SetString( "$basetexture", STUN_TEXTURE );
- m_EffectMaterial.Init( "__stuneffect", TEXTURE_GROUP_CLIENT_EFFECTS, pVMTKeyValues );
- m_StunTexture.Init( STUN_TEXTURE, TEXTURE_GROUP_CLIENT_EFFECTS );
-}
-
-void CStunEffect::Shutdown( void )
-{
- m_EffectMaterial.Shutdown();
- m_StunTexture.Shutdown();
-}
-
-//------------------------------------------------------------------------------
-// Purpose: Pick up changes in our parameters
-//------------------------------------------------------------------------------
-void CStunEffect::SetParameters( KeyValues *params )
-{
- if( params->FindKey( "duration" ) )
- {
- m_flDuration = params->GetFloat( "duration" );
- m_flFinishTime = gpGlobals->curtime + m_flDuration;
- m_bUpdateView = true;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Render the effect
-//-----------------------------------------------------------------------------
-void CStunEffect::Render( int x, int y, int w, int h )
-{
- // Make sure we're ready to play this effect
- if ( m_flFinishTime < gpGlobals->curtime )
- return;
-
- CMatRenderContextPtr pRenderContext( materials );
-
- // Set ourselves to the proper rendermode
- pRenderContext->MatrixMode( MATERIAL_VIEW );
- pRenderContext->PushMatrix();
- pRenderContext->LoadIdentity();
- pRenderContext->MatrixMode( MATERIAL_PROJECTION );
- pRenderContext->PushMatrix();
- pRenderContext->LoadIdentity();
-
- // Draw the texture if we're using it
- if ( m_bUpdateView )
- {
- // Save off this pass
- Rect_t srcRect;
- srcRect.x = x;
- srcRect.y = y;
- srcRect.width = w;
- srcRect.height = h;
- pRenderContext->CopyRenderTargetToTextureEx( m_StunTexture, 0, &srcRect, NULL );
- m_bUpdateView = false;
- }
-
- float flEffectPerc = ( m_flFinishTime - gpGlobals->curtime ) / m_flDuration;
-
- float viewOffs = ( flEffectPerc * 32.0f ) * ( cos( gpGlobals->curtime * 40.0f ) * sin( gpGlobals->curtime * 17.0f ) );
- float vX = x + viewOffs;
-
- if ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() >= 80 )
- {
- if ( g_pMaterialSystemHardwareConfig->GetHDRType() == HDR_TYPE_NONE )
- {
- m_EffectMaterial->ColorModulate( 1.0f, 1.0f, 1.0f );
- }
- else
- {
- // This is a stupid fix, but I don't have time to do a cleaner implementation. Since
- // the introblur.vmt material uses unlit generic, it will tone map, so I need to undo the tone mapping
- // using color modulate. The proper fix would be to use a different material type that
- // supports alpha blending but not tone mapping, which I don't think exists. Whatever. This works when
- // the tone mapping scalar is less than 1.0, which it is in the cases it's used in game.
- float flUnTonemap = pow( 1.0f / pRenderContext->GetToneMappingScaleLinear().x, 1.0f / 2.2f );
- m_EffectMaterial->ColorModulate( flUnTonemap, flUnTonemap, flUnTonemap );
- }
-
- // Set alpha blend value
- float flOverlayAlpha = clamp( ( 150.0f / 255.0f ) * flEffectPerc, 0.0f, 1.0f );
- m_EffectMaterial->AlphaModulate( flOverlayAlpha );
-
- // Draw full screen alpha-blended quad
- pRenderContext->DrawScreenSpaceRectangle( m_EffectMaterial, 0, 0, w, h,
- vX, 0, (m_StunTexture->GetActualWidth()-1)+vX, (m_StunTexture->GetActualHeight()-1),
- m_StunTexture->GetActualWidth(), m_StunTexture->GetActualHeight() );
- }
-
- // Save off this pass
- Rect_t srcRect;
- srcRect.x = x;
- srcRect.y = y;
- srcRect.width = w;
- srcRect.height = h;
- pRenderContext->CopyRenderTargetToTextureEx( m_StunTexture, 0, &srcRect, NULL );
-
- // Restore our state
- pRenderContext->MatrixMode( MATERIAL_VIEW );
- pRenderContext->PopMatrix();
- pRenderContext->MatrixMode( MATERIAL_PROJECTION );
- pRenderContext->PopMatrix();
-}
-
-// ================================================================================================================
-//
-// Ep 1. Intro blur
-//
-// ================================================================================================================
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CEP1IntroEffect::Init( void )
-{
- m_flDuration = 0.0f;
- m_flFinishTime = 0.0f;
- m_bUpdateView = true;
- m_bFadeOut = false;
-
- KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" );
- pVMTKeyValues->SetString( "$basetexture", STUN_TEXTURE );
- m_EffectMaterial.Init( "__ep1introeffect", TEXTURE_GROUP_CLIENT_EFFECTS, pVMTKeyValues );
- m_StunTexture.Init( STUN_TEXTURE, TEXTURE_GROUP_CLIENT_EFFECTS );
-}
-
-void CEP1IntroEffect::Shutdown( void )
-{
- m_EffectMaterial.Shutdown();
- m_StunTexture.Shutdown();
-}
-
-
-//------------------------------------------------------------------------------
-// Purpose: Pick up changes in our parameters
-//------------------------------------------------------------------------------
-void CEP1IntroEffect::SetParameters( KeyValues *params )
-{
- if( params->FindKey( "duration" ) )
- {
- m_flDuration = params->GetFloat( "duration" );
- m_flFinishTime = gpGlobals->curtime + m_flDuration;
- }
-
- if( params->FindKey( "fadeout" ) )
- {
- m_bFadeOut = ( params->GetInt( "fadeout" ) == 1 );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Get the alpha value depending on various factors and time
-//-----------------------------------------------------------------------------
-inline unsigned char CEP1IntroEffect::GetFadeAlpha( void )
-{
- // Find our percentage between fully "on" and "off" in the pulse range
- float flEffectPerc = ( m_flDuration == 0.0f ) ? 0.0f : ( m_flFinishTime - gpGlobals->curtime ) / m_flDuration;
- flEffectPerc = clamp( flEffectPerc, 0.0f, 1.0f );
-
- if ( m_bFadeOut )
- {
- // HDR requires us to be more subtle, or we get uber-brightening
- if ( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE )
- return (unsigned char) clamp( 50.0f * flEffectPerc, 0.0f, 50.0f );
-
- // Non-HDR
- return (unsigned char) clamp( 64.0f * flEffectPerc, 0.0f, 64.0f );
- }
- else
- {
- // HDR requires us to be more subtle, or we get uber-brightening
- if ( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE )
- return (unsigned char) clamp( 64.0f * flEffectPerc, 50.0f, 64.0f );
-
- // Non-HDR
- return (unsigned char) clamp( 128.0f * flEffectPerc, 64.0f, 128.0f );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Render the effect
-//-----------------------------------------------------------------------------
-void CEP1IntroEffect::Render( int x, int y, int w, int h )
-{
- if ( ( m_flFinishTime == 0 ) || ( IsEnabled() == false ) )
- return;
-
- CMatRenderContextPtr pRenderContext( materials );
-
- // Set ourselves to the proper rendermode
- pRenderContext->MatrixMode( MATERIAL_VIEW );
- pRenderContext->PushMatrix();
- pRenderContext->LoadIdentity();
- pRenderContext->MatrixMode( MATERIAL_PROJECTION );
- pRenderContext->PushMatrix();
- pRenderContext->LoadIdentity();
-
- // Draw the texture if we're using it
- if ( m_bUpdateView )
- {
- // Save off this pass
- Rect_t srcRect;
- srcRect.x = x;
- srcRect.y = y;
- srcRect.width = w;
- srcRect.height = h;
- pRenderContext->CopyRenderTargetToTextureEx( m_StunTexture, 0, &srcRect, NULL );
- m_bUpdateView = false;
- }
-
- byte overlaycolor[4] = { 255, 255, 255, 0 };
-
- // Get our fade value depending on our fade duration
- overlaycolor[3] = GetFadeAlpha();
- if ( g_pMaterialSystemHardwareConfig->UsesSRGBCorrectBlending() )
- {
- // For DX10 cards, alpha blending happens in linear space, so try to adjust by hacking alpha to 50%
- overlaycolor[3] *= 0.7f;
- }
-
- // Disable overself if we're done fading out
- if ( m_bFadeOut && overlaycolor[3] == 0 )
- {
- // Takes effect next frame (we don't want to hose our matrix stacks here)
- g_pScreenSpaceEffects->DisableScreenSpaceEffect( "episodic_intro" );
- m_bUpdateView = true;
- }
-
- // Calculate some wavey noise to jitter the view by
- float vX = 2.0f * -fabs( cosf( gpGlobals->curtime ) * cosf( gpGlobals->curtime * 6.0 ) );
- float vY = 2.0f * cosf( gpGlobals->curtime ) * cosf( gpGlobals->curtime * 5.0 );
-
- // Scale percentage
- float flScalePerc = 0.02f + ( 0.01f * cosf( gpGlobals->curtime * 2.0f ) * cosf( gpGlobals->curtime * 0.5f ) );
-
- // Scaled offsets for the UVs (as texels)
- float flUOffset = ( m_StunTexture->GetActualWidth() - 1 ) * flScalePerc * 0.5f;
- float flVOffset = ( m_StunTexture->GetActualHeight() - 1 ) * flScalePerc * 0.5f;
-
- // New UVs with scaling offsets
- float flU1 = flUOffset;
- float flU2 = ( m_StunTexture->GetActualWidth() - 1 ) - flUOffset;
- float flV1 = flVOffset;
- float flV2 = ( m_StunTexture->GetActualHeight() - 1 ) - flVOffset;
-
- // Draw the "zoomed" overlay
- pRenderContext->DrawScreenSpaceRectangle( m_EffectMaterial, vX, vY, w, h,
- flU1, flV1,
- flU2, flV2,
- m_StunTexture->GetActualWidth(), m_StunTexture->GetActualHeight() );
-
- render->ViewDrawFade( overlaycolor, m_EffectMaterial );
-
- // Save off this pass
- Rect_t srcRect;
- srcRect.x = x;
- srcRect.y = y;
- srcRect.width = w;
- srcRect.height = h;
- pRenderContext->CopyRenderTargetToTextureEx( m_StunTexture, 0, &srcRect, NULL );
-
- // Restore our state
- pRenderContext->MatrixMode( MATERIAL_VIEW );
- pRenderContext->PopMatrix();
- pRenderContext->MatrixMode( MATERIAL_PROJECTION );
- pRenderContext->PopMatrix();
-}
-
-// ================================================================================================================
-//
-// Ep 2. Groggy-player view
-//
-// ================================================================================================================
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CEP2StunEffect::Init( void )
-{
- m_flDuration = 0.0f;
- m_flFinishTime = 0.0f;
- m_bUpdateView = true;
- m_bFadeOut = false;
-
- KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" );
- pVMTKeyValues->SetString( "$basetexture", STUN_TEXTURE );
- m_EffectMaterial.Init( "__ep2stuneffect", TEXTURE_GROUP_CLIENT_EFFECTS, pVMTKeyValues );
- m_StunTexture.Init( STUN_TEXTURE, TEXTURE_GROUP_CLIENT_EFFECTS );
-}
-
-void CEP2StunEffect::Shutdown( void )
-{
- m_EffectMaterial.Shutdown();
- m_StunTexture.Shutdown();
-}
-
-//------------------------------------------------------------------------------
-// Purpose: Pick up changes in our parameters
-//------------------------------------------------------------------------------
-void CEP2StunEffect::SetParameters( KeyValues *params )
-{
- if( params->FindKey( "duration" ) )
- {
- m_flDuration = params->GetFloat( "duration" );
- m_flFinishTime = gpGlobals->curtime + m_flDuration;
- }
-
- if( params->FindKey( "fadeout" ) )
- {
- m_bFadeOut = ( params->GetInt( "fadeout" ) == 1 );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Get the alpha value depending on various factors and time
-//-----------------------------------------------------------------------------
-inline unsigned char CEP2StunEffect::GetFadeAlpha( void )
-{
- // Find our percentage between fully "on" and "off" in the pulse range
- float flEffectPerc = ( m_flDuration == 0.0f ) ? 0.0f : ( m_flFinishTime - gpGlobals->curtime ) / m_flDuration;
- flEffectPerc = clamp( flEffectPerc, 0.0f, 1.0f );
-
- if ( m_bFadeOut )
- {
- // HDR requires us to be more subtle, or we get uber-brightening
- if ( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE )
- return (unsigned char) clamp( 50.0f * flEffectPerc, 0.0f, 50.0f );
-
- // Non-HDR
- return (unsigned char) clamp( 64.0f * flEffectPerc, 0.0f, 64.0f );
- }
- else
- {
- // HDR requires us to be more subtle, or we get uber-brightening
- if ( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE )
- return (unsigned char) clamp( 164.0f * flEffectPerc, 128.0f, 164.0f );
-
- // Non-HDR
- return (unsigned char) clamp( 164.0f * flEffectPerc, 128.0f, 164.0f );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Render the effect
-//-----------------------------------------------------------------------------
-void CEP2StunEffect::Render( int x, int y, int w, int h )
-{
- if ( ( m_flFinishTime == 0 ) || ( IsEnabled() == false ) )
- return;
-
- CMatRenderContextPtr pRenderContext( materials );
-
- // Set ourselves to the proper rendermode
- pRenderContext->MatrixMode( MATERIAL_VIEW );
- pRenderContext->PushMatrix();
- pRenderContext->LoadIdentity();
- pRenderContext->MatrixMode( MATERIAL_PROJECTION );
- pRenderContext->PushMatrix();
- pRenderContext->LoadIdentity();
-
- if ( m_bUpdateView )
- {
- // Save off this pass
- Rect_t srcRect;
- srcRect.x = x;
- srcRect.y = y;
- srcRect.width = w;
- srcRect.height = h;
- pRenderContext->CopyRenderTargetToTextureEx( m_StunTexture, 0, &srcRect, NULL );
- m_bUpdateView = false;
- }
-
- byte overlaycolor[4] = { 255, 255, 255, 0 };
-
- // Get our fade value depending on our fade duration
- overlaycolor[3] = GetFadeAlpha();
-
- // Disable overself if we're done fading out
- if ( m_bFadeOut && overlaycolor[3] == 0 )
- {
- // Takes effect next frame (we don't want to hose our matrix stacks here)
- g_pScreenSpaceEffects->DisableScreenSpaceEffect( "ep2_groggy" );
- m_bUpdateView = true;
- }
-
- // Calculate some wavey noise to jitter the view by
- float vX = 4.0f * cosf( gpGlobals->curtime ) * cosf( gpGlobals->curtime * 6.0 );
- float vY = 2.0f * cosf( gpGlobals->curtime ) * cosf( gpGlobals->curtime * 5.0 );
-
- float flBaseScale = 0.2f + 0.005f * sinf( gpGlobals->curtime * 4.0f );
-
- // Scale percentage
- float flScalePerc = flBaseScale + ( 0.01f * cosf( gpGlobals->curtime * 2.0f ) * cosf( gpGlobals->curtime * 0.5f ) );
-
- // Scaled offsets for the UVs (as texels)
- float flUOffset = ( m_StunTexture->GetActualWidth() - 1 ) * flScalePerc * 0.5f;
- float flVOffset = ( m_StunTexture->GetActualHeight() - 1 ) * flScalePerc * 0.5f;
-
- // New UVs with scaling offsets
- float flU1 = flUOffset;
- float flU2 = ( m_StunTexture->GetActualWidth() - 1 ) - flUOffset;
- float flV1 = flVOffset;
- float flV2 = ( m_StunTexture->GetActualHeight() - 1 ) - flVOffset;
-
- // Draw the "zoomed" overlay
- pRenderContext->DrawScreenSpaceRectangle( m_EffectMaterial, vX, vY, w, h,
- flU1, flV1,
- flU2, flV2,
- m_StunTexture->GetActualWidth(), m_StunTexture->GetActualHeight() );
-
- render->ViewDrawFade( overlaycolor, m_EffectMaterial );
-
- // Save off this pass
- Rect_t srcRect;
- srcRect.x = x;
- srcRect.y = y;
- srcRect.width = w;
- srcRect.height = h;
- pRenderContext->CopyRenderTargetToTextureEx( m_StunTexture, 0, &srcRect, NULL );
-
- // Restore our state
- pRenderContext->MatrixMode( MATERIAL_VIEW );
- pRenderContext->PopMatrix();
- pRenderContext->MatrixMode( MATERIAL_PROJECTION );
- pRenderContext->PopMatrix();
-}
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Episodic screen-space effects +// + +#include "cbase.h" +#include "ScreenSpaceEffects.h" +#include "rendertexture.h" +#include "materialsystem/imaterialsystemhardwareconfig.h" +#include "materialsystem/imaterialsystem.h" +#include "materialsystem/imaterialvar.h" +#include "cdll_client_int.h" +#include "materialsystem/itexture.h" +#include "KeyValues.h" +#include "clienteffectprecachesystem.h" + +#include "episodic_screenspaceeffects.h" + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +#ifdef _X360 +#define STUN_TEXTURE "_rt_FullFrameFB2" +#else +#define STUN_TEXTURE "_rt_WaterRefraction" +#endif + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CStunEffect::Init( void ) +{ + m_flDuration = 0.0f; + m_flFinishTime = 0.0f; + m_bUpdateView = true; + + KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" ); + pVMTKeyValues->SetString( "$basetexture", STUN_TEXTURE ); + m_EffectMaterial.Init( "__stuneffect", TEXTURE_GROUP_CLIENT_EFFECTS, pVMTKeyValues ); + m_StunTexture.Init( STUN_TEXTURE, TEXTURE_GROUP_CLIENT_EFFECTS ); +} + +void CStunEffect::Shutdown( void ) +{ + m_EffectMaterial.Shutdown(); + m_StunTexture.Shutdown(); +} + +//------------------------------------------------------------------------------ +// Purpose: Pick up changes in our parameters +//------------------------------------------------------------------------------ +void CStunEffect::SetParameters( KeyValues *params ) +{ + if( params->FindKey( "duration" ) ) + { + m_flDuration = params->GetFloat( "duration" ); + m_flFinishTime = gpGlobals->curtime + m_flDuration; + m_bUpdateView = true; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Render the effect +//----------------------------------------------------------------------------- +void CStunEffect::Render( int x, int y, int w, int h ) +{ + // Make sure we're ready to play this effect + if ( m_flFinishTime < gpGlobals->curtime ) + return; + + CMatRenderContextPtr pRenderContext( materials ); + + // Set ourselves to the proper rendermode + pRenderContext->MatrixMode( MATERIAL_VIEW ); + pRenderContext->PushMatrix(); + pRenderContext->LoadIdentity(); + pRenderContext->MatrixMode( MATERIAL_PROJECTION ); + pRenderContext->PushMatrix(); + pRenderContext->LoadIdentity(); + + // Draw the texture if we're using it + if ( m_bUpdateView ) + { + // Save off this pass + Rect_t srcRect; + srcRect.x = x; + srcRect.y = y; + srcRect.width = w; + srcRect.height = h; + pRenderContext->CopyRenderTargetToTextureEx( m_StunTexture, 0, &srcRect, NULL ); + m_bUpdateView = false; + } + + float flEffectPerc = ( m_flFinishTime - gpGlobals->curtime ) / m_flDuration; + + float viewOffs = ( flEffectPerc * 32.0f ) * ( cos( gpGlobals->curtime * 40.0f ) * sin( gpGlobals->curtime * 17.0f ) ); + float vX = x + viewOffs; + + if ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() >= 80 ) + { + if ( g_pMaterialSystemHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + m_EffectMaterial->ColorModulate( 1.0f, 1.0f, 1.0f ); + } + else + { + // This is a stupid fix, but I don't have time to do a cleaner implementation. Since + // the introblur.vmt material uses unlit generic, it will tone map, so I need to undo the tone mapping + // using color modulate. The proper fix would be to use a different material type that + // supports alpha blending but not tone mapping, which I don't think exists. Whatever. This works when + // the tone mapping scalar is less than 1.0, which it is in the cases it's used in game. + float flUnTonemap = pow( 1.0f / pRenderContext->GetToneMappingScaleLinear().x, 1.0f / 2.2f ); + m_EffectMaterial->ColorModulate( flUnTonemap, flUnTonemap, flUnTonemap ); + } + + // Set alpha blend value + float flOverlayAlpha = clamp( ( 150.0f / 255.0f ) * flEffectPerc, 0.0f, 1.0f ); + m_EffectMaterial->AlphaModulate( flOverlayAlpha ); + + // Draw full screen alpha-blended quad + pRenderContext->DrawScreenSpaceRectangle( m_EffectMaterial, 0, 0, w, h, + vX, 0, (m_StunTexture->GetActualWidth()-1)+vX, (m_StunTexture->GetActualHeight()-1), + m_StunTexture->GetActualWidth(), m_StunTexture->GetActualHeight() ); + } + + // Save off this pass + Rect_t srcRect; + srcRect.x = x; + srcRect.y = y; + srcRect.width = w; + srcRect.height = h; + pRenderContext->CopyRenderTargetToTextureEx( m_StunTexture, 0, &srcRect, NULL ); + + // Restore our state + pRenderContext->MatrixMode( MATERIAL_VIEW ); + pRenderContext->PopMatrix(); + pRenderContext->MatrixMode( MATERIAL_PROJECTION ); + pRenderContext->PopMatrix(); +} + +// ================================================================================================================ +// +// Ep 1. Intro blur +// +// ================================================================================================================ + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CEP1IntroEffect::Init( void ) +{ + m_flDuration = 0.0f; + m_flFinishTime = 0.0f; + m_bUpdateView = true; + m_bFadeOut = false; + + KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" ); + pVMTKeyValues->SetString( "$basetexture", STUN_TEXTURE ); + m_EffectMaterial.Init( "__ep1introeffect", TEXTURE_GROUP_CLIENT_EFFECTS, pVMTKeyValues ); + m_StunTexture.Init( STUN_TEXTURE, TEXTURE_GROUP_CLIENT_EFFECTS ); +} + +void CEP1IntroEffect::Shutdown( void ) +{ + m_EffectMaterial.Shutdown(); + m_StunTexture.Shutdown(); +} + + +//------------------------------------------------------------------------------ +// Purpose: Pick up changes in our parameters +//------------------------------------------------------------------------------ +void CEP1IntroEffect::SetParameters( KeyValues *params ) +{ + if( params->FindKey( "duration" ) ) + { + m_flDuration = params->GetFloat( "duration" ); + m_flFinishTime = gpGlobals->curtime + m_flDuration; + } + + if( params->FindKey( "fadeout" ) ) + { + m_bFadeOut = ( params->GetInt( "fadeout" ) == 1 ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Get the alpha value depending on various factors and time +//----------------------------------------------------------------------------- +inline unsigned char CEP1IntroEffect::GetFadeAlpha( void ) +{ + // Find our percentage between fully "on" and "off" in the pulse range + float flEffectPerc = ( m_flDuration == 0.0f ) ? 0.0f : ( m_flFinishTime - gpGlobals->curtime ) / m_flDuration; + flEffectPerc = clamp( flEffectPerc, 0.0f, 1.0f ); + + if ( m_bFadeOut ) + { + // HDR requires us to be more subtle, or we get uber-brightening + if ( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE ) + return (unsigned char) clamp( 50.0f * flEffectPerc, 0.0f, 50.0f ); + + // Non-HDR + return (unsigned char) clamp( 64.0f * flEffectPerc, 0.0f, 64.0f ); + } + else + { + // HDR requires us to be more subtle, or we get uber-brightening + if ( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE ) + return (unsigned char) clamp( 64.0f * flEffectPerc, 50.0f, 64.0f ); + + // Non-HDR + return (unsigned char) clamp( 128.0f * flEffectPerc, 64.0f, 128.0f ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Render the effect +//----------------------------------------------------------------------------- +void CEP1IntroEffect::Render( int x, int y, int w, int h ) +{ + if ( ( m_flFinishTime == 0 ) || ( IsEnabled() == false ) ) + return; + + CMatRenderContextPtr pRenderContext( materials ); + + // Set ourselves to the proper rendermode + pRenderContext->MatrixMode( MATERIAL_VIEW ); + pRenderContext->PushMatrix(); + pRenderContext->LoadIdentity(); + pRenderContext->MatrixMode( MATERIAL_PROJECTION ); + pRenderContext->PushMatrix(); + pRenderContext->LoadIdentity(); + + // Draw the texture if we're using it + if ( m_bUpdateView ) + { + // Save off this pass + Rect_t srcRect; + srcRect.x = x; + srcRect.y = y; + srcRect.width = w; + srcRect.height = h; + pRenderContext->CopyRenderTargetToTextureEx( m_StunTexture, 0, &srcRect, NULL ); + m_bUpdateView = false; + } + + byte overlaycolor[4] = { 255, 255, 255, 0 }; + + // Get our fade value depending on our fade duration + overlaycolor[3] = GetFadeAlpha(); + if ( g_pMaterialSystemHardwareConfig->UsesSRGBCorrectBlending() ) + { + // For DX10 cards, alpha blending happens in linear space, so try to adjust by hacking alpha to 50% + overlaycolor[3] *= 0.7f; + } + + // Disable overself if we're done fading out + if ( m_bFadeOut && overlaycolor[3] == 0 ) + { + // Takes effect next frame (we don't want to hose our matrix stacks here) + g_pScreenSpaceEffects->DisableScreenSpaceEffect( "episodic_intro" ); + m_bUpdateView = true; + } + + // Calculate some wavey noise to jitter the view by + float vX = 2.0f * -fabs( cosf( gpGlobals->curtime ) * cosf( gpGlobals->curtime * 6.0 ) ); + float vY = 2.0f * cosf( gpGlobals->curtime ) * cosf( gpGlobals->curtime * 5.0 ); + + // Scale percentage + float flScalePerc = 0.02f + ( 0.01f * cosf( gpGlobals->curtime * 2.0f ) * cosf( gpGlobals->curtime * 0.5f ) ); + + // Scaled offsets for the UVs (as texels) + float flUOffset = ( m_StunTexture->GetActualWidth() - 1 ) * flScalePerc * 0.5f; + float flVOffset = ( m_StunTexture->GetActualHeight() - 1 ) * flScalePerc * 0.5f; + + // New UVs with scaling offsets + float flU1 = flUOffset; + float flU2 = ( m_StunTexture->GetActualWidth() - 1 ) - flUOffset; + float flV1 = flVOffset; + float flV2 = ( m_StunTexture->GetActualHeight() - 1 ) - flVOffset; + + // Draw the "zoomed" overlay + pRenderContext->DrawScreenSpaceRectangle( m_EffectMaterial, vX, vY, w, h, + flU1, flV1, + flU2, flV2, + m_StunTexture->GetActualWidth(), m_StunTexture->GetActualHeight() ); + + render->ViewDrawFade( overlaycolor, m_EffectMaterial ); + + // Save off this pass + Rect_t srcRect; + srcRect.x = x; + srcRect.y = y; + srcRect.width = w; + srcRect.height = h; + pRenderContext->CopyRenderTargetToTextureEx( m_StunTexture, 0, &srcRect, NULL ); + + // Restore our state + pRenderContext->MatrixMode( MATERIAL_VIEW ); + pRenderContext->PopMatrix(); + pRenderContext->MatrixMode( MATERIAL_PROJECTION ); + pRenderContext->PopMatrix(); +} + +// ================================================================================================================ +// +// Ep 2. Groggy-player view +// +// ================================================================================================================ + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CEP2StunEffect::Init( void ) +{ + m_flDuration = 0.0f; + m_flFinishTime = 0.0f; + m_bUpdateView = true; + m_bFadeOut = false; + + KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" ); + pVMTKeyValues->SetString( "$basetexture", STUN_TEXTURE ); + m_EffectMaterial.Init( "__ep2stuneffect", TEXTURE_GROUP_CLIENT_EFFECTS, pVMTKeyValues ); + m_StunTexture.Init( STUN_TEXTURE, TEXTURE_GROUP_CLIENT_EFFECTS ); +} + +void CEP2StunEffect::Shutdown( void ) +{ + m_EffectMaterial.Shutdown(); + m_StunTexture.Shutdown(); +} + +//------------------------------------------------------------------------------ +// Purpose: Pick up changes in our parameters +//------------------------------------------------------------------------------ +void CEP2StunEffect::SetParameters( KeyValues *params ) +{ + if( params->FindKey( "duration" ) ) + { + m_flDuration = params->GetFloat( "duration" ); + m_flFinishTime = gpGlobals->curtime + m_flDuration; + } + + if( params->FindKey( "fadeout" ) ) + { + m_bFadeOut = ( params->GetInt( "fadeout" ) == 1 ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Get the alpha value depending on various factors and time +//----------------------------------------------------------------------------- +inline unsigned char CEP2StunEffect::GetFadeAlpha( void ) +{ + // Find our percentage between fully "on" and "off" in the pulse range + float flEffectPerc = ( m_flDuration == 0.0f ) ? 0.0f : ( m_flFinishTime - gpGlobals->curtime ) / m_flDuration; + flEffectPerc = clamp( flEffectPerc, 0.0f, 1.0f ); + + if ( m_bFadeOut ) + { + // HDR requires us to be more subtle, or we get uber-brightening + if ( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE ) + return (unsigned char) clamp( 50.0f * flEffectPerc, 0.0f, 50.0f ); + + // Non-HDR + return (unsigned char) clamp( 64.0f * flEffectPerc, 0.0f, 64.0f ); + } + else + { + // HDR requires us to be more subtle, or we get uber-brightening + if ( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE ) + return (unsigned char) clamp( 164.0f * flEffectPerc, 128.0f, 164.0f ); + + // Non-HDR + return (unsigned char) clamp( 164.0f * flEffectPerc, 128.0f, 164.0f ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Render the effect +//----------------------------------------------------------------------------- +void CEP2StunEffect::Render( int x, int y, int w, int h ) +{ + if ( ( m_flFinishTime == 0 ) || ( IsEnabled() == false ) ) + return; + + CMatRenderContextPtr pRenderContext( materials ); + + // Set ourselves to the proper rendermode + pRenderContext->MatrixMode( MATERIAL_VIEW ); + pRenderContext->PushMatrix(); + pRenderContext->LoadIdentity(); + pRenderContext->MatrixMode( MATERIAL_PROJECTION ); + pRenderContext->PushMatrix(); + pRenderContext->LoadIdentity(); + + if ( m_bUpdateView ) + { + // Save off this pass + Rect_t srcRect; + srcRect.x = x; + srcRect.y = y; + srcRect.width = w; + srcRect.height = h; + pRenderContext->CopyRenderTargetToTextureEx( m_StunTexture, 0, &srcRect, NULL ); + m_bUpdateView = false; + } + + byte overlaycolor[4] = { 255, 255, 255, 0 }; + + // Get our fade value depending on our fade duration + overlaycolor[3] = GetFadeAlpha(); + + // Disable overself if we're done fading out + if ( m_bFadeOut && overlaycolor[3] == 0 ) + { + // Takes effect next frame (we don't want to hose our matrix stacks here) + g_pScreenSpaceEffects->DisableScreenSpaceEffect( "ep2_groggy" ); + m_bUpdateView = true; + } + + // Calculate some wavey noise to jitter the view by + float vX = 4.0f * cosf( gpGlobals->curtime ) * cosf( gpGlobals->curtime * 6.0 ); + float vY = 2.0f * cosf( gpGlobals->curtime ) * cosf( gpGlobals->curtime * 5.0 ); + + float flBaseScale = 0.2f + 0.005f * sinf( gpGlobals->curtime * 4.0f ); + + // Scale percentage + float flScalePerc = flBaseScale + ( 0.01f * cosf( gpGlobals->curtime * 2.0f ) * cosf( gpGlobals->curtime * 0.5f ) ); + + // Scaled offsets for the UVs (as texels) + float flUOffset = ( m_StunTexture->GetActualWidth() - 1 ) * flScalePerc * 0.5f; + float flVOffset = ( m_StunTexture->GetActualHeight() - 1 ) * flScalePerc * 0.5f; + + // New UVs with scaling offsets + float flU1 = flUOffset; + float flU2 = ( m_StunTexture->GetActualWidth() - 1 ) - flUOffset; + float flV1 = flVOffset; + float flV2 = ( m_StunTexture->GetActualHeight() - 1 ) - flVOffset; + + // Draw the "zoomed" overlay + pRenderContext->DrawScreenSpaceRectangle( m_EffectMaterial, vX, vY, w, h, + flU1, flV1, + flU2, flV2, + m_StunTexture->GetActualWidth(), m_StunTexture->GetActualHeight() ); + + render->ViewDrawFade( overlaycolor, m_EffectMaterial ); + + // Save off this pass + Rect_t srcRect; + srcRect.x = x; + srcRect.y = y; + srcRect.width = w; + srcRect.height = h; + pRenderContext->CopyRenderTargetToTextureEx( m_StunTexture, 0, &srcRect, NULL ); + + // Restore our state + pRenderContext->MatrixMode( MATERIAL_VIEW ); + pRenderContext->PopMatrix(); + pRenderContext->MatrixMode( MATERIAL_PROJECTION ); + pRenderContext->PopMatrix(); +} diff --git a/mp/src/game/client/episodic/episodic_screenspaceeffects.h b/mp/src/game/client/episodic/episodic_screenspaceeffects.h index 0ed6687e..ff5bc716 100644 --- a/mp/src/game/client/episodic/episodic_screenspaceeffects.h +++ b/mp/src/game/client/episodic/episodic_screenspaceeffects.h @@ -1,119 +1,119 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================
-
-#ifndef EPISODIC_SCREENSPACEEFFECTS_H
-#define EPISODIC_SCREENSPACEEFFECTS_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "ScreenSpaceEffects.h"
-
-class CStunEffect : public IScreenSpaceEffect
-{
-public:
- CStunEffect( void ) :
- m_flDuration( 0.0f ),
- m_flFinishTime( 0.0f ),
- m_bUpdateView( true ) {}
-
- virtual void Init( void );
- virtual void Shutdown( void );
- virtual void SetParameters( KeyValues *params );
- virtual void Enable( bool bEnable ) {};
- virtual bool IsEnabled( ) { return true; }
-
- virtual void Render( int x, int y, int w, int h );
-
-private:
- CTextureReference m_StunTexture;
- CMaterialReference m_EffectMaterial;
- float m_flDuration;
- float m_flFinishTime;
- bool m_bUpdateView;
-};
-
-ADD_SCREENSPACE_EFFECT( CStunEffect, episodic_stun );
-
-//
-// EP1 Intro Blur
-//
-
-class CEP1IntroEffect : public IScreenSpaceEffect
-{
-public:
- CEP1IntroEffect( void ) :
- m_flDuration( 0.0f ),
- m_flFinishTime( 0.0f ),
- m_bUpdateView( true ),
- m_bEnabled( false ),
- m_bFadeOut( false ) {}
-
- virtual void Init( void );
- virtual void Shutdown( void );
- virtual void SetParameters( KeyValues *params );
- virtual void Enable( bool bEnable ) { m_bEnabled = bEnable; }
- virtual bool IsEnabled( ) { return m_bEnabled; }
-
- virtual void Render( int x, int y, int w, int h );
-
-private:
-
- inline unsigned char GetFadeAlpha( void );
-
- CTextureReference m_StunTexture;
- CMaterialReference m_EffectMaterial;
- float m_flDuration;
- float m_flFinishTime;
- bool m_bUpdateView;
- bool m_bEnabled;
- bool m_bFadeOut;
-};
-
-ADD_SCREENSPACE_EFFECT( CEP1IntroEffect, episodic_intro );
-
-//
-// EP2 Player Stunned Effect
-//
-
-//
-// EP1 Intro Blur
-//
-
-class CEP2StunEffect : public IScreenSpaceEffect
-{
-public:
- CEP2StunEffect( void ) :
- m_flDuration( 0.0f ),
- m_flFinishTime( 0.0f ),
- m_bUpdateView( true ),
- m_bEnabled( false ),
- m_bFadeOut( false ) {}
-
- virtual void Init( void );
- virtual void Shutdown( void );
- virtual void SetParameters( KeyValues *params );
- virtual void Enable( bool bEnable ) { m_bEnabled = bEnable; }
- virtual bool IsEnabled( ) { return m_bEnabled; }
-
- virtual void Render( int x, int y, int w, int h );
-
-private:
-
- inline unsigned char GetFadeAlpha( void );
-
- CTextureReference m_StunTexture;
- CMaterialReference m_EffectMaterial;
- float m_flDuration;
- float m_flFinishTime;
- bool m_bUpdateView;
- bool m_bEnabled;
- bool m_bFadeOut;
-};
-
-ADD_SCREENSPACE_EFFECT( CEP2StunEffect, ep2_groggy );
-
-#endif // EPISODIC_SCREENSPACEEFFECTS_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef EPISODIC_SCREENSPACEEFFECTS_H +#define EPISODIC_SCREENSPACEEFFECTS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "ScreenSpaceEffects.h" + +class CStunEffect : public IScreenSpaceEffect +{ +public: + CStunEffect( void ) : + m_flDuration( 0.0f ), + m_flFinishTime( 0.0f ), + m_bUpdateView( true ) {} + + virtual void Init( void ); + virtual void Shutdown( void ); + virtual void SetParameters( KeyValues *params ); + virtual void Enable( bool bEnable ) {}; + virtual bool IsEnabled( ) { return true; } + + virtual void Render( int x, int y, int w, int h ); + +private: + CTextureReference m_StunTexture; + CMaterialReference m_EffectMaterial; + float m_flDuration; + float m_flFinishTime; + bool m_bUpdateView; +}; + +ADD_SCREENSPACE_EFFECT( CStunEffect, episodic_stun ); + +// +// EP1 Intro Blur +// + +class CEP1IntroEffect : public IScreenSpaceEffect +{ +public: + CEP1IntroEffect( void ) : + m_flDuration( 0.0f ), + m_flFinishTime( 0.0f ), + m_bUpdateView( true ), + m_bEnabled( false ), + m_bFadeOut( false ) {} + + virtual void Init( void ); + virtual void Shutdown( void ); + virtual void SetParameters( KeyValues *params ); + virtual void Enable( bool bEnable ) { m_bEnabled = bEnable; } + virtual bool IsEnabled( ) { return m_bEnabled; } + + virtual void Render( int x, int y, int w, int h ); + +private: + + inline unsigned char GetFadeAlpha( void ); + + CTextureReference m_StunTexture; + CMaterialReference m_EffectMaterial; + float m_flDuration; + float m_flFinishTime; + bool m_bUpdateView; + bool m_bEnabled; + bool m_bFadeOut; +}; + +ADD_SCREENSPACE_EFFECT( CEP1IntroEffect, episodic_intro ); + +// +// EP2 Player Stunned Effect +// + +// +// EP1 Intro Blur +// + +class CEP2StunEffect : public IScreenSpaceEffect +{ +public: + CEP2StunEffect( void ) : + m_flDuration( 0.0f ), + m_flFinishTime( 0.0f ), + m_bUpdateView( true ), + m_bEnabled( false ), + m_bFadeOut( false ) {} + + virtual void Init( void ); + virtual void Shutdown( void ); + virtual void SetParameters( KeyValues *params ); + virtual void Enable( bool bEnable ) { m_bEnabled = bEnable; } + virtual bool IsEnabled( ) { return m_bEnabled; } + + virtual void Render( int x, int y, int w, int h ); + +private: + + inline unsigned char GetFadeAlpha( void ); + + CTextureReference m_StunTexture; + CMaterialReference m_EffectMaterial; + float m_flDuration; + float m_flFinishTime; + bool m_bUpdateView; + bool m_bEnabled; + bool m_bFadeOut; +}; + +ADD_SCREENSPACE_EFFECT( CEP2StunEffect, ep2_groggy ); + +#endif // EPISODIC_SCREENSPACEEFFECTS_H diff --git a/mp/src/game/client/episodic/flesh_internal_material_proxy.cpp b/mp/src/game/client/episodic/flesh_internal_material_proxy.cpp index 8407ee44..6d182ea1 100644 --- a/mp/src/game/client/episodic/flesh_internal_material_proxy.cpp +++ b/mp/src/game/client/episodic/flesh_internal_material_proxy.cpp @@ -1,225 +1,225 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-// Purpose:
-//
-// $NoKeywords: $
-//=====================================================================================//
-#include "cbase.h"
-#include "proxyentity.h"
-#include "materialsystem/imaterial.h"
-#include "materialsystem/imaterialvar.h"
-#include "debugoverlay_shared.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-class C_FleshEffectTarget;
-void AddFleshProxyTarget( C_FleshEffectTarget *pTarget );
-void RemoveFleshProxy( C_FleshEffectTarget *pTarget );
-
-//=============================================================================
-//
-// Flesh effect target (used for orchestrating the "Invisible Alyx" moment
-//
-//=============================================================================
-
-class C_FleshEffectTarget : public C_BaseEntity
-{
- DECLARE_CLASS( C_FleshEffectTarget, C_BaseEntity );
-
-public:
- float GetRadius( void )
- {
- if ( m_flScaleTime <= 0.0f )
- return m_flRadius;
-
- float dt = ( gpGlobals->curtime - m_flScaleStartTime );
- if ( dt >= m_flScaleTime )
- return m_flRadius;
-
- return SimpleSplineRemapVal( ( dt / m_flScaleTime ), 0.0f, 1.0f, m_flStartRadius, m_flRadius );
- }
-
- virtual void Release( void )
- {
- // Remove us from the list of targets
- RemoveFleshProxy( this );
- }
-
- virtual void OnDataChanged( DataUpdateType_t updateType )
- {
- BaseClass::OnDataChanged( updateType );
-
- if ( updateType == DATA_UPDATE_CREATED )
- {
- // Add us to the list of flesh proxy targets
- AddFleshProxyTarget( this );
- }
- }
-
- float m_flRadius;
- float m_flStartRadius;
- float m_flScaleStartTime;
- float m_flScaleTime;
-
- DECLARE_CLIENTCLASS();
-};
-
-void RecvProxy_FleshEffect_Radius( const CRecvProxyData *pData, void *pStruct, void *pOut )
-{
- C_FleshEffectTarget *pTarget = (C_FleshEffectTarget *) pStruct;
- float flRadius = pData->m_Value.m_Float;
-
- //If changed, update our internal information
- if ( pTarget->m_flRadius != flRadius )
- {
- pTarget->m_flStartRadius = pTarget->m_flRadius;
- pTarget->m_flScaleStartTime = gpGlobals->curtime;
- }
-
- pTarget->m_flRadius = flRadius;
-}
-
-IMPLEMENT_CLIENTCLASS_DT( C_FleshEffectTarget, DT_FleshEffectTarget, CFleshEffectTarget )
- RecvPropFloat( RECVINFO(m_flRadius), 0, RecvProxy_FleshEffect_Radius ),
- RecvPropFloat( RECVINFO(m_flScaleTime) ),
-END_RECV_TABLE()
-
-CUtlVector< C_FleshEffectTarget * > g_FleshProxyTargets;
-
-void AddFleshProxyTarget( C_FleshEffectTarget *pTarget )
-{
- // Take it!
- g_FleshProxyTargets.AddToTail( pTarget );
-}
-
-void RemoveFleshProxy( C_FleshEffectTarget *pTarget )
-{
- int nIndex = g_FleshProxyTargets.Find( pTarget );
- if ( nIndex != g_FleshProxyTargets.InvalidIndex() )
- {
- g_FleshProxyTargets.Remove( nIndex );
- }
-}
-
-// $sineVar : name of variable that controls the FleshInterior level (float)
-class CFleshInteriorMaterialProxy : public CEntityMaterialProxy
-{
-public:
- CFleshInteriorMaterialProxy();
- virtual ~CFleshInteriorMaterialProxy();
- virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
- virtual void OnBind( C_BaseEntity *pEntity );
- virtual IMaterial *GetMaterial();
-
-private:
- IMaterialVar *m_pMaterialParamFleshEffectCenterRadius1;
- IMaterialVar *m_pMaterialParamFleshEffectCenterRadius2;
- IMaterialVar *m_pMaterialParamFleshEffectCenterRadius3;
- IMaterialVar *m_pMaterialParamFleshEffectCenterRadius4;
- IMaterialVar *m_pMaterialParamFleshGlobalOpacity;
- IMaterialVar *m_pMaterialParamFleshSubsurfaceTint;
-};
-
-CFleshInteriorMaterialProxy::CFleshInteriorMaterialProxy()
-{
- m_pMaterialParamFleshEffectCenterRadius1 = NULL;
- m_pMaterialParamFleshEffectCenterRadius2 = NULL;
- m_pMaterialParamFleshEffectCenterRadius3 = NULL;
- m_pMaterialParamFleshEffectCenterRadius4 = NULL;
- m_pMaterialParamFleshGlobalOpacity = NULL;
- m_pMaterialParamFleshSubsurfaceTint = NULL;
-}
-
-CFleshInteriorMaterialProxy::~CFleshInteriorMaterialProxy()
-{
- // Do nothing
-}
-
-bool CFleshInteriorMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
-{
- bool bFoundVar = false;
-
- m_pMaterialParamFleshEffectCenterRadius1 = pMaterial->FindVar( "$FleshEffectCenterRadius1", &bFoundVar, false );
- if ( bFoundVar == false)
- return false;
-
- m_pMaterialParamFleshEffectCenterRadius2 = pMaterial->FindVar( "$FleshEffectCenterRadius2", &bFoundVar, false );
- if ( bFoundVar == false)
- return false;
-
- m_pMaterialParamFleshEffectCenterRadius3 = pMaterial->FindVar( "$FleshEffectCenterRadius3", &bFoundVar, false );
- if ( bFoundVar == false)
- return false;
-
- m_pMaterialParamFleshEffectCenterRadius4 = pMaterial->FindVar( "$FleshEffectCenterRadius4", &bFoundVar, false );
- if ( bFoundVar == false)
- return false;
-
- m_pMaterialParamFleshGlobalOpacity = pMaterial->FindVar( "$FleshGlobalOpacity", &bFoundVar, false );
- if ( bFoundVar == false)
- return false;
-
- m_pMaterialParamFleshSubsurfaceTint = pMaterial->FindVar( "$FleshSubsurfaceTint", &bFoundVar, false );
- if ( bFoundVar == false)
- return false;
-
- return true;
-}
-
-void CFleshInteriorMaterialProxy::OnBind( C_BaseEntity *pEnt )
-{
- IMaterialVar *pParams[] =
- {
- m_pMaterialParamFleshEffectCenterRadius1,
- m_pMaterialParamFleshEffectCenterRadius2,
- m_pMaterialParamFleshEffectCenterRadius3,
- m_pMaterialParamFleshEffectCenterRadius4
- };
-
- float vEffectCenterRadius[4];
- for ( int i = 0; i < ARRAYSIZE( pParams ); i++ )
- {
- if ( i < g_FleshProxyTargets.Count() )
- {
- // Setup the target
- if ( g_FleshProxyTargets[i]->IsAbsQueriesValid() == false )
- continue;
-
- Vector vecAbsOrigin = g_FleshProxyTargets[i]->GetAbsOrigin();
- vEffectCenterRadius[0] = vecAbsOrigin.x;
- vEffectCenterRadius[1] = vecAbsOrigin.y;
- vEffectCenterRadius[2] = vecAbsOrigin.z;
- vEffectCenterRadius[3] = g_FleshProxyTargets[i]->GetRadius();
- }
- else
- {
- // Clear the target
- vEffectCenterRadius[0] = vEffectCenterRadius[1] = vEffectCenterRadius[2] = vEffectCenterRadius[3] = 0.0f;
- }
-
- // Set the value either way
- pParams[i]->SetVecValue( vEffectCenterRadius, 4 );
- }
-
- // Subsurface texture. NOTE: This texture bleeds through the color of the flesh texture so expect
- // to have to set this brighter than white to really see the subsurface texture glow through.
- if ( m_pMaterialParamFleshSubsurfaceTint != NULL )
- {
- float vSubsurfaceTintColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
-
- // !!! Test code. REPLACE ME!
- // vSubsurfaceTintColor[0] = vSubsurfaceTintColor[1] = vSubsurfaceTintColor[2] = sinf( gpGlobals->curtime * 3.0f ) + 1.0f; // * 0.5f + 0.5f;
-
- m_pMaterialParamFleshSubsurfaceTint->SetVecValue( vSubsurfaceTintColor, 4 );
- }
-}
-
-IMaterial *CFleshInteriorMaterialProxy::GetMaterial()
-{
- if ( m_pMaterialParamFleshEffectCenterRadius1 == NULL)
- return NULL;
-
- return m_pMaterialParamFleshEffectCenterRadius1->GetOwningMaterial();
-}
-
-EXPOSE_INTERFACE( CFleshInteriorMaterialProxy, IMaterialProxy, "FleshInterior" IMATERIAL_PROXY_INTERFACE_VERSION );
+//========= Copyright Valve Corporation, All rights reserved. ============// +// Purpose: +// +// $NoKeywords: $ +//=====================================================================================// +#include "cbase.h" +#include "proxyentity.h" +#include "materialsystem/imaterial.h" +#include "materialsystem/imaterialvar.h" +#include "debugoverlay_shared.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +class C_FleshEffectTarget; +void AddFleshProxyTarget( C_FleshEffectTarget *pTarget ); +void RemoveFleshProxy( C_FleshEffectTarget *pTarget ); + +//============================================================================= +// +// Flesh effect target (used for orchestrating the "Invisible Alyx" moment +// +//============================================================================= + +class C_FleshEffectTarget : public C_BaseEntity +{ + DECLARE_CLASS( C_FleshEffectTarget, C_BaseEntity ); + +public: + float GetRadius( void ) + { + if ( m_flScaleTime <= 0.0f ) + return m_flRadius; + + float dt = ( gpGlobals->curtime - m_flScaleStartTime ); + if ( dt >= m_flScaleTime ) + return m_flRadius; + + return SimpleSplineRemapVal( ( dt / m_flScaleTime ), 0.0f, 1.0f, m_flStartRadius, m_flRadius ); + } + + virtual void Release( void ) + { + // Remove us from the list of targets + RemoveFleshProxy( this ); + } + + virtual void OnDataChanged( DataUpdateType_t updateType ) + { + BaseClass::OnDataChanged( updateType ); + + if ( updateType == DATA_UPDATE_CREATED ) + { + // Add us to the list of flesh proxy targets + AddFleshProxyTarget( this ); + } + } + + float m_flRadius; + float m_flStartRadius; + float m_flScaleStartTime; + float m_flScaleTime; + + DECLARE_CLIENTCLASS(); +}; + +void RecvProxy_FleshEffect_Radius( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + C_FleshEffectTarget *pTarget = (C_FleshEffectTarget *) pStruct; + float flRadius = pData->m_Value.m_Float; + + //If changed, update our internal information + if ( pTarget->m_flRadius != flRadius ) + { + pTarget->m_flStartRadius = pTarget->m_flRadius; + pTarget->m_flScaleStartTime = gpGlobals->curtime; + } + + pTarget->m_flRadius = flRadius; +} + +IMPLEMENT_CLIENTCLASS_DT( C_FleshEffectTarget, DT_FleshEffectTarget, CFleshEffectTarget ) + RecvPropFloat( RECVINFO(m_flRadius), 0, RecvProxy_FleshEffect_Radius ), + RecvPropFloat( RECVINFO(m_flScaleTime) ), +END_RECV_TABLE() + +CUtlVector< C_FleshEffectTarget * > g_FleshProxyTargets; + +void AddFleshProxyTarget( C_FleshEffectTarget *pTarget ) +{ + // Take it! + g_FleshProxyTargets.AddToTail( pTarget ); +} + +void RemoveFleshProxy( C_FleshEffectTarget *pTarget ) +{ + int nIndex = g_FleshProxyTargets.Find( pTarget ); + if ( nIndex != g_FleshProxyTargets.InvalidIndex() ) + { + g_FleshProxyTargets.Remove( nIndex ); + } +} + +// $sineVar : name of variable that controls the FleshInterior level (float) +class CFleshInteriorMaterialProxy : public CEntityMaterialProxy +{ +public: + CFleshInteriorMaterialProxy(); + virtual ~CFleshInteriorMaterialProxy(); + virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues ); + virtual void OnBind( C_BaseEntity *pEntity ); + virtual IMaterial *GetMaterial(); + +private: + IMaterialVar *m_pMaterialParamFleshEffectCenterRadius1; + IMaterialVar *m_pMaterialParamFleshEffectCenterRadius2; + IMaterialVar *m_pMaterialParamFleshEffectCenterRadius3; + IMaterialVar *m_pMaterialParamFleshEffectCenterRadius4; + IMaterialVar *m_pMaterialParamFleshGlobalOpacity; + IMaterialVar *m_pMaterialParamFleshSubsurfaceTint; +}; + +CFleshInteriorMaterialProxy::CFleshInteriorMaterialProxy() +{ + m_pMaterialParamFleshEffectCenterRadius1 = NULL; + m_pMaterialParamFleshEffectCenterRadius2 = NULL; + m_pMaterialParamFleshEffectCenterRadius3 = NULL; + m_pMaterialParamFleshEffectCenterRadius4 = NULL; + m_pMaterialParamFleshGlobalOpacity = NULL; + m_pMaterialParamFleshSubsurfaceTint = NULL; +} + +CFleshInteriorMaterialProxy::~CFleshInteriorMaterialProxy() +{ + // Do nothing +} + +bool CFleshInteriorMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues ) +{ + bool bFoundVar = false; + + m_pMaterialParamFleshEffectCenterRadius1 = pMaterial->FindVar( "$FleshEffectCenterRadius1", &bFoundVar, false ); + if ( bFoundVar == false) + return false; + + m_pMaterialParamFleshEffectCenterRadius2 = pMaterial->FindVar( "$FleshEffectCenterRadius2", &bFoundVar, false ); + if ( bFoundVar == false) + return false; + + m_pMaterialParamFleshEffectCenterRadius3 = pMaterial->FindVar( "$FleshEffectCenterRadius3", &bFoundVar, false ); + if ( bFoundVar == false) + return false; + + m_pMaterialParamFleshEffectCenterRadius4 = pMaterial->FindVar( "$FleshEffectCenterRadius4", &bFoundVar, false ); + if ( bFoundVar == false) + return false; + + m_pMaterialParamFleshGlobalOpacity = pMaterial->FindVar( "$FleshGlobalOpacity", &bFoundVar, false ); + if ( bFoundVar == false) + return false; + + m_pMaterialParamFleshSubsurfaceTint = pMaterial->FindVar( "$FleshSubsurfaceTint", &bFoundVar, false ); + if ( bFoundVar == false) + return false; + + return true; +} + +void CFleshInteriorMaterialProxy::OnBind( C_BaseEntity *pEnt ) +{ + IMaterialVar *pParams[] = + { + m_pMaterialParamFleshEffectCenterRadius1, + m_pMaterialParamFleshEffectCenterRadius2, + m_pMaterialParamFleshEffectCenterRadius3, + m_pMaterialParamFleshEffectCenterRadius4 + }; + + float vEffectCenterRadius[4]; + for ( int i = 0; i < ARRAYSIZE( pParams ); i++ ) + { + if ( i < g_FleshProxyTargets.Count() ) + { + // Setup the target + if ( g_FleshProxyTargets[i]->IsAbsQueriesValid() == false ) + continue; + + Vector vecAbsOrigin = g_FleshProxyTargets[i]->GetAbsOrigin(); + vEffectCenterRadius[0] = vecAbsOrigin.x; + vEffectCenterRadius[1] = vecAbsOrigin.y; + vEffectCenterRadius[2] = vecAbsOrigin.z; + vEffectCenterRadius[3] = g_FleshProxyTargets[i]->GetRadius(); + } + else + { + // Clear the target + vEffectCenterRadius[0] = vEffectCenterRadius[1] = vEffectCenterRadius[2] = vEffectCenterRadius[3] = 0.0f; + } + + // Set the value either way + pParams[i]->SetVecValue( vEffectCenterRadius, 4 ); + } + + // Subsurface texture. NOTE: This texture bleeds through the color of the flesh texture so expect + // to have to set this brighter than white to really see the subsurface texture glow through. + if ( m_pMaterialParamFleshSubsurfaceTint != NULL ) + { + float vSubsurfaceTintColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + + // !!! Test code. REPLACE ME! + // vSubsurfaceTintColor[0] = vSubsurfaceTintColor[1] = vSubsurfaceTintColor[2] = sinf( gpGlobals->curtime * 3.0f ) + 1.0f; // * 0.5f + 0.5f; + + m_pMaterialParamFleshSubsurfaceTint->SetVecValue( vSubsurfaceTintColor, 4 ); + } +} + +IMaterial *CFleshInteriorMaterialProxy::GetMaterial() +{ + if ( m_pMaterialParamFleshEffectCenterRadius1 == NULL) + return NULL; + + return m_pMaterialParamFleshEffectCenterRadius1->GetOwningMaterial(); +} + +EXPOSE_INTERFACE( CFleshInteriorMaterialProxy, IMaterialProxy, "FleshInterior" IMATERIAL_PROXY_INTERFACE_VERSION ); |