summaryrefslogtreecommitdiff
path: root/game/client/sdk
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/sdk
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/client/sdk')
-rw-r--r--game/client/sdk/c_sdk_env_sparkler.cpp194
-rw-r--r--game/client/sdk/c_sdk_player.cpp407
-rw-r--r--game/client/sdk/c_sdk_player.h87
-rw-r--r--game/client/sdk/c_sdk_team.cpp33
-rw-r--r--game/client/sdk/c_sdk_team.h36
-rw-r--r--game/client/sdk/c_te_firebullets.cpp62
-rw-r--r--game/client/sdk/clientmode_sdk.cpp131
-rw-r--r--game/client/sdk/clientmode_sdk.h48
-rw-r--r--game/client/sdk/sdk_fx_impacts.cpp44
-rw-r--r--game/client/sdk/sdk_fx_weaponfx.cpp40
-rw-r--r--game/client/sdk/sdk_hud_ammo.cpp426
-rw-r--r--game/client/sdk/sdk_hud_chat.cpp471
-rw-r--r--game/client/sdk/sdk_hud_chat.h68
-rw-r--r--game/client/sdk/sdk_hud_health.cpp170
-rw-r--r--game/client/sdk/sdk_hud_message.cpp107
-rw-r--r--game/client/sdk/sdk_hud_weaponselection.cpp761
-rw-r--r--game/client/sdk/sdk_in_main.cpp23
-rw-r--r--game/client/sdk/sdk_prediction.cpp53
-rw-r--r--game/client/sdk/vgui/sdkviewport.cpp85
-rw-r--r--game/client/sdk/vgui/sdkviewport.h40
-rw-r--r--game/client/sdk/vgui/vgui_rootpanel_sdk.cpp106
-rw-r--r--game/client/sdk/vgui/vgui_rootpanel_sdk.h56
22 files changed, 3448 insertions, 0 deletions
diff --git a/game/client/sdk/c_sdk_env_sparkler.cpp b/game/client/sdk/c_sdk_env_sparkler.cpp
new file mode 100644
index 0000000..7e4cb62
--- /dev/null
+++ b/game/client/sdk/c_sdk_env_sparkler.cpp
@@ -0,0 +1,194 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: A simple test entity for creating special effects
+//
+//=============================================================================
+
+#include "cbase.h"
+#include "c_te_effect_dispatch.h"
+#include "particles_simple.h"
+
+// Declare the sparkler entity for the client-side
+class C_Sparkler : public C_BaseEntity
+{
+public:
+ DECLARE_CLIENTCLASS();
+ DECLARE_CLASS( C_Sparkler, C_BaseEntity );
+
+ virtual void OnDataChanged( DataUpdateType_t updateType ); // Called when data changes on the server
+ virtual void ClientThink( void ); // Client-side think function for the entity
+
+private:
+ bool m_bEmit; // Determines whether or not we should emit particles
+ float m_flScale; // Size of the effect
+
+ CSmartPtr<CSimpleEmitter> m_hEmitter; // Particle emitter for this entity
+ PMaterialHandle m_hMaterial; // Material handle used for this entity's particles
+ TimedEvent m_tParticleTimer; // Timer used to control particle emission rate
+};
+
+// Declare the data-table for server/client communication
+IMPLEMENT_CLIENTCLASS_DT( C_Sparkler, DT_Sparkler, CSparkler )
+ RecvPropInt( RECVINFO( m_bEmit ) ), // Boolean state from the server
+ RecvPropFloat( RECVINFO( m_flScale ) ),
+END_RECV_TABLE()
+
+//-----------------------------------------------------------------------------
+// Purpose: Called when data changes on the server
+//-----------------------------------------------------------------------------
+void C_Sparkler::OnDataChanged( DataUpdateType_t updateType )
+{
+ // NOTE: We MUST call the base classes' implementation of this function
+ BaseClass::OnDataChanged( updateType );
+
+ // Setup our entity's particle system on creation
+ if ( updateType == DATA_UPDATE_CREATED )
+ {
+ // Creat the emitter
+ m_hEmitter = CSimpleEmitter::Create( "env_sparkler" );
+
+ // Obtain a reference handle to our particle's desired material
+ if ( m_hEmitter.IsValid() )
+ {
+ m_hMaterial = m_hEmitter->GetPMaterial( "effects/yellowflare" );
+ }
+
+ // Spawn 128 particles per second
+ m_tParticleTimer.Init( 128 );
+
+ // Call our ClientThink() function once every client frame
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Client-side think function for the entity
+//-----------------------------------------------------------------------------
+void C_Sparkler::ClientThink( void )
+{
+ // We must have a valid emitter
+ if ( m_hEmitter == NULL )
+ return;
+
+ // We must be allowed to emit particles by the server
+ if ( m_bEmit == false )
+ return;
+
+ SimpleParticle *pParticle;
+
+ float curTime = gpGlobals->frametime;
+
+ // Add as many particles as required this frame
+ while ( m_tParticleTimer.NextEvent( curTime ) )
+ {
+ // Create the particle
+ pParticle = m_hEmitter->AddSimpleParticle( m_hMaterial, GetAbsOrigin() );
+
+ if ( pParticle == NULL )
+ return;
+
+ // Setup our size
+ pParticle->m_uchStartSize = (unsigned char) m_flScale;
+ pParticle->m_uchEndSize = 0;
+
+ // Setup our roll
+ pParticle->m_flRoll = random->RandomFloat( 0, 2*M_PI );
+ pParticle->m_flRollDelta = random->RandomFloat( -DEG2RAD( 180 ), DEG2RAD( 180 ) );
+
+ // Set our color
+ pParticle->m_uchColor[0] = 255;
+ pParticle->m_uchColor[1] = 255;
+ pParticle->m_uchColor[2] = 255;
+
+ // Setup our alpha values
+ pParticle->m_uchStartAlpha = 255;
+ pParticle->m_uchEndAlpha = 255;
+
+ // Obtain a random direction
+ Vector velocity = RandomVector( -1.0f, 1.0f );
+ VectorNormalize( velocity );
+
+ // Obtain a random speed
+ float speed = random->RandomFloat( 4.0f, 8.0f ) * m_flScale;
+
+ // Set our velocity
+ pParticle->m_vecVelocity = velocity * speed;
+
+ // Die in a short range of time
+ pParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f );
+ }
+}
+
+// ============================================================================
+//
+// Dispatch Effect version
+//
+// ============================================================================
+
+//-----------------------------------------------------------------------------
+// Purpose: Callback to create a sparkle effect on the client
+// Input : &data - information about the effect
+//-----------------------------------------------------------------------------
+void SparkleCallback( const CEffectData &data )
+{
+ // Create a simple particle emitter
+ CSmartPtr<CSimpleEmitter> pSparkleEmitter = CSimpleEmitter::Create( "Sparkle" );
+
+ if ( pSparkleEmitter == NULL )
+ return;
+
+ // Make local versions of our passed in data
+ Vector origin = data.m_vOrigin;
+ float scale = data.m_flScale;
+
+ // Set our sort origin to make the system cull properly
+ pSparkleEmitter->SetSortOrigin( origin );
+
+ // Find the material handle we wish to use for these particles
+ PMaterialHandle hMaterial = pSparkleEmitter->GetPMaterial( "effects/yellowflare" );
+
+ SimpleParticle *pParticle;
+
+ // Make a group of particles in the world
+ for ( int i = 0; i < 64; i++ )
+ {
+ // Create a particle
+ pParticle = pSparkleEmitter->AddSimpleParticle( hMaterial, origin );
+
+ if ( pParticle == NULL )
+ return;
+
+ // Set our sizes
+ pParticle->m_uchStartSize = (unsigned char) scale;
+ pParticle->m_uchEndSize = 0;
+
+ // Set our roll
+ pParticle->m_flRoll = random->RandomFloat( 0, 2*M_PI );
+ pParticle->m_flRollDelta = random->RandomFloat( -DEG2RAD( 180 ), DEG2RAD( 180 ) );
+
+ // Set our color
+ pParticle->m_uchColor[0] = 255; // Red
+ pParticle->m_uchColor[1] = 255; // Green
+ pParticle->m_uchColor[2] = 255; // Blue
+
+ // Set our alpha
+ pParticle->m_uchStartAlpha = 0;
+ pParticle->m_uchEndAlpha = 255;
+
+ // Create a random vector
+ Vector velocity = RandomVector( -1.0f, 1.0f );
+ VectorNormalize( velocity );
+
+ // Find a random speed for the particle
+ float speed = random->RandomFloat( 4.0f, 8.0f ) * scale;
+
+ // Build and set the velocity of the particle
+ pParticle->m_vecVelocity = velocity * speed;
+
+ // Declare our lifetime
+ pParticle->m_flDieTime = 1.0f;
+ }
+}
+
+// This links our server-side call to a client-side function
+DECLARE_CLIENT_EFFECT( "Sparkle", SparkleCallback );
diff --git a/game/client/sdk/c_sdk_player.cpp b/game/client/sdk/c_sdk_player.cpp
new file mode 100644
index 0000000..414e4e7
--- /dev/null
+++ b/game/client/sdk/c_sdk_player.cpp
@@ -0,0 +1,407 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "c_sdk_player.h"
+#include "weapon_sdkbase.h"
+#include "c_basetempentity.h"
+
+#if defined( CSDKPlayer )
+ #undef CSDKPlayer
+#endif
+
+
+
+
+// -------------------------------------------------------------------------------- //
+// Player animation event. Sent to the client when a player fires, jumps, reloads, etc..
+// -------------------------------------------------------------------------------- //
+
+class C_TEPlayerAnimEvent : public C_BaseTempEntity
+{
+public:
+ DECLARE_CLASS( C_TEPlayerAnimEvent, C_BaseTempEntity );
+ DECLARE_CLIENTCLASS();
+
+ virtual void PostDataUpdate( DataUpdateType_t updateType )
+ {
+ // Create the effect.
+ C_SDKPlayer *pPlayer = dynamic_cast< C_SDKPlayer* >( m_hPlayer.Get() );
+ if ( pPlayer && !pPlayer->IsDormant() )
+ {
+ pPlayer->DoAnimationEvent( (PlayerAnimEvent_t)m_iEvent.Get(), m_nData );
+ }
+ }
+
+public:
+ CNetworkHandle( CBasePlayer, m_hPlayer );
+ CNetworkVar( int, m_iEvent );
+ CNetworkVar( int, m_nData );
+};
+
+IMPLEMENT_CLIENTCLASS_EVENT( C_TEPlayerAnimEvent, DT_TEPlayerAnimEvent, CTEPlayerAnimEvent );
+
+BEGIN_RECV_TABLE_NOBASE( C_TEPlayerAnimEvent, DT_TEPlayerAnimEvent )
+ RecvPropEHandle( RECVINFO( m_hPlayer ) ),
+ RecvPropInt( RECVINFO( m_iEvent ) ),
+ RecvPropInt( RECVINFO( m_nData ) )
+END_RECV_TABLE()
+
+BEGIN_RECV_TABLE_NOBASE( C_SDKPlayer, DT_SDKLocalPlayerExclusive )
+ RecvPropInt( RECVINFO( m_iShotsFired ) ),
+END_RECV_TABLE()
+
+
+IMPLEMENT_CLIENTCLASS_DT( C_SDKPlayer, DT_SDKPlayer, CSDKPlayer )
+ RecvPropDataTable( "sdklocaldata", 0, 0, &REFERENCE_RECV_TABLE(DT_SDKLocalPlayerExclusive) ),
+ RecvPropFloat( RECVINFO( m_angEyeAngles[0] ) ),
+ RecvPropFloat( RECVINFO( m_angEyeAngles[1] ) ),
+ RecvPropInt( RECVINFO( m_iThrowGrenadeCounter ) ),
+ RecvPropEHandle( RECVINFO( m_hRagdoll ) ),
+END_RECV_TABLE()
+
+BEGIN_PREDICTION_DATA( C_SDKPlayer )
+ DEFINE_PRED_FIELD( m_flCycle, FIELD_FLOAT, FTYPEDESC_OVERRIDE | FTYPEDESC_PRIVATE | FTYPEDESC_NOERRORCHECK ),
+ DEFINE_PRED_FIELD( m_iShotsFired, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
+END_PREDICTION_DATA()
+
+class C_SDKRagdoll : public C_BaseAnimatingOverlay
+{
+public:
+ DECLARE_CLASS( C_SDKRagdoll, C_BaseAnimatingOverlay );
+ DECLARE_CLIENTCLASS();
+
+ C_SDKRagdoll();
+ ~C_SDKRagdoll();
+
+ virtual void OnDataChanged( DataUpdateType_t type );
+
+ int GetPlayerEntIndex() const;
+ IRagdoll* GetIRagdoll() const;
+
+ void ImpactTrace( trace_t *pTrace, int iDamageType, const char *pCustomImpactName );
+
+private:
+
+ C_SDKRagdoll( const C_SDKRagdoll & ) {}
+
+ void Interp_Copy( C_BaseAnimatingOverlay *pSourceEntity );
+
+ void CreateRagdoll();
+
+
+private:
+
+ EHANDLE m_hPlayer;
+ CNetworkVector( m_vecRagdollVelocity );
+ CNetworkVector( m_vecRagdollOrigin );
+};
+
+
+IMPLEMENT_CLIENTCLASS_DT_NOBASE( C_SDKRagdoll, DT_SDKRagdoll, CSDKRagdoll )
+ RecvPropVector( RECVINFO(m_vecRagdollOrigin) ),
+ RecvPropEHandle( RECVINFO( m_hPlayer ) ),
+ RecvPropInt( RECVINFO( m_nModelIndex ) ),
+ RecvPropInt( RECVINFO(m_nForceBone) ),
+ RecvPropVector( RECVINFO(m_vecForce) ),
+ RecvPropVector( RECVINFO( m_vecRagdollVelocity ) )
+END_RECV_TABLE()
+
+
+C_SDKRagdoll::C_SDKRagdoll()
+{
+}
+
+C_SDKRagdoll::~C_SDKRagdoll()
+{
+ PhysCleanupFrictionSounds( this );
+}
+
+void C_SDKRagdoll::Interp_Copy( C_BaseAnimatingOverlay *pSourceEntity )
+{
+ if ( !pSourceEntity )
+ return;
+
+ VarMapping_t *pSrc = pSourceEntity->GetVarMapping();
+ VarMapping_t *pDest = GetVarMapping();
+
+ // Find all the VarMapEntry_t's that represent the same variable.
+ for ( int i = 0; i < pDest->m_Entries.Count(); i++ )
+ {
+ VarMapEntry_t *pDestEntry = &pDest->m_Entries[i];
+ for ( int j=0; j < pSrc->m_Entries.Count(); j++ )
+ {
+ VarMapEntry_t *pSrcEntry = &pSrc->m_Entries[j];
+ if ( !Q_strcmp( pSrcEntry->watcher->GetDebugName(),
+ pDestEntry->watcher->GetDebugName() ) )
+ {
+ pDestEntry->watcher->Copy( pSrcEntry->watcher );
+ break;
+ }
+ }
+ }
+}
+
+void C_SDKRagdoll::ImpactTrace( trace_t *pTrace, int iDamageType, const char *pCustomImpactName )
+{
+ IPhysicsObject *pPhysicsObject = VPhysicsGetObject();
+
+ if( !pPhysicsObject )
+ return;
+
+ Vector dir = pTrace->endpos - pTrace->startpos;
+
+ if ( iDamageType == DMG_BLAST )
+ {
+ dir *= 4000; // adjust impact strenght
+
+ // apply force at object mass center
+ pPhysicsObject->ApplyForceCenter( dir );
+ }
+ else
+ {
+ Vector hitpos;
+
+ VectorMA( pTrace->startpos, pTrace->fraction, dir, hitpos );
+ VectorNormalize( dir );
+
+ dir *= 4000; // adjust impact strenght
+
+ // apply force where we hit it
+ pPhysicsObject->ApplyForceOffset( dir, hitpos );
+ }
+
+ m_pRagdoll->ResetRagdollSleepAfterTime();
+}
+
+
+void C_SDKRagdoll::CreateRagdoll()
+{
+ // First, initialize all our data. If we have the player's entity on our client,
+ // then we can make ourselves start out exactly where the player is.
+ C_SDKPlayer *pPlayer = dynamic_cast< C_SDKPlayer* >( m_hPlayer.Get() );
+
+ if ( pPlayer && !pPlayer->IsDormant() )
+ {
+ // move my current model instance to the ragdoll's so decals are preserved.
+ pPlayer->SnatchModelInstance( this );
+
+ VarMapping_t *varMap = GetVarMapping();
+
+ // Copy all the interpolated vars from the player entity.
+ // The entity uses the interpolated history to get bone velocity.
+ bool bRemotePlayer = (pPlayer != C_BasePlayer::GetLocalPlayer());
+ if ( bRemotePlayer )
+ {
+ Interp_Copy( pPlayer );
+
+ SetAbsAngles( pPlayer->GetRenderAngles() );
+ GetRotationInterpolator().Reset();
+
+ m_flAnimTime = pPlayer->m_flAnimTime;
+ SetSequence( pPlayer->GetSequence() );
+ m_flPlaybackRate = pPlayer->GetPlaybackRate();
+ }
+ else
+ {
+ // This is the local player, so set them in a default
+ // pose and slam their velocity, angles and origin
+ SetAbsOrigin( m_vecRagdollOrigin );
+
+ SetAbsAngles( pPlayer->GetRenderAngles() );
+
+ SetAbsVelocity( m_vecRagdollVelocity );
+
+ int iSeq = LookupSequence( "walk_lower" );
+ if ( iSeq == -1 )
+ {
+ Assert( false ); // missing walk_lower?
+ iSeq = 0;
+ }
+
+ SetSequence( iSeq ); // walk_lower, basic pose
+ SetCycle( 0.0 );
+
+ Interp_Reset( varMap );
+ }
+ }
+ else
+ {
+ // overwrite network origin so later interpolation will
+ // use this position
+ SetNetworkOrigin( m_vecRagdollOrigin );
+
+ SetAbsOrigin( m_vecRagdollOrigin );
+ SetAbsVelocity( m_vecRagdollVelocity );
+
+ Interp_Reset( GetVarMapping() );
+
+ }
+
+ SetModelIndex( m_nModelIndex );
+
+ // Make us a ragdoll..
+ m_nRenderFX = kRenderFxRagdoll;
+
+ matrix3x4_t boneDelta0[MAXSTUDIOBONES];
+ matrix3x4_t boneDelta1[MAXSTUDIOBONES];
+ matrix3x4_t currentBones[MAXSTUDIOBONES];
+ const float boneDt = 0.05f;
+
+ if ( pPlayer && !pPlayer->IsDormant() )
+ {
+ pPlayer->GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt );
+ }
+ else
+ {
+ GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt );
+ }
+
+ InitAsClientRagdoll( boneDelta0, boneDelta1, currentBones, boneDt );
+}
+
+
+void C_SDKRagdoll::OnDataChanged( DataUpdateType_t type )
+{
+ BaseClass::OnDataChanged( type );
+
+ if ( type == DATA_UPDATE_CREATED )
+ {
+ CreateRagdoll();
+ }
+}
+
+IRagdoll* C_SDKRagdoll::GetIRagdoll() const
+{
+ return m_pRagdoll;
+}
+
+C_BaseAnimating * C_SDKPlayer::BecomeRagdollOnClient()
+{
+ // Let the C_CSRagdoll entity do this.
+ // m_builtRagdoll = true;
+ return NULL;
+}
+
+
+IRagdoll* C_SDKPlayer::GetRepresentativeRagdoll() const
+{
+ if ( m_hRagdoll.Get() )
+ {
+ C_SDKRagdoll *pRagdoll = (C_SDKRagdoll*)m_hRagdoll.Get();
+
+ return pRagdoll->GetIRagdoll();
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+
+
+C_SDKPlayer::C_SDKPlayer() :
+ m_iv_angEyeAngles( "C_SDKPlayer::m_iv_angEyeAngles" )
+{
+ m_PlayerAnimState = CreatePlayerAnimState( this, this, LEGANIM_9WAY, true );
+
+ m_angEyeAngles.Init();
+ AddVar( &m_angEyeAngles, &m_iv_angEyeAngles, LATCH_SIMULATION_VAR );
+}
+
+
+C_SDKPlayer::~C_SDKPlayer()
+{
+ m_PlayerAnimState->Release();
+}
+
+
+C_SDKPlayer* C_SDKPlayer::GetLocalSDKPlayer()
+{
+ return ToSDKPlayer( C_BasePlayer::GetLocalPlayer() );
+}
+
+
+const QAngle& C_SDKPlayer::GetRenderAngles()
+{
+ if ( IsRagdoll() )
+ {
+ return vec3_angle;
+ }
+ else
+ {
+ return m_PlayerAnimState->GetRenderAngles();
+ }
+}
+
+
+void C_SDKPlayer::UpdateClientSideAnimation()
+{
+ // Update the animation data. It does the local check here so this works when using
+ // a third-person camera (and we don't have valid player angles).
+ if ( this == C_SDKPlayer::GetLocalSDKPlayer() )
+ m_PlayerAnimState->Update( EyeAngles()[YAW], m_angEyeAngles[PITCH] );
+ else
+ m_PlayerAnimState->Update( m_angEyeAngles[YAW], m_angEyeAngles[PITCH] );
+
+ BaseClass::UpdateClientSideAnimation();
+}
+
+
+void C_SDKPlayer::PostDataUpdate( DataUpdateType_t updateType )
+{
+ // C_BaseEntity assumes we're networking the entity's angles, so pretend that it
+ // networked the same value we already have.
+ SetNetworkAngles( GetLocalAngles() );
+
+ BaseClass::PostDataUpdate( updateType );
+}
+
+void C_SDKPlayer::OnDataChanged( DataUpdateType_t type )
+{
+ BaseClass::OnDataChanged( type );
+
+ if ( type == DATA_UPDATE_CREATED )
+ {
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+ }
+
+ UpdateVisibility();
+}
+
+
+void C_SDKPlayer::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
+{
+ if ( event == PLAYERANIMEVENT_THROW_GRENADE )
+ {
+ // Let the server handle this event. It will update m_iThrowGrenadeCounter and the client will
+ // pick up the event in CCSPlayerAnimState.
+ }
+ else
+ {
+ m_PlayerAnimState->DoAnimationEvent( event, nData );
+ }
+}
+
+bool C_SDKPlayer::ShouldDraw( void )
+{
+ // If we're dead, our ragdoll will be drawn for us instead.
+ if ( !IsAlive() )
+ return false;
+
+ if( GetTeamNumber() == TEAM_SPECTATOR )
+ return false;
+
+ if( IsLocalPlayer() && IsRagdoll() )
+ return true;
+
+ return BaseClass::ShouldDraw();
+}
+
+CWeaponSDKBase* C_SDKPlayer::GetActiveSDKWeapon() const
+{
+ return dynamic_cast< CWeaponSDKBase* >( GetActiveWeapon() );
+} \ No newline at end of file
diff --git a/game/client/sdk/c_sdk_player.h b/game/client/sdk/c_sdk_player.h
new file mode 100644
index 0000000..e4986b9
--- /dev/null
+++ b/game/client/sdk/c_sdk_player.h
@@ -0,0 +1,87 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef C_SDK_PLAYER_H
+#define C_SDK_PLAYER_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "sdk_playeranimstate.h"
+#include "c_baseplayer.h"
+#include "sdk_shareddefs.h"
+#include "baseparticleentity.h"
+
+
+class C_SDKPlayer : public C_BasePlayer, public ISDKPlayerAnimStateHelpers
+{
+public:
+ DECLARE_CLASS( C_SDKPlayer, C_BasePlayer );
+ DECLARE_CLIENTCLASS();
+ DECLARE_PREDICTABLE();
+ DECLARE_INTERPOLATION();
+
+ C_SDKPlayer();
+ ~C_SDKPlayer();
+
+ static C_SDKPlayer* GetLocalSDKPlayer();
+
+ virtual const QAngle& GetRenderAngles();
+ virtual void UpdateClientSideAnimation();
+ virtual void PostDataUpdate( DataUpdateType_t updateType );
+ virtual void OnDataChanged( DataUpdateType_t updateType );
+
+
+// Called by shared code.
+public:
+
+ // ISDKPlayerAnimState overrides.
+ virtual CWeaponSDKBase* SDKAnim_GetActiveWeapon();
+ virtual bool SDKAnim_CanMove();
+
+ void DoAnimationEvent( PlayerAnimEvent_t event, int nData = 0 );
+ bool ShouldDraw();
+
+ ISDKPlayerAnimState *m_PlayerAnimState;
+
+ QAngle m_angEyeAngles;
+ CInterpolatedVar< QAngle > m_iv_angEyeAngles;
+
+ CNetworkVar( int, m_iThrowGrenadeCounter ); // used to trigger grenade throw animations.
+ CNetworkVar( int, m_iShotsFired ); // number of shots fired recently
+
+ EHANDLE m_hRagdoll;
+
+ CWeaponSDKBase *GetActiveSDKWeapon() const;
+
+ C_BaseAnimating *BecomeRagdollOnClient();
+ IRagdoll* C_SDKPlayer::GetRepresentativeRagdoll() const;
+
+ void FireBullet(
+ Vector vecSrc,
+ const QAngle &shootAngles,
+ float vecSpread,
+ int iDamage,
+ int iBulletType,
+ CBaseEntity *pevAttacker,
+ bool bDoEffects,
+ float x,
+ float y );
+
+private:
+ C_SDKPlayer( const C_SDKPlayer & );
+};
+
+
+inline C_SDKPlayer* ToSDKPlayer( CBaseEntity *pPlayer )
+{
+ Assert( dynamic_cast< C_SDKPlayer* >( pPlayer ) != NULL );
+ return static_cast< C_SDKPlayer* >( pPlayer );
+}
+
+
+#endif // C_SDK_PLAYER_H
diff --git a/game/client/sdk/c_sdk_team.cpp b/game/client/sdk/c_sdk_team.cpp
new file mode 100644
index 0000000..47ab46a
--- /dev/null
+++ b/game/client/sdk/c_sdk_team.cpp
@@ -0,0 +1,33 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Client side C_SDKTeam class
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "engine/IEngineSound.h"
+#include "hud.h"
+#include "recvproxy.h"
+#include "c_sdk_team.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+IMPLEMENT_CLIENTCLASS_DT(C_SDKTeam, DT_SDKTeam, CSDKTeam)
+END_RECV_TABLE()
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_SDKTeam::C_SDKTeam()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_SDKTeam::~C_SDKTeam()
+{
+}
+
diff --git a/game/client/sdk/c_sdk_team.h b/game/client/sdk/c_sdk_team.h
new file mode 100644
index 0000000..4cd2702
--- /dev/null
+++ b/game/client/sdk/c_sdk_team.h
@@ -0,0 +1,36 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Client side CTFTeam class
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef C_SDK_TEAM_H
+#define C_SDK_TEAM_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "c_team.h"
+#include "shareddefs.h"
+
+class C_BaseEntity;
+class C_BaseObject;
+class CBaseTechnology;
+
+//-----------------------------------------------------------------------------
+// Purpose: TF's Team manager
+//-----------------------------------------------------------------------------
+class C_SDKTeam : public C_Team
+{
+ DECLARE_CLASS( C_SDKTeam, C_Team );
+ DECLARE_CLIENTCLASS();
+
+public:
+
+ C_SDKTeam();
+ virtual ~C_SDKTeam();
+};
+
+
+#endif // C_SDK_TEAM_H
diff --git a/game/client/sdk/c_te_firebullets.cpp b/game/client/sdk/c_te_firebullets.cpp
new file mode 100644
index 0000000..846be23
--- /dev/null
+++ b/game/client/sdk/c_te_firebullets.cpp
@@ -0,0 +1,62 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "sdk_fx_shared.h"
+#include "c_sdk_player.h"
+#include "c_basetempentity.h"
+#include <cliententitylist.h>
+
+
+class C_TEFireBullets : public C_BaseTempEntity
+{
+public:
+ DECLARE_CLASS( C_TEFireBullets, C_BaseTempEntity );
+ DECLARE_CLIENTCLASS();
+
+ virtual void PostDataUpdate( DataUpdateType_t updateType );
+
+public:
+ int m_iPlayer;
+ Vector m_vecOrigin;
+ QAngle m_vecAngles;
+ int m_iWeaponID;
+ int m_iMode;
+ int m_iSeed;
+ float m_flSpread;
+};
+
+
+void C_TEFireBullets::PostDataUpdate( DataUpdateType_t updateType )
+{
+ // Create the effect.
+
+ m_vecAngles.z = 0;
+
+ FX_FireBullets(
+ m_iPlayer+1,
+ m_vecOrigin,
+ m_vecAngles,
+ m_iWeaponID,
+ m_iMode,
+ m_iSeed,
+ m_flSpread );
+}
+
+
+IMPLEMENT_CLIENTCLASS_EVENT( C_TEFireBullets, DT_TEFireBullets, CTEFireBullets );
+
+
+BEGIN_RECV_TABLE_NOBASE(C_TEFireBullets, DT_TEFireBullets)
+ RecvPropVector( RECVINFO( m_vecOrigin ) ),
+ RecvPropFloat( RECVINFO( m_vecAngles[0] ) ),
+ RecvPropFloat( RECVINFO( m_vecAngles[1] ) ),
+ RecvPropInt( RECVINFO( m_iWeaponID ) ),
+ RecvPropInt( RECVINFO( m_iMode ) ),
+ RecvPropInt( RECVINFO( m_iSeed ) ),
+ RecvPropInt( RECVINFO( m_iPlayer ) ),
+ RecvPropFloat( RECVINFO( m_flSpread ) ),
+END_RECV_TABLE() \ No newline at end of file
diff --git a/game/client/sdk/clientmode_sdk.cpp b/game/client/sdk/clientmode_sdk.cpp
new file mode 100644
index 0000000..284d609
--- /dev/null
+++ b/game/client/sdk/clientmode_sdk.cpp
@@ -0,0 +1,131 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//===========================================================================//
+#include "cbase.h"
+#include "hud.h"
+#include "clientmode_sdk.h"
+#include "cdll_client_int.h"
+#include "iinput.h"
+#include "vgui/ISurface.h"
+#include "vgui/IPanel.h"
+#include <vgui_controls/AnimationController.h>
+#include "ivmodemanager.h"
+#include "buymenu.h"
+#include "filesystem.h"
+#include "vgui/IVGui.h"
+#include "hud_chat.h"
+#include "view_shared.h"
+#include "view.h"
+#include "ivrenderview.h"
+#include "model_types.h"
+#include "iefx.h"
+#include "dlight.h"
+#include <imapoverview.h>
+#include "c_playerresource.h"
+#include <KeyValues.h>
+#include "text_message.h"
+#include "panelmetaclassmgr.h"
+
+
+ConVar default_fov( "default_fov", "90", FCVAR_CHEAT );
+
+IClientMode *g_pClientMode = NULL;
+
+
+// --------------------------------------------------------------------------------- //
+// CSDKModeManager.
+// --------------------------------------------------------------------------------- //
+
+class CSDKModeManager : public IVModeManager
+{
+public:
+ virtual void Init();
+ virtual void SwitchMode( bool commander, bool force ) {}
+ virtual void LevelInit( const char *newmap );
+ virtual void LevelShutdown( void );
+ virtual void ActivateMouse( bool isactive ) {}
+};
+
+static CSDKModeManager g_ModeManager;
+IVModeManager *modemanager = ( IVModeManager * )&g_ModeManager;
+
+// --------------------------------------------------------------------------------- //
+// CSDKModeManager implementation.
+// --------------------------------------------------------------------------------- //
+
+#define SCREEN_FILE "scripts/vgui_screens.txt"
+
+void CSDKModeManager::Init()
+{
+ g_pClientMode = GetClientModeNormal();
+
+ PanelMetaClassMgr()->LoadMetaClassDefinitionFile( SCREEN_FILE );
+}
+
+void CSDKModeManager::LevelInit( const char *newmap )
+{
+ g_pClientMode->LevelInit( newmap );
+}
+
+void CSDKModeManager::LevelShutdown( void )
+{
+ g_pClientMode->LevelShutdown();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+ClientModeSDKNormal::ClientModeSDKNormal()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: If you don't know what a destructor is by now, you are probably going to get fired
+//-----------------------------------------------------------------------------
+ClientModeSDKNormal::~ClientModeSDKNormal()
+{
+}
+
+
+void ClientModeSDKNormal::InitViewport()
+{
+ m_pViewport = new SDKViewport();
+ m_pViewport->Start( gameuifuncs, gameeventmanager );
+}
+
+ClientModeSDKNormal g_ClientModeNormal;
+
+IClientMode *GetClientModeNormal()
+{
+ return &g_ClientModeNormal;
+}
+
+
+ClientModeSDKNormal* GetClientModeSDKNormal()
+{
+ Assert( dynamic_cast< ClientModeSDKNormal* >( GetClientModeNormal() ) );
+
+ return static_cast< ClientModeSDKNormal* >( GetClientModeNormal() );
+}
+
+float ClientModeSDKNormal::GetViewModelFOV( void )
+{
+ return 74.0f;
+}
+
+int ClientModeSDKNormal::GetDeathMessageStartHeight( void )
+{
+ return m_pViewport->GetDeathMessageStartHeight();
+}
+
+void ClientModeSDKNormal::PostRenderVGui()
+{
+}
+
+
+
+
diff --git a/game/client/sdk/clientmode_sdk.h b/game/client/sdk/clientmode_sdk.h
new file mode 100644
index 0000000..cbe11cc
--- /dev/null
+++ b/game/client/sdk/clientmode_sdk.h
@@ -0,0 +1,48 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef SDK_CLIENTMODE_H
+#define SDK_CLIENTMODE_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "clientmode_shared.h"
+#include "sdkviewport.h"
+
+class ClientModeSDKNormal : public ClientModeShared
+{
+DECLARE_CLASS( ClientModeSDKNormal, ClientModeShared );
+
+private:
+
+// IClientMode overrides.
+public:
+
+ ClientModeSDKNormal();
+ virtual ~ClientModeSDKNormal();
+
+ virtual void InitViewport();
+
+ virtual float GetViewModelFOV( void );
+
+ int GetDeathMessageStartHeight( void );
+
+ virtual void PostRenderVGui();
+
+
+private:
+
+ // void UpdateSpectatorMode( void );
+
+};
+
+
+extern IClientMode *GetClientModeNormal();
+extern ClientModeSDKNormal* GetClientModeSDKNormal();
+
+
+#endif // SDK_CLIENTMODE_H
diff --git a/game/client/sdk/sdk_fx_impacts.cpp b/game/client/sdk/sdk_fx_impacts.cpp
new file mode 100644
index 0000000..c1ae37f
--- /dev/null
+++ b/game/client/sdk/sdk_fx_impacts.cpp
@@ -0,0 +1,44 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Game-specific impact effect hooks
+//
+//=============================================================================//
+#include "cbase.h"
+#include "fx_impact.h"
+#include "engine/IEngineSound.h"
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handle weapon impacts
+//-----------------------------------------------------------------------------
+void ImpactCallback( const CEffectData &data )
+{
+ trace_t tr;
+ Vector vecOrigin, vecStart, vecShotDir;
+ int iMaterial, iDamageType, iHitbox;
+ short nSurfaceProp;
+
+ C_BaseEntity *pEntity = ParseImpactData( data, &vecOrigin, &vecStart, &vecShotDir, nSurfaceProp, iMaterial, iDamageType, iHitbox );
+
+ if ( !pEntity )
+ return;
+
+ // If we hit, perform our custom effects and play the sound
+ if ( Impact( vecOrigin, vecStart, iMaterial, iDamageType, iHitbox, pEntity, tr ) )
+ {
+ // Check for custom effects based on the Decal index
+ PerformCustomEffects( vecOrigin, tr, vecShotDir, iMaterial, 1.0 );
+
+ //Play a ricochet sound some of the time
+ if( random->RandomInt(1,10) <= 3 && (iDamageType == DMG_BULLET) )
+ {
+ CLocalPlayerFilter filter;
+ C_BaseEntity::EmitSound( filter, SOUND_FROM_WORLD, "Bounce.Shrapnel", &vecOrigin );
+ }
+ }
+
+ PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
+}
+
+DECLARE_CLIENT_EFFECT( "Impact", ImpactCallback );
diff --git a/game/client/sdk/sdk_fx_weaponfx.cpp b/game/client/sdk/sdk_fx_weaponfx.cpp
new file mode 100644
index 0000000..b0fe4f1
--- /dev/null
+++ b/game/client/sdk/sdk_fx_weaponfx.cpp
@@ -0,0 +1,40 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Game-specific impact effect hooks
+//
+//=============================================================================//
+#include "cbase.h"
+#include "fx_impact.h"
+#include "tempent.h"
+#include "c_te_effect_dispatch.h"
+#include "c_te_legacytempents.h"
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handle weapon effect callbacks
+//-----------------------------------------------------------------------------
+void SDK_EjectBrass( int shell, const CEffectData &data )
+{
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+
+ if( !pPlayer )
+ return;
+
+ tempents->CSEjectBrass( data.m_vOrigin, data.m_vAngles, data.m_fFlags, shell, pPlayer );
+}
+
+void SDK_FX_EjectBrass_9mm_Callback( const CEffectData &data )
+{
+ SDK_EjectBrass( CS_SHELL_9MM, data );
+}
+
+void SDK_FX_EjectBrass_12Gauge_Callback( const CEffectData &data )
+{
+ SDK_EjectBrass( CS_SHELL_12GAUGE, data );
+}
+
+
+
+DECLARE_CLIENT_EFFECT( "EjectBrass_9mm", SDK_FX_EjectBrass_9mm_Callback );
+DECLARE_CLIENT_EFFECT( "EjectBrass_12Gauge",SDK_FX_EjectBrass_12Gauge_Callback );
+
diff --git a/game/client/sdk/sdk_hud_ammo.cpp b/game/client/sdk/sdk_hud_ammo.cpp
new file mode 100644
index 0000000..a5dfb6a
--- /dev/null
+++ b/game/client/sdk/sdk_hud_ammo.cpp
@@ -0,0 +1,426 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "hud.h"
+#include "hudelement.h"
+#include "hud_macros.h"
+#include "hud_numericdisplay.h"
+#include "iclientmode.h"
+#include "iclientvehicle.h"
+#include <vgui_controls/AnimationController.h>
+#include <vgui/ILocalize.h>
+#include "ihudlcd.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: Displays current ammunition level
+//-----------------------------------------------------------------------------
+class CHudAmmo : public CHudNumericDisplay, public CHudElement
+{
+ DECLARE_CLASS_SIMPLE( CHudAmmo, CHudNumericDisplay );
+
+public:
+ CHudAmmo( const char *pElementName );
+ void Init( void );
+ void VidInit( void );
+ void Reset();
+
+ void SetAmmo(int ammo, bool playAnimation);
+ void SetAmmo2(int ammo2, bool playAnimation);
+
+protected:
+ virtual void OnThink();
+
+ void UpdateAmmoDisplays();
+ void UpdatePlayerAmmo( C_BasePlayer *player );
+
+private:
+ CHandle< C_BaseCombatWeapon > m_hCurrentActiveWeapon;
+ CHandle< C_BaseEntity > m_hCurrentVehicle;
+ int m_iAmmo;
+ int m_iAmmo2;
+};
+
+DECLARE_HUDELEMENT( CHudAmmo );
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CHudAmmo::CHudAmmo( const char *pElementName ) : BaseClass(NULL, "HudAmmo"), CHudElement( pElementName )
+{
+ SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT | HIDEHUD_WEAPONSELECTION );
+
+ hudlcd->SetGlobalStat( "(ammo_primary)", "0" );
+ hudlcd->SetGlobalStat( "(ammo_secondary)", "0" );
+ hudlcd->SetGlobalStat( "(weapon_print_name)", "" );
+ hudlcd->SetGlobalStat( "(weapon_name)", "" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudAmmo::Init( void )
+{
+ m_iAmmo = -1;
+ m_iAmmo2 = -1;
+
+ wchar_t *tempString = g_pVGuiLocalize->Find("#Valve_Hud_AMMO");
+ if (tempString)
+ {
+ SetLabelText(tempString);
+ }
+ else
+ {
+ SetLabelText(L"AMMO");
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudAmmo::VidInit( void )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Resets hud after save/restore
+//-----------------------------------------------------------------------------
+void CHudAmmo::Reset()
+{
+ BaseClass::Reset();
+
+ m_hCurrentActiveWeapon = NULL;
+ m_hCurrentVehicle = NULL;
+ m_iAmmo = 0;
+ m_iAmmo2 = 0;
+
+ UpdateAmmoDisplays();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: called every frame to get ammo info from the weapon
+//-----------------------------------------------------------------------------
+void CHudAmmo::UpdatePlayerAmmo( C_BasePlayer *player )
+{
+ // Clear out the vehicle entity
+ m_hCurrentVehicle = NULL;
+
+ C_BaseCombatWeapon *wpn = GetActiveWeapon();
+
+ hudlcd->SetGlobalStat( "(weapon_print_name)", wpn ? wpn->GetPrintName() : " " );
+ hudlcd->SetGlobalStat( "(weapon_name)", wpn ? wpn->GetName() : " " );
+
+ if ( !wpn || !player || !wpn->UsesPrimaryAmmo() )
+ {
+ hudlcd->SetGlobalStat( "(ammo_primary)", "n/a" );
+ hudlcd->SetGlobalStat( "(ammo_secondary)", "n/a" );
+
+ SetPaintEnabled(false);
+ SetPaintBackgroundEnabled(false);
+ return;
+ }
+
+ SetPaintEnabled(true);
+ SetPaintBackgroundEnabled(true);
+
+ // get the ammo in our clip
+ int ammo1 = wpn->Clip1();
+ int ammo2;
+ if (ammo1 < 0)
+ {
+ // we don't use clip ammo, just use the total ammo count
+ ammo1 = player->GetAmmoCount(wpn->GetPrimaryAmmoType());
+ ammo2 = 0;
+ }
+ else
+ {
+ // we use clip ammo, so the second ammo is the total ammo
+ ammo2 = player->GetAmmoCount(wpn->GetPrimaryAmmoType());
+ }
+
+ hudlcd->SetGlobalStat( "(ammo_primary)", VarArgs( "%d", ammo1 ) );
+ hudlcd->SetGlobalStat( "(ammo_secondary)", VarArgs( "%d", ammo2 ) );
+
+ if (wpn == m_hCurrentActiveWeapon)
+ {
+ // same weapon, just update counts
+ SetAmmo(ammo1, true);
+ SetAmmo2(ammo2, true);
+ }
+ else
+ {
+ // diferent weapon, change without triggering
+ SetAmmo(ammo1, false);
+ SetAmmo2(ammo2, false);
+
+ // update whether or not we show the total ammo display
+ if (wpn->UsesClipsForAmmo1())
+ {
+ SetShouldDisplaySecondaryValue(true);
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponUsesClips");
+ }
+ else
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponDoesNotUseClips");
+ SetShouldDisplaySecondaryValue(false);
+ }
+
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponChanged");
+ m_hCurrentActiveWeapon = wpn;
+ }
+}
+
+/*
+void CHudAmmo::UpdateVehicleAmmo( C_BasePlayer *player, IClientVehicle *pVehicle )
+{
+ m_hCurrentActiveWeapon = NULL;
+ CBaseEntity *pVehicleEnt = pVehicle->GetVehicleEnt();
+
+ if ( !pVehicleEnt || pVehicle->GetPrimaryAmmoType() < 0 )
+ {
+ SetPaintEnabled(false);
+ SetPaintBackgroundEnabled(false);
+ return;
+ }
+
+ SetPaintEnabled(true);
+ SetPaintBackgroundEnabled(true);
+
+ // get the ammo in our clip
+ int ammo1 = pVehicle->GetPrimaryAmmoClip();
+ int ammo2;
+ if (ammo1 < 0)
+ {
+ // we don't use clip ammo, just use the total ammo count
+ ammo1 = pVehicle->GetPrimaryAmmoCount();
+ ammo2 = 0;
+ }
+ else
+ {
+ // we use clip ammo, so the second ammo is the total ammo
+ ammo2 = pVehicle->GetPrimaryAmmoCount();
+ }
+
+ if (pVehicleEnt == m_hCurrentVehicle)
+ {
+ // same weapon, just update counts
+ SetAmmo(ammo1, true);
+ SetAmmo2(ammo2, true);
+ }
+ else
+ {
+ // diferent weapon, change without triggering
+ SetAmmo(ammo1, false);
+ SetAmmo2(ammo2, false);
+
+ // update whether or not we show the total ammo display
+ if (pVehicle->PrimaryAmmoUsesClips())
+ {
+ SetShouldDisplaySecondaryValue(true);
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponUsesClips");
+ }
+ else
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponDoesNotUseClips");
+ SetShouldDisplaySecondaryValue(false);
+ }
+
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponChanged");
+ m_hCurrentVehicle = pVehicleEnt;
+ }
+}
+*/
+
+//-----------------------------------------------------------------------------
+// Purpose: called every frame to get ammo info from the weapon
+//-----------------------------------------------------------------------------
+void CHudAmmo::OnThink()
+{
+ UpdateAmmoDisplays();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: updates the ammo display counts
+//-----------------------------------------------------------------------------
+void CHudAmmo::UpdateAmmoDisplays()
+{
+ C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
+
+ UpdatePlayerAmmo( player );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Updates ammo display
+//-----------------------------------------------------------------------------
+void CHudAmmo::SetAmmo(int ammo, bool playAnimation)
+{
+ if (ammo != m_iAmmo)
+ {
+ if (ammo == 0)
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoEmpty");
+ }
+ else if (ammo < m_iAmmo)
+ {
+ // ammo has decreased
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoDecreased");
+ }
+ else
+ {
+ // ammunition has increased
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoIncreased");
+ }
+
+ m_iAmmo = ammo;
+ }
+
+ SetDisplayValue(ammo);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Updates 2nd ammo display
+//-----------------------------------------------------------------------------
+void CHudAmmo::SetAmmo2(int ammo2, bool playAnimation)
+{
+ if (ammo2 != m_iAmmo2)
+ {
+ if (ammo2 == 0)
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("Ammo2Empty");
+ }
+ else if (ammo2 < m_iAmmo2)
+ {
+ // ammo has decreased
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("Ammo2Decreased");
+ }
+ else
+ {
+ // ammunition has increased
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("Ammo2Increased");
+ }
+
+ m_iAmmo2 = ammo2;
+ }
+
+ SetSecondaryValue(ammo2);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Displays the secondary ammunition level
+//-----------------------------------------------------------------------------
+class CHudSecondaryAmmo : public CHudNumericDisplay, public CHudElement
+{
+ DECLARE_CLASS_SIMPLE( CHudSecondaryAmmo, CHudNumericDisplay );
+
+public:
+ CHudSecondaryAmmo( const char *pElementName ) : BaseClass( NULL, "HudAmmoSecondary" ), CHudElement( pElementName )
+ {
+ m_iAmmo = -1;
+
+ SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_WEAPONSELECTION | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
+ }
+
+ void Init( void )
+ {
+ }
+
+ void VidInit( void )
+ {
+ }
+
+ void SetAmmo( int ammo )
+ {
+ if (ammo != m_iAmmo)
+ {
+ if (ammo == 0)
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoSecondaryEmpty");
+ }
+ else if (ammo < m_iAmmo)
+ {
+ // ammo has decreased
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoSecondaryDecreased");
+ }
+ else
+ {
+ // ammunition has increased
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoSecondaryIncreased");
+ }
+
+ m_iAmmo = ammo;
+ }
+ SetDisplayValue( ammo );
+ }
+
+ void Reset()
+ {
+ // hud reset, update ammo state
+ BaseClass::Reset();
+ m_iAmmo = 0;
+ m_hCurrentActiveWeapon = NULL;
+ SetAlpha( 0 );
+ UpdateAmmoState();
+ }
+
+protected:
+ virtual void OnThink()
+ {
+ // set whether or not the panel draws based on if we have a weapon that supports secondary ammo
+ C_BaseCombatWeapon *wpn = GetActiveWeapon();
+ C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
+ IClientVehicle *pVehicle = player ? player->GetVehicle() : NULL;
+ if (!wpn || !player || pVehicle)
+ {
+ m_hCurrentActiveWeapon = NULL;
+ SetPaintEnabled(false);
+ SetPaintBackgroundEnabled(false);
+ return;
+ }
+ else
+ {
+ SetPaintEnabled(true);
+ SetPaintBackgroundEnabled(true);
+ }
+
+ UpdateAmmoState();
+ }
+
+ void UpdateAmmoState()
+ {
+ C_BaseCombatWeapon *wpn = GetActiveWeapon();
+ C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
+
+ if (player && wpn && wpn->UsesSecondaryAmmo())
+ {
+ SetAmmo(player->GetAmmoCount(wpn->GetSecondaryAmmoType()));
+ }
+
+ if ( m_hCurrentActiveWeapon != wpn )
+ {
+ if ( wpn->UsesSecondaryAmmo() )
+ {
+ // we've changed to a weapon that uses secondary ammo
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponUsesSecondaryAmmo");
+ }
+ else
+ {
+ // we've changed away from a weapon that uses secondary ammo
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponDoesNotUseSecondaryAmmo");
+ }
+ m_hCurrentActiveWeapon = wpn;
+ }
+ }
+
+private:
+ CHandle< C_BaseCombatWeapon > m_hCurrentActiveWeapon;
+ int m_iAmmo;
+};
+
+DECLARE_HUDELEMENT( CHudSecondaryAmmo );
+
diff --git a/game/client/sdk/sdk_hud_chat.cpp b/game/client/sdk/sdk_hud_chat.cpp
new file mode 100644
index 0000000..bdeaf48
--- /dev/null
+++ b/game/client/sdk/sdk_hud_chat.cpp
@@ -0,0 +1,471 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "sdk_hud_chat.h"
+//#include "c_sdk_player.h"
+//#include "c_sdk_playerresource.h"
+#include "hud_macros.h"
+#include "text_message.h"
+#include "vguicenterprint.h"
+#include "vgui/ILocalize.h"
+#include "ihudlcd.h"
+
+ConVar cl_showtextmsg( "cl_showtextmsg", "1", 0, "Enable/disable text messages printing on the screen." );
+
+float g_ColorGreen[3] = { 153, 255, 153 };
+float g_ColorYellow[3] = { 255, 178.5, 0.0 };
+
+float *GetClientColor( int clientIndex )
+{
+ if ( clientIndex == 0 ) // console msg
+ {
+ return g_ColorGreen;
+ }
+ else
+ {
+ return g_ColorYellow;
+ }
+}
+
+// converts all '\r' characters to '\n', so that the engine can deal with the properly
+// returns a pointer to str
+static char* ConvertCRtoNL( char *str )
+{
+ for ( char *ch = str; *ch != 0; ch++ )
+ if ( *ch == '\r' )
+ *ch = '\n';
+ return str;
+}
+
+// converts all '\r' characters to '\n', so that the engine can deal with the properly
+// returns a pointer to str
+static wchar_t* ConvertCRtoNL( wchar_t *str )
+{
+ for ( wchar_t *ch = str; *ch != 0; ch++ )
+ if ( *ch == L'\r' )
+ *ch = L'\n';
+ return str;
+}
+
+static void StripEndNewlineFromString( char *str )
+{
+ int s = strlen( str ) - 1;
+ if ( s >= 0 )
+ {
+ if ( str[s] == '\n' || str[s] == '\r' )
+ str[s] = 0;
+ }
+}
+
+static void StripEndNewlineFromString( wchar_t *str )
+{
+ int s = wcslen( str ) - 1;
+ if ( s >= 0 )
+ {
+ if ( str[s] == L'\n' || str[s] == L'\r' )
+ str[s] = 0;
+ }
+}
+
+DECLARE_HUDELEMENT( CHudChat );
+
+DECLARE_HUD_MESSAGE( CHudChat, SayText );
+DECLARE_HUD_MESSAGE( CHudChat, TextMsg );
+
+
+//=====================
+//CHudChatLine
+//=====================
+
+void CHudChatLine::ApplySchemeSettings(vgui::IScheme *pScheme)
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ m_hFont = pScheme->GetFont( "ChatFont" );
+ SetBorder( NULL );
+ SetBgColor( Color( 0, 0, 0, 0 ) );
+ SetFgColor( Color( 0, 0, 0, 0 ) );
+
+ SetFont( m_hFont );
+}
+
+void CHudChatLine::PerformFadeout( void )
+{
+ // Flash + Extra bright when new
+ float curtime = gpGlobals->curtime;
+
+ int lr = m_clrText[0];
+ int lg = m_clrText[1];
+ int lb = m_clrText[2];
+
+ //CSPort chat only fades out, no blinking.
+ if ( curtime <= m_flExpireTime && curtime > m_flExpireTime - CHATLINE_FADE_TIME )
+ {
+ float frac = ( m_flExpireTime - curtime ) / CHATLINE_FADE_TIME;
+
+ int alpha = frac * 255;
+ alpha = clamp( alpha, 0, 255 );
+
+ wchar_t wbuf[4096];
+
+ GetText(0, wbuf, sizeof(wbuf));
+
+ SetText( "" );
+
+ if ( m_iNameLength > 0 )
+ {
+ wchar_t wText[4096];
+ // draw the first x characters in the player color
+ wcsncpy( wText, wbuf, MIN( m_iNameLength + 1, MAX_PLAYER_NAME_LENGTH+32) );
+ wText[ MIN( m_iNameLength, MAX_PLAYER_NAME_LENGTH+31) ] = 0;
+
+ m_clrNameColor[3] = alpha;
+
+ InsertColorChange( m_clrNameColor );
+ InsertString( wText );
+
+ wcsncpy( wText, wbuf + ( m_iNameLength ), wcslen( wbuf + m_iNameLength ) );
+ wText[ wcslen( wbuf + m_iNameLength ) ] = '\0';
+ InsertColorChange( Color( g_ColorYellow[0], g_ColorYellow[1], g_ColorYellow[2], alpha ) );
+ InsertString( wText );
+ InvalidateLayout( true );
+ }
+ else
+ {
+ InsertColorChange( Color( lr, lg, lb, alpha ) );
+ InsertString( wbuf );
+ }
+ }
+
+ OnThink();
+}
+
+
+
+//=====================
+//CHudChatInputLine
+//=====================
+
+void CHudChatInputLine::ApplySchemeSettings(vgui::IScheme *pScheme)
+{
+ BaseClass::ApplySchemeSettings(pScheme);
+
+ vgui::HFont hFont = pScheme->GetFont( "ChatFont" );
+
+ m_pPrompt->SetFont( hFont );
+ m_pInput->SetFont( hFont );
+
+ m_pInput->SetFgColor( pScheme->GetColor( "Chat.TypingText", pScheme->GetColor( "Panel.FgColor", Color( 255, 255, 255, 255 ) ) ) );
+}
+
+
+
+//=====================
+//CHudChat
+//=====================
+
+CHudChat::CHudChat( const char *pElementName ) : BaseClass( pElementName )
+{
+
+}
+
+void CHudChat::CreateChatInputLine( void )
+{
+ m_pChatInput = new CHudChatInputLine( this, "ChatInputLine" );
+ m_pChatInput->SetVisible( false );
+}
+
+void CHudChat::CreateChatLines( void )
+{
+ for ( int i = 0; i < CHAT_INTERFACE_LINES; i++ )
+ {
+ char sz[ 32 ];
+ Q_snprintf( sz, sizeof( sz ), "ChatLine%02i", i );
+ m_ChatLines[ i ] = new CHudChatLine( this, sz );
+ m_ChatLines[ i ]->SetVisible( false );
+ }
+}
+
+void CHudChat::ApplySchemeSettings( vgui::IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ SetBgColor( Color( 0, 0, 0, 0 ) );
+ SetFgColor( Color( 0, 0, 0, 0 ) );
+}
+
+
+void CHudChat::Init( void )
+{
+ BaseClass::Init();
+
+ HOOK_HUD_MESSAGE( CHudChat, SayText );
+ HOOK_HUD_MESSAGE( CHudChat, TextMsg );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Overrides base reset to not cancel chat at round restart
+//-----------------------------------------------------------------------------
+void CHudChat::Reset( void )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pszName -
+// iSize -
+// *pbuf -
+//-----------------------------------------------------------------------------
+void CHudChat::MsgFunc_SayText( bf_read &msg )
+{
+ char szString[256];
+
+ int client = msg.ReadByte();
+ msg.ReadString( szString, sizeof(szString) );
+ bool bWantsToChat = msg.ReadByte();
+
+ if ( bWantsToChat )
+ {
+ // print raw chat text
+ ChatPrintf( client, "%s", szString );
+ }
+ else
+ {
+ // try to lookup translated string
+ Printf( "%s", hudtextmessage->LookupString( szString ) );
+ }
+
+ Msg( "%s", szString );
+}
+
+wchar_t* ReadLocalizedRadioCommandString( bf_read &msg, wchar_t *pOut, int outSize, bool bStripNewline )
+{
+ char szString[2048];
+ msg.ReadString( szString, sizeof(szString) );
+
+ const wchar_t *pBuf = g_pVGuiLocalize->Find( szString );
+ if ( pBuf )
+ {
+ wcsncpy( pOut, pBuf, outSize/sizeof(wchar_t) );
+ pOut[outSize/sizeof(wchar_t)-1] = 0;
+ }
+ else
+ {
+ g_pVGuiLocalize->ConvertANSIToUnicode( szString, pOut, outSize );
+ }
+
+ if ( bStripNewline )
+ StripEndNewlineFromString( pOut );
+
+ return pOut;
+}
+
+// Message handler for text messages
+// displays a string, looking them up from the titles.txt file, which can be localised
+// parameters:
+// byte: message direction ( HUD_PRINTCONSOLE, HUD_PRINTNOTIFY, HUD_PRINTCENTER, HUD_PRINTTALK )
+// string: message
+// optional parameters:
+// string: message parameter 1
+// string: message parameter 2
+// string: message parameter 3
+// string: message parameter 4
+// any string that starts with the character '#' is a message name, and is used to look up the real message in titles.txt
+// the next (optional) one to four strings are parameters for that string (which can also be message names if they begin with '#')
+void CHudChat::MsgFunc_TextMsg( bf_read &msg )
+{
+ char szString[2048];
+ int msg_dest = msg.ReadByte();
+
+ wchar_t szBuf[5][128];
+ wchar_t outputBuf[256];
+
+ for ( int i=0; i<5; ++i )
+ {
+ msg.ReadString( szString, sizeof(szString) );
+ char *tmpStr = hudtextmessage->LookupString( szString, &msg_dest );
+ const wchar_t *pBuf = g_pVGuiLocalize->Find( tmpStr );
+ if ( pBuf )
+ {
+ // Copy pBuf into szBuf[i].
+ int nMaxChars = sizeof( szBuf[i] ) / sizeof( wchar_t );
+ wcsncpy( szBuf[i], pBuf, nMaxChars );
+ szBuf[i][nMaxChars-1] = 0;
+ }
+ else
+ {
+ if ( i )
+ {
+ StripEndNewlineFromString( tmpStr ); // these strings are meant for subsitution into the main strings, so cull the automatic end newlines
+ }
+ g_pVGuiLocalize->ConvertANSIToUnicode( tmpStr, szBuf[i], sizeof(szBuf[i]) );
+ }
+ }
+
+ if ( !cl_showtextmsg.GetInt() )
+ return;
+
+ int len;
+ switch ( msg_dest )
+ {
+ case HUD_PRINTCENTER:
+ g_pVGuiLocalize->ConstructString( outputBuf, sizeof(outputBuf), szBuf[0], 4, szBuf[1], szBuf[2], szBuf[3], szBuf[4] );
+ internalCenterPrint->Print( ConvertCRtoNL( outputBuf ) );
+ break;
+
+ case HUD_PRINTNOTIFY:
+ g_pVGuiLocalize->ConstructString( outputBuf, sizeof(outputBuf), szBuf[0], 4, szBuf[1], szBuf[2], szBuf[3], szBuf[4] );
+ g_pVGuiLocalize->ConvertUnicodeToANSI( outputBuf, szString, sizeof(szString) );
+ len = strlen( szString );
+ if ( len && szString[len-1] != '\n' && szString[len-1] != '\r' )
+ {
+ Q_strncat( szString, "\n", sizeof(szString), 1 );
+ }
+ Msg( "%s", ConvertCRtoNL( szString ) );
+ break;
+
+ case HUD_PRINTTALK:
+ g_pVGuiLocalize->ConstructString( outputBuf, sizeof(outputBuf), szBuf[0], 4, szBuf[1], szBuf[2], szBuf[3], szBuf[4] );
+ g_pVGuiLocalize->ConvertUnicodeToANSI( outputBuf, szString, sizeof(szString) );
+ len = strlen( szString );
+ if ( len && szString[len-1] != '\n' && szString[len-1] != '\r' )
+ {
+ Q_strncat( szString, "\n", sizeof(szString), 1 );
+ }
+ Printf( "%s", ConvertCRtoNL( szString ) );
+ break;
+
+ case HUD_PRINTCONSOLE:
+ g_pVGuiLocalize->ConstructString( outputBuf, sizeof(outputBuf), szBuf[0], 4, szBuf[1], szBuf[2], szBuf[3], szBuf[4] );
+ g_pVGuiLocalize->ConvertUnicodeToANSI( outputBuf, szString, sizeof(szString) );
+ len = strlen( szString );
+ if ( len && szString[len-1] != '\n' && szString[len-1] != '\r' )
+ {
+ Q_strncat( szString, "\n", sizeof(szString), 1 );
+ }
+ Msg( "%s", ConvertCRtoNL( szString ) );
+ break;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *fmt -
+// ... -
+//-----------------------------------------------------------------------------
+void CHudChat::ChatPrintf( int iPlayerIndex, const char *fmt, ... )
+{
+ va_list marker;
+ char msg[4096];
+
+ va_start(marker, fmt);
+ Q_vsnprintf(msg, sizeof( msg), fmt, marker);
+ va_end(marker);
+
+ // Strip any trailing '\n'
+ if ( strlen( msg ) > 0 && msg[ strlen( msg )-1 ] == '\n' )
+ {
+ msg[ strlen( msg ) - 1 ] = 0;
+ }
+
+ // Strip leading \n characters ( or notify/color signifiers )
+ char *pmsg = msg;
+ while ( *pmsg && ( *pmsg == '\n' || *pmsg == 1 || *pmsg == 2 ) )
+ {
+ pmsg++;
+ }
+
+ if ( !*pmsg )
+ return;
+
+ if ( *pmsg < 32 )
+ {
+ hudlcd->AddChatLine( pmsg + 1 );
+ }
+ else
+ {
+ hudlcd->AddChatLine( pmsg );
+ }
+
+ CHudChatLine *line = (CHudChatLine *)FindUnusedChatLine();
+ if ( !line )
+ {
+ ExpireOldest();
+ line = (CHudChatLine *)FindUnusedChatLine();
+ }
+
+ if ( !line )
+ {
+ return;
+ }
+
+ line->SetText( "" );
+
+ int iNameLength = 0;
+
+ player_info_t sPlayerInfo;
+ if ( iPlayerIndex == 0 )
+ {
+ Q_memset( &sPlayerInfo, 0, sizeof(player_info_t) );
+ Q_strncpy( sPlayerInfo.name, "Console", sizeof(sPlayerInfo.name) );
+ }
+ else
+ {
+ engine->GetPlayerInfo( iPlayerIndex, &sPlayerInfo );
+ }
+
+ const char *pName = sPlayerInfo.name;
+
+ if ( pName )
+ {
+ const char *nameInString = strstr( pmsg, pName );
+
+ if ( nameInString )
+ {
+ iNameLength = strlen( pName ) + (nameInString - pmsg);
+ }
+ }
+ else
+ line->InsertColorChange( Color( g_ColorYellow[0], g_ColorYellow[1], g_ColorYellow[2], 255 ) );
+
+ char *buf = static_cast<char *>( _alloca( strlen( pmsg ) + 1 ) );
+ wchar_t *wbuf = static_cast<wchar_t *>( _alloca( (strlen( pmsg ) + 1 ) * sizeof(wchar_t) ) );
+ if ( buf )
+ {
+ float *flColor = GetClientColor( iPlayerIndex );
+
+ line->SetExpireTime();
+
+ // draw the first x characters in the player color
+ Q_strncpy( buf, pmsg, MIN( iNameLength + 1, MAX_PLAYER_NAME_LENGTH+32) );
+ buf[ MIN( iNameLength, MAX_PLAYER_NAME_LENGTH+31) ] = 0;
+ line->InsertColorChange( Color( flColor[0], flColor[1], flColor[2], 255 ) );
+ line->InsertString( buf );
+ Q_strncpy( buf, pmsg + iNameLength, strlen( pmsg ));
+ buf[ strlen( pmsg + iNameLength ) ] = '\0';
+ line->InsertColorChange( Color( g_ColorYellow[0], g_ColorYellow[1], g_ColorYellow[2], 255 ) );
+ g_pVGuiLocalize->ConvertANSIToUnicode( buf, wbuf, strlen(pmsg)*sizeof(wchar_t));
+ line->InsertString( wbuf );
+ line->SetVisible( true );
+ line->SetNameLength( iNameLength );
+ line->SetNameColor( Color( flColor[0], flColor[1], flColor[2], 255 ) );
+ }
+
+ CLocalPlayerFilter filter;
+ C_BaseEntity::EmitSound( filter, -1 /*SOUND_FROM_LOCAL_PLAYER*/, "HudChat.Message" );
+}
+
+int CHudChat::GetChatInputOffset( void )
+{
+ if ( m_pChatInput->IsVisible() )
+ {
+ return m_iFontHeight;
+ }
+ else
+ return 0;
+}
diff --git a/game/client/sdk/sdk_hud_chat.h b/game/client/sdk/sdk_hud_chat.h
new file mode 100644
index 0000000..26d3e58
--- /dev/null
+++ b/game/client/sdk/sdk_hud_chat.h
@@ -0,0 +1,68 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef SDK_HUD_CHAT_H
+#define SDK_HUD_CHAT_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <hud_basechat.h>
+
+class CHudChatLine : public CBaseHudChatLine
+{
+ DECLARE_CLASS_SIMPLE( CHudChatLine, CBaseHudChatLine );
+
+public:
+ CHudChatLine( vgui::Panel *parent, const char *panelName ) : CBaseHudChatLine( parent, panelName ) {}
+
+ virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
+
+ void PerformFadeout( void );
+
+ void MsgFunc_SayText(bf_read &msg);
+
+private:
+ CHudChatLine( const CHudChatLine & ); // not defined, not accessible
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: The prompt and text entry area for chat messages
+//-----------------------------------------------------------------------------
+class CHudChatInputLine : public CBaseHudChatInputLine
+{
+ DECLARE_CLASS_SIMPLE( CHudChatInputLine, CBaseHudChatInputLine );
+
+public:
+ CHudChatInputLine( CBaseHudChat *parent, char const *panelName ) : CBaseHudChatInputLine( parent, panelName ) {}
+
+ virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
+};
+
+class CHudChat : public CBaseHudChat
+{
+ DECLARE_CLASS_SIMPLE( CHudChat, CBaseHudChat );
+
+public:
+ CHudChat( const char *pElementName );
+
+ virtual void CreateChatInputLine( void );
+ virtual void CreateChatLines( void );
+
+ virtual void Init( void );
+ virtual void Reset( void );
+ virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
+
+ void MsgFunc_SayText( bf_read &msg );
+ void MsgFunc_TextMsg( bf_read &msg );
+
+ void ChatPrintf( int iPlayerIndex, PRINTF_FORMAT_STRING const char *fmt, ... );
+
+ int GetChatInputOffset( void );
+};
+
+#endif //SDK_HUD_CHAT_H \ No newline at end of file
diff --git a/game/client/sdk/sdk_hud_health.cpp b/game/client/sdk/sdk_hud_health.cpp
new file mode 100644
index 0000000..9f984a0
--- /dev/null
+++ b/game/client/sdk/sdk_hud_health.cpp
@@ -0,0 +1,170 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+//
+// Health.cpp
+//
+// implementation of CHudHealth class
+//
+#include "cbase.h"
+#include "hud.h"
+#include "hud_macros.h"
+#include "view.h"
+
+#include "iclientmode.h"
+
+#include <KeyValues.h>
+#include <vgui/ISurface.h>
+#include <vgui/ISystem.h>
+#include <vgui_controls/AnimationController.h>
+
+#include <vgui/ILocalize.h>
+
+using namespace vgui;
+
+#include "hudelement.h"
+#include "hud_numericdisplay.h"
+
+#include "ConVar.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#define INIT_HEALTH -1
+
+//-----------------------------------------------------------------------------
+// Purpose: Health panel
+//-----------------------------------------------------------------------------
+class CHudHealth : public CHudElement, public CHudNumericDisplay
+{
+ DECLARE_CLASS_SIMPLE( CHudHealth, CHudNumericDisplay );
+
+public:
+ CHudHealth( const char *pElementName );
+ virtual void Init( void );
+ virtual void VidInit( void );
+ virtual void Reset( void );
+ virtual void OnThink();
+ void MsgFunc_Damage( bf_read &msg );
+
+private:
+ // old variables
+ int m_iHealth;
+
+ int m_bitsDamage;
+};
+
+DECLARE_HUDELEMENT( CHudHealth );
+DECLARE_HUD_MESSAGE( CHudHealth, Damage );
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CHudHealth::CHudHealth( const char *pElementName ) : CHudElement( pElementName ), CHudNumericDisplay(NULL, "HudHealth")
+{
+ SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudHealth::Init()
+{
+ HOOK_HUD_MESSAGE( CHudHealth, Damage );
+ Reset();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudHealth::Reset()
+{
+ m_iHealth = INIT_HEALTH;
+ m_bitsDamage = 0;
+
+ wchar_t *tempString = g_pVGuiLocalize->Find("#Valve_Hud_HEALTH");
+
+ if (tempString)
+ {
+ SetLabelText(tempString);
+ }
+ else
+ {
+ SetLabelText(L"HEALTH");
+ }
+ SetDisplayValue(m_iHealth);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudHealth::VidInit()
+{
+ Reset();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudHealth::OnThink()
+{
+ int newHealth = 0;
+ C_BasePlayer *local = C_BasePlayer::GetLocalPlayer();
+ if ( local )
+ {
+ // Never below zero
+ newHealth = MAX( local->GetHealth(), 0 );
+ }
+
+ // Only update the fade if we've changed health
+ if ( newHealth == m_iHealth )
+ {
+ return;
+ }
+
+ m_iHealth = newHealth;
+
+ if ( m_iHealth >= 20 )
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("HealthIncreasedAbove20");
+ }
+ else if ( m_iHealth > 0 )
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("HealthIncreasedBelow20");
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("HealthLow");
+ }
+
+ SetDisplayValue(m_iHealth);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudHealth::MsgFunc_Damage( bf_read &msg )
+{
+
+ int armor = msg.ReadByte(); // armor
+ int damageTaken = msg.ReadByte(); // health
+ long bitsDamage = msg.ReadLong(); // damage bits
+ bitsDamage; // variable still sent but not used
+
+ Vector vecFrom;
+
+ vecFrom.x = msg.ReadBitCoord();
+ vecFrom.y = msg.ReadBitCoord();
+ vecFrom.z = msg.ReadBitCoord();
+
+ // Actually took damage?
+ if ( damageTaken > 0 || armor > 0 )
+ {
+ if ( damageTaken > 0 )
+ {
+ // start the animation
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("HealthDamageTaken");
+ }
+ }
+} \ No newline at end of file
diff --git a/game/client/sdk/sdk_hud_message.cpp b/game/client/sdk/sdk_hud_message.cpp
new file mode 100644
index 0000000..a774abf
--- /dev/null
+++ b/game/client/sdk/sdk_hud_message.cpp
@@ -0,0 +1,107 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Simple HUD element
+//
+//=============================================================================
+
+#include "cbase.h"
+#include "hudelement.h"
+#include "hud_macros.h"
+#include "iclientmode.h"
+#include "view.h"
+
+using namespace vgui;
+
+#include <vgui_controls/Panel.h>
+#include <vgui_controls/Frame.h>
+#include <vgui/IScheme.h>
+#include <vgui/ISurface.h>
+#include <vgui/ILocalize.h>
+
+class CHudGameMessage : public CHudElement, public vgui::Panel
+{
+private:
+ DECLARE_CLASS_SIMPLE( CHudGameMessage, vgui::Panel );
+
+public:
+
+ CHudGameMessage( const char *pElementName ) : CHudElement( pElementName ), vgui::Panel( NULL, "HudGameMessage" )
+ {
+ // Set our parent window
+ SetParent( g_pClientMode->GetViewport() );
+
+ m_pIcon = NULL;
+
+ // Never hide
+ SetHiddenBits( 0 );
+ };
+
+ void Init( void );
+ void VidInit( void );
+ void Paint( void );
+
+ // Callback function for the "GameMessage" user message
+ void MsgFunc_GameMessage( bf_read &msg );
+
+private:
+ CHudTexture *m_pIcon; // Icon texture reference
+ wchar_t m_pText[256]; // Unicode text buffer
+
+ float m_flStartTime; // When the message was recevied
+ float m_flDuration; // Duration of the message
+};
+
+DECLARE_HUDELEMENT( CHudGameMessage );
+DECLARE_HUD_MESSAGE( CHudGameMessage, GameMessage );
+
+void CHudGameMessage::VidInit( void )
+{
+ // Store off a reference to our icon
+ m_pIcon = gHUD.GetIcon( "message_icon" );
+
+ m_pText[0] = '\0';
+}
+
+void CHudGameMessage::Init( void )
+{
+ HOOK_HUD_MESSAGE( CHudGameMessage, GameMessage );
+}
+
+void CHudGameMessage::MsgFunc_GameMessage( bf_read &msg )
+{
+ // Read in our string
+ char szString[256];
+ msg.ReadString( szString, sizeof(szString) );
+
+ // Convert it to localize friendly unicode
+ g_pVGuiLocalize->ConvertANSIToUnicode( szString, m_pText, sizeof(m_pText) );
+
+ // Setup our time trackers
+ m_flStartTime = gpGlobals->curtime;
+ m_flDuration = 5.0f;
+}
+
+void CHudGameMessage::Paint( void )
+{
+ if ( !m_pIcon )
+ return;
+
+ // Find our fade based on our time shown
+ float dt = ( m_flStartTime - gpGlobals->curtime );
+ float flAlpha = SimpleSplineRemapVal( dt, 0.0f, m_flDuration, 255, 0 );
+ flAlpha = clamp( flAlpha, 0.0f, 255.0f );
+
+ // Draw our icon
+ m_pIcon->DrawSelf( 0, 0, 32, 32, Color(255,255,255,flAlpha) );
+
+ // Get our scheme and font information
+ vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
+ vgui::HFont hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "Default" );
+
+ // Draw our text
+ surface()->DrawSetTextFont( hFont ); // set the font
+ surface()->DrawSetTextColor( 255, 255, 255, flAlpha ); // white
+ surface()->DrawSetTextPos( 32, 8 ); // x,y position
+ surface()->DrawPrintText( m_pText, wcslen(m_pText) ); // print text
+}
+
diff --git a/game/client/sdk/sdk_hud_weaponselection.cpp b/game/client/sdk/sdk_hud_weaponselection.cpp
new file mode 100644
index 0000000..7757747
--- /dev/null
+++ b/game/client/sdk/sdk_hud_weaponselection.cpp
@@ -0,0 +1,761 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "weapon_selection.h"
+#include "iclientmode.h"
+#include "history_resource.h"
+#include "input.h"
+
+#include <KeyValues.h>
+#include <vgui/IScheme.h>
+#include <vgui/ISurface.h>
+#include <vgui/ISystem.h>
+#include <vgui_controls/AnimationController.h>
+#include <vgui_controls/Panel.h>
+
+#include "vgui/ILocalize.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: hl2 weapon selection hud element
+//-----------------------------------------------------------------------------
+class CHudWeaponSelection : public CBaseHudWeaponSelection, public vgui::Panel
+{
+ DECLARE_CLASS_SIMPLE( CHudWeaponSelection, vgui::Panel );
+
+public:
+ CHudWeaponSelection(const char *pElementName );
+
+ virtual bool ShouldDraw();
+ virtual void OnWeaponPickup( C_BaseCombatWeapon *pWeapon );
+
+ virtual void CycleToNextWeapon( void );
+ virtual void CycleToPrevWeapon( void );
+
+ virtual C_BaseCombatWeapon *GetWeaponInSlot( int iSlot, int iSlotPos );
+ virtual void SelectWeaponSlot( int iSlot );
+
+ virtual C_BaseCombatWeapon *GetSelectedWeapon( void )
+ {
+ return m_hSelectedWeapon;
+ }
+
+ virtual void OpenSelection( void );
+ virtual void HideSelection( void );
+
+ virtual void LevelInit();
+
+protected:
+ virtual void OnThink();
+ virtual void Paint();
+ virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
+
+ virtual bool IsWeaponSelectable()
+ {
+ if (IsInSelectionMode())
+ return true;
+
+ return false;
+ }
+
+private:
+ C_BaseCombatWeapon *FindNextWeaponInWeaponSelection(int iCurrentSlot, int iCurrentPosition);
+ C_BaseCombatWeapon *FindPrevWeaponInWeaponSelection(int iCurrentSlot, int iCurrentPosition);
+
+ void FastWeaponSwitch( int iWeaponSlot );
+
+ virtual void SetSelectedWeapon( C_BaseCombatWeapon *pWeapon )
+ {
+ m_hSelectedWeapon = pWeapon;
+ }
+
+ void DrawBox(int x, int y, int wide, int tall, Color color, float normalizedAlpha, int number);
+
+ CPanelAnimationVar( vgui::HFont, m_hNumberFont, "NumberFont", "HudSelectionNumbers" );
+ CPanelAnimationVar( vgui::HFont, m_hTextFont, "TextFont", "HudSelectionText" );
+
+ CPanelAnimationVarAliasType( float, m_flSmallBoxSize, "SmallBoxSize", "32", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flLargeBoxWide, "LargeBoxWide", "108", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flLargeBoxTall, "LargeBoxTall", "72", "proportional_float" );
+
+ CPanelAnimationVarAliasType( float, m_flBoxGap, "BoxGap", "12", "proportional_float" );
+
+ CPanelAnimationVarAliasType( float, m_flSelectionNumberXPos, "SelectionNumberXPos", "4", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flSelectionNumberYPos, "SelectionNumberYPos", "4", "proportional_float" );
+
+ CPanelAnimationVarAliasType( float, m_flTextYPos, "TextYPos", "54", "proportional_float" );
+
+ CPanelAnimationVar( float, m_flAlphaOverride, "Alpha", "255" );
+ CPanelAnimationVar( float, m_flSelectionAlphaOverride, "SelectionAlpha", "255" );
+
+
+ CPanelAnimationVar( Color, m_TextColor, "TextColor", "SelectionTextFg" );
+ CPanelAnimationVar( Color, m_NumberColor, "NumberColor", "SelectionNumberFg" );
+ CPanelAnimationVar( Color, m_EmptyBoxColor, "EmptyBoxColor", "SelectionEmptyBoxBg" );
+ CPanelAnimationVar( Color, m_BoxColor, "BoxColor", "SelectionBoxBg" );
+ CPanelAnimationVar( Color, m_SelectedBoxColor, "SelectedBoxClor", "SelectionSelectedBoxBg" );
+
+ CPanelAnimationVar( float, m_flWeaponPickupGrowTime, "SelectionGrowTime", "0.1" );
+
+ CPanelAnimationVar( float, m_flTextScan, "TextScan", "1.0" );
+
+ bool m_bFadingOut;
+};
+
+DECLARE_HUDELEMENT( CHudWeaponSelection );
+
+using namespace vgui;
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CHudWeaponSelection::CHudWeaponSelection( const char *pElementName ) : CBaseHudWeaponSelection(pElementName), BaseClass(NULL, "HudWeaponSelection")
+{
+ vgui::Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+ m_bFadingOut = false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: sets up display for showing weapon pickup
+//-----------------------------------------------------------------------------
+void CHudWeaponSelection::OnWeaponPickup( C_BaseCombatWeapon *pWeapon )
+{
+ // add to pickup history
+ CHudHistoryResource *pHudHR = GET_HUDELEMENT( CHudHistoryResource );
+ if ( pHudHR )
+ {
+ pHudHR->AddToHistory( pWeapon );
+ }
+}
+
+#define SELECTION_TIMEOUT_THRESHOLD 5.0f // Seconds
+#define SELECTION_FADEOUT_TIME 1.5f
+
+//-----------------------------------------------------------------------------
+// Purpose: updates animation status
+//-----------------------------------------------------------------------------
+void CHudWeaponSelection::OnThink( void )
+{
+ // Time out after awhile of inactivity
+ if ( ( gpGlobals->curtime - m_flSelectionTime ) > SELECTION_TIMEOUT_THRESHOLD )
+ {
+ if (!m_bFadingOut)
+ {
+ // start fading out
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "FadeOutWeaponSelectionMenu" );
+ m_bFadingOut = true;
+ }
+ else if (gpGlobals->curtime - m_flSelectionTime > SELECTION_TIMEOUT_THRESHOLD + SELECTION_FADEOUT_TIME)
+ {
+ // finished fade, close
+ HideSelection();
+ }
+ }
+ else if (m_bFadingOut)
+ {
+ // stop us fading out, show the animation again
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "OpenWeaponSelectionMenu" );
+ m_bFadingOut = false;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns true if the panel should draw
+//-----------------------------------------------------------------------------
+bool CHudWeaponSelection::ShouldDraw()
+{
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ {
+ if ( IsInSelectionMode() )
+ {
+ HideSelection();
+ }
+ return false;
+ }
+
+ bool bret = CBaseHudWeaponSelection::ShouldDraw();
+ if ( !bret )
+ return false;
+
+ return ( m_bSelectionVisible ) ? true : false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudWeaponSelection::LevelInit()
+{
+ CHudElement::LevelInit();
+}
+
+//-------------------------------------------------------------------------
+// Purpose: draws the selection area
+//-------------------------------------------------------------------------
+void CHudWeaponSelection::Paint()
+{
+ if (!ShouldDraw())
+ return;
+
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ // find and display our current selection
+ C_BaseCombatWeapon *pSelectedWeapon = GetSelectedWeapon();
+ if ( !pSelectedWeapon )
+ return;
+
+ int iActiveSlot = (pSelectedWeapon ? pSelectedWeapon->GetSlot() : -1);
+
+ // interpolate the selected box size between the small box size and the large box size
+ // interpolation has been removed since there is no weapon pickup animation anymore, so it's all at the largest size
+ float percentageDone = 1.0f; //min(1.0f, (gpGlobals->curtime - m_flPickupStartTime) / m_flWeaponPickupGrowTime);
+ int largeBoxWide = m_flSmallBoxSize + ((m_flLargeBoxWide - m_flSmallBoxSize) * percentageDone);
+ int largeBoxTall = m_flSmallBoxSize + ((m_flLargeBoxTall - m_flSmallBoxSize) * percentageDone);
+ Color selectedColor;
+ {for (int i = 0; i < 4; i++)
+ {
+ selectedColor[i] = m_BoxColor[i] + ((m_SelectedBoxColor[i] - m_BoxColor[i]) * percentageDone);
+ }}
+
+ // calculate where to start drawing
+ int width = (MAX_WEAPON_SLOTS - 1) * (m_flSmallBoxSize + m_flBoxGap) + largeBoxWide;
+ int xpos = (GetWide() - width) / 2;
+ int ypos = 0;
+
+ // iterate over all the weapon slots
+ for ( int i = 0; i < MAX_WEAPON_SLOTS; i++ )
+ {
+ if ( i == iActiveSlot )
+ {
+ bool bFirstItem = true;
+ for (int slotpos = 0; slotpos < MAX_WEAPON_POSITIONS; slotpos++)
+ {
+ C_BaseCombatWeapon *pWeapon = GetWeaponInSlot(i, slotpos);
+ if ( !pWeapon )
+ continue;
+
+ // draw box for selected weapon
+ DrawBox(xpos, ypos, largeBoxWide, largeBoxTall, selectedColor, m_flSelectionAlphaOverride, bFirstItem ? i + 1 : -1);
+
+ // draw icon
+ Color col = GetFgColor();
+ if ( pWeapon->GetSpriteActive() )
+ {
+ // find the center of the box to draw in
+ int iconWidth = pWeapon->GetSpriteActive()->Width();
+ int iconHeight = pWeapon->GetSpriteActive()->Height();
+
+ int x_offs = (largeBoxWide - iconWidth) / 2;
+ int y_offs = (largeBoxTall - iconHeight) / 2;
+
+ if (!pWeapon->CanBeSelected())
+ {
+ // unselectable weapon, display as such
+ col = Color(255, 0, 0, col[3]);
+ }
+ else if (pWeapon == pSelectedWeapon)
+ {
+ // currently selected weapon, display brighter
+ col[3] = m_flSelectionAlphaOverride;
+
+ // draw an active version over the top
+ pWeapon->GetSpriteActive()->DrawSelf( xpos + x_offs, ypos + y_offs, col );
+ }
+
+ // draw the inactive version
+ pWeapon->GetSpriteInactive()->DrawSelf( xpos + x_offs, ypos + y_offs, col );
+ }
+
+ // draw text
+ col = m_TextColor;
+ const FileWeaponInfo_t &weaponInfo = pWeapon->GetWpnData();
+
+ if (pWeapon == pSelectedWeapon)
+ {
+ wchar_t text[128];
+ wchar_t *tempString = g_pVGuiLocalize->Find(weaponInfo.szPrintName);
+
+ // setup our localized string
+ if ( tempString )
+ {
+#ifdef WIN32
+ _snwprintf(text, sizeof(text)/sizeof(wchar_t) - 1, L"%s", tempString);
+#else
+ _snwprintf(text, sizeof(text)/sizeof(wchar_t) - 1, L"%S", tempString);
+#endif
+ text[sizeof(text)/sizeof(wchar_t) - 1] = 0;
+ }
+ else
+ {
+ // string wasn't found by g_pVGuiLocalize->Find()
+ g_pVGuiLocalize->ConvertANSIToUnicode(weaponInfo.szPrintName, text, sizeof(text));
+ }
+
+ surface()->DrawSetTextColor( col );
+ surface()->DrawSetTextFont( m_hTextFont );
+
+ // count the position
+ int slen = 0, charCount = 0, maxslen = 0;
+ int firstslen = 0;
+ {
+ for (wchar_t *pch = text; *pch != 0; pch++)
+ {
+ if (*pch == '\n')
+ {
+ // newline character, drop to the next line
+ if (slen > maxslen)
+ {
+ maxslen = slen;
+ }
+ if (!firstslen)
+ {
+ firstslen = slen;
+ }
+
+ slen = 0;
+ }
+ else if (*pch == '\r')
+ {
+ // do nothing
+ }
+ else
+ {
+ slen += surface()->GetCharacterWidth( m_hTextFont, *pch );
+ charCount++;
+ }
+ }
+ }
+ if (slen > maxslen)
+ {
+ maxslen = slen;
+ }
+ if (!firstslen)
+ {
+ firstslen = maxslen;
+ }
+
+ int tx = xpos + ((largeBoxWide - firstslen) / 2);
+ int ty = ypos + (int)m_flTextYPos;
+ surface()->DrawSetTextPos( tx, ty );
+ // adjust the charCount by the scan amount
+ charCount *= m_flTextScan;
+ for (wchar_t *pch = text; charCount > 0; pch++)
+ {
+ if (*pch == '\n')
+ {
+ // newline character, move to the next line
+ surface()->DrawSetTextPos( xpos + ((largeBoxWide - slen) / 2), ty + (surface()->GetFontTall(m_hTextFont) * 1.1f));
+ }
+ else if (*pch == '\r')
+ {
+ // do nothing
+ }
+ else
+ {
+ surface()->DrawUnicodeChar(*pch);
+ charCount--;
+ }
+ }
+ }
+
+ ypos += (largeBoxTall + m_flBoxGap);
+ bFirstItem = false;
+ }
+
+ xpos += largeBoxWide;
+ }
+ else
+ {
+ // check to see if there is a weapons in this bucket
+ if ( GetFirstPos( i ) )
+ {
+ // draw has weapon in slot
+ DrawBox(xpos, ypos, m_flSmallBoxSize, m_flSmallBoxSize, m_BoxColor, m_flAlphaOverride, i + 1);
+ }
+ else
+ {
+ // draw empty slot
+ DrawBox(xpos, ypos, m_flSmallBoxSize, m_flSmallBoxSize, m_EmptyBoxColor, m_flAlphaOverride, -1);
+ }
+
+ xpos += m_flSmallBoxSize;
+ }
+
+ // reset position
+ ypos = 0;
+ xpos += m_flBoxGap;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: draws a selection box
+//-----------------------------------------------------------------------------
+void CHudWeaponSelection::DrawBox(int x, int y, int wide, int tall, Color color, float normalizedAlpha, int number)
+{
+ BaseClass::DrawBox( x, y, wide, tall, color, normalizedAlpha / 255.0f );
+
+ // draw the number
+ if (number >= 0)
+ {
+ Color numberColor = m_NumberColor;
+ numberColor[3] *= normalizedAlpha / 255.0f;
+ surface()->DrawSetTextColor(numberColor);
+ surface()->DrawSetTextFont(m_hNumberFont);
+ wchar_t wch = '0' + number;
+ surface()->DrawSetTextPos(x + m_flSelectionNumberXPos, y + m_flSelectionNumberYPos);
+ surface()->DrawUnicodeChar(wch);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: hud scheme settings
+//-----------------------------------------------------------------------------
+void CHudWeaponSelection::ApplySchemeSettings(vgui::IScheme *pScheme)
+{
+ BaseClass::ApplySchemeSettings(pScheme);
+ SetPaintBackgroundEnabled(false);
+
+ // set our size
+ int screenWide, screenTall;
+ int x, y;
+ GetPos(x, y);
+ GetHudSize(screenWide, screenTall);
+ SetBounds(0, y, screenWide, screenTall - y);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Opens weapon selection control
+//-----------------------------------------------------------------------------
+void CHudWeaponSelection::OpenSelection( void )
+{
+ Assert(!IsInSelectionMode());
+
+ CBaseHudWeaponSelection::OpenSelection();
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("OpenWeaponSelectionMenu");
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Closes weapon selection control immediately
+//-----------------------------------------------------------------------------
+void CHudWeaponSelection::HideSelection( void )
+{
+ CBaseHudWeaponSelection::HideSelection();
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("CloseWeaponSelectionMenu");
+ m_bFadingOut = false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns the next available weapon item in the weapon selection
+//-----------------------------------------------------------------------------
+C_BaseCombatWeapon *CHudWeaponSelection::FindNextWeaponInWeaponSelection(int iCurrentSlot, int iCurrentPosition)
+{
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return NULL;
+
+ C_BaseCombatWeapon *pNextWeapon = NULL;
+
+ // search all the weapons looking for the closest next
+ int iLowestNextSlot = MAX_WEAPON_SLOTS;
+ int iLowestNextPosition = MAX_WEAPON_POSITIONS;
+ for ( int i = 0; i < MAX_WEAPONS; i++ )
+ {
+ C_BaseCombatWeapon *pWeapon = pPlayer->GetWeapon(i);
+ if ( !pWeapon )
+ continue;
+
+ if ( pWeapon->CanBeSelected() )
+ {
+ int weaponSlot = pWeapon->GetSlot(), weaponPosition = pWeapon->GetPosition();
+
+ // see if this weapon is further ahead in the selection list
+ if ( weaponSlot > iCurrentSlot || (weaponSlot == iCurrentSlot && weaponPosition > iCurrentPosition) )
+ {
+ // see if this weapon is closer than the current lowest
+ if ( weaponSlot < iLowestNextSlot || (weaponSlot == iLowestNextSlot && weaponPosition < iLowestNextPosition) )
+ {
+ iLowestNextSlot = weaponSlot;
+ iLowestNextPosition = weaponPosition;
+ pNextWeapon = pWeapon;
+ }
+ }
+ }
+ }
+
+ return pNextWeapon;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns the prior available weapon item in the weapon selection
+//-----------------------------------------------------------------------------
+C_BaseCombatWeapon *CHudWeaponSelection::FindPrevWeaponInWeaponSelection(int iCurrentSlot, int iCurrentPosition)
+{
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return NULL;
+
+ C_BaseCombatWeapon *pPrevWeapon = NULL;
+
+ // search all the weapons looking for the closest next
+ int iLowestPrevSlot = -1;
+ int iLowestPrevPosition = -1;
+ for ( int i = 0; i < MAX_WEAPONS; i++ )
+ {
+ C_BaseCombatWeapon *pWeapon = pPlayer->GetWeapon(i);
+ if ( !pWeapon )
+ continue;
+
+ if ( pWeapon->CanBeSelected() )
+ {
+ int weaponSlot = pWeapon->GetSlot(), weaponPosition = pWeapon->GetPosition();
+
+ // see if this weapon is further ahead in the selection list
+ if ( weaponSlot < iCurrentSlot || (weaponSlot == iCurrentSlot && weaponPosition < iCurrentPosition) )
+ {
+ // see if this weapon is closer than the current lowest
+ if ( weaponSlot > iLowestPrevSlot || (weaponSlot == iLowestPrevSlot && weaponPosition > iLowestPrevPosition) )
+ {
+ iLowestPrevSlot = weaponSlot;
+ iLowestPrevPosition = weaponPosition;
+ pPrevWeapon = pWeapon;
+ }
+ }
+ }
+ }
+
+ return pPrevWeapon;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Moves the selection to the next item in the menu
+//-----------------------------------------------------------------------------
+void CHudWeaponSelection::CycleToNextWeapon( void )
+{
+ // Get the local player.
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ C_BaseCombatWeapon *pNextWeapon = NULL;
+ if ( IsInSelectionMode() )
+ {
+ // find the next selection spot
+ C_BaseCombatWeapon *pWeapon = GetSelectedWeapon();
+ if ( !pWeapon )
+ return;
+
+ pNextWeapon = FindNextWeaponInWeaponSelection( pWeapon->GetSlot(), pWeapon->GetPosition() );
+ }
+ else
+ {
+ // open selection at the current place
+ pNextWeapon = pPlayer->GetActiveWeapon();
+ if ( pNextWeapon )
+ {
+ pNextWeapon = FindNextWeaponInWeaponSelection( pNextWeapon->GetSlot(), pNextWeapon->GetPosition() );
+ }
+ }
+
+ if ( !pNextWeapon )
+ {
+ // wrap around back to start
+ pNextWeapon = FindNextWeaponInWeaponSelection(-1, -1);
+ }
+
+ if ( pNextWeapon )
+ {
+ SetSelectedWeapon( pNextWeapon );
+
+ if ( !IsInSelectionMode() )
+ {
+ OpenSelection();
+ }
+
+ // Play the "cycle to next weapon" sound
+ pPlayer->EmitSound( "Player.WeaponSelectionMoveSlot" );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Moves the selection to the previous item in the menu
+//-----------------------------------------------------------------------------
+void CHudWeaponSelection::CycleToPrevWeapon( void )
+{
+ // Get the local player.
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ C_BaseCombatWeapon *pNextWeapon = NULL;
+ if ( IsInSelectionMode() )
+ {
+ // find the next selection spot
+ C_BaseCombatWeapon *pWeapon = GetSelectedWeapon();
+ if ( !pWeapon )
+ return;
+
+ pNextWeapon = FindPrevWeaponInWeaponSelection( pWeapon->GetSlot(), pWeapon->GetPosition() );
+ }
+ else
+ {
+ // open selection at the current place
+ pNextWeapon = pPlayer->GetActiveWeapon();
+ if ( pNextWeapon )
+ {
+ pNextWeapon = FindPrevWeaponInWeaponSelection( pNextWeapon->GetSlot(), pNextWeapon->GetPosition() );
+ }
+ }
+
+ if ( !pNextWeapon )
+ {
+ // wrap around back to end of weapon list
+ pNextWeapon = FindPrevWeaponInWeaponSelection(MAX_WEAPON_SLOTS, MAX_WEAPON_POSITIONS);
+ }
+
+ if ( pNextWeapon )
+ {
+ SetSelectedWeapon( pNextWeapon );
+
+ if ( !IsInSelectionMode() )
+ {
+ OpenSelection();
+ }
+
+ // Play the "cycle to next weapon" sound
+ pPlayer->EmitSound( "Player.WeaponSelectionMoveSlot" );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns the weapon in the specified slot
+//-----------------------------------------------------------------------------
+C_BaseCombatWeapon *CHudWeaponSelection::GetWeaponInSlot( int iSlot, int iSlotPos )
+{
+ C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
+ if ( !player )
+ return NULL;
+
+ for ( int i = 0; i < MAX_WEAPONS; i++ )
+ {
+ C_BaseCombatWeapon *pWeapon = player->GetWeapon(i);
+
+ if ( pWeapon == NULL )
+ continue;
+
+ if ( pWeapon->GetSlot() == iSlot && pWeapon->GetPosition() == iSlotPos )
+ return pWeapon;
+ }
+
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Opens the next weapon in the slot
+//-----------------------------------------------------------------------------
+void CHudWeaponSelection::FastWeaponSwitch( int iWeaponSlot )
+{
+ // get the slot the player's weapon is in
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ // see where we should start selection
+ int iPosition = -1;
+ C_BaseCombatWeapon *pActiveWeapon = pPlayer->GetActiveWeapon();
+ if ( pActiveWeapon && pActiveWeapon->GetSlot() == iWeaponSlot )
+ {
+ // start after this weapon
+ iPosition = pActiveWeapon->GetPosition();
+ }
+
+ C_BaseCombatWeapon *pNextWeapon = NULL;
+
+ // search for the weapon after the current one
+ pNextWeapon = FindNextWeaponInWeaponSelection(iWeaponSlot, iPosition);
+ // make sure it's in the same bucket
+ if ( !pNextWeapon || pNextWeapon->GetSlot() != iWeaponSlot )
+ {
+ // just look for any weapon in this slot
+ pNextWeapon = FindNextWeaponInWeaponSelection(iWeaponSlot, -1);
+ }
+
+ // see if we found a weapon that's different from the current and in the selected slot
+ if ( pNextWeapon && pNextWeapon != pActiveWeapon && pNextWeapon->GetSlot() == iWeaponSlot )
+ {
+ // select the new weapon
+ ::input->MakeWeaponSelection( pNextWeapon );
+ }
+ else if ( pNextWeapon != pActiveWeapon )
+ {
+ // error sound
+ pPlayer->EmitSound( "Player.DenyWeaponSelection" );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Moves selection to the specified slot
+//-----------------------------------------------------------------------------
+void CHudWeaponSelection::SelectWeaponSlot( int iSlot )
+{
+ // iSlot is one higher than it should be, since it's the number key, not the 0-based index into the weapons
+ --iSlot;
+
+ // Get the local player.
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ // Don't try and read past our possible number of slots
+ if ( iSlot > MAX_WEAPON_SLOTS )
+ return;
+
+ // Make sure the player's allowed to switch weapons
+ if ( pPlayer->IsAllowedToSwitchWeapons() == false )
+ return;
+
+ // do a fast switch if set
+ if ( hud_fastswitch.GetBool() )
+ {
+ FastWeaponSwitch( iSlot );
+ return;
+ }
+
+ int slotPos = 0;
+ C_BaseCombatWeapon *pActiveWeapon = GetSelectedWeapon();
+
+ // start later in the list
+ if ( IsInSelectionMode() && pActiveWeapon && pActiveWeapon->GetSlot() == iSlot )
+ {
+ slotPos = pActiveWeapon->GetPosition() + 1;
+ }
+
+ // find the weapon in this slot
+ pActiveWeapon = GetNextActivePos( iSlot, slotPos );
+ if ( !pActiveWeapon )
+ {
+ pActiveWeapon = GetNextActivePos( iSlot, 0 );
+ }
+
+ if ( pActiveWeapon != NULL )
+ {
+ if ( !IsInSelectionMode() )
+ {
+ // open the weapon selection
+ OpenSelection();
+ }
+
+ // Mark the change
+ SetSelectedWeapon( pActiveWeapon );
+ }
+
+ pPlayer->EmitSound( "Player.WeaponSelectionMoveSlot" );
+}
diff --git a/game/client/sdk/sdk_in_main.cpp b/game/client/sdk/sdk_in_main.cpp
new file mode 100644
index 0000000..1ce48c7
--- /dev/null
+++ b/game/client/sdk/sdk_in_main.cpp
@@ -0,0 +1,23 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: TF2 specific input handling
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "kbutton.h"
+#include "input.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: TF Input interface
+//-----------------------------------------------------------------------------
+class CSDKInput : public CInput
+{
+public:
+};
+
+static CSDKInput g_Input;
+
+// Expose this interface
+IInput *input = ( IInput * )&g_Input;
+
diff --git a/game/client/sdk/sdk_prediction.cpp b/game/client/sdk/sdk_prediction.cpp
new file mode 100644
index 0000000..c72a990
--- /dev/null
+++ b/game/client/sdk/sdk_prediction.cpp
@@ -0,0 +1,53 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "prediction.h"
+#include "c_baseplayer.h"
+#include "igamemovement.h"
+
+
+static CMoveData g_MoveData;
+CMoveData *g_pMoveData = &g_MoveData;
+
+
+class CSDKPrediction : public CPrediction
+{
+DECLARE_CLASS( CSDKPrediction, CPrediction );
+
+public:
+ virtual void SetupMove( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move );
+ virtual void FinishMove( C_BasePlayer *player, CUserCmd *ucmd, CMoveData *move );
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CSDKPrediction::SetupMove( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper,
+ CMoveData *move )
+{
+ // Call the default SetupMove code.
+ BaseClass::SetupMove( player, ucmd, pHelper, move );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CSDKPrediction::FinishMove( C_BasePlayer *player, CUserCmd *ucmd, CMoveData *move )
+{
+ // Call the default FinishMove code.
+ BaseClass::FinishMove( player, ucmd, move );
+}
+
+
+// Expose interface to engine
+// Expose interface to engine
+static CSDKPrediction g_Prediction;
+
+EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CSDKPrediction, IPrediction, VCLIENT_PREDICTION_INTERFACE_VERSION, g_Prediction );
+
+CPrediction *prediction = &g_Prediction;
+
diff --git a/game/client/sdk/vgui/sdkviewport.cpp b/game/client/sdk/vgui/sdkviewport.cpp
new file mode 100644
index 0000000..5fd3627
--- /dev/null
+++ b/game/client/sdk/vgui/sdkviewport.cpp
@@ -0,0 +1,85 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Client DLL VGUI2 Viewport
+//
+// $Workfile: $
+// $Date: $
+//
+//-----------------------------------------------------------------------------
+// $Log: $
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+
+#pragma warning( disable : 4800 ) // disable forcing int to bool performance warning
+
+// VGUI panel includes
+#include <vgui_controls/Panel.h>
+#include <vgui/ISurface.h>
+#include <KeyValues.h>
+#include <vgui/Cursor.h>
+#include <vgui/IScheme.h>
+#include <vgui/IVGui.h>
+#include <vgui/ILocalize.h>
+#include <vgui/VGUI.h>
+
+// client dll/engine defines
+#include "hud.h"
+#include <voice_status.h>
+
+// viewport definitions
+#include <baseviewport.h>
+#include "SDKViewport.h"
+
+#include "vguicenterprint.h"
+#include "text_message.h"
+
+
+void SDKViewport::ApplySchemeSettings( vgui::IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ gHUD.InitColors( pScheme );
+
+ SetPaintBackgroundEnabled( false );
+}
+
+
+IViewPortPanel* SDKViewport::CreatePanelByName(const char *szPanelName)
+{
+ IViewPortPanel* newpanel = NULL;
+
+// Up here, strcmp against each type of panel we know how to create.
+// else if ( Q_strcmp(PANEL_OVERVIEW, szPanelName) == 0 )
+// {
+// newpanel = new CCSMapOverview( this );
+// }
+
+ // create a generic base panel, don't add twice
+ newpanel = BaseClass::CreatePanelByName( szPanelName );
+
+ return newpanel;
+}
+
+void SDKViewport::CreateDefaultPanels( void )
+{
+ BaseClass::CreateDefaultPanels();
+}
+
+int SDKViewport::GetDeathMessageStartHeight( void )
+{
+ int x = YRES(2);
+
+ IViewPortPanel *spectator = gViewPortInterface->FindPanelByName( PANEL_SPECGUI );
+
+ //TODO: Link to actual height of spectator bar
+ if ( spectator && spectator->IsVisible() )
+ {
+ x += YRES(52);
+ }
+
+ return x;
+}
+
diff --git a/game/client/sdk/vgui/sdkviewport.h b/game/client/sdk/vgui/sdkviewport.h
new file mode 100644
index 0000000..159da39
--- /dev/null
+++ b/game/client/sdk/vgui/sdkviewport.h
@@ -0,0 +1,40 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef SDKVIEWPORT_H
+#define SDKVIEWPORT_H
+
+
+#include "sdk_shareddefs.h"
+#include "baseviewport.h"
+
+
+using namespace vgui;
+
+namespace vgui
+{
+ class Panel;
+}
+
+class SDKViewport : public CBaseViewport
+{
+
+private:
+ DECLARE_CLASS_SIMPLE( SDKViewport, CBaseViewport );
+
+public:
+
+ IViewPortPanel* CreatePanelByName(const char *szPanelName);
+ void CreateDefaultPanels( void );
+
+ virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
+
+ int GetDeathMessageStartHeight( void );
+};
+
+
+#endif // SDKViewport_H
diff --git a/game/client/sdk/vgui/vgui_rootpanel_sdk.cpp b/game/client/sdk/vgui/vgui_rootpanel_sdk.cpp
new file mode 100644
index 0000000..e756829
--- /dev/null
+++ b/game/client/sdk/vgui/vgui_rootpanel_sdk.cpp
@@ -0,0 +1,106 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "vgui_int.h"
+#include "ienginevgui.h"
+#include "vgui_rootpanel_sdk.h"
+#include "vgui/IVGui.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+C_SDKRootPanel *g_pRootPanel = NULL;
+
+
+//-----------------------------------------------------------------------------
+// Global functions.
+//-----------------------------------------------------------------------------
+void VGUI_CreateClientDLLRootPanel( void )
+{
+ g_pRootPanel = new C_SDKRootPanel( enginevgui->GetPanel( PANEL_CLIENTDLL ) );
+}
+
+void VGUI_DestroyClientDLLRootPanel( void )
+{
+ delete g_pRootPanel;
+ g_pRootPanel = NULL;
+}
+
+vgui::VPANEL VGui_GetClientDLLRootPanel( void )
+{
+ return g_pRootPanel->GetVPanel();
+}
+
+
+//-----------------------------------------------------------------------------
+// C_SDKRootPanel implementation.
+//-----------------------------------------------------------------------------
+C_SDKRootPanel::C_SDKRootPanel( vgui::VPANEL parent )
+ : BaseClass( NULL, "SDK Root Panel" )
+{
+ SetParent( parent );
+ SetPaintEnabled( false );
+ SetPaintBorderEnabled( false );
+ SetPaintBackgroundEnabled( false );
+
+ // This panel does post child painting
+ SetPostChildPaintEnabled( true );
+
+ // Make it screen sized
+ SetBounds( 0, 0, ScreenWidth(), ScreenHeight() );
+
+ // Ask for OnTick messages
+ vgui::ivgui()->AddTickSignal( GetVPanel() );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_SDKRootPanel::~C_SDKRootPanel( void )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_SDKRootPanel::PostChildPaint()
+{
+ BaseClass::PostChildPaint();
+
+ // Draw all panel effects
+ RenderPanelEffects();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: For each panel effect, check if it wants to draw and draw it on
+// this panel/surface if so
+//-----------------------------------------------------------------------------
+void C_SDKRootPanel::RenderPanelEffects( void )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_SDKRootPanel::OnTick( void )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Reset effects on level load/shutdown
+//-----------------------------------------------------------------------------
+void C_SDKRootPanel::LevelInit( void )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_SDKRootPanel::LevelShutdown( void )
+{
+}
+
diff --git a/game/client/sdk/vgui/vgui_rootpanel_sdk.h b/game/client/sdk/vgui/vgui_rootpanel_sdk.h
new file mode 100644
index 0000000..448abbc
--- /dev/null
+++ b/game/client/sdk/vgui/vgui_rootpanel_sdk.h
@@ -0,0 +1,56 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef VGUI_ROOTPANEL_SDK_H
+#define VGUI_ROOTPANEL_SDK_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include <vgui_controls/Panel.h>
+#include <vgui_controls/EditablePanel.h>
+#include "utlvector.h"
+
+
+class CPanelEffect;
+
+
+// Serial under of effect, for safe lookup
+typedef unsigned int EFFECT_HANDLE;
+
+//-----------------------------------------------------------------------------
+// Purpose: Sits between engine and client .dll panels
+// Responsible for drawing screen overlays
+//-----------------------------------------------------------------------------
+class C_SDKRootPanel : public vgui::Panel
+{
+ typedef vgui::Panel BaseClass;
+public:
+ C_SDKRootPanel( vgui::VPANEL parent );
+ virtual ~C_SDKRootPanel( void );
+
+ // Draw Panel effects here
+ virtual void PostChildPaint();
+
+ // Clear list of Panel Effects
+ virtual void LevelInit( void );
+ virtual void LevelShutdown( void );
+
+ // Run effects and let them decide whether to remove themselves
+ void OnTick( void );
+
+private:
+
+ // Render all panel effects
+ void RenderPanelEffects( void );
+
+ // List of current panel effects
+ CUtlVector< CPanelEffect *> m_Effects;
+};
+
+
+#endif // VGUI_ROOTPANEL_SDK_H