aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/client/episodic
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /mp/src/game/client/episodic
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/game/client/episodic')
-rw-r--r--mp/src/game/client/episodic/c_npc_advisor.cpp502
-rw-r--r--mp/src/game/client/episodic/c_npc_puppet.cpp334
-rw-r--r--mp/src/game/client/episodic/c_prop_coreball.cpp282
-rw-r--r--mp/src/game/client/episodic/c_prop_scalable.cpp392
-rw-r--r--mp/src/game/client/episodic/c_vehicle_jeep_episodic.cpp266
-rw-r--r--mp/src/game/client/episodic/c_vort_charge_token.cpp1200
-rw-r--r--mp/src/game/client/episodic/c_weapon_hopwire.cpp842
-rw-r--r--mp/src/game/client/episodic/episodic_screenspaceeffects.cpp928
-rw-r--r--mp/src/game/client/episodic/episodic_screenspaceeffects.h238
-rw-r--r--mp/src/game/client/episodic/flesh_internal_material_proxy.cpp450
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 );