aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/client/hl2
diff options
context:
space:
mode:
authorNarendra Umate <[email protected]>2013-12-02 23:36:05 -0800
committerNarendra Umate <[email protected]>2013-12-02 23:36:05 -0800
commit8737f191f3b59f001a77bf6c08091109211c1c9f (patch)
treedbbf05c004d9b026f2c1f23f06600fe0add82c36 /mp/src/game/client/hl2
parentUpdate .gitignore. (diff)
parentMake .xcconfigs text files too. (diff)
downloadsource-sdk-2013-8737f191f3b59f001a77bf6c08091109211c1c9f.tar.xz
source-sdk-2013-8737f191f3b59f001a77bf6c08091109211c1c9f.zip
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'mp/src/game/client/hl2')
-rw-r--r--mp/src/game/client/hl2/C_Func_Monitor.cpp58
-rw-r--r--mp/src/game/client/hl2/c_antlion_dust.cpp438
-rw-r--r--mp/src/game/client/hl2/c_ar2_explosion.cpp950
-rw-r--r--mp/src/game/client/hl2/c_barnacle.cpp626
-rw-r--r--mp/src/game/client/hl2/c_barney.cpp82
-rw-r--r--mp/src/game/client/hl2/c_basehelicopter.cpp182
-rw-r--r--mp/src/game/client/hl2/c_basehelicopter.h66
-rw-r--r--mp/src/game/client/hl2/c_basehlcombatweapon.cpp40
-rw-r--r--mp/src/game/client/hl2/c_basehlcombatweapon.h72
-rw-r--r--mp/src/game/client/hl2/c_basehlplayer.cpp1298
-rw-r--r--mp/src/game/client/hl2/c_basehlplayer.h162
-rw-r--r--mp/src/game/client/hl2/c_citadel_effects.cpp966
-rw-r--r--mp/src/game/client/hl2/c_corpse.cpp132
-rw-r--r--mp/src/game/client/hl2/c_corpse.h62
-rw-r--r--mp/src/game/client/hl2/c_energy_wave.cpp832
-rw-r--r--mp/src/game/client/hl2/c_env_alyxtemp.cpp972
-rw-r--r--mp/src/game/client/hl2/c_env_headcrabcanister.cpp194
-rw-r--r--mp/src/game/client/hl2/c_env_starfield.cpp262
-rw-r--r--mp/src/game/client/hl2/c_extinguisher.cpp826
-rw-r--r--mp/src/game/client/hl2/c_func_tankmortar.cpp498
-rw-r--r--mp/src/game/client/hl2/c_hl2_playerlocaldata.cpp104
-rw-r--r--mp/src/game/client/hl2/c_hl2_playerlocaldata.h110
-rw-r--r--mp/src/game/client/hl2/c_info_teleporter_countdown.cpp388
-rw-r--r--mp/src/game/client/hl2/c_npc_antlionguard.cpp320
-rw-r--r--mp/src/game/client/hl2/c_npc_combinegunship.cpp952
-rw-r--r--mp/src/game/client/hl2/c_npc_hydra.cpp772
-rw-r--r--mp/src/game/client/hl2/c_npc_manhack.cpp364
-rw-r--r--mp/src/game/client/hl2/c_npc_rollermine.cpp346
-rw-r--r--mp/src/game/client/hl2/c_plasma_beam_node.cpp558
-rw-r--r--mp/src/game/client/hl2/c_prop_combine_ball.cpp678
-rw-r--r--mp/src/game/client/hl2/c_prop_combine_ball.h88
-rw-r--r--mp/src/game/client/hl2/c_rotorwash.cpp612
-rw-r--r--mp/src/game/client/hl2/c_script_intro.cpp654
-rw-r--r--mp/src/game/client/hl2/c_strider.cpp2096
-rw-r--r--mp/src/game/client/hl2/c_te_concussiveexplosion.cpp218
-rw-r--r--mp/src/game/client/hl2/c_te_flare.cpp828
-rw-r--r--mp/src/game/client/hl2/c_thumper_dust.cpp338
-rw-r--r--mp/src/game/client/hl2/c_vehicle_airboat.cpp1862
-rw-r--r--mp/src/game/client/hl2/c_vehicle_cannon.cpp374
-rw-r--r--mp/src/game/client/hl2/c_vehicle_crane.cpp302
-rw-r--r--mp/src/game/client/hl2/c_vehicle_crane.h160
-rw-r--r--mp/src/game/client/hl2/c_vehicle_prisoner_pod.cpp474
-rw-r--r--mp/src/game/client/hl2/c_waterbullet.cpp242
-rw-r--r--mp/src/game/client/hl2/c_weapon__stubs_hl2.cpp94
-rw-r--r--mp/src/game/client/hl2/c_weapon_crossbow.cpp318
-rw-r--r--mp/src/game/client/hl2/c_weapon_gravitygun.cpp332
-rw-r--r--mp/src/game/client/hl2/c_weapon_physcannon.cpp884
-rw-r--r--mp/src/game/client/hl2/c_weapon_stunstick.cpp374
-rw-r--r--mp/src/game/client/hl2/clientmode_hlnormal.cpp198
-rw-r--r--mp/src/game/client/hl2/clientmode_hlnormal.h90
-rw-r--r--mp/src/game/client/hl2/fx_antlion.cpp668
-rw-r--r--mp/src/game/client/hl2/fx_bugbait.cpp126
-rw-r--r--mp/src/game/client/hl2/fx_hl2_impacts.cpp550
-rw-r--r--mp/src/game/client/hl2/fx_hl2_tracers.cpp1390
-rw-r--r--mp/src/game/client/hl2/hl2_clientmode.cpp154
-rw-r--r--mp/src/game/client/hl2/hl_in_main.cpp50
-rw-r--r--mp/src/game/client/hl2/hl_prediction.cpp48
-rw-r--r--mp/src/game/client/hl2/hud_ammo.cpp1004
-rw-r--r--mp/src/game/client/hl2/hud_autoaim.cpp938
-rw-r--r--mp/src/game/client/hl2/hud_battery.cpp294
-rw-r--r--mp/src/game/client/hl2/hud_blood.cpp68
-rw-r--r--mp/src/game/client/hl2/hud_bonusprogress.cpp392
-rw-r--r--mp/src/game/client/hl2/hud_credits.cpp1470
-rw-r--r--mp/src/game/client/hl2/hud_damageindicator.cpp922
-rw-r--r--mp/src/game/client/hl2/hud_filmdemo.cpp380
-rw-r--r--mp/src/game/client/hl2/hud_flashlight.cpp324
-rw-r--r--mp/src/game/client/hl2/hud_hdrdemo.cpp348
-rw-r--r--mp/src/game/client/hl2/hud_health.cpp338
-rw-r--r--mp/src/game/client/hl2/hud_locator.cpp638
-rw-r--r--mp/src/game/client/hl2/hud_poisondamageindicator.cpp310
-rw-r--r--mp/src/game/client/hl2/hud_quickinfo.cpp816
-rw-r--r--mp/src/game/client/hl2/hud_radar.cpp1174
-rw-r--r--mp/src/game/client/hl2/hud_radar.h156
-rw-r--r--mp/src/game/client/hl2/hud_suitpower.cpp514
-rw-r--r--mp/src/game/client/hl2/hud_suitpower.h114
-rw-r--r--mp/src/game/client/hl2/hud_weaponselection.cpp3022
-rw-r--r--mp/src/game/client/hl2/hud_zoom.cpp544
-rw-r--r--mp/src/game/client/hl2/shieldproxy.cpp220
-rw-r--r--mp/src/game/client/hl2/vgui_rootpanel_hl2.cpp74
79 files changed, 20447 insertions, 20447 deletions
diff --git a/mp/src/game/client/hl2/C_Func_Monitor.cpp b/mp/src/game/client/hl2/C_Func_Monitor.cpp
index a98aa10f..17ce78ba 100644
--- a/mp/src/game/client/hl2/C_Func_Monitor.cpp
+++ b/mp/src/game/client/hl2/C_Func_Monitor.cpp
@@ -1,29 +1,29 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-class C_FuncMonitor : public C_BaseEntity
-{
-public:
- DECLARE_CLASS( C_FuncMonitor, C_BaseEntity );
- DECLARE_CLIENTCLASS();
-
-// C_BaseEntity.
-public:
- virtual bool ShouldDraw();
-};
-
-IMPLEMENT_CLIENTCLASS_DT( C_FuncMonitor, DT_FuncMonitor, CFuncMonitor )
-END_RECV_TABLE()
-
-bool C_FuncMonitor::ShouldDraw()
-{
- return true;
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+class C_FuncMonitor : public C_BaseEntity
+{
+public:
+ DECLARE_CLASS( C_FuncMonitor, C_BaseEntity );
+ DECLARE_CLIENTCLASS();
+
+// C_BaseEntity.
+public:
+ virtual bool ShouldDraw();
+};
+
+IMPLEMENT_CLIENTCLASS_DT( C_FuncMonitor, DT_FuncMonitor, CFuncMonitor )
+END_RECV_TABLE()
+
+bool C_FuncMonitor::ShouldDraw()
+{
+ return true;
+}
diff --git a/mp/src/game/client/hl2/c_antlion_dust.cpp b/mp/src/game/client/hl2/c_antlion_dust.cpp
index 3b15532d..f883cc74 100644
--- a/mp/src/game/client/hl2/c_antlion_dust.cpp
+++ b/mp/src/game/client/hl2/c_antlion_dust.cpp
@@ -1,219 +1,219 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#include "cbase.h"
-#include "fx.h"
-#include "particlemgr.h"
-#include "particle_prototype.h"
-#include "particle_util.h"
-#include "c_te_particlesystem.h"
-#include "particles_ez.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-#define DUST_STARTSIZE 16
-#define DUST_ENDSIZE 48
-#define DUST_RADIUS 32.0f
-#define DUST_STARTALPHA 0.3f
-#define DUST_ENDALPHA 0.0f
-#define DUST_LIFETIME 2.0f
-
-static Vector g_AntlionDustColor( 0.3f, 0.25f, 0.2f );
-
-extern IPhysicsSurfaceProps *physprops;
-
-class CAntlionDustEmitter : public CSimpleEmitter
-{
-public:
- static CAntlionDustEmitter *Create( const char *debugname )
- {
- return new CAntlionDustEmitter( debugname );
- }
-
- void UpdateVelocity( SimpleParticle *pParticle, float timeDelta )
- {
- //FIXME: Incorrect
- pParticle->m_vecVelocity *= 0.9f;
- }
-
-private:
- CAntlionDustEmitter( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
- CAntlionDustEmitter( const CAntlionDustEmitter & ); // not defined, not accessible
-};
-
-//==================================================
-// C_TEAntlionDust
-//==================================================
-
-class C_TEAntlionDust: public C_TEParticleSystem
-{
-public:
-
- DECLARE_CLASS( C_TEAntlionDust, C_TEParticleSystem );
- DECLARE_CLIENTCLASS();
-
- C_TEAntlionDust();
- virtual ~C_TEAntlionDust();
-
-//C_BaseEntity
-public:
- virtual void PostDataUpdate( DataUpdateType_t updateType );
- virtual bool ShouldDraw() { return true; }
-
-
-//IParticleEffect
-public:
- virtual void RenderParticles( CParticleRenderIterator *pIterator );
- virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
-
-public:
- PMaterialHandle m_MaterialHandle;
-
- Vector m_vecOrigin;
- QAngle m_vecAngles;
- bool m_bBlockedSpawner;
-
-protected:
- void GetDustColor( Vector &color );
-};
-
-// Expose to the particle app.
-EXPOSE_PROTOTYPE_EFFECT( AntlionDust, C_TEAntlionDust );
-
-IMPLEMENT_CLIENTCLASS_EVENT_DT( C_TEAntlionDust, DT_TEAntlionDust, CTEAntlionDust )
- RecvPropVector(RECVINFO( m_vecOrigin )),
- RecvPropVector(RECVINFO( m_vecAngles )),
- RecvPropBool(RECVINFO( m_bBlockedSpawner )),
-END_RECV_TABLE()
-
-//==================================================
-// C_TEAntlionDust
-//==================================================
-
-C_TEAntlionDust::C_TEAntlionDust()
-{
- m_MaterialHandle = INVALID_MATERIAL_HANDLE;
- m_vecOrigin.Init();
- m_vecAngles.Init();
- m_bBlockedSpawner = false;
-}
-
-C_TEAntlionDust::~C_TEAntlionDust()
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : bNewEntity - whether or not to start a new entity
-//-----------------------------------------------------------------------------
-
-void C_TEAntlionDust::PostDataUpdate( DataUpdateType_t updateType )
-{
- // This style of creating dust emitters is now deprecated; we use the simple particle singleton exclusively.
- /*
- CSmartPtr<CAntlionDustEmitter> pDustEmitter = CAntlionDustEmitter::Create( "TEAntlionDust" );
- Assert( pDustEmitter );
- if ( pDustEmitter == NULL )
- return;
-
- pDustEmitter->SetSortOrigin( m_vecOrigin );
- pDustEmitter->SetNearClip( 32, 64 );
- pDustEmitter->GetBinding().SetBBox( m_vecOrigin - Vector( 32, 32, 32 ), m_vecOrigin + Vector( 32, 32, 32 ) );
- */
-
- Vector offset;
- Vector vecColor;
- GetDustColor( vecColor );
-
- int iParticleCount = 16;
-
- if ( m_bBlockedSpawner == true )
- {
- iParticleCount = 8;
- }
-
- //Spawn the dust
- SimpleParticle particle;
- for ( int i = 0; i < iParticleCount; i++ )
- {
- //Offset this dust puff's origin
- offset[0] = random->RandomFloat( -DUST_RADIUS, DUST_RADIUS );
- offset[1] = random->RandomFloat( -DUST_RADIUS, DUST_RADIUS );
- offset[2] = random->RandomFloat( -16, 8 );
-
- offset += m_vecOrigin;
-
- particle.m_Pos = offset;
- particle.m_flDieTime = random->RandomFloat( 0.75f, 1.25f );
- particle.m_flLifetime = 0.0f;
-
- Vector dir = particle.m_Pos - m_vecOrigin;
- particle.m_vecVelocity = dir * random->RandomFloat( 0.5f, 1.0f );
- dir.z = fabs(dir.z);
-
- float colorRamp = random->RandomFloat( 0.5f, 1.0f );
- Vector color = vecColor*colorRamp;
-
- color[0] = clamp( color[0], 0.0f, 1.0f );
- color[1] = clamp( color[1], 0.0f, 1.0f );
- color[2] = clamp( color[2], 0.0f, 1.0f );
-
- color *= 255;
-
- particle.m_uchColor[0] = color[0];
- particle.m_uchColor[1] = color[1];
- particle.m_uchColor[2] = color[2];
-
- particle.m_uchStartAlpha= random->RandomFloat( 64, 128 );
- particle.m_uchEndAlpha = 0;
-
- particle.m_uchStartSize = random->RandomInt( 16, 32 );
- particle.m_uchEndSize = particle.m_uchStartSize * 3;
- particle.m_flRoll = random->RandomInt( 0, 360 );
- particle.m_flRollDelta = random->RandomFloat( -0.2f, 0.2f );
-
- // Though it appears there are two particle handle entries in g_Mat_DustPuff, in fact
- // only the one present at index 0 actually draws. Trying to spawn a particle with
- // the other material will give you no particle at all. Therefore while instead of this:
- // AddSimpleParticle( &particle, g_Mat_DustPuff[random->RandomInt(0,1) );
- // we have to do this:
- AddSimpleParticle( &particle, g_Mat_DustPuff[0] );
- }
-}
-
-void GetColorForSurface( trace_t *trace, Vector *color );
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : &color -
-//-----------------------------------------------------------------------------
-void C_TEAntlionDust::GetDustColor( Vector &color )
-{
- trace_t tr;
- UTIL_TraceLine( m_vecOrigin+Vector(0,0,1), m_vecOrigin+Vector(0,0,-32),
- MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &tr );
-
- if ( tr.fraction < 1.0f )
- {
- GetColorForSurface( &tr, &color );
- }
- else
- {
- //Fill in a fallback
- color = g_AntlionDustColor;
- }
-}
-
-void C_TEAntlionDust::RenderParticles( CParticleRenderIterator *pIterator )
-{
-}
-
-void C_TEAntlionDust::SimulateParticles( CParticleSimulateIterator *pIterator )
-{
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "fx.h"
+#include "particlemgr.h"
+#include "particle_prototype.h"
+#include "particle_util.h"
+#include "c_te_particlesystem.h"
+#include "particles_ez.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#define DUST_STARTSIZE 16
+#define DUST_ENDSIZE 48
+#define DUST_RADIUS 32.0f
+#define DUST_STARTALPHA 0.3f
+#define DUST_ENDALPHA 0.0f
+#define DUST_LIFETIME 2.0f
+
+static Vector g_AntlionDustColor( 0.3f, 0.25f, 0.2f );
+
+extern IPhysicsSurfaceProps *physprops;
+
+class CAntlionDustEmitter : public CSimpleEmitter
+{
+public:
+ static CAntlionDustEmitter *Create( const char *debugname )
+ {
+ return new CAntlionDustEmitter( debugname );
+ }
+
+ void UpdateVelocity( SimpleParticle *pParticle, float timeDelta )
+ {
+ //FIXME: Incorrect
+ pParticle->m_vecVelocity *= 0.9f;
+ }
+
+private:
+ CAntlionDustEmitter( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
+ CAntlionDustEmitter( const CAntlionDustEmitter & ); // not defined, not accessible
+};
+
+//==================================================
+// C_TEAntlionDust
+//==================================================
+
+class C_TEAntlionDust: public C_TEParticleSystem
+{
+public:
+
+ DECLARE_CLASS( C_TEAntlionDust, C_TEParticleSystem );
+ DECLARE_CLIENTCLASS();
+
+ C_TEAntlionDust();
+ virtual ~C_TEAntlionDust();
+
+//C_BaseEntity
+public:
+ virtual void PostDataUpdate( DataUpdateType_t updateType );
+ virtual bool ShouldDraw() { return true; }
+
+
+//IParticleEffect
+public:
+ virtual void RenderParticles( CParticleRenderIterator *pIterator );
+ virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
+
+public:
+ PMaterialHandle m_MaterialHandle;
+
+ Vector m_vecOrigin;
+ QAngle m_vecAngles;
+ bool m_bBlockedSpawner;
+
+protected:
+ void GetDustColor( Vector &color );
+};
+
+// Expose to the particle app.
+EXPOSE_PROTOTYPE_EFFECT( AntlionDust, C_TEAntlionDust );
+
+IMPLEMENT_CLIENTCLASS_EVENT_DT( C_TEAntlionDust, DT_TEAntlionDust, CTEAntlionDust )
+ RecvPropVector(RECVINFO( m_vecOrigin )),
+ RecvPropVector(RECVINFO( m_vecAngles )),
+ RecvPropBool(RECVINFO( m_bBlockedSpawner )),
+END_RECV_TABLE()
+
+//==================================================
+// C_TEAntlionDust
+//==================================================
+
+C_TEAntlionDust::C_TEAntlionDust()
+{
+ m_MaterialHandle = INVALID_MATERIAL_HANDLE;
+ m_vecOrigin.Init();
+ m_vecAngles.Init();
+ m_bBlockedSpawner = false;
+}
+
+C_TEAntlionDust::~C_TEAntlionDust()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : bNewEntity - whether or not to start a new entity
+//-----------------------------------------------------------------------------
+
+void C_TEAntlionDust::PostDataUpdate( DataUpdateType_t updateType )
+{
+ // This style of creating dust emitters is now deprecated; we use the simple particle singleton exclusively.
+ /*
+ CSmartPtr<CAntlionDustEmitter> pDustEmitter = CAntlionDustEmitter::Create( "TEAntlionDust" );
+ Assert( pDustEmitter );
+ if ( pDustEmitter == NULL )
+ return;
+
+ pDustEmitter->SetSortOrigin( m_vecOrigin );
+ pDustEmitter->SetNearClip( 32, 64 );
+ pDustEmitter->GetBinding().SetBBox( m_vecOrigin - Vector( 32, 32, 32 ), m_vecOrigin + Vector( 32, 32, 32 ) );
+ */
+
+ Vector offset;
+ Vector vecColor;
+ GetDustColor( vecColor );
+
+ int iParticleCount = 16;
+
+ if ( m_bBlockedSpawner == true )
+ {
+ iParticleCount = 8;
+ }
+
+ //Spawn the dust
+ SimpleParticle particle;
+ for ( int i = 0; i < iParticleCount; i++ )
+ {
+ //Offset this dust puff's origin
+ offset[0] = random->RandomFloat( -DUST_RADIUS, DUST_RADIUS );
+ offset[1] = random->RandomFloat( -DUST_RADIUS, DUST_RADIUS );
+ offset[2] = random->RandomFloat( -16, 8 );
+
+ offset += m_vecOrigin;
+
+ particle.m_Pos = offset;
+ particle.m_flDieTime = random->RandomFloat( 0.75f, 1.25f );
+ particle.m_flLifetime = 0.0f;
+
+ Vector dir = particle.m_Pos - m_vecOrigin;
+ particle.m_vecVelocity = dir * random->RandomFloat( 0.5f, 1.0f );
+ dir.z = fabs(dir.z);
+
+ float colorRamp = random->RandomFloat( 0.5f, 1.0f );
+ Vector color = vecColor*colorRamp;
+
+ color[0] = clamp( color[0], 0.0f, 1.0f );
+ color[1] = clamp( color[1], 0.0f, 1.0f );
+ color[2] = clamp( color[2], 0.0f, 1.0f );
+
+ color *= 255;
+
+ particle.m_uchColor[0] = color[0];
+ particle.m_uchColor[1] = color[1];
+ particle.m_uchColor[2] = color[2];
+
+ particle.m_uchStartAlpha= random->RandomFloat( 64, 128 );
+ particle.m_uchEndAlpha = 0;
+
+ particle.m_uchStartSize = random->RandomInt( 16, 32 );
+ particle.m_uchEndSize = particle.m_uchStartSize * 3;
+ particle.m_flRoll = random->RandomInt( 0, 360 );
+ particle.m_flRollDelta = random->RandomFloat( -0.2f, 0.2f );
+
+ // Though it appears there are two particle handle entries in g_Mat_DustPuff, in fact
+ // only the one present at index 0 actually draws. Trying to spawn a particle with
+ // the other material will give you no particle at all. Therefore while instead of this:
+ // AddSimpleParticle( &particle, g_Mat_DustPuff[random->RandomInt(0,1) );
+ // we have to do this:
+ AddSimpleParticle( &particle, g_Mat_DustPuff[0] );
+ }
+}
+
+void GetColorForSurface( trace_t *trace, Vector *color );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &color -
+//-----------------------------------------------------------------------------
+void C_TEAntlionDust::GetDustColor( Vector &color )
+{
+ trace_t tr;
+ UTIL_TraceLine( m_vecOrigin+Vector(0,0,1), m_vecOrigin+Vector(0,0,-32),
+ MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &tr );
+
+ if ( tr.fraction < 1.0f )
+ {
+ GetColorForSurface( &tr, &color );
+ }
+ else
+ {
+ //Fill in a fallback
+ color = g_AntlionDustColor;
+ }
+}
+
+void C_TEAntlionDust::RenderParticles( CParticleRenderIterator *pIterator )
+{
+}
+
+void C_TEAntlionDust::SimulateParticles( CParticleSimulateIterator *pIterator )
+{
+}
+
diff --git a/mp/src/game/client/hl2/c_ar2_explosion.cpp b/mp/src/game/client/hl2/c_ar2_explosion.cpp
index 191eb8b4..e60343e6 100644
--- a/mp/src/game/client/hl2/c_ar2_explosion.cpp
+++ b/mp/src/game/client/hl2/c_ar2_explosion.cpp
@@ -1,475 +1,475 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "particlemgr.h"
-#include "particle_prototype.h"
-#include "particle_util.h"
-#include "surfinfo.h"
-#include "baseparticleentity.h"
-#include "materialsystem/imaterialsystemhardwareconfig.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-// ------------------------------------------------------------------------- //
-// Definitions
-// ------------------------------------------------------------------------- //
-
-#define NUM_AR2_EXPLOSION_PARTICLES 70
-#define AR2_DUST_RADIUS 240 // 340
-#define AR2_DUST_LIFETIME 4
-#define AR2_DUST_LIFETIME_DELTA 6
-#define AR2_DUST_SPEED 10000
-#define AR2_DUST_STARTSIZE 8
-#define AR2_DUST_ENDSIZE 32
-#define AR2_DUST_ALPHA 0.5f
-#define AR2_DUST_FADE_IN_TIME 0.25f
-
-static Vector g_AR2DustColor1(0.35, 0.345, 0.33 );
-static Vector g_AR2DustColor2(0.75, 0.75, 0.7);
-
-
-// ------------------------------------------------------------------------- //
-// Classes
-// ------------------------------------------------------------------------- //
-
-class C_AR2Explosion : public C_BaseParticleEntity, public IPrototypeAppEffect
-{
-public:
- DECLARE_CLASS( C_AR2Explosion, C_BaseParticleEntity );
- DECLARE_CLIENTCLASS();
-
- C_AR2Explosion();
- ~C_AR2Explosion();
-
-private:
-
- class AR2ExplosionParticle : public StandardParticle_t
- {
- public:
- float m_Dist;
- Vector m_Start;
- float m_Roll;
- float m_RollSpeed;
- float m_Dwell;
- };
-
-// C_BaseEntity.
-public:
- virtual void OnDataChanged(DataUpdateType_t updateType);
-
-// IPrototypeAppEffect.
-public:
- virtual void Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs);
-
-// IParticleEffect.
-public:
- virtual void Update(float fTimeDelta);
-
- virtual void RenderParticles( CParticleRenderIterator *pIterator );
- virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
-
-
-public:
- CParticleMgr *m_pParticleMgr;
- PMaterialHandle m_MaterialHandle;
-
-private:
-
- char m_szMaterialName[255];
-
- C_AR2Explosion( const C_AR2Explosion & );
-};
-
-// Expose to the particle app.
-EXPOSE_PROTOTYPE_EFFECT(AR2Explosion, C_AR2Explosion);
-
-IMPLEMENT_CLIENTCLASS_DT(C_AR2Explosion, DT_AR2Explosion, AR2Explosion)
- RecvPropString( RECVINFO( m_szMaterialName ) ),
-END_RECV_TABLE()
-
-
-
-// ------------------------------------------------------------------------- //
-// Helpers.
-// ------------------------------------------------------------------------- //
-
-// Given a line segment from vStart to vEnd
-// and a list of convex polygons in pSurfInfos and nSurfInfos,
-// fill in the list of which polygons the segment intersects.
-// Returns the number of intersected surfaces.
-static int IntersectSegmentWithSurfInfos(
- const Vector &vStart,
- const Vector &vEnd,
- SurfInfo *pSurfInfos,
- const int nSurfInfos,
- SurfInfo ** pIntersections,
- Vector *pIntersectionPositions,
- int nMaxIntersections)
-{
- if(nMaxIntersections == 0)
- return 0;
-
- int nIntersections = 0;
- for(int i=0; i < nSurfInfos; i++)
- {
- SurfInfo *pSurf = &pSurfInfos[i];
-
- // Does it intersect the plane?
- float dot1 = pSurf->m_Plane.DistTo(vStart);
- float dot2 = pSurf->m_Plane.DistTo(vEnd);
- if((dot1 > 0) != (dot2 > 0))
- {
- float t = dot1 / (dot1 - dot2);
- Vector vIntersection = vStart + (vEnd - vStart) * t;
-
- // If the intersection is behind any edge plane, then it's not inside the polygon.
- unsigned long iEdge;
- for(iEdge=0; iEdge < pSurf->m_nVerts; iEdge++)
- {
- VPlane edgePlane;
- edgePlane.m_Normal = pSurf->m_Plane.m_Normal.Cross(pSurf->m_Verts[iEdge] - pSurf->m_Verts[(iEdge+1)%pSurf->m_nVerts]);
- VectorNormalize( edgePlane.m_Normal );
- edgePlane.m_Dist = edgePlane.m_Normal.Dot(pSurf->m_Verts[iEdge]);
-
- if(edgePlane.DistTo(vIntersection) < 0.0f)
- break;
- }
-
- if(iEdge == pSurf->m_nVerts)
- {
- pIntersections[nIntersections] = pSurf;
- pIntersectionPositions[nIntersections] = vIntersection;
- ++nIntersections;
- if(nIntersections >= nMaxIntersections)
- break;
- }
- }
- }
-
- return nIntersections;
-}
-
-
-
-// ------------------------------------------------------------------------- //
-// C_AR2Explosion
-// ------------------------------------------------------------------------- //
-C_AR2Explosion::C_AR2Explosion()
-{
- m_pParticleMgr = NULL;
- m_MaterialHandle = INVALID_MATERIAL_HANDLE;
-}
-
-
-C_AR2Explosion::~C_AR2Explosion()
-{
-}
-
-
-void C_AR2Explosion::OnDataChanged(DataUpdateType_t updateType)
-{
- C_BaseEntity::OnDataChanged(updateType);
-
- if(updateType == DATA_UPDATE_CREATED)
- {
- Start(ParticleMgr(), NULL);
- }
-}
-
-static ConVar mat_reduceparticles( "mat_reduceparticles", "0" );
-
-void C_AR2Explosion::Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs)
-{
- m_pParticleMgr = pParticleMgr;
- if(!pParticleMgr->AddEffect(&m_ParticleEffect, this))
- return;
-
- if (!m_szMaterialName[0])
- {
- Q_strncpy(m_szMaterialName, "particle/particle_noisesphere", sizeof( m_szMaterialName ) );
- }
-
- m_MaterialHandle = m_ParticleEffect.FindOrAddMaterial(m_szMaterialName);
-
- // Precalculate stuff for the particle spawning..
- #define NUM_DUSTEMITTER_SURFINFOS 128
- SurfInfo surfInfos[NUM_DUSTEMITTER_SURFINFOS];
- int nSurfInfos;
-
- // Center of explosion.
- Vector vCenter = GetAbsOrigin(); // HACKHACK.. when the engine bug is fixed, use origin.
-
- if ( IsXbox() )
- {
- m_ParticleEffect.SetBBox( vCenter-Vector(300,300,300), vCenter+Vector(300,300,300) );
- }
-
- #ifdef PARTICLEPROTOTYPE_APP
- float surfSize = 10000;
- nSurfInfos = 1;
- surfInfos[0].m_Verts[0].Init(-surfSize,-surfSize,0);
- surfInfos[0].m_Verts[1].Init(-surfSize,surfSize,0);
- surfInfos[0].m_Verts[2].Init(surfSize, surfSize,0);
- surfInfos[0].m_Verts[3].Init(surfSize,-surfSize,0);
- surfInfos[0].m_nVerts = 4;
- surfInfos[0].m_Plane.m_Normal.Init(0,0,1);
- surfInfos[0].m_Plane.m_Dist = -3;
- #else
- {
- nSurfInfos = 0;
- C_BaseEntity *ent = cl_entitylist->GetEnt( 0 );
- if ( ent )
- {
- nSurfInfos = engine->GetIntersectingSurfaces(
- ent->GetModel(),
- vCenter,
- AR2_DUST_RADIUS,
- true,
- surfInfos,
- NUM_DUSTEMITTER_SURFINFOS);
- }
- }
- #endif
-
- int nParticles = 0;
-
- int iParticlesToSpawn = NUM_AR2_EXPLOSION_PARTICLES;
-
- // In DX7, much fewer particles
- if ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80 )
- {
- iParticlesToSpawn *= 0.25;
- }
- else if ( mat_reduceparticles.GetBool() )
- {
- iParticlesToSpawn *= 0.025;
- }
-
- if( nSurfInfos > 0 )
- {
- // For nParticles*N, generate a ray and cast it out. If it hits anything, spawn a particle there.
- int nTestsPerParticle=3;
- for(int i=0; i < iParticlesToSpawn; i++)
- {
- for(int iTest=0; iTest < nTestsPerParticle; iTest++)
- {
- Vector randVec = RandomVector(-1,1);
- VectorNormalize( randVec );
- Vector startPos = vCenter + randVec * AR2_DUST_RADIUS;
-
- randVec = RandomVector(-1,1);
- VectorNormalize( randVec );
- Vector endPos = vCenter + randVec * AR2_DUST_RADIUS;
-
- #define MAX_SURFINFO_INTERSECTIONS 4
- SurfInfo *pIntersected[MAX_SURFINFO_INTERSECTIONS];
- Vector vIntersections[MAX_SURFINFO_INTERSECTIONS];
- int nIntersections;
- nIntersections = IntersectSegmentWithSurfInfos(
- startPos,
- endPos,
- surfInfos,
- nSurfInfos,
- pIntersected,
- vIntersections,
- MAX_SURFINFO_INTERSECTIONS);
-
- if(nIntersections)
- {
- int iIntersection = rand() % nIntersections;
-
- Vector velocity;
- //velocity.Init(-1.0f + ((float)rand()/VALVE_RAND_MAX) * 2.0f, -1.0f + ((float)rand()/VALVE_RAND_MAX) * 2.0f, -1.0f + ((float)rand()/VALVE_RAND_MAX) * 2.0f);
- //velocity = velocity * FRand(m_MinSpeed, m_MaxSpeed);
- Vector direction = (vIntersections[iIntersection] - vCenter );
- float dist = VectorNormalize( direction );
- if(dist > AR2_DUST_RADIUS)
- dist = AR2_DUST_RADIUS;
-
- static float power = 2.0f;
- float falloffMul = pow(1.0f - dist / AR2_DUST_RADIUS, power);
-
- Vector reflection = direction - 2 * DotProduct( direction, pIntersected[iIntersection]->m_Plane.m_Normal ) * pIntersected[iIntersection]->m_Plane.m_Normal;
- VectorNormalize( reflection );
-
- velocity = reflection * AR2_DUST_SPEED * falloffMul;
- // velocity = velocity + (vIntersections[iIntersection] - vCenter) * falloffMul;
-
-
- /*
- debugoverlay->AddLineOverlay( vIntersections[iIntersection],
- vIntersections[iIntersection] + reflection * 64,
- 128, 128, 255, false, 15.0 );
- */
-#if 1
- AR2ExplosionParticle *pParticle =
- (AR2ExplosionParticle*)m_ParticleEffect.AddParticle( sizeof(AR2ExplosionParticle), m_MaterialHandle );
-
- if(pParticle)
- {
- pParticle->m_Pos = vIntersections[iIntersection];
- pParticle->m_Start = pParticle->m_Pos;
- pParticle->m_Dist = 8.0;
- pParticle->m_Velocity = velocity;
- // sound == 13031.496062992125984251968503937ips
- pParticle->m_Lifetime = -dist / 13031.5f - 0.1;
- pParticle->m_Roll = FRand( 0, M_PI * 2 );
- pParticle->m_RollSpeed = FRand( -1, 1 ) * 0.4;
- pParticle->m_Dwell = AR2_DUST_LIFETIME + random->RandomFloat( 0, AR2_DUST_LIFETIME_DELTA );
- nParticles++;
- break;
- }
-#endif
- }
- }
- }
- }
-
- // build interior smoke particles
- for(int i=nParticles; i < iParticlesToSpawn; i++)
- {
- Vector randVec = RandomVector(-1,1);
- VectorNormalize( randVec );
- Vector endPos = vCenter + randVec * AR2_DUST_RADIUS / 4.0;
-
- Vector direction = (endPos - vCenter );
- float dist = VectorNormalize( direction ) + random->RandomFloat( 0, AR2_DUST_RADIUS / 4.0 );
- if(dist > AR2_DUST_RADIUS)
- dist = AR2_DUST_RADIUS;
-
- static float power = 2.0f;
- float falloffMul = pow(1.0f - dist / (AR2_DUST_RADIUS / 2), power);
-
- Vector velocity = direction * AR2_DUST_SPEED * falloffMul;
- AR2ExplosionParticle *pParticle =
- (AR2ExplosionParticle*)m_ParticleEffect.AddParticle( sizeof(AR2ExplosionParticle), m_MaterialHandle );
-
- if(pParticle)
- {
- pParticle->m_Pos = endPos;
- pParticle->m_Start = pParticle->m_Pos;
- pParticle->m_Dist = 8.0;
- pParticle->m_Velocity = velocity;
- // sound == 13031.496062992125984251968503937ips
- pParticle->m_Lifetime = -dist / 13031.5f - 0.1;
- pParticle->m_Roll = FRand( 0, M_PI * 2 );
- pParticle->m_RollSpeed = FRand( -1, 1 ) * 4.0;
- pParticle->m_Dwell = 0.5 * (AR2_DUST_LIFETIME + random->RandomFloat( 0, AR2_DUST_LIFETIME_DELTA ));
- }
- }
-}
-
-
-void C_AR2Explosion::Update(float fTimeDelta)
-{
- if(!m_pParticleMgr)
- return;
-}
-
-
-void C_AR2Explosion::SimulateParticles( CParticleSimulateIterator *pIterator )
-{
- float dt = pIterator->GetTimeDelta();
-
- AR2ExplosionParticle *pParticle = (AR2ExplosionParticle*)pIterator->GetFirst();
- while ( pParticle )
- {
- if (dt > 0.05)
- dt = 0.05; // yuck, air resistance function craps out at less then 20fps
-
- // Update its lifetime.
- pParticle->m_Lifetime += dt; // pDraw->GetTimeDelta();
- if(pParticle->m_Lifetime > pParticle->m_Dwell)
- {
- // faded to nothing....
- pIterator->RemoveParticle( pParticle );
- }
- else
- {
- // Spin the thing
- pParticle->m_Roll += pParticle->m_RollSpeed * pIterator->GetTimeDelta();
-
- // delayed?
- if ( pParticle->m_Lifetime >= 0.0f )
- {
- // Move it (this comes after rendering to make it clear that moving the particle here won't change
- // its rendering for this frame since m_TransformedPos has already been set).
- pParticle->m_Pos = pParticle->m_Pos + pParticle->m_Velocity * dt;
-
- // keep track of distance traveled
- pParticle->m_Dist = pParticle->m_Dist + pParticle->m_Velocity.Length() * dt;
-
- // Dampen velocity.
- float dist = pParticle->m_Velocity.Length() * dt;
- float r = dist * dist;
- // FIXME: this is a really screwy air-resistance function....
- pParticle->m_Velocity = pParticle->m_Velocity * (100 / (100 + r ));
-
- // dampen roll
- static float dtime;
- static float decay;
- if (dtime != dt)
- {
- dtime = dt;
- decay = ExponentialDecay( 0.3, 1.0, dtime );
- }
- if (fabs(pParticle->m_RollSpeed) > 0.2)
- pParticle->m_RollSpeed = pParticle->m_RollSpeed * decay;
- }
- }
-
- pParticle = (AR2ExplosionParticle*)pIterator->GetNext();
- }
-}
-
-
-void C_AR2Explosion::RenderParticles( CParticleRenderIterator *pIterator )
-{
- const AR2ExplosionParticle *pParticle = (const AR2ExplosionParticle *)pIterator->GetFirst();
- while ( pParticle )
- {
- float sortKey = 0;
- if ( pParticle->m_Lifetime >= 0.0f )
- {
- // Draw.
- float lifetimePercent = ( pParticle->m_Lifetime - AR2_DUST_FADE_IN_TIME ) / pParticle->m_Dwell;
-
- // FIXME: base color should be a dirty version of the material color
- Vector color = g_AR2DustColor1 * (1.0 - lifetimePercent) + g_AR2DustColor2 * lifetimePercent;
-
- Vector tPos;
- TransformParticle(m_pParticleMgr->GetModelView(), pParticle->m_Pos, tPos);
- sortKey = tPos.z;
-
- float alpha;
-
- if ( pParticle->m_Lifetime < AR2_DUST_FADE_IN_TIME )
- {
- alpha = AR2_DUST_ALPHA * ( pParticle->m_Lifetime / AR2_DUST_FADE_IN_TIME );
- }
- else
- {
- alpha = AR2_DUST_ALPHA * ( 1.0f - lifetimePercent );
- }
-
- alpha *= GetAlphaDistanceFade( tPos, IsXbox() ? 100 : 50, IsXbox() ? 200 : 150 );
-
- RenderParticle_ColorSizeAngle(
- pIterator->GetParticleDraw(),
- tPos,
- color,
- alpha,
- pParticle->m_Dist, // size based on how far it's traveled
- pParticle->m_Roll);
- }
-
- pParticle = (const AR2ExplosionParticle *)pIterator->GetNext( sortKey );
- }
-}
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "particlemgr.h"
+#include "particle_prototype.h"
+#include "particle_util.h"
+#include "surfinfo.h"
+#include "baseparticleentity.h"
+#include "materialsystem/imaterialsystemhardwareconfig.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+// ------------------------------------------------------------------------- //
+// Definitions
+// ------------------------------------------------------------------------- //
+
+#define NUM_AR2_EXPLOSION_PARTICLES 70
+#define AR2_DUST_RADIUS 240 // 340
+#define AR2_DUST_LIFETIME 4
+#define AR2_DUST_LIFETIME_DELTA 6
+#define AR2_DUST_SPEED 10000
+#define AR2_DUST_STARTSIZE 8
+#define AR2_DUST_ENDSIZE 32
+#define AR2_DUST_ALPHA 0.5f
+#define AR2_DUST_FADE_IN_TIME 0.25f
+
+static Vector g_AR2DustColor1(0.35, 0.345, 0.33 );
+static Vector g_AR2DustColor2(0.75, 0.75, 0.7);
+
+
+// ------------------------------------------------------------------------- //
+// Classes
+// ------------------------------------------------------------------------- //
+
+class C_AR2Explosion : public C_BaseParticleEntity, public IPrototypeAppEffect
+{
+public:
+ DECLARE_CLASS( C_AR2Explosion, C_BaseParticleEntity );
+ DECLARE_CLIENTCLASS();
+
+ C_AR2Explosion();
+ ~C_AR2Explosion();
+
+private:
+
+ class AR2ExplosionParticle : public StandardParticle_t
+ {
+ public:
+ float m_Dist;
+ Vector m_Start;
+ float m_Roll;
+ float m_RollSpeed;
+ float m_Dwell;
+ };
+
+// C_BaseEntity.
+public:
+ virtual void OnDataChanged(DataUpdateType_t updateType);
+
+// IPrototypeAppEffect.
+public:
+ virtual void Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs);
+
+// IParticleEffect.
+public:
+ virtual void Update(float fTimeDelta);
+
+ virtual void RenderParticles( CParticleRenderIterator *pIterator );
+ virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
+
+
+public:
+ CParticleMgr *m_pParticleMgr;
+ PMaterialHandle m_MaterialHandle;
+
+private:
+
+ char m_szMaterialName[255];
+
+ C_AR2Explosion( const C_AR2Explosion & );
+};
+
+// Expose to the particle app.
+EXPOSE_PROTOTYPE_EFFECT(AR2Explosion, C_AR2Explosion);
+
+IMPLEMENT_CLIENTCLASS_DT(C_AR2Explosion, DT_AR2Explosion, AR2Explosion)
+ RecvPropString( RECVINFO( m_szMaterialName ) ),
+END_RECV_TABLE()
+
+
+
+// ------------------------------------------------------------------------- //
+// Helpers.
+// ------------------------------------------------------------------------- //
+
+// Given a line segment from vStart to vEnd
+// and a list of convex polygons in pSurfInfos and nSurfInfos,
+// fill in the list of which polygons the segment intersects.
+// Returns the number of intersected surfaces.
+static int IntersectSegmentWithSurfInfos(
+ const Vector &vStart,
+ const Vector &vEnd,
+ SurfInfo *pSurfInfos,
+ const int nSurfInfos,
+ SurfInfo ** pIntersections,
+ Vector *pIntersectionPositions,
+ int nMaxIntersections)
+{
+ if(nMaxIntersections == 0)
+ return 0;
+
+ int nIntersections = 0;
+ for(int i=0; i < nSurfInfos; i++)
+ {
+ SurfInfo *pSurf = &pSurfInfos[i];
+
+ // Does it intersect the plane?
+ float dot1 = pSurf->m_Plane.DistTo(vStart);
+ float dot2 = pSurf->m_Plane.DistTo(vEnd);
+ if((dot1 > 0) != (dot2 > 0))
+ {
+ float t = dot1 / (dot1 - dot2);
+ Vector vIntersection = vStart + (vEnd - vStart) * t;
+
+ // If the intersection is behind any edge plane, then it's not inside the polygon.
+ unsigned long iEdge;
+ for(iEdge=0; iEdge < pSurf->m_nVerts; iEdge++)
+ {
+ VPlane edgePlane;
+ edgePlane.m_Normal = pSurf->m_Plane.m_Normal.Cross(pSurf->m_Verts[iEdge] - pSurf->m_Verts[(iEdge+1)%pSurf->m_nVerts]);
+ VectorNormalize( edgePlane.m_Normal );
+ edgePlane.m_Dist = edgePlane.m_Normal.Dot(pSurf->m_Verts[iEdge]);
+
+ if(edgePlane.DistTo(vIntersection) < 0.0f)
+ break;
+ }
+
+ if(iEdge == pSurf->m_nVerts)
+ {
+ pIntersections[nIntersections] = pSurf;
+ pIntersectionPositions[nIntersections] = vIntersection;
+ ++nIntersections;
+ if(nIntersections >= nMaxIntersections)
+ break;
+ }
+ }
+ }
+
+ return nIntersections;
+}
+
+
+
+// ------------------------------------------------------------------------- //
+// C_AR2Explosion
+// ------------------------------------------------------------------------- //
+C_AR2Explosion::C_AR2Explosion()
+{
+ m_pParticleMgr = NULL;
+ m_MaterialHandle = INVALID_MATERIAL_HANDLE;
+}
+
+
+C_AR2Explosion::~C_AR2Explosion()
+{
+}
+
+
+void C_AR2Explosion::OnDataChanged(DataUpdateType_t updateType)
+{
+ C_BaseEntity::OnDataChanged(updateType);
+
+ if(updateType == DATA_UPDATE_CREATED)
+ {
+ Start(ParticleMgr(), NULL);
+ }
+}
+
+static ConVar mat_reduceparticles( "mat_reduceparticles", "0" );
+
+void C_AR2Explosion::Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs)
+{
+ m_pParticleMgr = pParticleMgr;
+ if(!pParticleMgr->AddEffect(&m_ParticleEffect, this))
+ return;
+
+ if (!m_szMaterialName[0])
+ {
+ Q_strncpy(m_szMaterialName, "particle/particle_noisesphere", sizeof( m_szMaterialName ) );
+ }
+
+ m_MaterialHandle = m_ParticleEffect.FindOrAddMaterial(m_szMaterialName);
+
+ // Precalculate stuff for the particle spawning..
+ #define NUM_DUSTEMITTER_SURFINFOS 128
+ SurfInfo surfInfos[NUM_DUSTEMITTER_SURFINFOS];
+ int nSurfInfos;
+
+ // Center of explosion.
+ Vector vCenter = GetAbsOrigin(); // HACKHACK.. when the engine bug is fixed, use origin.
+
+ if ( IsXbox() )
+ {
+ m_ParticleEffect.SetBBox( vCenter-Vector(300,300,300), vCenter+Vector(300,300,300) );
+ }
+
+ #ifdef PARTICLEPROTOTYPE_APP
+ float surfSize = 10000;
+ nSurfInfos = 1;
+ surfInfos[0].m_Verts[0].Init(-surfSize,-surfSize,0);
+ surfInfos[0].m_Verts[1].Init(-surfSize,surfSize,0);
+ surfInfos[0].m_Verts[2].Init(surfSize, surfSize,0);
+ surfInfos[0].m_Verts[3].Init(surfSize,-surfSize,0);
+ surfInfos[0].m_nVerts = 4;
+ surfInfos[0].m_Plane.m_Normal.Init(0,0,1);
+ surfInfos[0].m_Plane.m_Dist = -3;
+ #else
+ {
+ nSurfInfos = 0;
+ C_BaseEntity *ent = cl_entitylist->GetEnt( 0 );
+ if ( ent )
+ {
+ nSurfInfos = engine->GetIntersectingSurfaces(
+ ent->GetModel(),
+ vCenter,
+ AR2_DUST_RADIUS,
+ true,
+ surfInfos,
+ NUM_DUSTEMITTER_SURFINFOS);
+ }
+ }
+ #endif
+
+ int nParticles = 0;
+
+ int iParticlesToSpawn = NUM_AR2_EXPLOSION_PARTICLES;
+
+ // In DX7, much fewer particles
+ if ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80 )
+ {
+ iParticlesToSpawn *= 0.25;
+ }
+ else if ( mat_reduceparticles.GetBool() )
+ {
+ iParticlesToSpawn *= 0.025;
+ }
+
+ if( nSurfInfos > 0 )
+ {
+ // For nParticles*N, generate a ray and cast it out. If it hits anything, spawn a particle there.
+ int nTestsPerParticle=3;
+ for(int i=0; i < iParticlesToSpawn; i++)
+ {
+ for(int iTest=0; iTest < nTestsPerParticle; iTest++)
+ {
+ Vector randVec = RandomVector(-1,1);
+ VectorNormalize( randVec );
+ Vector startPos = vCenter + randVec * AR2_DUST_RADIUS;
+
+ randVec = RandomVector(-1,1);
+ VectorNormalize( randVec );
+ Vector endPos = vCenter + randVec * AR2_DUST_RADIUS;
+
+ #define MAX_SURFINFO_INTERSECTIONS 4
+ SurfInfo *pIntersected[MAX_SURFINFO_INTERSECTIONS];
+ Vector vIntersections[MAX_SURFINFO_INTERSECTIONS];
+ int nIntersections;
+ nIntersections = IntersectSegmentWithSurfInfos(
+ startPos,
+ endPos,
+ surfInfos,
+ nSurfInfos,
+ pIntersected,
+ vIntersections,
+ MAX_SURFINFO_INTERSECTIONS);
+
+ if(nIntersections)
+ {
+ int iIntersection = rand() % nIntersections;
+
+ Vector velocity;
+ //velocity.Init(-1.0f + ((float)rand()/VALVE_RAND_MAX) * 2.0f, -1.0f + ((float)rand()/VALVE_RAND_MAX) * 2.0f, -1.0f + ((float)rand()/VALVE_RAND_MAX) * 2.0f);
+ //velocity = velocity * FRand(m_MinSpeed, m_MaxSpeed);
+ Vector direction = (vIntersections[iIntersection] - vCenter );
+ float dist = VectorNormalize( direction );
+ if(dist > AR2_DUST_RADIUS)
+ dist = AR2_DUST_RADIUS;
+
+ static float power = 2.0f;
+ float falloffMul = pow(1.0f - dist / AR2_DUST_RADIUS, power);
+
+ Vector reflection = direction - 2 * DotProduct( direction, pIntersected[iIntersection]->m_Plane.m_Normal ) * pIntersected[iIntersection]->m_Plane.m_Normal;
+ VectorNormalize( reflection );
+
+ velocity = reflection * AR2_DUST_SPEED * falloffMul;
+ // velocity = velocity + (vIntersections[iIntersection] - vCenter) * falloffMul;
+
+
+ /*
+ debugoverlay->AddLineOverlay( vIntersections[iIntersection],
+ vIntersections[iIntersection] + reflection * 64,
+ 128, 128, 255, false, 15.0 );
+ */
+#if 1
+ AR2ExplosionParticle *pParticle =
+ (AR2ExplosionParticle*)m_ParticleEffect.AddParticle( sizeof(AR2ExplosionParticle), m_MaterialHandle );
+
+ if(pParticle)
+ {
+ pParticle->m_Pos = vIntersections[iIntersection];
+ pParticle->m_Start = pParticle->m_Pos;
+ pParticle->m_Dist = 8.0;
+ pParticle->m_Velocity = velocity;
+ // sound == 13031.496062992125984251968503937ips
+ pParticle->m_Lifetime = -dist / 13031.5f - 0.1;
+ pParticle->m_Roll = FRand( 0, M_PI * 2 );
+ pParticle->m_RollSpeed = FRand( -1, 1 ) * 0.4;
+ pParticle->m_Dwell = AR2_DUST_LIFETIME + random->RandomFloat( 0, AR2_DUST_LIFETIME_DELTA );
+ nParticles++;
+ break;
+ }
+#endif
+ }
+ }
+ }
+ }
+
+ // build interior smoke particles
+ for(int i=nParticles; i < iParticlesToSpawn; i++)
+ {
+ Vector randVec = RandomVector(-1,1);
+ VectorNormalize( randVec );
+ Vector endPos = vCenter + randVec * AR2_DUST_RADIUS / 4.0;
+
+ Vector direction = (endPos - vCenter );
+ float dist = VectorNormalize( direction ) + random->RandomFloat( 0, AR2_DUST_RADIUS / 4.0 );
+ if(dist > AR2_DUST_RADIUS)
+ dist = AR2_DUST_RADIUS;
+
+ static float power = 2.0f;
+ float falloffMul = pow(1.0f - dist / (AR2_DUST_RADIUS / 2), power);
+
+ Vector velocity = direction * AR2_DUST_SPEED * falloffMul;
+ AR2ExplosionParticle *pParticle =
+ (AR2ExplosionParticle*)m_ParticleEffect.AddParticle( sizeof(AR2ExplosionParticle), m_MaterialHandle );
+
+ if(pParticle)
+ {
+ pParticle->m_Pos = endPos;
+ pParticle->m_Start = pParticle->m_Pos;
+ pParticle->m_Dist = 8.0;
+ pParticle->m_Velocity = velocity;
+ // sound == 13031.496062992125984251968503937ips
+ pParticle->m_Lifetime = -dist / 13031.5f - 0.1;
+ pParticle->m_Roll = FRand( 0, M_PI * 2 );
+ pParticle->m_RollSpeed = FRand( -1, 1 ) * 4.0;
+ pParticle->m_Dwell = 0.5 * (AR2_DUST_LIFETIME + random->RandomFloat( 0, AR2_DUST_LIFETIME_DELTA ));
+ }
+ }
+}
+
+
+void C_AR2Explosion::Update(float fTimeDelta)
+{
+ if(!m_pParticleMgr)
+ return;
+}
+
+
+void C_AR2Explosion::SimulateParticles( CParticleSimulateIterator *pIterator )
+{
+ float dt = pIterator->GetTimeDelta();
+
+ AR2ExplosionParticle *pParticle = (AR2ExplosionParticle*)pIterator->GetFirst();
+ while ( pParticle )
+ {
+ if (dt > 0.05)
+ dt = 0.05; // yuck, air resistance function craps out at less then 20fps
+
+ // Update its lifetime.
+ pParticle->m_Lifetime += dt; // pDraw->GetTimeDelta();
+ if(pParticle->m_Lifetime > pParticle->m_Dwell)
+ {
+ // faded to nothing....
+ pIterator->RemoveParticle( pParticle );
+ }
+ else
+ {
+ // Spin the thing
+ pParticle->m_Roll += pParticle->m_RollSpeed * pIterator->GetTimeDelta();
+
+ // delayed?
+ if ( pParticle->m_Lifetime >= 0.0f )
+ {
+ // Move it (this comes after rendering to make it clear that moving the particle here won't change
+ // its rendering for this frame since m_TransformedPos has already been set).
+ pParticle->m_Pos = pParticle->m_Pos + pParticle->m_Velocity * dt;
+
+ // keep track of distance traveled
+ pParticle->m_Dist = pParticle->m_Dist + pParticle->m_Velocity.Length() * dt;
+
+ // Dampen velocity.
+ float dist = pParticle->m_Velocity.Length() * dt;
+ float r = dist * dist;
+ // FIXME: this is a really screwy air-resistance function....
+ pParticle->m_Velocity = pParticle->m_Velocity * (100 / (100 + r ));
+
+ // dampen roll
+ static float dtime;
+ static float decay;
+ if (dtime != dt)
+ {
+ dtime = dt;
+ decay = ExponentialDecay( 0.3, 1.0, dtime );
+ }
+ if (fabs(pParticle->m_RollSpeed) > 0.2)
+ pParticle->m_RollSpeed = pParticle->m_RollSpeed * decay;
+ }
+ }
+
+ pParticle = (AR2ExplosionParticle*)pIterator->GetNext();
+ }
+}
+
+
+void C_AR2Explosion::RenderParticles( CParticleRenderIterator *pIterator )
+{
+ const AR2ExplosionParticle *pParticle = (const AR2ExplosionParticle *)pIterator->GetFirst();
+ while ( pParticle )
+ {
+ float sortKey = 0;
+ if ( pParticle->m_Lifetime >= 0.0f )
+ {
+ // Draw.
+ float lifetimePercent = ( pParticle->m_Lifetime - AR2_DUST_FADE_IN_TIME ) / pParticle->m_Dwell;
+
+ // FIXME: base color should be a dirty version of the material color
+ Vector color = g_AR2DustColor1 * (1.0 - lifetimePercent) + g_AR2DustColor2 * lifetimePercent;
+
+ Vector tPos;
+ TransformParticle(m_pParticleMgr->GetModelView(), pParticle->m_Pos, tPos);
+ sortKey = tPos.z;
+
+ float alpha;
+
+ if ( pParticle->m_Lifetime < AR2_DUST_FADE_IN_TIME )
+ {
+ alpha = AR2_DUST_ALPHA * ( pParticle->m_Lifetime / AR2_DUST_FADE_IN_TIME );
+ }
+ else
+ {
+ alpha = AR2_DUST_ALPHA * ( 1.0f - lifetimePercent );
+ }
+
+ alpha *= GetAlphaDistanceFade( tPos, IsXbox() ? 100 : 50, IsXbox() ? 200 : 150 );
+
+ RenderParticle_ColorSizeAngle(
+ pIterator->GetParticleDraw(),
+ tPos,
+ color,
+ alpha,
+ pParticle->m_Dist, // size based on how far it's traveled
+ pParticle->m_Roll);
+ }
+
+ pParticle = (const AR2ExplosionParticle *)pIterator->GetNext( sortKey );
+ }
+}
+
+
diff --git a/mp/src/game/client/hl2/c_barnacle.cpp b/mp/src/game/client/hl2/c_barnacle.cpp
index d4dbbed8..344ac0e1 100644
--- a/mp/src/game/client/hl2/c_barnacle.cpp
+++ b/mp/src/game/client/hl2/c_barnacle.cpp
@@ -1,313 +1,313 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#include "cbase.h"
-#include "c_ai_basenpc.h"
-#include "engine/ivmodelinfo.h"
-#include "rope_physics.h"
-#include "materialsystem/imaterialsystem.h"
-#include "fx_line.h"
-#include "engine/ivdebugoverlay.h"
-#include "bone_setup.h"
-#include "model_types.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-#define BARNACLE_TONGUE_POINTS 7
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-class C_NPC_Barnacle : public C_AI_BaseNPC
-{
-public:
-
- DECLARE_CLASS( C_NPC_Barnacle, C_AI_BaseNPC );
- DECLARE_CLIENTCLASS();
-
- C_NPC_Barnacle( void );
-
- virtual void GetRenderBounds( Vector &theMins, Vector &theMaxs )
- {
- BaseClass::GetRenderBounds( theMins, theMaxs );
-
- // Extend our bounding box downwards the length of the tongue
- theMins -= Vector( 0, 0, m_flAltitude );
- }
-
- // Purpose: Initialize absmin & absmax to the appropriate box
- virtual void ComputeWorldSpaceSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs )
- {
- // Extend our bounding box downwards the length of the tongue
- CollisionProp()->WorldSpaceAABB( pVecWorldMins, pVecWorldMaxs );
-
- // We really care about the tongue tip. The altitude is not really relevant.
- VectorMin( *pVecWorldMins, m_vecTip, *pVecWorldMins );
- VectorMax( *pVecWorldMaxs, m_vecTip, *pVecWorldMaxs );
-
-// pVecWorldMins->z -= m_flAltitude;
- }
-
- void OnDataChanged( DataUpdateType_t updateType );
- void InitTonguePhysics( void );
- void ClientThink( void );
- void StandardBlendingRules( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], float currentTime, int boneMask );
-
- void SetVecTip( const float *pPosition );
- void SetAltitude( float flAltitude );
-
- // Purpose:
- void ComputeVisualTipPoint( Vector *pTip );
-
-protected:
- Vector m_vecTipPrevious;
- Vector m_vecRoot;
- Vector m_vecTip;
- Vector m_vecTipDrawOffset;
-
-private:
- // Tongue points
- float m_flAltitude;
- Vector m_vecTonguePoints[BARNACLE_TONGUE_POINTS];
- CRopePhysics<BARNACLE_TONGUE_POINTS> m_TonguePhysics;
-
- // Tongue physics delegate
- class CBarnaclePhysicsDelegate : public CSimplePhysics::IHelper
- {
- public:
- virtual void GetNodeForces( CSimplePhysics::CNode *pNodes, int iNode, Vector *pAccel );
- virtual void ApplyConstraints( CSimplePhysics::CNode *pNodes, int nNodes );
-
- C_NPC_Barnacle *m_pBarnacle;
- };
- friend class CBarnaclePhysicsDelegate;
- CBarnaclePhysicsDelegate m_PhysicsDelegate;
-
-private:
- C_NPC_Barnacle( const C_NPC_Barnacle & ); // not defined, not accessible
-};
-
-static void RecvProxy_VecTip( const CRecvProxyData *pData, void *pStruct, void *pOut )
-{
- ((C_NPC_Barnacle*)pStruct)->SetVecTip( pData->m_Value.m_Vector );
-}
-
-IMPLEMENT_CLIENTCLASS_DT( C_NPC_Barnacle, DT_Barnacle, CNPC_Barnacle )
- RecvPropFloat( RECVINFO( m_flAltitude ) ),
- RecvPropVector( RECVINFO( m_vecRoot ) ),
- RecvPropVector( RECVINFO( m_vecTip ), 0, RecvProxy_VecTip ),
- RecvPropVector( RECVINFO( m_vecTipDrawOffset ) ),
-END_RECV_TABLE()
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-C_NPC_Barnacle::C_NPC_Barnacle( void )
-{
- m_PhysicsDelegate.m_pBarnacle = this;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_NPC_Barnacle::OnDataChanged( DataUpdateType_t updateType )
-{
- BaseClass::OnDataChanged( updateType );
-
- if ( updateType == DATA_UPDATE_CREATED )
- {
- InitTonguePhysics();
-
- // We want to think every frame.
- SetNextClientThink( CLIENT_THINK_ALWAYS );
- return;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Sets the tongue altitude
-//-----------------------------------------------------------------------------
-void C_NPC_Barnacle::SetAltitude( float flAltitude )
-{
- m_flAltitude = flAltitude;
-}
-
-void C_NPC_Barnacle::SetVecTip( const float *pPosition )
-{
- Vector vecNewTip;
- vecNewTip.Init( pPosition[0], pPosition[1], pPosition[2] );
- if ( vecNewTip != m_vecTip )
- {
- m_vecTip = vecNewTip;
- CollisionProp()->MarkSurroundingBoundsDirty();
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_NPC_Barnacle::InitTonguePhysics( void )
-{
- // Init tongue spline
- // First point is at the top
- m_TonguePhysics.SetupSimulation( m_flAltitude / (BARNACLE_TONGUE_POINTS-1), &m_PhysicsDelegate );
- m_TonguePhysics.Restart();
-
- // Initialize the positions of the nodes.
- m_TonguePhysics.GetFirstNode()->m_vPos = m_vecRoot;
- m_TonguePhysics.GetFirstNode()->m_vPrevPos = m_TonguePhysics.GetFirstNode()->m_vPos;
- float flAltitude = m_flAltitude;
- for( int i = 1; i < m_TonguePhysics.NumNodes(); i++ )
- {
- flAltitude *= 0.5;
- CSimplePhysics::CNode *pNode = m_TonguePhysics.GetNode( i );
- pNode->m_vPos = m_TonguePhysics.GetNode(i-1)->m_vPos - Vector(0,0,flAltitude);
- pNode->m_vPrevPos = pNode->m_vPos;
-
- // Set the length of the node's spring
- //m_TonguePhysics.ResetNodeSpringLength( i-1, flAltitude );
- }
-
- m_vecTipPrevious = m_vecTip;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_NPC_Barnacle::ClientThink( void )
-{
- m_TonguePhysics.Simulate( gpGlobals->frametime );
-
- // Set the spring's length to that of the tongue's extension
- m_TonguePhysics.ResetSpringLength( m_flAltitude / (BARNACLE_TONGUE_POINTS-1) );
-
- // Necessary because ComputeVisualTipPoint depends on m_vecTipPrevious
- Vector vecTemp;
- ComputeVisualTipPoint( &vecTemp );
- m_vecTipPrevious = vecTemp;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_NPC_Barnacle::StandardBlendingRules( CStudioHdr *hdr, Vector pos[], Quaternion q[], float currentTime, int boneMask )
-{
- BaseClass::StandardBlendingRules( hdr, pos, q, currentTime, boneMask );
-
- if ( !hdr )
- return;
-
- int firstBone = Studio_BoneIndexByName( hdr, "Barnacle.tongue1" );
-
- Vector vecPrevRight;
- GetVectors( NULL, &vecPrevRight, NULL );
-
- Vector vecPrev = pos[Studio_BoneIndexByName( hdr, "Barnacle.base" )];
- Vector vecCurr = vec3_origin;
- Vector vecForward;
- for ( int i = 0; i <= BARNACLE_TONGUE_POINTS; i++ )
- {
- // We double up the bones at the last node.
- if ( i == BARNACLE_TONGUE_POINTS )
- {
- vecCurr = m_TonguePhysics.GetLastNode()->m_vPos;
- }
- else
- {
- vecCurr = m_TonguePhysics.GetNode(i)->m_vPos;
- }
-
- //debugoverlay->AddBoxOverlay( vecCurr, -Vector(2,2,2), Vector(2,2,2), vec3_angle, 0,255,0, 128, 0.1 );
-
- // Fill out the positions in local space
- VectorITransform( vecCurr, EntityToWorldTransform(), pos[firstBone+i] );
- vecCurr = pos[firstBone+i];
-
- // Disallow twist in the tongue visually
- // Forward vector has to follow the tongue, right + up have to minimize twist from
- // the previous bone
-
- // Fill out the angles
- if ( i != BARNACLE_TONGUE_POINTS )
- {
- vecForward = (vecCurr - vecPrev);
- if ( VectorNormalize( vecForward ) < 1e-3 )
- {
- vecForward.Init( 0, 0, 1 );
- }
- }
-
- // Project the previous vecRight into a plane perpendicular to vecForward
- // that's the vector closest to what we want...
- Vector vecRight, vecUp;
- VectorMA( vecPrevRight, -DotProduct( vecPrevRight, vecForward ), vecForward, vecRight );
- VectorNormalize( vecRight );
- CrossProduct( vecForward, vecRight, vecUp );
-
- BasisToQuaternion( vecForward, vecRight, vecUp, q[firstBone+i] );
-
- vecPrev = vecCurr;
- vecPrevRight = vecRight;
- }
-}
-
-//===============================================================================================================================
-// BARNACLE TONGUE PHYSICS
-//===============================================================================================================================
-#define TONGUE_GRAVITY 0, 0, -1000
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_NPC_Barnacle::CBarnaclePhysicsDelegate::GetNodeForces( CSimplePhysics::CNode *pNodes, int iNode, Vector *pAccel )
-{
- // Gravity.
- pAccel->Init( TONGUE_GRAVITY );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-#define TIP_SNAP_FACTOR 200
-// Todo: this really ought to be SIMD.
-void C_NPC_Barnacle::ComputeVisualTipPoint( Vector *pTip )
-{
- float flTipMove = TIP_SNAP_FACTOR * gpGlobals->frametime;
- Vector tipIdeal;
- VectorAdd(m_vecTip, m_vecTipDrawOffset, tipIdeal);
- if ( tipIdeal.DistToSqr( m_vecTipPrevious ) > (flTipMove * flTipMove) )
- {
- // Inch the visual tip toward the actual tip
- VectorSubtract( tipIdeal, m_vecTipPrevious, *pTip );
- VectorNormalize( *pTip );
- *pTip *= flTipMove;
- *pTip += m_vecTipPrevious;
- }
- else
- {
- *pTip = tipIdeal;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_NPC_Barnacle::CBarnaclePhysicsDelegate::ApplyConstraints( CSimplePhysics::CNode *pNodes, int nNodes )
-{
- // Startpoint always stays at the root
- pNodes[0].m_vPos = m_pBarnacle->m_vecRoot;
-
- // Endpoint always stays at the tip
- m_pBarnacle->ComputeVisualTipPoint( &pNodes[nNodes-1].m_vPos );
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "c_ai_basenpc.h"
+#include "engine/ivmodelinfo.h"
+#include "rope_physics.h"
+#include "materialsystem/imaterialsystem.h"
+#include "fx_line.h"
+#include "engine/ivdebugoverlay.h"
+#include "bone_setup.h"
+#include "model_types.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#define BARNACLE_TONGUE_POINTS 7
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class C_NPC_Barnacle : public C_AI_BaseNPC
+{
+public:
+
+ DECLARE_CLASS( C_NPC_Barnacle, C_AI_BaseNPC );
+ DECLARE_CLIENTCLASS();
+
+ C_NPC_Barnacle( void );
+
+ virtual void GetRenderBounds( Vector &theMins, Vector &theMaxs )
+ {
+ BaseClass::GetRenderBounds( theMins, theMaxs );
+
+ // Extend our bounding box downwards the length of the tongue
+ theMins -= Vector( 0, 0, m_flAltitude );
+ }
+
+ // Purpose: Initialize absmin & absmax to the appropriate box
+ virtual void ComputeWorldSpaceSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs )
+ {
+ // Extend our bounding box downwards the length of the tongue
+ CollisionProp()->WorldSpaceAABB( pVecWorldMins, pVecWorldMaxs );
+
+ // We really care about the tongue tip. The altitude is not really relevant.
+ VectorMin( *pVecWorldMins, m_vecTip, *pVecWorldMins );
+ VectorMax( *pVecWorldMaxs, m_vecTip, *pVecWorldMaxs );
+
+// pVecWorldMins->z -= m_flAltitude;
+ }
+
+ void OnDataChanged( DataUpdateType_t updateType );
+ void InitTonguePhysics( void );
+ void ClientThink( void );
+ void StandardBlendingRules( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], float currentTime, int boneMask );
+
+ void SetVecTip( const float *pPosition );
+ void SetAltitude( float flAltitude );
+
+ // Purpose:
+ void ComputeVisualTipPoint( Vector *pTip );
+
+protected:
+ Vector m_vecTipPrevious;
+ Vector m_vecRoot;
+ Vector m_vecTip;
+ Vector m_vecTipDrawOffset;
+
+private:
+ // Tongue points
+ float m_flAltitude;
+ Vector m_vecTonguePoints[BARNACLE_TONGUE_POINTS];
+ CRopePhysics<BARNACLE_TONGUE_POINTS> m_TonguePhysics;
+
+ // Tongue physics delegate
+ class CBarnaclePhysicsDelegate : public CSimplePhysics::IHelper
+ {
+ public:
+ virtual void GetNodeForces( CSimplePhysics::CNode *pNodes, int iNode, Vector *pAccel );
+ virtual void ApplyConstraints( CSimplePhysics::CNode *pNodes, int nNodes );
+
+ C_NPC_Barnacle *m_pBarnacle;
+ };
+ friend class CBarnaclePhysicsDelegate;
+ CBarnaclePhysicsDelegate m_PhysicsDelegate;
+
+private:
+ C_NPC_Barnacle( const C_NPC_Barnacle & ); // not defined, not accessible
+};
+
+static void RecvProxy_VecTip( const CRecvProxyData *pData, void *pStruct, void *pOut )
+{
+ ((C_NPC_Barnacle*)pStruct)->SetVecTip( pData->m_Value.m_Vector );
+}
+
+IMPLEMENT_CLIENTCLASS_DT( C_NPC_Barnacle, DT_Barnacle, CNPC_Barnacle )
+ RecvPropFloat( RECVINFO( m_flAltitude ) ),
+ RecvPropVector( RECVINFO( m_vecRoot ) ),
+ RecvPropVector( RECVINFO( m_vecTip ), 0, RecvProxy_VecTip ),
+ RecvPropVector( RECVINFO( m_vecTipDrawOffset ) ),
+END_RECV_TABLE()
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_NPC_Barnacle::C_NPC_Barnacle( void )
+{
+ m_PhysicsDelegate.m_pBarnacle = this;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_NPC_Barnacle::OnDataChanged( DataUpdateType_t updateType )
+{
+ BaseClass::OnDataChanged( updateType );
+
+ if ( updateType == DATA_UPDATE_CREATED )
+ {
+ InitTonguePhysics();
+
+ // We want to think every frame.
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+ return;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Sets the tongue altitude
+//-----------------------------------------------------------------------------
+void C_NPC_Barnacle::SetAltitude( float flAltitude )
+{
+ m_flAltitude = flAltitude;
+}
+
+void C_NPC_Barnacle::SetVecTip( const float *pPosition )
+{
+ Vector vecNewTip;
+ vecNewTip.Init( pPosition[0], pPosition[1], pPosition[2] );
+ if ( vecNewTip != m_vecTip )
+ {
+ m_vecTip = vecNewTip;
+ CollisionProp()->MarkSurroundingBoundsDirty();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_NPC_Barnacle::InitTonguePhysics( void )
+{
+ // Init tongue spline
+ // First point is at the top
+ m_TonguePhysics.SetupSimulation( m_flAltitude / (BARNACLE_TONGUE_POINTS-1), &m_PhysicsDelegate );
+ m_TonguePhysics.Restart();
+
+ // Initialize the positions of the nodes.
+ m_TonguePhysics.GetFirstNode()->m_vPos = m_vecRoot;
+ m_TonguePhysics.GetFirstNode()->m_vPrevPos = m_TonguePhysics.GetFirstNode()->m_vPos;
+ float flAltitude = m_flAltitude;
+ for( int i = 1; i < m_TonguePhysics.NumNodes(); i++ )
+ {
+ flAltitude *= 0.5;
+ CSimplePhysics::CNode *pNode = m_TonguePhysics.GetNode( i );
+ pNode->m_vPos = m_TonguePhysics.GetNode(i-1)->m_vPos - Vector(0,0,flAltitude);
+ pNode->m_vPrevPos = pNode->m_vPos;
+
+ // Set the length of the node's spring
+ //m_TonguePhysics.ResetNodeSpringLength( i-1, flAltitude );
+ }
+
+ m_vecTipPrevious = m_vecTip;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_NPC_Barnacle::ClientThink( void )
+{
+ m_TonguePhysics.Simulate( gpGlobals->frametime );
+
+ // Set the spring's length to that of the tongue's extension
+ m_TonguePhysics.ResetSpringLength( m_flAltitude / (BARNACLE_TONGUE_POINTS-1) );
+
+ // Necessary because ComputeVisualTipPoint depends on m_vecTipPrevious
+ Vector vecTemp;
+ ComputeVisualTipPoint( &vecTemp );
+ m_vecTipPrevious = vecTemp;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_NPC_Barnacle::StandardBlendingRules( CStudioHdr *hdr, Vector pos[], Quaternion q[], float currentTime, int boneMask )
+{
+ BaseClass::StandardBlendingRules( hdr, pos, q, currentTime, boneMask );
+
+ if ( !hdr )
+ return;
+
+ int firstBone = Studio_BoneIndexByName( hdr, "Barnacle.tongue1" );
+
+ Vector vecPrevRight;
+ GetVectors( NULL, &vecPrevRight, NULL );
+
+ Vector vecPrev = pos[Studio_BoneIndexByName( hdr, "Barnacle.base" )];
+ Vector vecCurr = vec3_origin;
+ Vector vecForward;
+ for ( int i = 0; i <= BARNACLE_TONGUE_POINTS; i++ )
+ {
+ // We double up the bones at the last node.
+ if ( i == BARNACLE_TONGUE_POINTS )
+ {
+ vecCurr = m_TonguePhysics.GetLastNode()->m_vPos;
+ }
+ else
+ {
+ vecCurr = m_TonguePhysics.GetNode(i)->m_vPos;
+ }
+
+ //debugoverlay->AddBoxOverlay( vecCurr, -Vector(2,2,2), Vector(2,2,2), vec3_angle, 0,255,0, 128, 0.1 );
+
+ // Fill out the positions in local space
+ VectorITransform( vecCurr, EntityToWorldTransform(), pos[firstBone+i] );
+ vecCurr = pos[firstBone+i];
+
+ // Disallow twist in the tongue visually
+ // Forward vector has to follow the tongue, right + up have to minimize twist from
+ // the previous bone
+
+ // Fill out the angles
+ if ( i != BARNACLE_TONGUE_POINTS )
+ {
+ vecForward = (vecCurr - vecPrev);
+ if ( VectorNormalize( vecForward ) < 1e-3 )
+ {
+ vecForward.Init( 0, 0, 1 );
+ }
+ }
+
+ // Project the previous vecRight into a plane perpendicular to vecForward
+ // that's the vector closest to what we want...
+ Vector vecRight, vecUp;
+ VectorMA( vecPrevRight, -DotProduct( vecPrevRight, vecForward ), vecForward, vecRight );
+ VectorNormalize( vecRight );
+ CrossProduct( vecForward, vecRight, vecUp );
+
+ BasisToQuaternion( vecForward, vecRight, vecUp, q[firstBone+i] );
+
+ vecPrev = vecCurr;
+ vecPrevRight = vecRight;
+ }
+}
+
+//===============================================================================================================================
+// BARNACLE TONGUE PHYSICS
+//===============================================================================================================================
+#define TONGUE_GRAVITY 0, 0, -1000
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_NPC_Barnacle::CBarnaclePhysicsDelegate::GetNodeForces( CSimplePhysics::CNode *pNodes, int iNode, Vector *pAccel )
+{
+ // Gravity.
+ pAccel->Init( TONGUE_GRAVITY );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+#define TIP_SNAP_FACTOR 200
+// Todo: this really ought to be SIMD.
+void C_NPC_Barnacle::ComputeVisualTipPoint( Vector *pTip )
+{
+ float flTipMove = TIP_SNAP_FACTOR * gpGlobals->frametime;
+ Vector tipIdeal;
+ VectorAdd(m_vecTip, m_vecTipDrawOffset, tipIdeal);
+ if ( tipIdeal.DistToSqr( m_vecTipPrevious ) > (flTipMove * flTipMove) )
+ {
+ // Inch the visual tip toward the actual tip
+ VectorSubtract( tipIdeal, m_vecTipPrevious, *pTip );
+ VectorNormalize( *pTip );
+ *pTip *= flTipMove;
+ *pTip += m_vecTipPrevious;
+ }
+ else
+ {
+ *pTip = tipIdeal;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_NPC_Barnacle::CBarnaclePhysicsDelegate::ApplyConstraints( CSimplePhysics::CNode *pNodes, int nNodes )
+{
+ // Startpoint always stays at the root
+ pNodes[0].m_vPos = m_pBarnacle->m_vecRoot;
+
+ // Endpoint always stays at the tip
+ m_pBarnacle->ComputeVisualTipPoint( &pNodes[nNodes-1].m_vPos );
+}
diff --git a/mp/src/game/client/hl2/c_barney.cpp b/mp/src/game/client/hl2/c_barney.cpp
index b66c5f8c..85d6173e 100644
--- a/mp/src/game/client/hl2/c_barney.cpp
+++ b/mp/src/game/client/hl2/c_barney.cpp
@@ -1,41 +1,41 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "c_ai_basenpc.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-class C_Barney : public C_AI_BaseNPC
-{
-public:
- DECLARE_CLASS( C_Barney, C_AI_BaseNPC );
- DECLARE_CLIENTCLASS();
-
- C_Barney();
- virtual ~C_Barney();
-
-private:
- C_Barney( const C_Barney & ); // not defined, not accessible
-};
-
-IMPLEMENT_CLIENTCLASS_DT(C_Barney, DT_NPC_Barney, CNPC_Barney)
-END_RECV_TABLE()
-
-C_Barney::C_Barney()
-{
-}
-
-
-C_Barney::~C_Barney()
-{
-}
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "c_ai_basenpc.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class C_Barney : public C_AI_BaseNPC
+{
+public:
+ DECLARE_CLASS( C_Barney, C_AI_BaseNPC );
+ DECLARE_CLIENTCLASS();
+
+ C_Barney();
+ virtual ~C_Barney();
+
+private:
+ C_Barney( const C_Barney & ); // not defined, not accessible
+};
+
+IMPLEMENT_CLIENTCLASS_DT(C_Barney, DT_NPC_Barney, CNPC_Barney)
+END_RECV_TABLE()
+
+C_Barney::C_Barney()
+{
+}
+
+
+C_Barney::~C_Barney()
+{
+}
+
+
diff --git a/mp/src/game/client/hl2/c_basehelicopter.cpp b/mp/src/game/client/hl2/c_basehelicopter.cpp
index 53cea1db..abc37286 100644
--- a/mp/src/game/client/hl2/c_basehelicopter.cpp
+++ b/mp/src/game/client/hl2/c_basehelicopter.cpp
@@ -1,91 +1,91 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "c_basehelicopter.h"
-#include "proxyentity.h"
-#include "materialsystem/imaterial.h"
-#include "materialsystem/imaterialvar.h"
-#include "KeyValues.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-IMPLEMENT_CLIENTCLASS_DT( C_BaseHelicopter, DT_BaseHelicopter, CBaseHelicopter )
- RecvPropTime( RECVINFO( m_flStartupTime ) ),
-END_RECV_TABLE()
-
-
-C_BaseHelicopter::C_BaseHelicopter()
-{
-}
-
-
-//-----------------------------------------------------------------------------
-// Chopper blade fade-in time
-//-----------------------------------------------------------------------------
-#define FADE_IN_TIME 2.0f
-
-
-//-----------------------------------------------------------------------------
-// Sets the fade of the blades when the chopper starts up
-//-----------------------------------------------------------------------------
-class CHeliBladeMaterialProxy : public CEntityMaterialProxy
-{
-public:
- CHeliBladeMaterialProxy() { m_AlphaVar = NULL; }
- virtual ~CHeliBladeMaterialProxy() {}
- virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
- virtual void OnBind( C_BaseEntity *pEntity );
- virtual IMaterial *GetMaterial();
-
-private:
- IMaterialVar *m_AlphaVar;
- bool m_bFadeOut;
-};
-
-bool CHeliBladeMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
-{
- bool foundVar;
- m_AlphaVar = pMaterial->FindVar( "$alpha", &foundVar, false );
- m_bFadeOut = pKeyValues->GetInt( "$fadeout", 0 ) != 0;
- return foundVar;
-}
-
-void CHeliBladeMaterialProxy::OnBind( C_BaseEntity *pEnt )
-{
- if (!m_AlphaVar)
- return;
-
- C_BaseHelicopter *pHeli = dynamic_cast<C_BaseHelicopter*>( pEnt );
- if ( pHeli )
- {
- float dt = gpGlobals->curtime - pHeli->StartupTime();
- dt /= FADE_IN_TIME;
- dt = clamp( dt, 0.0f, 1.0f );
- if ( m_bFadeOut )
- {
- dt = 1.0f - dt;
- }
-
- m_AlphaVar->SetFloatValue( dt );
- }
- else
- {
- m_AlphaVar->SetFloatValue( 1.0f );
- }
-}
-
-IMaterial *CHeliBladeMaterialProxy::GetMaterial()
-{
- if ( !m_AlphaVar )
- return NULL;
-
- return m_AlphaVar->GetOwningMaterial();
-}
-
-EXPOSE_INTERFACE( CHeliBladeMaterialProxy, IMaterialProxy, "HeliBlade" IMATERIAL_PROXY_INTERFACE_VERSION );
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "c_basehelicopter.h"
+#include "proxyentity.h"
+#include "materialsystem/imaterial.h"
+#include "materialsystem/imaterialvar.h"
+#include "KeyValues.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+IMPLEMENT_CLIENTCLASS_DT( C_BaseHelicopter, DT_BaseHelicopter, CBaseHelicopter )
+ RecvPropTime( RECVINFO( m_flStartupTime ) ),
+END_RECV_TABLE()
+
+
+C_BaseHelicopter::C_BaseHelicopter()
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Chopper blade fade-in time
+//-----------------------------------------------------------------------------
+#define FADE_IN_TIME 2.0f
+
+
+//-----------------------------------------------------------------------------
+// Sets the fade of the blades when the chopper starts up
+//-----------------------------------------------------------------------------
+class CHeliBladeMaterialProxy : public CEntityMaterialProxy
+{
+public:
+ CHeliBladeMaterialProxy() { m_AlphaVar = NULL; }
+ virtual ~CHeliBladeMaterialProxy() {}
+ virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
+ virtual void OnBind( C_BaseEntity *pEntity );
+ virtual IMaterial *GetMaterial();
+
+private:
+ IMaterialVar *m_AlphaVar;
+ bool m_bFadeOut;
+};
+
+bool CHeliBladeMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
+{
+ bool foundVar;
+ m_AlphaVar = pMaterial->FindVar( "$alpha", &foundVar, false );
+ m_bFadeOut = pKeyValues->GetInt( "$fadeout", 0 ) != 0;
+ return foundVar;
+}
+
+void CHeliBladeMaterialProxy::OnBind( C_BaseEntity *pEnt )
+{
+ if (!m_AlphaVar)
+ return;
+
+ C_BaseHelicopter *pHeli = dynamic_cast<C_BaseHelicopter*>( pEnt );
+ if ( pHeli )
+ {
+ float dt = gpGlobals->curtime - pHeli->StartupTime();
+ dt /= FADE_IN_TIME;
+ dt = clamp( dt, 0.0f, 1.0f );
+ if ( m_bFadeOut )
+ {
+ dt = 1.0f - dt;
+ }
+
+ m_AlphaVar->SetFloatValue( dt );
+ }
+ else
+ {
+ m_AlphaVar->SetFloatValue( 1.0f );
+ }
+}
+
+IMaterial *CHeliBladeMaterialProxy::GetMaterial()
+{
+ if ( !m_AlphaVar )
+ return NULL;
+
+ return m_AlphaVar->GetOwningMaterial();
+}
+
+EXPOSE_INTERFACE( CHeliBladeMaterialProxy, IMaterialProxy, "HeliBlade" IMATERIAL_PROXY_INTERFACE_VERSION );
+
diff --git a/mp/src/game/client/hl2/c_basehelicopter.h b/mp/src/game/client/hl2/c_basehelicopter.h
index c02c6b51..6ef2d930 100644
--- a/mp/src/game/client/hl2/c_basehelicopter.h
+++ b/mp/src/game/client/hl2/c_basehelicopter.h
@@ -1,33 +1,33 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#ifndef C_BASEHELICOPTER_H
-#define C_BASEHELICOPTER_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-
-#include "c_ai_basenpc.h"
-
-
-class C_BaseHelicopter : public C_AI_BaseNPC
-{
-public:
- DECLARE_CLASS( C_BaseHelicopter, C_AI_BaseNPC );
- DECLARE_CLIENTCLASS();
-
- C_BaseHelicopter();
-
- float StartupTime() const { return m_flStartupTime; }
-
-private:
- C_BaseHelicopter( const C_BaseHelicopter &other ) {}
- float m_flStartupTime;
-};
-
-
-#endif // C_BASEHELICOPTER_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef C_BASEHELICOPTER_H
+#define C_BASEHELICOPTER_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "c_ai_basenpc.h"
+
+
+class C_BaseHelicopter : public C_AI_BaseNPC
+{
+public:
+ DECLARE_CLASS( C_BaseHelicopter, C_AI_BaseNPC );
+ DECLARE_CLIENTCLASS();
+
+ C_BaseHelicopter();
+
+ float StartupTime() const { return m_flStartupTime; }
+
+private:
+ C_BaseHelicopter( const C_BaseHelicopter &other ) {}
+ float m_flStartupTime;
+};
+
+
+#endif // C_BASEHELICOPTER_H
diff --git a/mp/src/game/client/hl2/c_basehlcombatweapon.cpp b/mp/src/game/client/hl2/c_basehlcombatweapon.cpp
index 02bda7b5..bc3e5a3e 100644
--- a/mp/src/game/client/hl2/c_basehlcombatweapon.cpp
+++ b/mp/src/game/client/hl2/c_basehlcombatweapon.cpp
@@ -1,21 +1,21 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "c_basehlcombatweapon.h"
-#include "igamemovement.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-IMPLEMENT_CLIENTCLASS_DT( C_HLMachineGun, DT_HLMachineGun, CHLMachineGun )
-END_RECV_TABLE()
-
-IMPLEMENT_CLIENTCLASS_DT( C_HLSelectFireMachineGun, DT_HLSelectFireMachineGun, CHLSelectFireMachineGun )
-END_RECV_TABLE()
-
-IMPLEMENT_CLIENTCLASS_DT( C_BaseHLBludgeonWeapon, DT_BaseHLBludgeonWeapon, CBaseHLBludgeonWeapon )
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "c_basehlcombatweapon.h"
+#include "igamemovement.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+IMPLEMENT_CLIENTCLASS_DT( C_HLMachineGun, DT_HLMachineGun, CHLMachineGun )
+END_RECV_TABLE()
+
+IMPLEMENT_CLIENTCLASS_DT( C_HLSelectFireMachineGun, DT_HLSelectFireMachineGun, CHLSelectFireMachineGun )
+END_RECV_TABLE()
+
+IMPLEMENT_CLIENTCLASS_DT( C_BaseHLBludgeonWeapon, DT_BaseHLBludgeonWeapon, CBaseHLBludgeonWeapon )
END_RECV_TABLE() \ No newline at end of file
diff --git a/mp/src/game/client/hl2/c_basehlcombatweapon.h b/mp/src/game/client/hl2/c_basehlcombatweapon.h
index 88132917..72440cc3 100644
--- a/mp/src/game/client/hl2/c_basehlcombatweapon.h
+++ b/mp/src/game/client/hl2/c_basehlcombatweapon.h
@@ -1,36 +1,36 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "basehlcombatweapon_shared.h"
-
-#ifndef C_BASEHLCOMBATWEAPON_H
-#define C_BASEHLCOMBATWEAPON_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-class C_HLMachineGun : public C_BaseHLCombatWeapon
-{
-public:
- DECLARE_CLASS( C_HLMachineGun, C_BaseHLCombatWeapon );
- DECLARE_CLIENTCLASS();
-};
-
-class C_HLSelectFireMachineGun : public C_HLMachineGun
-{
-public:
- DECLARE_CLASS( C_HLSelectFireMachineGun, C_HLMachineGun );
- DECLARE_CLIENTCLASS();
-};
-
-class C_BaseHLBludgeonWeapon : public C_BaseHLCombatWeapon
-{
-public:
- DECLARE_CLASS( C_BaseHLBludgeonWeapon, C_BaseHLCombatWeapon );
- DECLARE_CLIENTCLASS();
-};
-
-#endif // C_BASEHLCOMBATWEAPON_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "basehlcombatweapon_shared.h"
+
+#ifndef C_BASEHLCOMBATWEAPON_H
+#define C_BASEHLCOMBATWEAPON_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+class C_HLMachineGun : public C_BaseHLCombatWeapon
+{
+public:
+ DECLARE_CLASS( C_HLMachineGun, C_BaseHLCombatWeapon );
+ DECLARE_CLIENTCLASS();
+};
+
+class C_HLSelectFireMachineGun : public C_HLMachineGun
+{
+public:
+ DECLARE_CLASS( C_HLSelectFireMachineGun, C_HLMachineGun );
+ DECLARE_CLIENTCLASS();
+};
+
+class C_BaseHLBludgeonWeapon : public C_BaseHLCombatWeapon
+{
+public:
+ DECLARE_CLASS( C_BaseHLBludgeonWeapon, C_BaseHLCombatWeapon );
+ DECLARE_CLIENTCLASS();
+};
+
+#endif // C_BASEHLCOMBATWEAPON_H
diff --git a/mp/src/game/client/hl2/c_basehlplayer.cpp b/mp/src/game/client/hl2/c_basehlplayer.cpp
index 230a720a..fbc40eb2 100644
--- a/mp/src/game/client/hl2/c_basehlplayer.cpp
+++ b/mp/src/game/client/hl2/c_basehlplayer.cpp
@@ -1,649 +1,649 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "c_basehlplayer.h"
-#include "playerandobjectenumerator.h"
-#include "engine/ivdebugoverlay.h"
-#include "c_ai_basenpc.h"
-#include "in_buttons.h"
-#include "collisionutils.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-// How fast to avoid collisions with center of other object, in units per second
-#define AVOID_SPEED 2000.0f
-extern ConVar cl_forwardspeed;
-extern ConVar cl_backspeed;
-extern ConVar cl_sidespeed;
-
-extern ConVar zoom_sensitivity_ratio;
-extern ConVar default_fov;
-extern ConVar sensitivity;
-
-ConVar cl_npc_speedmod_intime( "cl_npc_speedmod_intime", "0.25", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
-ConVar cl_npc_speedmod_outtime( "cl_npc_speedmod_outtime", "1.5", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
-
-IMPLEMENT_CLIENTCLASS_DT(C_BaseHLPlayer, DT_HL2_Player, CHL2_Player)
- RecvPropDataTable( RECVINFO_DT(m_HL2Local),0, &REFERENCE_RECV_TABLE(DT_HL2Local) ),
- RecvPropBool( RECVINFO( m_fIsSprinting ) ),
-END_RECV_TABLE()
-
-BEGIN_PREDICTION_DATA( C_BaseHLPlayer )
- DEFINE_PRED_TYPEDESCRIPTION( m_HL2Local, C_HL2PlayerLocalData ),
- DEFINE_PRED_FIELD( m_fIsSprinting, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
-END_PREDICTION_DATA()
-
-//-----------------------------------------------------------------------------
-// Purpose: Drops player's primary weapon
-//-----------------------------------------------------------------------------
-void CC_DropPrimary( void )
-{
- C_BasePlayer *pPlayer = (C_BasePlayer *) C_BasePlayer::GetLocalPlayer();
-
- if ( pPlayer == NULL )
- return;
-
- pPlayer->Weapon_DropPrimary();
-}
-
-static ConCommand dropprimary("dropprimary", CC_DropPrimary, "dropprimary: Drops the primary weapon of the player.");
-
-//-----------------------------------------------------------------------------
-// Constructor
-//-----------------------------------------------------------------------------
-C_BaseHLPlayer::C_BaseHLPlayer()
-{
- AddVar( &m_Local.m_vecPunchAngle, &m_Local.m_iv_vecPunchAngle, LATCH_SIMULATION_VAR );
- AddVar( &m_Local.m_vecPunchAngleVel, &m_Local.m_iv_vecPunchAngleVel, LATCH_SIMULATION_VAR );
-
- m_flZoomStart = 0.0f;
- m_flZoomEnd = 0.0f;
- m_flZoomRate = 0.0f;
- m_flZoomStartTime = 0.0f;
- m_flSpeedMod = cl_forwardspeed.GetFloat();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : updateType -
-//-----------------------------------------------------------------------------
-void C_BaseHLPlayer::OnDataChanged( DataUpdateType_t updateType )
-{
- // Make sure we're thinking
- if ( updateType == DATA_UPDATE_CREATED )
- {
- SetNextClientThink( CLIENT_THINK_ALWAYS );
- }
-
- BaseClass::OnDataChanged( updateType );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_BaseHLPlayer::Weapon_DropPrimary( void )
-{
- engine->ServerCmd( "DropPrimary" );
-}
-
-float C_BaseHLPlayer::GetFOV()
-{
- //Find our FOV with offset zoom value
- float flFOVOffset = BaseClass::GetFOV() + GetZoom();
-
- // Clamp FOV in MP
- int min_fov = ( gpGlobals->maxClients == 1 ) ? 5 : default_fov.GetInt();
-
- // Don't let it go too low
- flFOVOffset = MAX( min_fov, flFOVOffset );
-
- return flFOVOffset;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : float
-//-----------------------------------------------------------------------------
-float C_BaseHLPlayer::GetZoom( void )
-{
- float fFOV = m_flZoomEnd;
-
- //See if we need to lerp the values
- if ( ( m_flZoomStart != m_flZoomEnd ) && ( m_flZoomRate > 0.0f ) )
- {
- float deltaTime = (float)( gpGlobals->curtime - m_flZoomStartTime ) / m_flZoomRate;
-
- if ( deltaTime >= 1.0f )
- {
- //If we're past the zoom time, just take the new value and stop lerping
- fFOV = m_flZoomStart = m_flZoomEnd;
- }
- else
- {
- fFOV = SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, m_flZoomStart, m_flZoomEnd );
- }
- }
-
- return fFOV;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : FOVOffset -
-// time -
-//-----------------------------------------------------------------------------
-void C_BaseHLPlayer::Zoom( float FOVOffset, float time )
-{
- m_flZoomStart = GetZoom();
- m_flZoomEnd = FOVOffset;
- m_flZoomRate = time;
- m_flZoomStartTime = gpGlobals->curtime;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Hack to zero out player's pitch, use value from poseparameter instead
-// Input : flags -
-// Output : int
-//-----------------------------------------------------------------------------
-int C_BaseHLPlayer::DrawModel( int flags )
-{
- // Not pitch for player
- QAngle saveAngles = GetLocalAngles();
-
- QAngle useAngles = saveAngles;
- useAngles[ PITCH ] = 0.0f;
-
- SetLocalAngles( useAngles );
-
- int iret = BaseClass::DrawModel( flags );
-
- SetLocalAngles( saveAngles );
-
- return iret;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Helper to remove from ladder
-//-----------------------------------------------------------------------------
-void C_BaseHLPlayer::ExitLadder()
-{
- if ( MOVETYPE_LADDER != GetMoveType() )
- return;
-
- SetMoveType( MOVETYPE_WALK );
- SetMoveCollide( MOVECOLLIDE_DEFAULT );
- // Remove from ladder
- m_HL2Local.m_hLadder = NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Determines if a player can be safely moved towards a point
-// Input: pos - position to test move to, fVertDist - how far to trace downwards to see if the player would fall,
-// radius - how close the player can be to the object, objPos - position of the object to avoid,
-// objDir - direction the object is travelling
-//-----------------------------------------------------------------------------
-bool C_BaseHLPlayer::TestMove( const Vector &pos, float fVertDist, float radius, const Vector &objPos, const Vector &objDir )
-{
- trace_t trUp;
- trace_t trOver;
- trace_t trDown;
- float flHit1, flHit2;
-
- UTIL_TraceHull( GetAbsOrigin(), pos, GetPlayerMins(), GetPlayerMaxs(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trOver );
- if ( trOver.fraction < 1.0f )
- {
- // check if the endpos intersects with the direction the object is travelling. if it doesn't, this is a good direction to move.
- if ( objDir.IsZero() ||
- ( IntersectInfiniteRayWithSphere( objPos, objDir, trOver.endpos, radius, &flHit1, &flHit2 ) &&
- ( ( flHit1 >= 0.0f ) || ( flHit2 >= 0.0f ) ) )
- )
- {
- // our first trace failed, so see if we can go farther if we step up.
-
- // trace up to see if we have enough room.
- UTIL_TraceHull( GetAbsOrigin(), GetAbsOrigin() + Vector( 0, 0, m_Local.m_flStepSize ),
- GetPlayerMins(), GetPlayerMaxs(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trUp );
-
- // do a trace from the stepped up height
- UTIL_TraceHull( trUp.endpos, pos + Vector( 0, 0, trUp.endpos.z - trUp.startpos.z ),
- GetPlayerMins(), GetPlayerMaxs(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trOver );
-
- if ( trOver.fraction < 1.0f )
- {
- // check if the endpos intersects with the direction the object is travelling. if it doesn't, this is a good direction to move.
- if ( objDir.IsZero() ||
- ( IntersectInfiniteRayWithSphere( objPos, objDir, trOver.endpos, radius, &flHit1, &flHit2 ) && ( ( flHit1 >= 0.0f ) || ( flHit2 >= 0.0f ) ) ) )
- {
- return false;
- }
- }
- }
- }
-
- // trace down to see if this position is on the ground
- UTIL_TraceLine( trOver.endpos, trOver.endpos - Vector( 0, 0, fVertDist ),
- MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &trDown );
-
- if ( trDown.fraction == 1.0f )
- return false;
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Client-side obstacle avoidance
-//-----------------------------------------------------------------------------
-void C_BaseHLPlayer::PerformClientSideObstacleAvoidance( float flFrameTime, CUserCmd *pCmd )
-{
- // Don't avoid if noclipping or in movetype none
- switch ( GetMoveType() )
- {
- case MOVETYPE_NOCLIP:
- case MOVETYPE_NONE:
- case MOVETYPE_OBSERVER:
- return;
- default:
- break;
- }
-
- // Try to steer away from any objects/players we might interpenetrate
- Vector size = WorldAlignSize();
-
- float radius = 0.7f * sqrt( size.x * size.x + size.y * size.y );
- float curspeed = GetLocalVelocity().Length2D();
-
- //int slot = 1;
- //engine->Con_NPrintf( slot++, "speed %f\n", curspeed );
- //engine->Con_NPrintf( slot++, "radius %f\n", radius );
-
- // If running, use a larger radius
- float factor = 1.0f;
-
- if ( curspeed > 150.0f )
- {
- curspeed = MIN( 2048.0f, curspeed );
- factor = ( 1.0f + ( curspeed - 150.0f ) / 150.0f );
-
- //engine->Con_NPrintf( slot++, "scaleup (%f) to radius %f\n", factor, radius * factor );
-
- radius = radius * factor;
- }
-
- Vector currentdir;
- Vector rightdir;
-
- QAngle vAngles = pCmd->viewangles;
- vAngles.x = 0;
-
- AngleVectors( vAngles, &currentdir, &rightdir, NULL );
-
- bool istryingtomove = false;
- bool ismovingforward = false;
- if ( fabs( pCmd->forwardmove ) > 0.0f ||
- fabs( pCmd->sidemove ) > 0.0f )
- {
- istryingtomove = true;
- if ( pCmd->forwardmove > 1.0f )
- {
- ismovingforward = true;
- }
- }
-
- if ( istryingtomove == true )
- radius *= 1.3f;
-
- CPlayerAndObjectEnumerator avoid( radius );
- partition->EnumerateElementsInSphere( PARTITION_CLIENT_SOLID_EDICTS, GetAbsOrigin(), radius, false, &avoid );
-
- // Okay, decide how to avoid if there's anything close by
- int c = avoid.GetObjectCount();
- if ( c <= 0 )
- return;
-
- //engine->Con_NPrintf( slot++, "moving %s forward %s\n", istryingtomove ? "true" : "false", ismovingforward ? "true" : "false" );
-
- float adjustforwardmove = 0.0f;
- float adjustsidemove = 0.0f;
-
- for ( int i = 0; i < c; i++ )
- {
- C_AI_BaseNPC *obj = dynamic_cast< C_AI_BaseNPC *>(avoid.GetObject( i ));
-
- if( !obj )
- continue;
-
- Vector vecToObject = obj->GetAbsOrigin() - GetAbsOrigin();
-
- float flDist = vecToObject.Length2D();
-
- // Figure out a 2D radius for the object
- Vector vecWorldMins, vecWorldMaxs;
- obj->CollisionProp()->WorldSpaceAABB( &vecWorldMins, &vecWorldMaxs );
- Vector objSize = vecWorldMaxs - vecWorldMins;
-
- float objectradius = 0.5f * sqrt( objSize.x * objSize.x + objSize.y * objSize.y );
-
- //Don't run this code if the NPC is not moving UNLESS we are in stuck inside of them.
- if ( !obj->IsMoving() && flDist > objectradius )
- continue;
-
- if ( flDist > objectradius && obj->IsEffectActive( EF_NODRAW ) )
- {
- obj->RemoveEffects( EF_NODRAW );
- }
-
- Vector vecNPCVelocity;
- obj->EstimateAbsVelocity( vecNPCVelocity );
- float flNPCSpeed = VectorNormalize( vecNPCVelocity );
-
- Vector vPlayerVel = GetAbsVelocity();
- VectorNormalize( vPlayerVel );
-
- float flHit1, flHit2;
- Vector vRayDir = vecToObject;
- VectorNormalize( vRayDir );
-
- float flVelProduct = DotProduct( vecNPCVelocity, vPlayerVel );
- float flDirProduct = DotProduct( vRayDir, vPlayerVel );
-
- if ( !IntersectInfiniteRayWithSphere(
- GetAbsOrigin(),
- vRayDir,
- obj->GetAbsOrigin(),
- radius,
- &flHit1,
- &flHit2 ) )
- continue;
-
- Vector dirToObject = -vecToObject;
- VectorNormalize( dirToObject );
-
- float fwd = 0;
- float rt = 0;
-
- float sidescale = 2.0f;
- float forwardscale = 1.0f;
- bool foundResult = false;
-
- Vector vMoveDir = vecNPCVelocity;
- if ( flNPCSpeed > 0.001f )
- {
- // This NPC is moving. First try deflecting the player left or right relative to the NPC's velocity.
- // Start with whatever side they're on relative to the NPC's velocity.
- Vector vecNPCTrajectoryRight = CrossProduct( vecNPCVelocity, Vector( 0, 0, 1) );
- int iDirection = ( vecNPCTrajectoryRight.Dot( dirToObject ) > 0 ) ? 1 : -1;
- for ( int nTries = 0; nTries < 2; nTries++ )
- {
- Vector vecTryMove = vecNPCTrajectoryRight * iDirection;
- VectorNormalize( vecTryMove );
-
- Vector vTestPosition = GetAbsOrigin() + vecTryMove * radius * 2;
-
- if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
- {
- fwd = currentdir.Dot( vecTryMove );
- rt = rightdir.Dot( vecTryMove );
-
- //Msg( "PUSH DEFLECT fwd=%f, rt=%f\n", fwd, rt );
-
- foundResult = true;
- break;
- }
- else
- {
- // Try the other direction.
- iDirection *= -1;
- }
- }
- }
- else
- {
- // the object isn't moving, so try moving opposite the way it's facing
- Vector vecNPCForward;
- obj->GetVectors( &vecNPCForward, NULL, NULL );
-
- Vector vTestPosition = GetAbsOrigin() - vecNPCForward * radius * 2;
- if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
- {
- fwd = currentdir.Dot( -vecNPCForward );
- rt = rightdir.Dot( -vecNPCForward );
-
- if ( flDist < objectradius )
- {
- obj->AddEffects( EF_NODRAW );
- }
-
- //Msg( "PUSH AWAY FACE fwd=%f, rt=%f\n", fwd, rt );
-
- foundResult = true;
- }
- }
-
- if ( !foundResult )
- {
- // test if we can move in the direction the object is moving
- Vector vTestPosition = GetAbsOrigin() + vMoveDir * radius * 2;
- if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
- {
- fwd = currentdir.Dot( vMoveDir );
- rt = rightdir.Dot( vMoveDir );
-
- if ( flDist < objectradius )
- {
- obj->AddEffects( EF_NODRAW );
- }
-
- //Msg( "PUSH ALONG fwd=%f, rt=%f\n", fwd, rt );
-
- foundResult = true;
- }
- else
- {
- // try moving directly away from the object
- Vector vTestPosition = GetAbsOrigin() - dirToObject * radius * 2;
- if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
- {
- fwd = currentdir.Dot( -dirToObject );
- rt = rightdir.Dot( -dirToObject );
- foundResult = true;
-
- //Msg( "PUSH AWAY fwd=%f, rt=%f\n", fwd, rt );
- }
- }
- }
-
- if ( !foundResult )
- {
- // test if we can move through the object
- Vector vTestPosition = GetAbsOrigin() - vMoveDir * radius * 2;
- fwd = currentdir.Dot( -vMoveDir );
- rt = rightdir.Dot( -vMoveDir );
-
- if ( flDist < objectradius )
- {
- obj->AddEffects( EF_NODRAW );
- }
-
- //Msg( "PUSH THROUGH fwd=%f, rt=%f\n", fwd, rt );
-
- foundResult = true;
- }
-
- // If running, then do a lot more sideways veer since we're not going to do anything to
- // forward velocity
- if ( istryingtomove )
- {
- sidescale = 6.0f;
- }
-
- if ( flVelProduct > 0.0f && flDirProduct > 0.0f )
- {
- sidescale = 0.1f;
- }
-
- float force = 1.0f;
- float forward = forwardscale * fwd * force * AVOID_SPEED;
- float side = sidescale * rt * force * AVOID_SPEED;
-
- adjustforwardmove += forward;
- adjustsidemove += side;
- }
-
- pCmd->forwardmove += adjustforwardmove;
- pCmd->sidemove += adjustsidemove;
-
- // Clamp the move to within legal limits, preserving direction. This is a little
- // complicated because we have different limits for forward, back, and side
-
- //Msg( "PRECLAMP: forwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove );
-
- float flForwardScale = 1.0f;
- if ( pCmd->forwardmove > fabs( cl_forwardspeed.GetFloat() ) )
- {
- flForwardScale = fabs( cl_forwardspeed.GetFloat() ) / pCmd->forwardmove;
- }
- else if ( pCmd->forwardmove < -fabs( cl_backspeed.GetFloat() ) )
- {
- flForwardScale = fabs( cl_backspeed.GetFloat() ) / fabs( pCmd->forwardmove );
- }
-
- float flSideScale = 1.0f;
- if ( fabs( pCmd->sidemove ) > fabs( cl_sidespeed.GetFloat() ) )
- {
- flSideScale = fabs( cl_sidespeed.GetFloat() ) / fabs( pCmd->sidemove );
- }
-
- float flScale = MIN( flForwardScale, flSideScale );
- pCmd->forwardmove *= flScale;
- pCmd->sidemove *= flScale;
-
- //Msg( "POSTCLAMP: forwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove );
-}
-
-
-void C_BaseHLPlayer::PerformClientSideNPCSpeedModifiers( float flFrameTime, CUserCmd *pCmd )
-{
- if ( m_hClosestNPC == NULL )
- {
- if ( m_flSpeedMod != cl_forwardspeed.GetFloat() )
- {
- float flDeltaTime = (m_flSpeedModTime - gpGlobals->curtime);
- m_flSpeedMod = RemapValClamped( flDeltaTime, cl_npc_speedmod_outtime.GetFloat(), 0, m_flExitSpeedMod, cl_forwardspeed.GetFloat() );
- }
- }
- else
- {
- C_AI_BaseNPC *pNPC = dynamic_cast< C_AI_BaseNPC *>( m_hClosestNPC.Get() );
-
- if ( pNPC )
- {
- float flDist = (GetAbsOrigin() - pNPC->GetAbsOrigin()).LengthSqr();
- bool bShouldModSpeed = false;
-
- // Within range?
- if ( flDist < pNPC->GetSpeedModifyRadius() )
- {
- // Now, only slowdown if we're facing & running parallel to the target's movement
- // Facing check first (in 2D)
- Vector vecTargetOrigin = pNPC->GetAbsOrigin();
- Vector los = ( vecTargetOrigin - EyePosition() );
- los.z = 0;
- VectorNormalize( los );
- Vector facingDir;
- AngleVectors( GetAbsAngles(), &facingDir );
- float flDot = DotProduct( los, facingDir );
- if ( flDot > 0.8 )
- {
- /*
- // Velocity check (abort if the target isn't moving)
- Vector vecTargetVelocity;
- pNPC->EstimateAbsVelocity( vecTargetVelocity );
- float flSpeed = VectorNormalize(vecTargetVelocity);
- Vector vecMyVelocity = GetAbsVelocity();
- VectorNormalize(vecMyVelocity);
- if ( flSpeed > 1.0 )
- {
- // Velocity roughly parallel?
- if ( DotProduct(vecTargetVelocity,vecMyVelocity) > 0.4 )
- {
- bShouldModSpeed = true;
- }
- }
- else
- {
- // NPC's not moving, slow down if we're moving at him
- //Msg("Dot: %.2f\n", DotProduct( los, vecMyVelocity ) );
- if ( DotProduct( los, vecMyVelocity ) > 0.8 )
- {
- bShouldModSpeed = true;
- }
- }
- */
-
- bShouldModSpeed = true;
- }
- }
-
- if ( !bShouldModSpeed )
- {
- m_hClosestNPC = NULL;
- m_flSpeedModTime = gpGlobals->curtime + cl_npc_speedmod_outtime.GetFloat();
- m_flExitSpeedMod = m_flSpeedMod;
- return;
- }
- else
- {
- if ( m_flSpeedMod != pNPC->GetSpeedModifySpeed() )
- {
- float flDeltaTime = (m_flSpeedModTime - gpGlobals->curtime);
- m_flSpeedMod = RemapValClamped( flDeltaTime, cl_npc_speedmod_intime.GetFloat(), 0, cl_forwardspeed.GetFloat(), pNPC->GetSpeedModifySpeed() );
- }
- }
- }
- }
-
- if ( pCmd->forwardmove > 0.0f )
- {
- pCmd->forwardmove = clamp( pCmd->forwardmove, -m_flSpeedMod, m_flSpeedMod );
- }
- else
- {
- pCmd->forwardmove = clamp( pCmd->forwardmove, -m_flSpeedMod, m_flSpeedMod );
- }
- pCmd->sidemove = clamp( pCmd->sidemove, -m_flSpeedMod, m_flSpeedMod );
-
- //Msg( "fwd %f right %f\n", pCmd->forwardmove, pCmd->sidemove );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Input handling
-//-----------------------------------------------------------------------------
-bool C_BaseHLPlayer::CreateMove( float flInputSampleTime, CUserCmd *pCmd )
-{
- bool bResult = BaseClass::CreateMove( flInputSampleTime, pCmd );
-
- if ( !IsInAVehicle() )
- {
- PerformClientSideObstacleAvoidance( TICK_INTERVAL, pCmd );
- PerformClientSideNPCSpeedModifiers( TICK_INTERVAL, pCmd );
- }
-
- return bResult;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Input handling
-//-----------------------------------------------------------------------------
-void C_BaseHLPlayer::BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed )
-{
- BaseClass::BuildTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed );
- BuildFirstPersonMeathookTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed, "ValveBiped.Bip01_Head1" );
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "c_basehlplayer.h"
+#include "playerandobjectenumerator.h"
+#include "engine/ivdebugoverlay.h"
+#include "c_ai_basenpc.h"
+#include "in_buttons.h"
+#include "collisionutils.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+// How fast to avoid collisions with center of other object, in units per second
+#define AVOID_SPEED 2000.0f
+extern ConVar cl_forwardspeed;
+extern ConVar cl_backspeed;
+extern ConVar cl_sidespeed;
+
+extern ConVar zoom_sensitivity_ratio;
+extern ConVar default_fov;
+extern ConVar sensitivity;
+
+ConVar cl_npc_speedmod_intime( "cl_npc_speedmod_intime", "0.25", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
+ConVar cl_npc_speedmod_outtime( "cl_npc_speedmod_outtime", "1.5", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
+
+IMPLEMENT_CLIENTCLASS_DT(C_BaseHLPlayer, DT_HL2_Player, CHL2_Player)
+ RecvPropDataTable( RECVINFO_DT(m_HL2Local),0, &REFERENCE_RECV_TABLE(DT_HL2Local) ),
+ RecvPropBool( RECVINFO( m_fIsSprinting ) ),
+END_RECV_TABLE()
+
+BEGIN_PREDICTION_DATA( C_BaseHLPlayer )
+ DEFINE_PRED_TYPEDESCRIPTION( m_HL2Local, C_HL2PlayerLocalData ),
+ DEFINE_PRED_FIELD( m_fIsSprinting, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
+END_PREDICTION_DATA()
+
+//-----------------------------------------------------------------------------
+// Purpose: Drops player's primary weapon
+//-----------------------------------------------------------------------------
+void CC_DropPrimary( void )
+{
+ C_BasePlayer *pPlayer = (C_BasePlayer *) C_BasePlayer::GetLocalPlayer();
+
+ if ( pPlayer == NULL )
+ return;
+
+ pPlayer->Weapon_DropPrimary();
+}
+
+static ConCommand dropprimary("dropprimary", CC_DropPrimary, "dropprimary: Drops the primary weapon of the player.");
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+C_BaseHLPlayer::C_BaseHLPlayer()
+{
+ AddVar( &m_Local.m_vecPunchAngle, &m_Local.m_iv_vecPunchAngle, LATCH_SIMULATION_VAR );
+ AddVar( &m_Local.m_vecPunchAngleVel, &m_Local.m_iv_vecPunchAngleVel, LATCH_SIMULATION_VAR );
+
+ m_flZoomStart = 0.0f;
+ m_flZoomEnd = 0.0f;
+ m_flZoomRate = 0.0f;
+ m_flZoomStartTime = 0.0f;
+ m_flSpeedMod = cl_forwardspeed.GetFloat();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : updateType -
+//-----------------------------------------------------------------------------
+void C_BaseHLPlayer::OnDataChanged( DataUpdateType_t updateType )
+{
+ // Make sure we're thinking
+ if ( updateType == DATA_UPDATE_CREATED )
+ {
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+ }
+
+ BaseClass::OnDataChanged( updateType );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_BaseHLPlayer::Weapon_DropPrimary( void )
+{
+ engine->ServerCmd( "DropPrimary" );
+}
+
+float C_BaseHLPlayer::GetFOV()
+{
+ //Find our FOV with offset zoom value
+ float flFOVOffset = BaseClass::GetFOV() + GetZoom();
+
+ // Clamp FOV in MP
+ int min_fov = ( gpGlobals->maxClients == 1 ) ? 5 : default_fov.GetInt();
+
+ // Don't let it go too low
+ flFOVOffset = MAX( min_fov, flFOVOffset );
+
+ return flFOVOffset;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : float
+//-----------------------------------------------------------------------------
+float C_BaseHLPlayer::GetZoom( void )
+{
+ float fFOV = m_flZoomEnd;
+
+ //See if we need to lerp the values
+ if ( ( m_flZoomStart != m_flZoomEnd ) && ( m_flZoomRate > 0.0f ) )
+ {
+ float deltaTime = (float)( gpGlobals->curtime - m_flZoomStartTime ) / m_flZoomRate;
+
+ if ( deltaTime >= 1.0f )
+ {
+ //If we're past the zoom time, just take the new value and stop lerping
+ fFOV = m_flZoomStart = m_flZoomEnd;
+ }
+ else
+ {
+ fFOV = SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, m_flZoomStart, m_flZoomEnd );
+ }
+ }
+
+ return fFOV;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : FOVOffset -
+// time -
+//-----------------------------------------------------------------------------
+void C_BaseHLPlayer::Zoom( float FOVOffset, float time )
+{
+ m_flZoomStart = GetZoom();
+ m_flZoomEnd = FOVOffset;
+ m_flZoomRate = time;
+ m_flZoomStartTime = gpGlobals->curtime;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Hack to zero out player's pitch, use value from poseparameter instead
+// Input : flags -
+// Output : int
+//-----------------------------------------------------------------------------
+int C_BaseHLPlayer::DrawModel( int flags )
+{
+ // Not pitch for player
+ QAngle saveAngles = GetLocalAngles();
+
+ QAngle useAngles = saveAngles;
+ useAngles[ PITCH ] = 0.0f;
+
+ SetLocalAngles( useAngles );
+
+ int iret = BaseClass::DrawModel( flags );
+
+ SetLocalAngles( saveAngles );
+
+ return iret;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Helper to remove from ladder
+//-----------------------------------------------------------------------------
+void C_BaseHLPlayer::ExitLadder()
+{
+ if ( MOVETYPE_LADDER != GetMoveType() )
+ return;
+
+ SetMoveType( MOVETYPE_WALK );
+ SetMoveCollide( MOVECOLLIDE_DEFAULT );
+ // Remove from ladder
+ m_HL2Local.m_hLadder = NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Determines if a player can be safely moved towards a point
+// Input: pos - position to test move to, fVertDist - how far to trace downwards to see if the player would fall,
+// radius - how close the player can be to the object, objPos - position of the object to avoid,
+// objDir - direction the object is travelling
+//-----------------------------------------------------------------------------
+bool C_BaseHLPlayer::TestMove( const Vector &pos, float fVertDist, float radius, const Vector &objPos, const Vector &objDir )
+{
+ trace_t trUp;
+ trace_t trOver;
+ trace_t trDown;
+ float flHit1, flHit2;
+
+ UTIL_TraceHull( GetAbsOrigin(), pos, GetPlayerMins(), GetPlayerMaxs(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trOver );
+ if ( trOver.fraction < 1.0f )
+ {
+ // check if the endpos intersects with the direction the object is travelling. if it doesn't, this is a good direction to move.
+ if ( objDir.IsZero() ||
+ ( IntersectInfiniteRayWithSphere( objPos, objDir, trOver.endpos, radius, &flHit1, &flHit2 ) &&
+ ( ( flHit1 >= 0.0f ) || ( flHit2 >= 0.0f ) ) )
+ )
+ {
+ // our first trace failed, so see if we can go farther if we step up.
+
+ // trace up to see if we have enough room.
+ UTIL_TraceHull( GetAbsOrigin(), GetAbsOrigin() + Vector( 0, 0, m_Local.m_flStepSize ),
+ GetPlayerMins(), GetPlayerMaxs(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trUp );
+
+ // do a trace from the stepped up height
+ UTIL_TraceHull( trUp.endpos, pos + Vector( 0, 0, trUp.endpos.z - trUp.startpos.z ),
+ GetPlayerMins(), GetPlayerMaxs(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trOver );
+
+ if ( trOver.fraction < 1.0f )
+ {
+ // check if the endpos intersects with the direction the object is travelling. if it doesn't, this is a good direction to move.
+ if ( objDir.IsZero() ||
+ ( IntersectInfiniteRayWithSphere( objPos, objDir, trOver.endpos, radius, &flHit1, &flHit2 ) && ( ( flHit1 >= 0.0f ) || ( flHit2 >= 0.0f ) ) ) )
+ {
+ return false;
+ }
+ }
+ }
+ }
+
+ // trace down to see if this position is on the ground
+ UTIL_TraceLine( trOver.endpos, trOver.endpos - Vector( 0, 0, fVertDist ),
+ MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &trDown );
+
+ if ( trDown.fraction == 1.0f )
+ return false;
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Client-side obstacle avoidance
+//-----------------------------------------------------------------------------
+void C_BaseHLPlayer::PerformClientSideObstacleAvoidance( float flFrameTime, CUserCmd *pCmd )
+{
+ // Don't avoid if noclipping or in movetype none
+ switch ( GetMoveType() )
+ {
+ case MOVETYPE_NOCLIP:
+ case MOVETYPE_NONE:
+ case MOVETYPE_OBSERVER:
+ return;
+ default:
+ break;
+ }
+
+ // Try to steer away from any objects/players we might interpenetrate
+ Vector size = WorldAlignSize();
+
+ float radius = 0.7f * sqrt( size.x * size.x + size.y * size.y );
+ float curspeed = GetLocalVelocity().Length2D();
+
+ //int slot = 1;
+ //engine->Con_NPrintf( slot++, "speed %f\n", curspeed );
+ //engine->Con_NPrintf( slot++, "radius %f\n", radius );
+
+ // If running, use a larger radius
+ float factor = 1.0f;
+
+ if ( curspeed > 150.0f )
+ {
+ curspeed = MIN( 2048.0f, curspeed );
+ factor = ( 1.0f + ( curspeed - 150.0f ) / 150.0f );
+
+ //engine->Con_NPrintf( slot++, "scaleup (%f) to radius %f\n", factor, radius * factor );
+
+ radius = radius * factor;
+ }
+
+ Vector currentdir;
+ Vector rightdir;
+
+ QAngle vAngles = pCmd->viewangles;
+ vAngles.x = 0;
+
+ AngleVectors( vAngles, &currentdir, &rightdir, NULL );
+
+ bool istryingtomove = false;
+ bool ismovingforward = false;
+ if ( fabs( pCmd->forwardmove ) > 0.0f ||
+ fabs( pCmd->sidemove ) > 0.0f )
+ {
+ istryingtomove = true;
+ if ( pCmd->forwardmove > 1.0f )
+ {
+ ismovingforward = true;
+ }
+ }
+
+ if ( istryingtomove == true )
+ radius *= 1.3f;
+
+ CPlayerAndObjectEnumerator avoid( radius );
+ partition->EnumerateElementsInSphere( PARTITION_CLIENT_SOLID_EDICTS, GetAbsOrigin(), radius, false, &avoid );
+
+ // Okay, decide how to avoid if there's anything close by
+ int c = avoid.GetObjectCount();
+ if ( c <= 0 )
+ return;
+
+ //engine->Con_NPrintf( slot++, "moving %s forward %s\n", istryingtomove ? "true" : "false", ismovingforward ? "true" : "false" );
+
+ float adjustforwardmove = 0.0f;
+ float adjustsidemove = 0.0f;
+
+ for ( int i = 0; i < c; i++ )
+ {
+ C_AI_BaseNPC *obj = dynamic_cast< C_AI_BaseNPC *>(avoid.GetObject( i ));
+
+ if( !obj )
+ continue;
+
+ Vector vecToObject = obj->GetAbsOrigin() - GetAbsOrigin();
+
+ float flDist = vecToObject.Length2D();
+
+ // Figure out a 2D radius for the object
+ Vector vecWorldMins, vecWorldMaxs;
+ obj->CollisionProp()->WorldSpaceAABB( &vecWorldMins, &vecWorldMaxs );
+ Vector objSize = vecWorldMaxs - vecWorldMins;
+
+ float objectradius = 0.5f * sqrt( objSize.x * objSize.x + objSize.y * objSize.y );
+
+ //Don't run this code if the NPC is not moving UNLESS we are in stuck inside of them.
+ if ( !obj->IsMoving() && flDist > objectradius )
+ continue;
+
+ if ( flDist > objectradius && obj->IsEffectActive( EF_NODRAW ) )
+ {
+ obj->RemoveEffects( EF_NODRAW );
+ }
+
+ Vector vecNPCVelocity;
+ obj->EstimateAbsVelocity( vecNPCVelocity );
+ float flNPCSpeed = VectorNormalize( vecNPCVelocity );
+
+ Vector vPlayerVel = GetAbsVelocity();
+ VectorNormalize( vPlayerVel );
+
+ float flHit1, flHit2;
+ Vector vRayDir = vecToObject;
+ VectorNormalize( vRayDir );
+
+ float flVelProduct = DotProduct( vecNPCVelocity, vPlayerVel );
+ float flDirProduct = DotProduct( vRayDir, vPlayerVel );
+
+ if ( !IntersectInfiniteRayWithSphere(
+ GetAbsOrigin(),
+ vRayDir,
+ obj->GetAbsOrigin(),
+ radius,
+ &flHit1,
+ &flHit2 ) )
+ continue;
+
+ Vector dirToObject = -vecToObject;
+ VectorNormalize( dirToObject );
+
+ float fwd = 0;
+ float rt = 0;
+
+ float sidescale = 2.0f;
+ float forwardscale = 1.0f;
+ bool foundResult = false;
+
+ Vector vMoveDir = vecNPCVelocity;
+ if ( flNPCSpeed > 0.001f )
+ {
+ // This NPC is moving. First try deflecting the player left or right relative to the NPC's velocity.
+ // Start with whatever side they're on relative to the NPC's velocity.
+ Vector vecNPCTrajectoryRight = CrossProduct( vecNPCVelocity, Vector( 0, 0, 1) );
+ int iDirection = ( vecNPCTrajectoryRight.Dot( dirToObject ) > 0 ) ? 1 : -1;
+ for ( int nTries = 0; nTries < 2; nTries++ )
+ {
+ Vector vecTryMove = vecNPCTrajectoryRight * iDirection;
+ VectorNormalize( vecTryMove );
+
+ Vector vTestPosition = GetAbsOrigin() + vecTryMove * radius * 2;
+
+ if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
+ {
+ fwd = currentdir.Dot( vecTryMove );
+ rt = rightdir.Dot( vecTryMove );
+
+ //Msg( "PUSH DEFLECT fwd=%f, rt=%f\n", fwd, rt );
+
+ foundResult = true;
+ break;
+ }
+ else
+ {
+ // Try the other direction.
+ iDirection *= -1;
+ }
+ }
+ }
+ else
+ {
+ // the object isn't moving, so try moving opposite the way it's facing
+ Vector vecNPCForward;
+ obj->GetVectors( &vecNPCForward, NULL, NULL );
+
+ Vector vTestPosition = GetAbsOrigin() - vecNPCForward * radius * 2;
+ if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
+ {
+ fwd = currentdir.Dot( -vecNPCForward );
+ rt = rightdir.Dot( -vecNPCForward );
+
+ if ( flDist < objectradius )
+ {
+ obj->AddEffects( EF_NODRAW );
+ }
+
+ //Msg( "PUSH AWAY FACE fwd=%f, rt=%f\n", fwd, rt );
+
+ foundResult = true;
+ }
+ }
+
+ if ( !foundResult )
+ {
+ // test if we can move in the direction the object is moving
+ Vector vTestPosition = GetAbsOrigin() + vMoveDir * radius * 2;
+ if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
+ {
+ fwd = currentdir.Dot( vMoveDir );
+ rt = rightdir.Dot( vMoveDir );
+
+ if ( flDist < objectradius )
+ {
+ obj->AddEffects( EF_NODRAW );
+ }
+
+ //Msg( "PUSH ALONG fwd=%f, rt=%f\n", fwd, rt );
+
+ foundResult = true;
+ }
+ else
+ {
+ // try moving directly away from the object
+ Vector vTestPosition = GetAbsOrigin() - dirToObject * radius * 2;
+ if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
+ {
+ fwd = currentdir.Dot( -dirToObject );
+ rt = rightdir.Dot( -dirToObject );
+ foundResult = true;
+
+ //Msg( "PUSH AWAY fwd=%f, rt=%f\n", fwd, rt );
+ }
+ }
+ }
+
+ if ( !foundResult )
+ {
+ // test if we can move through the object
+ Vector vTestPosition = GetAbsOrigin() - vMoveDir * radius * 2;
+ fwd = currentdir.Dot( -vMoveDir );
+ rt = rightdir.Dot( -vMoveDir );
+
+ if ( flDist < objectradius )
+ {
+ obj->AddEffects( EF_NODRAW );
+ }
+
+ //Msg( "PUSH THROUGH fwd=%f, rt=%f\n", fwd, rt );
+
+ foundResult = true;
+ }
+
+ // If running, then do a lot more sideways veer since we're not going to do anything to
+ // forward velocity
+ if ( istryingtomove )
+ {
+ sidescale = 6.0f;
+ }
+
+ if ( flVelProduct > 0.0f && flDirProduct > 0.0f )
+ {
+ sidescale = 0.1f;
+ }
+
+ float force = 1.0f;
+ float forward = forwardscale * fwd * force * AVOID_SPEED;
+ float side = sidescale * rt * force * AVOID_SPEED;
+
+ adjustforwardmove += forward;
+ adjustsidemove += side;
+ }
+
+ pCmd->forwardmove += adjustforwardmove;
+ pCmd->sidemove += adjustsidemove;
+
+ // Clamp the move to within legal limits, preserving direction. This is a little
+ // complicated because we have different limits for forward, back, and side
+
+ //Msg( "PRECLAMP: forwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove );
+
+ float flForwardScale = 1.0f;
+ if ( pCmd->forwardmove > fabs( cl_forwardspeed.GetFloat() ) )
+ {
+ flForwardScale = fabs( cl_forwardspeed.GetFloat() ) / pCmd->forwardmove;
+ }
+ else if ( pCmd->forwardmove < -fabs( cl_backspeed.GetFloat() ) )
+ {
+ flForwardScale = fabs( cl_backspeed.GetFloat() ) / fabs( pCmd->forwardmove );
+ }
+
+ float flSideScale = 1.0f;
+ if ( fabs( pCmd->sidemove ) > fabs( cl_sidespeed.GetFloat() ) )
+ {
+ flSideScale = fabs( cl_sidespeed.GetFloat() ) / fabs( pCmd->sidemove );
+ }
+
+ float flScale = MIN( flForwardScale, flSideScale );
+ pCmd->forwardmove *= flScale;
+ pCmd->sidemove *= flScale;
+
+ //Msg( "POSTCLAMP: forwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove );
+}
+
+
+void C_BaseHLPlayer::PerformClientSideNPCSpeedModifiers( float flFrameTime, CUserCmd *pCmd )
+{
+ if ( m_hClosestNPC == NULL )
+ {
+ if ( m_flSpeedMod != cl_forwardspeed.GetFloat() )
+ {
+ float flDeltaTime = (m_flSpeedModTime - gpGlobals->curtime);
+ m_flSpeedMod = RemapValClamped( flDeltaTime, cl_npc_speedmod_outtime.GetFloat(), 0, m_flExitSpeedMod, cl_forwardspeed.GetFloat() );
+ }
+ }
+ else
+ {
+ C_AI_BaseNPC *pNPC = dynamic_cast< C_AI_BaseNPC *>( m_hClosestNPC.Get() );
+
+ if ( pNPC )
+ {
+ float flDist = (GetAbsOrigin() - pNPC->GetAbsOrigin()).LengthSqr();
+ bool bShouldModSpeed = false;
+
+ // Within range?
+ if ( flDist < pNPC->GetSpeedModifyRadius() )
+ {
+ // Now, only slowdown if we're facing & running parallel to the target's movement
+ // Facing check first (in 2D)
+ Vector vecTargetOrigin = pNPC->GetAbsOrigin();
+ Vector los = ( vecTargetOrigin - EyePosition() );
+ los.z = 0;
+ VectorNormalize( los );
+ Vector facingDir;
+ AngleVectors( GetAbsAngles(), &facingDir );
+ float flDot = DotProduct( los, facingDir );
+ if ( flDot > 0.8 )
+ {
+ /*
+ // Velocity check (abort if the target isn't moving)
+ Vector vecTargetVelocity;
+ pNPC->EstimateAbsVelocity( vecTargetVelocity );
+ float flSpeed = VectorNormalize(vecTargetVelocity);
+ Vector vecMyVelocity = GetAbsVelocity();
+ VectorNormalize(vecMyVelocity);
+ if ( flSpeed > 1.0 )
+ {
+ // Velocity roughly parallel?
+ if ( DotProduct(vecTargetVelocity,vecMyVelocity) > 0.4 )
+ {
+ bShouldModSpeed = true;
+ }
+ }
+ else
+ {
+ // NPC's not moving, slow down if we're moving at him
+ //Msg("Dot: %.2f\n", DotProduct( los, vecMyVelocity ) );
+ if ( DotProduct( los, vecMyVelocity ) > 0.8 )
+ {
+ bShouldModSpeed = true;
+ }
+ }
+ */
+
+ bShouldModSpeed = true;
+ }
+ }
+
+ if ( !bShouldModSpeed )
+ {
+ m_hClosestNPC = NULL;
+ m_flSpeedModTime = gpGlobals->curtime + cl_npc_speedmod_outtime.GetFloat();
+ m_flExitSpeedMod = m_flSpeedMod;
+ return;
+ }
+ else
+ {
+ if ( m_flSpeedMod != pNPC->GetSpeedModifySpeed() )
+ {
+ float flDeltaTime = (m_flSpeedModTime - gpGlobals->curtime);
+ m_flSpeedMod = RemapValClamped( flDeltaTime, cl_npc_speedmod_intime.GetFloat(), 0, cl_forwardspeed.GetFloat(), pNPC->GetSpeedModifySpeed() );
+ }
+ }
+ }
+ }
+
+ if ( pCmd->forwardmove > 0.0f )
+ {
+ pCmd->forwardmove = clamp( pCmd->forwardmove, -m_flSpeedMod, m_flSpeedMod );
+ }
+ else
+ {
+ pCmd->forwardmove = clamp( pCmd->forwardmove, -m_flSpeedMod, m_flSpeedMod );
+ }
+ pCmd->sidemove = clamp( pCmd->sidemove, -m_flSpeedMod, m_flSpeedMod );
+
+ //Msg( "fwd %f right %f\n", pCmd->forwardmove, pCmd->sidemove );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Input handling
+//-----------------------------------------------------------------------------
+bool C_BaseHLPlayer::CreateMove( float flInputSampleTime, CUserCmd *pCmd )
+{
+ bool bResult = BaseClass::CreateMove( flInputSampleTime, pCmd );
+
+ if ( !IsInAVehicle() )
+ {
+ PerformClientSideObstacleAvoidance( TICK_INTERVAL, pCmd );
+ PerformClientSideNPCSpeedModifiers( TICK_INTERVAL, pCmd );
+ }
+
+ return bResult;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Input handling
+//-----------------------------------------------------------------------------
+void C_BaseHLPlayer::BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed )
+{
+ BaseClass::BuildTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed );
+ BuildFirstPersonMeathookTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed, "ValveBiped.Bip01_Head1" );
+}
+
diff --git a/mp/src/game/client/hl2/c_basehlplayer.h b/mp/src/game/client/hl2/c_basehlplayer.h
index 78839389..c6507e95 100644
--- a/mp/src/game/client/hl2/c_basehlplayer.h
+++ b/mp/src/game/client/hl2/c_basehlplayer.h
@@ -1,81 +1,81 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $Workfile: $
-// $NoKeywords: $
-//=============================================================================//
-
-#if !defined( C_BASEHLPLAYER_H )
-#define C_BASEHLPLAYER_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-
-#include "c_baseplayer.h"
-#include "c_hl2_playerlocaldata.h"
-
-class C_BaseHLPlayer : public C_BasePlayer
-{
-public:
- DECLARE_CLASS( C_BaseHLPlayer, C_BasePlayer );
- DECLARE_CLIENTCLASS();
- DECLARE_PREDICTABLE();
-
- C_BaseHLPlayer();
-
- virtual void OnDataChanged( DataUpdateType_t updateType );
-
- void Weapon_DropPrimary( void );
-
- float GetFOV();
- void Zoom( float FOVOffset, float time );
- float GetZoom( void );
- bool IsZoomed( void ) { return m_HL2Local.m_bZooming; }
-
- bool IsSprinting( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_SPRINT; }
- bool IsFlashlightActive( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_FLASHLIGHT; }
- bool IsBreatherActive( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_BREATHER; }
-
- virtual int DrawModel( int flags );
- virtual void BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed );
-
- LadderMove_t *GetLadderMove() { return &m_HL2Local.m_LadderMove; }
- virtual void ExitLadder();
- bool IsSprinting() const { return m_fIsSprinting; }
-
- // Input handling
- virtual bool CreateMove( float flInputSampleTime, CUserCmd *pCmd );
- void PerformClientSideObstacleAvoidance( float flFrameTime, CUserCmd *pCmd );
- void PerformClientSideNPCSpeedModifiers( float flFrameTime, CUserCmd *pCmd );
-
- bool IsWeaponLowered( void ) { return m_HL2Local.m_bWeaponLowered; }
-
-public:
-
- C_HL2PlayerLocalData m_HL2Local;
- EHANDLE m_hClosestNPC;
- float m_flSpeedModTime;
- bool m_fIsSprinting;
-
-private:
- C_BaseHLPlayer( const C_BaseHLPlayer & ); // not defined, not accessible
-
- bool TestMove( const Vector &pos, float fVertDist, float radius, const Vector &objPos, const Vector &objDir );
-
- float m_flZoomStart;
- float m_flZoomEnd;
- float m_flZoomRate;
- float m_flZoomStartTime;
-
- bool m_bPlayUseDenySound; // Signaled by PlayerUse, but can be unset by HL2 ladder code...
- float m_flSpeedMod;
- float m_flExitSpeedMod;
-
-
-friend class CHL2GameMovement;
-};
-
-
-#endif
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $Workfile: $
+// $NoKeywords: $
+//=============================================================================//
+
+#if !defined( C_BASEHLPLAYER_H )
+#define C_BASEHLPLAYER_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "c_baseplayer.h"
+#include "c_hl2_playerlocaldata.h"
+
+class C_BaseHLPlayer : public C_BasePlayer
+{
+public:
+ DECLARE_CLASS( C_BaseHLPlayer, C_BasePlayer );
+ DECLARE_CLIENTCLASS();
+ DECLARE_PREDICTABLE();
+
+ C_BaseHLPlayer();
+
+ virtual void OnDataChanged( DataUpdateType_t updateType );
+
+ void Weapon_DropPrimary( void );
+
+ float GetFOV();
+ void Zoom( float FOVOffset, float time );
+ float GetZoom( void );
+ bool IsZoomed( void ) { return m_HL2Local.m_bZooming; }
+
+ bool IsSprinting( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_SPRINT; }
+ bool IsFlashlightActive( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_FLASHLIGHT; }
+ bool IsBreatherActive( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_BREATHER; }
+
+ virtual int DrawModel( int flags );
+ virtual void BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed );
+
+ LadderMove_t *GetLadderMove() { return &m_HL2Local.m_LadderMove; }
+ virtual void ExitLadder();
+ bool IsSprinting() const { return m_fIsSprinting; }
+
+ // Input handling
+ virtual bool CreateMove( float flInputSampleTime, CUserCmd *pCmd );
+ void PerformClientSideObstacleAvoidance( float flFrameTime, CUserCmd *pCmd );
+ void PerformClientSideNPCSpeedModifiers( float flFrameTime, CUserCmd *pCmd );
+
+ bool IsWeaponLowered( void ) { return m_HL2Local.m_bWeaponLowered; }
+
+public:
+
+ C_HL2PlayerLocalData m_HL2Local;
+ EHANDLE m_hClosestNPC;
+ float m_flSpeedModTime;
+ bool m_fIsSprinting;
+
+private:
+ C_BaseHLPlayer( const C_BaseHLPlayer & ); // not defined, not accessible
+
+ bool TestMove( const Vector &pos, float fVertDist, float radius, const Vector &objPos, const Vector &objDir );
+
+ float m_flZoomStart;
+ float m_flZoomEnd;
+ float m_flZoomRate;
+ float m_flZoomStartTime;
+
+ bool m_bPlayUseDenySound; // Signaled by PlayerUse, but can be unset by HL2 ladder code...
+ float m_flSpeedMod;
+ float m_flExitSpeedMod;
+
+
+friend class CHL2GameMovement;
+};
+
+
+#endif
diff --git a/mp/src/game/client/hl2/c_citadel_effects.cpp b/mp/src/game/client/hl2/c_citadel_effects.cpp
index f7612fa3..af43c4be 100644
--- a/mp/src/game/client/hl2/c_citadel_effects.cpp
+++ b/mp/src/game/client/hl2/c_citadel_effects.cpp
@@ -1,483 +1,483 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "particles_simple.h"
-#include "citadel_effects_shared.h"
-#include "particles_attractor.h"
-#include "fx_quad.h"
-
-class C_CitadelEnergyCore : public C_BaseEntity
-{
- DECLARE_CLASS( C_CitadelEnergyCore, C_BaseEntity );
- DECLARE_CLIENTCLASS();
-
-public:
- void OnDataChanged( DataUpdateType_t updateType );
- RenderGroup_t GetRenderGroup( void );
-
- void ClientThink( void );
- void NotifyShouldTransmit( ShouldTransmitState_t state );
-
- void UpdateIdle( float percentage );
- void UpdateCharging( float percentage );
- void UpdateDischarging( void );
-
-private:
-
- bool SetupEmitters( void );
- inline float GetStateDurationPercentage( void );
-
- float m_flScale;
- int m_nState;
- float m_flDuration;
- float m_flStartTime;
- int m_spawnflags;
-
- CSmartPtr<CSimpleEmitter> m_pSimpleEmitter;
- CSmartPtr<CParticleAttractor> m_pAttractorEmitter;
-};
-
-IMPLEMENT_CLIENTCLASS_DT( C_CitadelEnergyCore, DT_CitadelEnergyCore, CCitadelEnergyCore )
- RecvPropFloat( RECVINFO(m_flScale) ),
- RecvPropInt( RECVINFO(m_nState) ),
- RecvPropFloat( RECVINFO(m_flDuration) ),
- RecvPropFloat( RECVINFO(m_flStartTime) ),
- RecvPropInt( RECVINFO(m_spawnflags) ),
-END_RECV_TABLE()
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : RenderGroup_t
-//-----------------------------------------------------------------------------
-RenderGroup_t C_CitadelEnergyCore::GetRenderGroup( void )
-{
- return RENDER_GROUP_TRANSLUCENT_ENTITY;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : updateType -
-//-----------------------------------------------------------------------------
-void C_CitadelEnergyCore::OnDataChanged( DataUpdateType_t updateType )
-{
- BaseClass::OnDataChanged( updateType );
-
- if ( updateType == DATA_UPDATE_CREATED )
- {
- SetNextClientThink( CLIENT_THINK_ALWAYS );
- SetupEmitters();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool C_CitadelEnergyCore::SetupEmitters( void )
-{
- // Setup the basic core emitter
- if ( m_pSimpleEmitter.IsValid() == false )
- {
- m_pSimpleEmitter = CSimpleEmitter::Create( "energycore" );
-
- if ( m_pSimpleEmitter.IsValid() == false )
- return false;
- }
-
- // Setup the attractor emitter
- if ( m_pAttractorEmitter.IsValid() == false )
- {
- m_pAttractorEmitter = CParticleAttractor::Create( GetAbsOrigin(), "energyattractor" );
-
- if ( m_pAttractorEmitter.IsValid() == false )
- return false;
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : percentage -
-//-----------------------------------------------------------------------------
-void C_CitadelEnergyCore::UpdateIdle( float percentage )
-{
- // Only do these particles if required
- if ( m_spawnflags & SF_ENERGYCORE_NO_PARTICLES )
- return;
-
- // Must be active
- if ( percentage >= 1.0f )
- return;
-
- // Emitters must be valid
- if ( SetupEmitters() == false )
- return;
-
- // Reset our sort origin
- m_pSimpleEmitter->SetSortOrigin( GetAbsOrigin() );
-
- SimpleParticle *sParticle;
-
- // Do the charging particles
- m_pAttractorEmitter->SetAttractorOrigin( GetAbsOrigin() );
-
- Vector forward, right, up;
- AngleVectors( GetAbsAngles(), &forward, &right, &up );
-
- Vector offset;
- float dist;
-
- int numParticles = floor( 4.0f * percentage );
-
- for ( int i = 0; i < numParticles; i++ )
- {
- dist = random->RandomFloat( 4.0f * percentage, 64.0f * percentage );
-
- offset = forward * dist;
-
- dist = RemapValClamped( dist, 4.0f * percentage, 64.0f * percentage, 6.0f, 1.0f );
- offset += right * random->RandomFloat( -4.0f * dist, 4.0f * dist );
- offset += up * random->RandomFloat( -4.0f * dist, 4.0f * dist );
-
- offset += GetAbsOrigin();
-
- sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), m_pAttractorEmitter->GetPMaterial( "effects/strider_muzzle" ), offset );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_vecVelocity = Vector(0,0,8);
- sParticle->m_flDieTime = 0.5f;
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
- sParticle->m_flRollDelta = 0.0f;
-
- float alpha = 255 * percentage;
-
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = 0;
-
- sParticle->m_uchStartSize = random->RandomFloat( 1, 2 );
- sParticle->m_uchEndSize = 0;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : percentage -
-//-----------------------------------------------------------------------------
-void C_CitadelEnergyCore::UpdateCharging( float percentage )
-{
- // Emitters must be valid
- if ( SetupEmitters() == false )
- return;
-
- if ( percentage <= 0.0f )
- return;
-
- // Reset our sort origin
- m_pSimpleEmitter->SetSortOrigin( GetAbsOrigin() );
-
- float flScale = 4.0f * m_flScale * percentage;
-
- SimpleParticle *sParticle;
-
- // Do the core effects
- for ( int i = 0; i < 2; i++ )
- {
- sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( "effects/strider_muzzle" ), GetAbsOrigin() );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_vecVelocity = vec3_origin;
- sParticle->m_flDieTime = 0.1f;
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
- sParticle->m_flRollDelta = 0.0f;
-
- float alpha = 255;
-
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = 0;
-
- if ( i < 2 )
- {
- sParticle->m_uchStartSize = flScale * (i+1);
- sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
- }
- else
- {
- if ( random->RandomInt( 0, 20 ) == 0 )
- {
- sParticle->m_uchStartSize = flScale * (i+1);
- sParticle->m_uchEndSize = sParticle->m_uchStartSize * 4.0f;
- sParticle->m_flDieTime = 0.25f;
- }
- else
- {
- sParticle->m_uchStartSize = flScale * (i+1);
- sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
- }
- }
- }
-
- // Only do these particles if required
- if ( m_spawnflags & SF_ENERGYCORE_NO_PARTICLES )
- return;
-
- // Do the charging particles
- m_pAttractorEmitter->SetAttractorOrigin( GetAbsOrigin() );
-
- Vector forward, right, up;
- AngleVectors( GetAbsAngles(), &forward, &right, &up );
-
- Vector offset;
- float dist;
-
- int numParticles = floor( 4.0f * percentage );
-
- for ( int i = 0; i < numParticles; i++ )
- {
- dist = random->RandomFloat( 4.0f * percentage, 64.0f * percentage );
-
- offset = forward * dist;
-
- dist = RemapValClamped( dist, 4.0f * percentage, 64.0f * percentage, 6.0f, 1.0f );
- offset += right * random->RandomFloat( -4.0f * dist, 4.0f * dist );
- offset += up * random->RandomFloat( -4.0f * dist, 4.0f * dist );
-
- offset += GetAbsOrigin();
-
- sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), m_pAttractorEmitter->GetPMaterial( "effects/strider_muzzle" ), offset );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_vecVelocity = Vector(0,0,8);
- sParticle->m_flDieTime = 0.5f;
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
- sParticle->m_flRollDelta = 0.0f;
-
- float alpha = 255 * percentage;
-
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = 0;
-
- sParticle->m_uchStartSize = random->RandomFloat( 1, 2 );
- sParticle->m_uchEndSize = 0;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : percentage -
-//-----------------------------------------------------------------------------
-void C_CitadelEnergyCore::UpdateDischarging( void )
-{
- // Emitters must be valid
- if ( SetupEmitters() == false )
- return;
-
- // Reset our sort origin
- m_pSimpleEmitter->SetSortOrigin( GetAbsOrigin() );
-
- float flScale = 8.0f * m_flScale;
-
- Vector forward, right, up;
- AngleVectors( GetAbsAngles(), &forward, &right, &up );
-
- SimpleParticle *sParticle;
-
- // Base of the core effect
- sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( "effects/strider_muzzle" ), GetAbsOrigin() );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_vecVelocity = forward * 32.0f;
- sParticle->m_flDieTime = 0.2f;
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
- sParticle->m_flRollDelta = 0.0f;
-
- float alpha = 128;
-
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = 0;
-
- sParticle->m_uchStartSize = flScale * 2.0f;
- sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
-
- // Make sure we encompass the complete particle here!
- m_pSimpleEmitter->SetParticleCullRadius( sParticle->m_uchEndSize );
-
- // Do the core effects
- for ( int i = 0; i < 2; i++ )
- {
- sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( "effects/combinemuzzle2" ), GetAbsOrigin() );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_vecVelocity = forward * ( 32.0f * (i+1) );
- sParticle->m_flDieTime = 0.2f;
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
- sParticle->m_flRollDelta = 0.0f;
-
- float alpha = 100;
-
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = 0;
-
- if ( i < 1 )
- {
- sParticle->m_uchStartSize = flScale * (i+1);
- sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
- }
- else
- {
- if ( random->RandomInt( 0, 20 ) == 0 )
- {
- sParticle->m_uchStartSize = flScale * (i+1);
- sParticle->m_uchEndSize = 0.0f;
- sParticle->m_flDieTime = 0.25f;
- }
- else
- {
- sParticle->m_uchStartSize = flScale * (i+1);
- sParticle->m_uchEndSize = 0.0f;
- }
- }
- }
-
- // Only do these particles if required
- if ( m_spawnflags & SF_ENERGYCORE_NO_PARTICLES )
- return;
-
- // Do the charging particles
- m_pAttractorEmitter->SetAttractorOrigin( GetAbsOrigin() );
-
- Vector offset;
- float dist;
-
- for ( int i = 0; i < 4; i++ )
- {
- dist = random->RandomFloat( 4.0f * m_flScale, 64.0f * m_flScale );
-
- offset = forward * dist;
-
- dist = RemapValClamped( dist, 4.0f * m_flScale, 64.0f * m_flScale, 6.0f, 1.0f );
- offset += right * random->RandomFloat( -2.0f * dist * m_flScale, 2.0f * dist * m_flScale );
- offset += up * random->RandomFloat( -2.0f * dist * m_flScale, 2.0f * dist * m_flScale );
-
- offset += GetAbsOrigin();
-
- sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), m_pAttractorEmitter->GetPMaterial( "effects/combinemuzzle2_dark" ), offset );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_vecVelocity = Vector(0,0,2);
- sParticle->m_flDieTime = 0.5f;
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
- sParticle->m_flRollDelta = 0.0f;
-
- float alpha = 255;
-
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = 0;
-
- sParticle->m_uchStartSize = 1;
- sParticle->m_uchEndSize = 0;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : inline float
-//-----------------------------------------------------------------------------
-inline float C_CitadelEnergyCore::GetStateDurationPercentage( void )
-{
- if ( m_flDuration == 0 )
- return 0.0f;
-
- return RemapValClamped( ( gpGlobals->curtime - m_flStartTime ), 0, m_flDuration, 0, 1.0f );;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_CitadelEnergyCore::NotifyShouldTransmit( ShouldTransmitState_t state )
-{
- BaseClass::NotifyShouldTransmit( state );
-
- // Turn off
- if ( state == SHOULDTRANSMIT_END )
- {
- SetNextClientThink( CLIENT_THINK_NEVER );
- }
-
- // Turn on
- if ( state == SHOULDTRANSMIT_START )
- {
- SetNextClientThink( CLIENT_THINK_ALWAYS );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_CitadelEnergyCore::ClientThink( void )
-{
- if ( gpGlobals->frametime <= 0.0f )
- return;
-
- float flDuration = GetStateDurationPercentage();
-
- switch( m_nState )
- {
- case ENERGYCORE_STATE_OFF:
- UpdateIdle( 1.0f - flDuration );
- break;
-
- case ENERGYCORE_STATE_CHARGING:
- UpdateCharging( flDuration );
- break;
-
- case ENERGYCORE_STATE_DISCHARGING:
- UpdateDischarging( );
- break;
- }
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "particles_simple.h"
+#include "citadel_effects_shared.h"
+#include "particles_attractor.h"
+#include "fx_quad.h"
+
+class C_CitadelEnergyCore : public C_BaseEntity
+{
+ DECLARE_CLASS( C_CitadelEnergyCore, C_BaseEntity );
+ DECLARE_CLIENTCLASS();
+
+public:
+ void OnDataChanged( DataUpdateType_t updateType );
+ RenderGroup_t GetRenderGroup( void );
+
+ void ClientThink( void );
+ void NotifyShouldTransmit( ShouldTransmitState_t state );
+
+ void UpdateIdle( float percentage );
+ void UpdateCharging( float percentage );
+ void UpdateDischarging( void );
+
+private:
+
+ bool SetupEmitters( void );
+ inline float GetStateDurationPercentage( void );
+
+ float m_flScale;
+ int m_nState;
+ float m_flDuration;
+ float m_flStartTime;
+ int m_spawnflags;
+
+ CSmartPtr<CSimpleEmitter> m_pSimpleEmitter;
+ CSmartPtr<CParticleAttractor> m_pAttractorEmitter;
+};
+
+IMPLEMENT_CLIENTCLASS_DT( C_CitadelEnergyCore, DT_CitadelEnergyCore, CCitadelEnergyCore )
+ RecvPropFloat( RECVINFO(m_flScale) ),
+ RecvPropInt( RECVINFO(m_nState) ),
+ RecvPropFloat( RECVINFO(m_flDuration) ),
+ RecvPropFloat( RECVINFO(m_flStartTime) ),
+ RecvPropInt( RECVINFO(m_spawnflags) ),
+END_RECV_TABLE()
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : RenderGroup_t
+//-----------------------------------------------------------------------------
+RenderGroup_t C_CitadelEnergyCore::GetRenderGroup( void )
+{
+ return RENDER_GROUP_TRANSLUCENT_ENTITY;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : updateType -
+//-----------------------------------------------------------------------------
+void C_CitadelEnergyCore::OnDataChanged( DataUpdateType_t updateType )
+{
+ BaseClass::OnDataChanged( updateType );
+
+ if ( updateType == DATA_UPDATE_CREATED )
+ {
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+ SetupEmitters();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool C_CitadelEnergyCore::SetupEmitters( void )
+{
+ // Setup the basic core emitter
+ if ( m_pSimpleEmitter.IsValid() == false )
+ {
+ m_pSimpleEmitter = CSimpleEmitter::Create( "energycore" );
+
+ if ( m_pSimpleEmitter.IsValid() == false )
+ return false;
+ }
+
+ // Setup the attractor emitter
+ if ( m_pAttractorEmitter.IsValid() == false )
+ {
+ m_pAttractorEmitter = CParticleAttractor::Create( GetAbsOrigin(), "energyattractor" );
+
+ if ( m_pAttractorEmitter.IsValid() == false )
+ return false;
+ }
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : percentage -
+//-----------------------------------------------------------------------------
+void C_CitadelEnergyCore::UpdateIdle( float percentage )
+{
+ // Only do these particles if required
+ if ( m_spawnflags & SF_ENERGYCORE_NO_PARTICLES )
+ return;
+
+ // Must be active
+ if ( percentage >= 1.0f )
+ return;
+
+ // Emitters must be valid
+ if ( SetupEmitters() == false )
+ return;
+
+ // Reset our sort origin
+ m_pSimpleEmitter->SetSortOrigin( GetAbsOrigin() );
+
+ SimpleParticle *sParticle;
+
+ // Do the charging particles
+ m_pAttractorEmitter->SetAttractorOrigin( GetAbsOrigin() );
+
+ Vector forward, right, up;
+ AngleVectors( GetAbsAngles(), &forward, &right, &up );
+
+ Vector offset;
+ float dist;
+
+ int numParticles = floor( 4.0f * percentage );
+
+ for ( int i = 0; i < numParticles; i++ )
+ {
+ dist = random->RandomFloat( 4.0f * percentage, 64.0f * percentage );
+
+ offset = forward * dist;
+
+ dist = RemapValClamped( dist, 4.0f * percentage, 64.0f * percentage, 6.0f, 1.0f );
+ offset += right * random->RandomFloat( -4.0f * dist, 4.0f * dist );
+ offset += up * random->RandomFloat( -4.0f * dist, 4.0f * dist );
+
+ offset += GetAbsOrigin();
+
+ sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), m_pAttractorEmitter->GetPMaterial( "effects/strider_muzzle" ), offset );
+
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_vecVelocity = Vector(0,0,8);
+ sParticle->m_flDieTime = 0.5f;
+ sParticle->m_flLifetime = 0.0f;
+
+ sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = 0.0f;
+
+ float alpha = 255 * percentage;
+
+ sParticle->m_uchColor[0] = alpha;
+ sParticle->m_uchColor[1] = alpha;
+ sParticle->m_uchColor[2] = alpha;
+ sParticle->m_uchStartAlpha = alpha;
+ sParticle->m_uchEndAlpha = 0;
+
+ sParticle->m_uchStartSize = random->RandomFloat( 1, 2 );
+ sParticle->m_uchEndSize = 0;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : percentage -
+//-----------------------------------------------------------------------------
+void C_CitadelEnergyCore::UpdateCharging( float percentage )
+{
+ // Emitters must be valid
+ if ( SetupEmitters() == false )
+ return;
+
+ if ( percentage <= 0.0f )
+ return;
+
+ // Reset our sort origin
+ m_pSimpleEmitter->SetSortOrigin( GetAbsOrigin() );
+
+ float flScale = 4.0f * m_flScale * percentage;
+
+ SimpleParticle *sParticle;
+
+ // Do the core effects
+ for ( int i = 0; i < 2; i++ )
+ {
+ sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( "effects/strider_muzzle" ), GetAbsOrigin() );
+
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_vecVelocity = vec3_origin;
+ sParticle->m_flDieTime = 0.1f;
+ sParticle->m_flLifetime = 0.0f;
+
+ sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = 0.0f;
+
+ float alpha = 255;
+
+ sParticle->m_uchColor[0] = alpha;
+ sParticle->m_uchColor[1] = alpha;
+ sParticle->m_uchColor[2] = alpha;
+ sParticle->m_uchStartAlpha = alpha;
+ sParticle->m_uchEndAlpha = 0;
+
+ if ( i < 2 )
+ {
+ sParticle->m_uchStartSize = flScale * (i+1);
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
+ }
+ else
+ {
+ if ( random->RandomInt( 0, 20 ) == 0 )
+ {
+ sParticle->m_uchStartSize = flScale * (i+1);
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 4.0f;
+ sParticle->m_flDieTime = 0.25f;
+ }
+ else
+ {
+ sParticle->m_uchStartSize = flScale * (i+1);
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
+ }
+ }
+ }
+
+ // Only do these particles if required
+ if ( m_spawnflags & SF_ENERGYCORE_NO_PARTICLES )
+ return;
+
+ // Do the charging particles
+ m_pAttractorEmitter->SetAttractorOrigin( GetAbsOrigin() );
+
+ Vector forward, right, up;
+ AngleVectors( GetAbsAngles(), &forward, &right, &up );
+
+ Vector offset;
+ float dist;
+
+ int numParticles = floor( 4.0f * percentage );
+
+ for ( int i = 0; i < numParticles; i++ )
+ {
+ dist = random->RandomFloat( 4.0f * percentage, 64.0f * percentage );
+
+ offset = forward * dist;
+
+ dist = RemapValClamped( dist, 4.0f * percentage, 64.0f * percentage, 6.0f, 1.0f );
+ offset += right * random->RandomFloat( -4.0f * dist, 4.0f * dist );
+ offset += up * random->RandomFloat( -4.0f * dist, 4.0f * dist );
+
+ offset += GetAbsOrigin();
+
+ sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), m_pAttractorEmitter->GetPMaterial( "effects/strider_muzzle" ), offset );
+
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_vecVelocity = Vector(0,0,8);
+ sParticle->m_flDieTime = 0.5f;
+ sParticle->m_flLifetime = 0.0f;
+
+ sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = 0.0f;
+
+ float alpha = 255 * percentage;
+
+ sParticle->m_uchColor[0] = alpha;
+ sParticle->m_uchColor[1] = alpha;
+ sParticle->m_uchColor[2] = alpha;
+ sParticle->m_uchStartAlpha = alpha;
+ sParticle->m_uchEndAlpha = 0;
+
+ sParticle->m_uchStartSize = random->RandomFloat( 1, 2 );
+ sParticle->m_uchEndSize = 0;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : percentage -
+//-----------------------------------------------------------------------------
+void C_CitadelEnergyCore::UpdateDischarging( void )
+{
+ // Emitters must be valid
+ if ( SetupEmitters() == false )
+ return;
+
+ // Reset our sort origin
+ m_pSimpleEmitter->SetSortOrigin( GetAbsOrigin() );
+
+ float flScale = 8.0f * m_flScale;
+
+ Vector forward, right, up;
+ AngleVectors( GetAbsAngles(), &forward, &right, &up );
+
+ SimpleParticle *sParticle;
+
+ // Base of the core effect
+ sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( "effects/strider_muzzle" ), GetAbsOrigin() );
+
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_vecVelocity = forward * 32.0f;
+ sParticle->m_flDieTime = 0.2f;
+ sParticle->m_flLifetime = 0.0f;
+
+ sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = 0.0f;
+
+ float alpha = 128;
+
+ sParticle->m_uchColor[0] = alpha;
+ sParticle->m_uchColor[1] = alpha;
+ sParticle->m_uchColor[2] = alpha;
+ sParticle->m_uchStartAlpha = alpha;
+ sParticle->m_uchEndAlpha = 0;
+
+ sParticle->m_uchStartSize = flScale * 2.0f;
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
+
+ // Make sure we encompass the complete particle here!
+ m_pSimpleEmitter->SetParticleCullRadius( sParticle->m_uchEndSize );
+
+ // Do the core effects
+ for ( int i = 0; i < 2; i++ )
+ {
+ sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( "effects/combinemuzzle2" ), GetAbsOrigin() );
+
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_vecVelocity = forward * ( 32.0f * (i+1) );
+ sParticle->m_flDieTime = 0.2f;
+ sParticle->m_flLifetime = 0.0f;
+
+ sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = 0.0f;
+
+ float alpha = 100;
+
+ sParticle->m_uchColor[0] = alpha;
+ sParticle->m_uchColor[1] = alpha;
+ sParticle->m_uchColor[2] = alpha;
+ sParticle->m_uchStartAlpha = alpha;
+ sParticle->m_uchEndAlpha = 0;
+
+ if ( i < 1 )
+ {
+ sParticle->m_uchStartSize = flScale * (i+1);
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
+ }
+ else
+ {
+ if ( random->RandomInt( 0, 20 ) == 0 )
+ {
+ sParticle->m_uchStartSize = flScale * (i+1);
+ sParticle->m_uchEndSize = 0.0f;
+ sParticle->m_flDieTime = 0.25f;
+ }
+ else
+ {
+ sParticle->m_uchStartSize = flScale * (i+1);
+ sParticle->m_uchEndSize = 0.0f;
+ }
+ }
+ }
+
+ // Only do these particles if required
+ if ( m_spawnflags & SF_ENERGYCORE_NO_PARTICLES )
+ return;
+
+ // Do the charging particles
+ m_pAttractorEmitter->SetAttractorOrigin( GetAbsOrigin() );
+
+ Vector offset;
+ float dist;
+
+ for ( int i = 0; i < 4; i++ )
+ {
+ dist = random->RandomFloat( 4.0f * m_flScale, 64.0f * m_flScale );
+
+ offset = forward * dist;
+
+ dist = RemapValClamped( dist, 4.0f * m_flScale, 64.0f * m_flScale, 6.0f, 1.0f );
+ offset += right * random->RandomFloat( -2.0f * dist * m_flScale, 2.0f * dist * m_flScale );
+ offset += up * random->RandomFloat( -2.0f * dist * m_flScale, 2.0f * dist * m_flScale );
+
+ offset += GetAbsOrigin();
+
+ sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), m_pAttractorEmitter->GetPMaterial( "effects/combinemuzzle2_dark" ), offset );
+
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_vecVelocity = Vector(0,0,2);
+ sParticle->m_flDieTime = 0.5f;
+ sParticle->m_flLifetime = 0.0f;
+
+ sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = 0.0f;
+
+ float alpha = 255;
+
+ sParticle->m_uchColor[0] = alpha;
+ sParticle->m_uchColor[1] = alpha;
+ sParticle->m_uchColor[2] = alpha;
+ sParticle->m_uchStartAlpha = alpha;
+ sParticle->m_uchEndAlpha = 0;
+
+ sParticle->m_uchStartSize = 1;
+ sParticle->m_uchEndSize = 0;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : inline float
+//-----------------------------------------------------------------------------
+inline float C_CitadelEnergyCore::GetStateDurationPercentage( void )
+{
+ if ( m_flDuration == 0 )
+ return 0.0f;
+
+ return RemapValClamped( ( gpGlobals->curtime - m_flStartTime ), 0, m_flDuration, 0, 1.0f );;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_CitadelEnergyCore::NotifyShouldTransmit( ShouldTransmitState_t state )
+{
+ BaseClass::NotifyShouldTransmit( state );
+
+ // Turn off
+ if ( state == SHOULDTRANSMIT_END )
+ {
+ SetNextClientThink( CLIENT_THINK_NEVER );
+ }
+
+ // Turn on
+ if ( state == SHOULDTRANSMIT_START )
+ {
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_CitadelEnergyCore::ClientThink( void )
+{
+ if ( gpGlobals->frametime <= 0.0f )
+ return;
+
+ float flDuration = GetStateDurationPercentage();
+
+ switch( m_nState )
+ {
+ case ENERGYCORE_STATE_OFF:
+ UpdateIdle( 1.0f - flDuration );
+ break;
+
+ case ENERGYCORE_STATE_CHARGING:
+ UpdateCharging( flDuration );
+ break;
+
+ case ENERGYCORE_STATE_DISCHARGING:
+ UpdateDischarging( );
+ break;
+ }
+}
diff --git a/mp/src/game/client/hl2/c_corpse.cpp b/mp/src/game/client/hl2/c_corpse.cpp
index bc10398b..fddb07e7 100644
--- a/mp/src/game/client/hl2/c_corpse.cpp
+++ b/mp/src/game/client/hl2/c_corpse.cpp
@@ -1,66 +1,66 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Implements C_Corpse
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "c_corpse.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-IMPLEMENT_CLIENTCLASS_DT(C_Corpse, DT_Corpse, CCorpse)
- RecvPropInt(RECVINFO(m_nReferencePlayer))
-END_RECV_TABLE()
-
-
-
-
-C_Corpse::C_Corpse()
-{
- m_nReferencePlayer = 0;
-}
-
-
-int C_Corpse::DrawModel( int flags )
-{
- int drawn = 0;
- if ( m_nReferencePlayer <= 0 ||
- m_nReferencePlayer > gpGlobals->maxClients )
- {
- return drawn;
- };
-
- // Make sure m_pstudiohdr is valid for drawing
- if ( !GetModelPtr() )
- {
- return drawn;
- }
-
- if ( !m_bReadyToDraw )
- return 0;
-
- // get copy of player
- C_BasePlayer *player = dynamic_cast< C_BasePlayer *>( cl_entitylist->GetEnt( m_nReferencePlayer ) );
- if ( player )
- {
- Vector zero;
- zero.Init();
-
- drawn = modelrender->DrawModel(
- flags,
- this,
- MODEL_INSTANCE_INVALID,
- m_nReferencePlayer,
- GetModel(),
- GetAbsOrigin(),
- GetAbsAngles(),
- m_nSkin,
- m_nBody,
- m_nHitboxSet );
- }
-
- return drawn;
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Implements C_Corpse
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "c_corpse.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+IMPLEMENT_CLIENTCLASS_DT(C_Corpse, DT_Corpse, CCorpse)
+ RecvPropInt(RECVINFO(m_nReferencePlayer))
+END_RECV_TABLE()
+
+
+
+
+C_Corpse::C_Corpse()
+{
+ m_nReferencePlayer = 0;
+}
+
+
+int C_Corpse::DrawModel( int flags )
+{
+ int drawn = 0;
+ if ( m_nReferencePlayer <= 0 ||
+ m_nReferencePlayer > gpGlobals->maxClients )
+ {
+ return drawn;
+ };
+
+ // Make sure m_pstudiohdr is valid for drawing
+ if ( !GetModelPtr() )
+ {
+ return drawn;
+ }
+
+ if ( !m_bReadyToDraw )
+ return 0;
+
+ // get copy of player
+ C_BasePlayer *player = dynamic_cast< C_BasePlayer *>( cl_entitylist->GetEnt( m_nReferencePlayer ) );
+ if ( player )
+ {
+ Vector zero;
+ zero.Init();
+
+ drawn = modelrender->DrawModel(
+ flags,
+ this,
+ MODEL_INSTANCE_INVALID,
+ m_nReferencePlayer,
+ GetModel(),
+ GetAbsOrigin(),
+ GetAbsAngles(),
+ m_nSkin,
+ m_nBody,
+ m_nHitboxSet );
+ }
+
+ return drawn;
+}
+
diff --git a/mp/src/game/client/hl2/c_corpse.h b/mp/src/game/client/hl2/c_corpse.h
index 5ffe027b..1bd4a090 100644
--- a/mp/src/game/client/hl2/c_corpse.h
+++ b/mp/src/game/client/hl2/c_corpse.h
@@ -1,32 +1,32 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#if !defined( C_CORPSE_H )
-#define C_CORPSE_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-class C_Corpse : public C_BaseAnimating
-{
-public:
- DECLARE_CLASS( C_Corpse, C_BaseAnimating );
- DECLARE_CLIENTCLASS();
-
- C_Corpse( void );
-
- virtual int DrawModel( int flags );
-
-public:
- // The player whom we are copying our data from
- int m_nReferencePlayer;
-
-private:
- C_Corpse( const C_Corpse & );
-};
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#if !defined( C_CORPSE_H )
+#define C_CORPSE_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+class C_Corpse : public C_BaseAnimating
+{
+public:
+ DECLARE_CLASS( C_Corpse, C_BaseAnimating );
+ DECLARE_CLIENTCLASS();
+
+ C_Corpse( void );
+
+ virtual int DrawModel( int flags );
+
+public:
+ // The player whom we are copying our data from
+ int m_nReferencePlayer;
+
+private:
+ C_Corpse( const C_Corpse & );
+};
+
+
#endif // C_CORPSE_H \ No newline at end of file
diff --git a/mp/src/game/client/hl2/c_energy_wave.cpp b/mp/src/game/client/hl2/c_energy_wave.cpp
index 97655f53..31d8b323 100644
--- a/mp/src/game/client/hl2/c_energy_wave.cpp
+++ b/mp/src/game/client/hl2/c_energy_wave.cpp
@@ -1,416 +1,416 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Client's energy wave
-//
-// $Workfile: $
-// $Date: $
-//
-//-----------------------------------------------------------------------------
-// $Log: $
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "materialsystem/imaterialsystem.h"
-#include "materialsystem/imesh.h"
-#include "energy_wave_effect.h"
-#include "mathlib/vmatrix.h"
-#include "clienteffectprecachesystem.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-CLIENTEFFECT_REGISTER_BEGIN( PrecacheEnergyWave )
-CLIENTEFFECT_MATERIAL( "effects/energywave/energywave" )
-CLIENTEFFECT_REGISTER_END()
-
-//-----------------------------------------------------------------------------
-// Energy Wave:
-//-----------------------------------------------------------------------------
-
-class C_EnergyWave : public C_BaseEntity
-{
-public:
- DECLARE_CLASS( C_EnergyWave, C_BaseEntity );
- DECLARE_CLIENTCLASS();
-
- C_EnergyWave();
- ~C_EnergyWave();
-
- void PostDataUpdate( DataUpdateType_t updateType );
- int DrawModel( int flags );
- void ComputePoint( float s, float t, Vector& pt, Vector& normal, float& opacity );
- void DrawWireframeModel( );
-
- CEnergyWaveEffect m_EWaveEffect;
-
- IMaterial* m_pWireframe;
- IMaterial* m_pEWaveMat;
-
-private:
- C_EnergyWave( const C_EnergyWave & ); // not defined, not accessible
-
- void ComputeEWavePoints( Vector* pt, Vector* normal, float* opacity );
- void DrawEWavePoints(Vector* pt, Vector* normal, float* opacity);
-
-};
-
-
-EXTERN_RECV_TABLE(DT_BaseEntity);
-
-IMPLEMENT_CLIENTCLASS_DT(C_EnergyWave, DT_EWaveEffect, CEnergyWave)
-END_RECV_TABLE()
-
-
-// ----------------------------------------------------------------------------
-// Functions.
-// ----------------------------------------------------------------------------
-
-C_EnergyWave::C_EnergyWave() : m_EWaveEffect(NULL, NULL)
-{
- m_pWireframe = materials->FindMaterial("shadertest/wireframevertexcolor", TEXTURE_GROUP_OTHER);
- m_pEWaveMat = materials->FindMaterial("effects/energywave/energywave", TEXTURE_GROUP_CLIENT_EFFECTS);
- m_EWaveEffect.Spawn();
-}
-
-C_EnergyWave::~C_EnergyWave()
-{
-}
-
-void C_EnergyWave::PostDataUpdate( DataUpdateType_t updateType )
-{
- MarkMessageReceived();
-
- // Make sure that origin points to current origin, at least
- MoveToLastReceivedPosition();
-}
-
-
-
-enum
-{
- NUM_SUBDIVISIONS = 21,
-};
-
-
-static void ComputeIndices( int is, int it, int* idx )
-{
- int is0 = (is > 0) ? (is - 1) : is;
- int it0 = (it > 0) ? (it - 1) : it;
- int is1 = (is < EWAVE_NUM_HORIZONTAL_POINTS - 1) ? is + 1 : is;
- int it1 = (it < EWAVE_NUM_HORIZONTAL_POINTS - 1) ? it + 1 : it;
- int is2 = is + 2;
- int it2 = it + 2;
- if (is2 >= EWAVE_NUM_HORIZONTAL_POINTS)
- is2 = EWAVE_NUM_HORIZONTAL_POINTS - 1;
- if (it2 >= EWAVE_NUM_HORIZONTAL_POINTS)
- it2 = EWAVE_NUM_HORIZONTAL_POINTS - 1;
-
- idx[0] = is0 + it0 * EWAVE_NUM_HORIZONTAL_POINTS;
- idx[1] = is + it0 * EWAVE_NUM_HORIZONTAL_POINTS;
- idx[2] = is1 + it0 * EWAVE_NUM_HORIZONTAL_POINTS;
- idx[3] = is2 + it0 * EWAVE_NUM_HORIZONTAL_POINTS;
-
- idx[4] = is0 + it * EWAVE_NUM_HORIZONTAL_POINTS;
- idx[5] = is + it * EWAVE_NUM_HORIZONTAL_POINTS;
- idx[6] = is1 + it * EWAVE_NUM_HORIZONTAL_POINTS;
- idx[7] = is2 + it * EWAVE_NUM_HORIZONTAL_POINTS;
-
- idx[8] = is0 + it1 * EWAVE_NUM_HORIZONTAL_POINTS;
- idx[9] = is + it1 * EWAVE_NUM_HORIZONTAL_POINTS;
- idx[10] = is1 + it1 * EWAVE_NUM_HORIZONTAL_POINTS;
- idx[11] = is2 + it1 * EWAVE_NUM_HORIZONTAL_POINTS;
-
- idx[12] = is0 + it2 * EWAVE_NUM_HORIZONTAL_POINTS;
- idx[13] = is + it2 * EWAVE_NUM_HORIZONTAL_POINTS;
- idx[14] = is1 + it2 * EWAVE_NUM_HORIZONTAL_POINTS;
- idx[15] = is2 + it2 * EWAVE_NUM_HORIZONTAL_POINTS;
-}
-
-void C_EnergyWave::ComputePoint( float s, float t, Vector& pt, Vector& normal, float& opacity )
-{
- int is = (int)s;
- int it = (int)t;
- if( is >= EWAVE_NUM_HORIZONTAL_POINTS )
- is -= 1;
-
- if( it >= EWAVE_NUM_VERTICAL_POINTS )
- it -= 1;
-
- int idx[16];
- ComputeIndices( is, it, idx );
-
- // The patch equation is:
- // px = S * M * Gx * M^T * T^T
- // py = S * M * Gy * M^T * T^T
- // pz = S * M * Gz * M^T * T^T
- // where S = [s^3 s^2 s 1], T = [t^3 t^2 t 1]
- // M is the patch type matrix, in my case I'm using a catmull-rom
- // G is the array of control points. rows have constant t
- static VMatrix catmullRom( -0.5, 1.5, -1.5, 0.5,
- 1, -2.5, 2, -0.5,
- -0.5, 0, 0.5, 0,
- 0, 1, 0, 0 );
-
- VMatrix controlPointsX, controlPointsY, controlPointsZ, controlPointsO;
-
- Vector pos;
- for (int i = 0; i < 4; ++i)
- {
- for (int j = 0; j < 4; ++j)
- {
- const Vector& v = m_EWaveEffect.GetPoint( idx[i * 4 + j] );
-
- controlPointsX[j][i] = v.x;
- controlPointsY[j][i] = v.y;
- controlPointsZ[j][i] = v.z;
-
- controlPointsO[j][i] = m_EWaveEffect.ComputeOpacity( v, GetAbsOrigin() );
- }
- }
-
- float fs = s - is;
- float ft = t - it;
-
- VMatrix temp, mgm[4];
- MatrixTranspose( catmullRom, temp );
- MatrixMultiply( controlPointsX, temp, mgm[0] );
- MatrixMultiply( controlPointsY, temp, mgm[1] );
- MatrixMultiply( controlPointsZ, temp, mgm[2] );
- MatrixMultiply( controlPointsO, temp, mgm[3] );
-
- MatrixMultiply( catmullRom, mgm[0], mgm[0] );
- MatrixMultiply( catmullRom, mgm[1], mgm[1] );
- MatrixMultiply( catmullRom, mgm[2], mgm[2] );
- MatrixMultiply( catmullRom, mgm[3], mgm[3] );
-
- Vector4D svec, tvec;
- float ft2 = ft * ft;
- tvec[0] = ft2 * ft; tvec[1] = ft2; tvec[2] = ft; tvec[3] = 1.0f;
-
- float fs2 = fs * fs;
- svec[0] = fs2 * fs; svec[1] = fs2; svec[2] = fs; svec[3] = 1.0f;
-
- Vector4D tmp;
- Vector4DMultiply( mgm[0], tvec, tmp );
- pt[0] = DotProduct4D( tmp, svec );
- Vector4DMultiply( mgm[1], tvec, tmp );
- pt[1] = DotProduct4D( tmp, svec );
- Vector4DMultiply( mgm[2], tvec, tmp );
- pt[2] = DotProduct4D( tmp, svec );
-
- Vector4DMultiply( mgm[3], tvec, tmp );
- opacity = DotProduct4D( tmp, svec );
-
- if ((s == 0.0f) || (t == 0.0f) ||
- (s == (EWAVE_NUM_HORIZONTAL_POINTS-1.0f)) || (t == (EWAVE_NUM_VERTICAL_POINTS-1.0f)) )
- {
- opacity = 0.0f;
- }
-
- if ((s <= 0.3) || (t < 0.3))
- {
- opacity *= 0.35f;
- }
- if ((s == (EWAVE_NUM_HORIZONTAL_POINTS-0.7f)) || (t == (EWAVE_NUM_VERTICAL_POINTS-0.7f)) )
- {
- opacity *= 0.35f;
- }
-
- if (opacity < 0.0f)
- opacity = 0.0f;
- else if (opacity > 255.0f)
- opacity = 255.0f;
-
- // Normal computation
- Vector4D dsvec, dtvec;
- dsvec[0] = 3.0f * fs2; dsvec[1] = 2.0f * fs; dsvec[2] = 1.0f; dsvec[3] = 0.0f;
- dtvec[0] = 3.0f * ft2; dtvec[1] = 2.0f * ft; dtvec[2] = 1.0f; dtvec[3] = 0.0f;
-
- Vector ds, dt;
- Vector4DMultiply( mgm[0], tvec, tmp );
- ds[0] = DotProduct4D( tmp, dsvec );
- Vector4DMultiply( mgm[1], tvec, tmp );
- ds[1] = DotProduct4D( tmp, dsvec );
- Vector4DMultiply( mgm[2], tvec, tmp );
- ds[2] = DotProduct4D( tmp, dsvec );
-
- Vector4DMultiply( mgm[0], dtvec, tmp );
- dt[0] = DotProduct4D( tmp, svec );
- Vector4DMultiply( mgm[1], dtvec, tmp );
- dt[1] = DotProduct4D( tmp, svec );
- Vector4DMultiply( mgm[2], dtvec, tmp );
- dt[2] = DotProduct4D( tmp, svec );
-
- CrossProduct( ds, dt, normal );
- VectorNormalize( normal );
-}
-
-void C_EnergyWave::DrawWireframeModel( )
-{
- IMesh* pMesh = materials->GetDynamicMesh( true, NULL, NULL, m_pWireframe );
-
- int numLines = (EWAVE_NUM_VERTICAL_POINTS - 1) * EWAVE_NUM_HORIZONTAL_POINTS +
- EWAVE_NUM_VERTICAL_POINTS * (EWAVE_NUM_HORIZONTAL_POINTS - 1);
-
- CMeshBuilder meshBuilder;
- meshBuilder.Begin( pMesh, MATERIAL_LINES, numLines );
-
- Vector tmp;
- for (int i = 0; i < EWAVE_NUM_VERTICAL_POINTS; ++i)
- {
- for (int j = 0; j < EWAVE_NUM_HORIZONTAL_POINTS; ++j)
- {
- if ( i > 0 )
- {
- meshBuilder.Position3fv( m_EWaveEffect.GetPoint( j, i ).Base() );
- meshBuilder.Color4ub( 255, 255, 255, 128 );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Position3fv( m_EWaveEffect.GetPoint( j, i - 1 ).Base() );
- meshBuilder.Color4ub( 255, 255, 255, 128 );
- meshBuilder.AdvanceVertex();
- }
-
- if (j > 0)
- {
- meshBuilder.Position3fv( m_EWaveEffect.GetPoint( j, i ).Base() );
- meshBuilder.Color4ub( 255, 255, 255, 128 );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Position3fv( m_EWaveEffect.GetPoint( j - 1, i ).Base() );
- meshBuilder.Color4ub( 255, 255, 255, 128 );
- meshBuilder.AdvanceVertex();
- }
- }
- }
-
- meshBuilder.End();
- pMesh->Draw();
-}
-
-//-----------------------------------------------------------------------------
-// Compute the ewave points using catmull-rom
-//-----------------------------------------------------------------------------
-
-void C_EnergyWave::ComputeEWavePoints( Vector* pt, Vector* normal, float* opacity )
-{
- int i;
- for ( i = 0; i < NUM_SUBDIVISIONS; ++i)
- {
- float t = (EWAVE_NUM_VERTICAL_POINTS -1 ) * (float)i / (float)(NUM_SUBDIVISIONS - 1);
- for (int j = 0; j < NUM_SUBDIVISIONS; ++j)
- {
- float s = (EWAVE_NUM_HORIZONTAL_POINTS-1) * (float)j / (float)(NUM_SUBDIVISIONS - 1);
- int idx = i * NUM_SUBDIVISIONS + j;
-
- ComputePoint( s, t, pt[idx], normal[idx], opacity[idx] );
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Draws the base ewave
-//-----------------------------------------------------------------------------
-
-#define TRANSITION_REGION_WIDTH 0.5f
-
-void C_EnergyWave::DrawEWavePoints(Vector* pt, Vector* normal, float* opacity)
-{
- IMesh* pMesh = materials->GetDynamicMesh( true, NULL, NULL, m_pEWaveMat );
-
- int numTriangles = (NUM_SUBDIVISIONS - 1) * (NUM_SUBDIVISIONS - 1) * 2;
-
- CMeshBuilder meshBuilder;
- meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, numTriangles );
-
- float du = 1.0f / (float)(NUM_SUBDIVISIONS - 1);
- float dv = du;
-
- unsigned char color[3];
- color[0] = 255;
- color[1] = 255;
- color[2] = 255;
-
- for ( int i = 0; i < NUM_SUBDIVISIONS - 1; ++i)
- {
- float v = i * dv;
- for (int j = 0; j < NUM_SUBDIVISIONS - 1; ++j)
- {
- int idx = i * NUM_SUBDIVISIONS + j;
- float u = j * du;
-
- meshBuilder.Position3fv( pt[idx].Base() );
- meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx] );
- meshBuilder.Normal3fv( normal[idx].Base() );
- meshBuilder.TexCoord2f( 0, u, v );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Position3fv( pt[idx + NUM_SUBDIVISIONS].Base() );
- meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+NUM_SUBDIVISIONS] );
- meshBuilder.Normal3fv( normal[idx + NUM_SUBDIVISIONS].Base() );
- meshBuilder.TexCoord2f( 0, u, v + dv );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Position3fv( pt[idx + 1].Base() );
- meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+1] );
- meshBuilder.Normal3fv( normal[idx+1].Base() );
- meshBuilder.TexCoord2f( 0, u + du, v );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Position3fv( pt[idx + 1].Base() );
- meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+1] );
- meshBuilder.Normal3fv( normal[idx+1].Base() );
- meshBuilder.TexCoord2f( 0, u + du, v );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Position3fv( pt[idx + NUM_SUBDIVISIONS].Base() );
- meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+NUM_SUBDIVISIONS] );
- meshBuilder.Normal3fv( normal[idx + NUM_SUBDIVISIONS].Base() );
- meshBuilder.TexCoord2f( 0, u, v + dv );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Position3fv( pt[idx + NUM_SUBDIVISIONS + 1].Base() );
- meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+NUM_SUBDIVISIONS+1] );
- meshBuilder.Normal3fv( normal[idx + NUM_SUBDIVISIONS + 1].Base() );
- meshBuilder.TexCoord2f( 0, u + du, v + dv );
- meshBuilder.AdvanceVertex();
- }
- }
-
- meshBuilder.End();
- pMesh->Draw();
-}
-
-//-----------------------------------------------------------------------------
-// Main draw entry point
-//-----------------------------------------------------------------------------
-
-int C_EnergyWave::DrawModel( int flags )
-{
- if ( !m_bReadyToDraw )
- return 0;
-
- // NOTE: We've got a stiff spring case here, we need to simulate at
- // a fairly fast timestep. A better solution would be to use an
- // implicit method, which I'm going to not implement for the moment
-
- float dt = gpGlobals->frametime;
- m_EWaveEffect.SetPosition( GetAbsOrigin(), GetAbsAngles() );
- m_EWaveEffect.Simulate(dt);
-
- Vector pt[NUM_SUBDIVISIONS * NUM_SUBDIVISIONS];
- Vector normal[NUM_SUBDIVISIONS * NUM_SUBDIVISIONS];
- float opacity[NUM_SUBDIVISIONS * NUM_SUBDIVISIONS];
-
- ComputeEWavePoints( pt, normal, opacity );
-
- DrawEWavePoints( pt, normal, opacity );
-
- return 1;
-}
-
-
-
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Client's energy wave
+//
+// $Workfile: $
+// $Date: $
+//
+//-----------------------------------------------------------------------------
+// $Log: $
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "materialsystem/imaterialsystem.h"
+#include "materialsystem/imesh.h"
+#include "energy_wave_effect.h"
+#include "mathlib/vmatrix.h"
+#include "clienteffectprecachesystem.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+CLIENTEFFECT_REGISTER_BEGIN( PrecacheEnergyWave )
+CLIENTEFFECT_MATERIAL( "effects/energywave/energywave" )
+CLIENTEFFECT_REGISTER_END()
+
+//-----------------------------------------------------------------------------
+// Energy Wave:
+//-----------------------------------------------------------------------------
+
+class C_EnergyWave : public C_BaseEntity
+{
+public:
+ DECLARE_CLASS( C_EnergyWave, C_BaseEntity );
+ DECLARE_CLIENTCLASS();
+
+ C_EnergyWave();
+ ~C_EnergyWave();
+
+ void PostDataUpdate( DataUpdateType_t updateType );
+ int DrawModel( int flags );
+ void ComputePoint( float s, float t, Vector& pt, Vector& normal, float& opacity );
+ void DrawWireframeModel( );
+
+ CEnergyWaveEffect m_EWaveEffect;
+
+ IMaterial* m_pWireframe;
+ IMaterial* m_pEWaveMat;
+
+private:
+ C_EnergyWave( const C_EnergyWave & ); // not defined, not accessible
+
+ void ComputeEWavePoints( Vector* pt, Vector* normal, float* opacity );
+ void DrawEWavePoints(Vector* pt, Vector* normal, float* opacity);
+
+};
+
+
+EXTERN_RECV_TABLE(DT_BaseEntity);
+
+IMPLEMENT_CLIENTCLASS_DT(C_EnergyWave, DT_EWaveEffect, CEnergyWave)
+END_RECV_TABLE()
+
+
+// ----------------------------------------------------------------------------
+// Functions.
+// ----------------------------------------------------------------------------
+
+C_EnergyWave::C_EnergyWave() : m_EWaveEffect(NULL, NULL)
+{
+ m_pWireframe = materials->FindMaterial("shadertest/wireframevertexcolor", TEXTURE_GROUP_OTHER);
+ m_pEWaveMat = materials->FindMaterial("effects/energywave/energywave", TEXTURE_GROUP_CLIENT_EFFECTS);
+ m_EWaveEffect.Spawn();
+}
+
+C_EnergyWave::~C_EnergyWave()
+{
+}
+
+void C_EnergyWave::PostDataUpdate( DataUpdateType_t updateType )
+{
+ MarkMessageReceived();
+
+ // Make sure that origin points to current origin, at least
+ MoveToLastReceivedPosition();
+}
+
+
+
+enum
+{
+ NUM_SUBDIVISIONS = 21,
+};
+
+
+static void ComputeIndices( int is, int it, int* idx )
+{
+ int is0 = (is > 0) ? (is - 1) : is;
+ int it0 = (it > 0) ? (it - 1) : it;
+ int is1 = (is < EWAVE_NUM_HORIZONTAL_POINTS - 1) ? is + 1 : is;
+ int it1 = (it < EWAVE_NUM_HORIZONTAL_POINTS - 1) ? it + 1 : it;
+ int is2 = is + 2;
+ int it2 = it + 2;
+ if (is2 >= EWAVE_NUM_HORIZONTAL_POINTS)
+ is2 = EWAVE_NUM_HORIZONTAL_POINTS - 1;
+ if (it2 >= EWAVE_NUM_HORIZONTAL_POINTS)
+ it2 = EWAVE_NUM_HORIZONTAL_POINTS - 1;
+
+ idx[0] = is0 + it0 * EWAVE_NUM_HORIZONTAL_POINTS;
+ idx[1] = is + it0 * EWAVE_NUM_HORIZONTAL_POINTS;
+ idx[2] = is1 + it0 * EWAVE_NUM_HORIZONTAL_POINTS;
+ idx[3] = is2 + it0 * EWAVE_NUM_HORIZONTAL_POINTS;
+
+ idx[4] = is0 + it * EWAVE_NUM_HORIZONTAL_POINTS;
+ idx[5] = is + it * EWAVE_NUM_HORIZONTAL_POINTS;
+ idx[6] = is1 + it * EWAVE_NUM_HORIZONTAL_POINTS;
+ idx[7] = is2 + it * EWAVE_NUM_HORIZONTAL_POINTS;
+
+ idx[8] = is0 + it1 * EWAVE_NUM_HORIZONTAL_POINTS;
+ idx[9] = is + it1 * EWAVE_NUM_HORIZONTAL_POINTS;
+ idx[10] = is1 + it1 * EWAVE_NUM_HORIZONTAL_POINTS;
+ idx[11] = is2 + it1 * EWAVE_NUM_HORIZONTAL_POINTS;
+
+ idx[12] = is0 + it2 * EWAVE_NUM_HORIZONTAL_POINTS;
+ idx[13] = is + it2 * EWAVE_NUM_HORIZONTAL_POINTS;
+ idx[14] = is1 + it2 * EWAVE_NUM_HORIZONTAL_POINTS;
+ idx[15] = is2 + it2 * EWAVE_NUM_HORIZONTAL_POINTS;
+}
+
+void C_EnergyWave::ComputePoint( float s, float t, Vector& pt, Vector& normal, float& opacity )
+{
+ int is = (int)s;
+ int it = (int)t;
+ if( is >= EWAVE_NUM_HORIZONTAL_POINTS )
+ is -= 1;
+
+ if( it >= EWAVE_NUM_VERTICAL_POINTS )
+ it -= 1;
+
+ int idx[16];
+ ComputeIndices( is, it, idx );
+
+ // The patch equation is:
+ // px = S * M * Gx * M^T * T^T
+ // py = S * M * Gy * M^T * T^T
+ // pz = S * M * Gz * M^T * T^T
+ // where S = [s^3 s^2 s 1], T = [t^3 t^2 t 1]
+ // M is the patch type matrix, in my case I'm using a catmull-rom
+ // G is the array of control points. rows have constant t
+ static VMatrix catmullRom( -0.5, 1.5, -1.5, 0.5,
+ 1, -2.5, 2, -0.5,
+ -0.5, 0, 0.5, 0,
+ 0, 1, 0, 0 );
+
+ VMatrix controlPointsX, controlPointsY, controlPointsZ, controlPointsO;
+
+ Vector pos;
+ for (int i = 0; i < 4; ++i)
+ {
+ for (int j = 0; j < 4; ++j)
+ {
+ const Vector& v = m_EWaveEffect.GetPoint( idx[i * 4 + j] );
+
+ controlPointsX[j][i] = v.x;
+ controlPointsY[j][i] = v.y;
+ controlPointsZ[j][i] = v.z;
+
+ controlPointsO[j][i] = m_EWaveEffect.ComputeOpacity( v, GetAbsOrigin() );
+ }
+ }
+
+ float fs = s - is;
+ float ft = t - it;
+
+ VMatrix temp, mgm[4];
+ MatrixTranspose( catmullRom, temp );
+ MatrixMultiply( controlPointsX, temp, mgm[0] );
+ MatrixMultiply( controlPointsY, temp, mgm[1] );
+ MatrixMultiply( controlPointsZ, temp, mgm[2] );
+ MatrixMultiply( controlPointsO, temp, mgm[3] );
+
+ MatrixMultiply( catmullRom, mgm[0], mgm[0] );
+ MatrixMultiply( catmullRom, mgm[1], mgm[1] );
+ MatrixMultiply( catmullRom, mgm[2], mgm[2] );
+ MatrixMultiply( catmullRom, mgm[3], mgm[3] );
+
+ Vector4D svec, tvec;
+ float ft2 = ft * ft;
+ tvec[0] = ft2 * ft; tvec[1] = ft2; tvec[2] = ft; tvec[3] = 1.0f;
+
+ float fs2 = fs * fs;
+ svec[0] = fs2 * fs; svec[1] = fs2; svec[2] = fs; svec[3] = 1.0f;
+
+ Vector4D tmp;
+ Vector4DMultiply( mgm[0], tvec, tmp );
+ pt[0] = DotProduct4D( tmp, svec );
+ Vector4DMultiply( mgm[1], tvec, tmp );
+ pt[1] = DotProduct4D( tmp, svec );
+ Vector4DMultiply( mgm[2], tvec, tmp );
+ pt[2] = DotProduct4D( tmp, svec );
+
+ Vector4DMultiply( mgm[3], tvec, tmp );
+ opacity = DotProduct4D( tmp, svec );
+
+ if ((s == 0.0f) || (t == 0.0f) ||
+ (s == (EWAVE_NUM_HORIZONTAL_POINTS-1.0f)) || (t == (EWAVE_NUM_VERTICAL_POINTS-1.0f)) )
+ {
+ opacity = 0.0f;
+ }
+
+ if ((s <= 0.3) || (t < 0.3))
+ {
+ opacity *= 0.35f;
+ }
+ if ((s == (EWAVE_NUM_HORIZONTAL_POINTS-0.7f)) || (t == (EWAVE_NUM_VERTICAL_POINTS-0.7f)) )
+ {
+ opacity *= 0.35f;
+ }
+
+ if (opacity < 0.0f)
+ opacity = 0.0f;
+ else if (opacity > 255.0f)
+ opacity = 255.0f;
+
+ // Normal computation
+ Vector4D dsvec, dtvec;
+ dsvec[0] = 3.0f * fs2; dsvec[1] = 2.0f * fs; dsvec[2] = 1.0f; dsvec[3] = 0.0f;
+ dtvec[0] = 3.0f * ft2; dtvec[1] = 2.0f * ft; dtvec[2] = 1.0f; dtvec[3] = 0.0f;
+
+ Vector ds, dt;
+ Vector4DMultiply( mgm[0], tvec, tmp );
+ ds[0] = DotProduct4D( tmp, dsvec );
+ Vector4DMultiply( mgm[1], tvec, tmp );
+ ds[1] = DotProduct4D( tmp, dsvec );
+ Vector4DMultiply( mgm[2], tvec, tmp );
+ ds[2] = DotProduct4D( tmp, dsvec );
+
+ Vector4DMultiply( mgm[0], dtvec, tmp );
+ dt[0] = DotProduct4D( tmp, svec );
+ Vector4DMultiply( mgm[1], dtvec, tmp );
+ dt[1] = DotProduct4D( tmp, svec );
+ Vector4DMultiply( mgm[2], dtvec, tmp );
+ dt[2] = DotProduct4D( tmp, svec );
+
+ CrossProduct( ds, dt, normal );
+ VectorNormalize( normal );
+}
+
+void C_EnergyWave::DrawWireframeModel( )
+{
+ IMesh* pMesh = materials->GetDynamicMesh( true, NULL, NULL, m_pWireframe );
+
+ int numLines = (EWAVE_NUM_VERTICAL_POINTS - 1) * EWAVE_NUM_HORIZONTAL_POINTS +
+ EWAVE_NUM_VERTICAL_POINTS * (EWAVE_NUM_HORIZONTAL_POINTS - 1);
+
+ CMeshBuilder meshBuilder;
+ meshBuilder.Begin( pMesh, MATERIAL_LINES, numLines );
+
+ Vector tmp;
+ for (int i = 0; i < EWAVE_NUM_VERTICAL_POINTS; ++i)
+ {
+ for (int j = 0; j < EWAVE_NUM_HORIZONTAL_POINTS; ++j)
+ {
+ if ( i > 0 )
+ {
+ meshBuilder.Position3fv( m_EWaveEffect.GetPoint( j, i ).Base() );
+ meshBuilder.Color4ub( 255, 255, 255, 128 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( m_EWaveEffect.GetPoint( j, i - 1 ).Base() );
+ meshBuilder.Color4ub( 255, 255, 255, 128 );
+ meshBuilder.AdvanceVertex();
+ }
+
+ if (j > 0)
+ {
+ meshBuilder.Position3fv( m_EWaveEffect.GetPoint( j, i ).Base() );
+ meshBuilder.Color4ub( 255, 255, 255, 128 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( m_EWaveEffect.GetPoint( j - 1, i ).Base() );
+ meshBuilder.Color4ub( 255, 255, 255, 128 );
+ meshBuilder.AdvanceVertex();
+ }
+ }
+ }
+
+ meshBuilder.End();
+ pMesh->Draw();
+}
+
+//-----------------------------------------------------------------------------
+// Compute the ewave points using catmull-rom
+//-----------------------------------------------------------------------------
+
+void C_EnergyWave::ComputeEWavePoints( Vector* pt, Vector* normal, float* opacity )
+{
+ int i;
+ for ( i = 0; i < NUM_SUBDIVISIONS; ++i)
+ {
+ float t = (EWAVE_NUM_VERTICAL_POINTS -1 ) * (float)i / (float)(NUM_SUBDIVISIONS - 1);
+ for (int j = 0; j < NUM_SUBDIVISIONS; ++j)
+ {
+ float s = (EWAVE_NUM_HORIZONTAL_POINTS-1) * (float)j / (float)(NUM_SUBDIVISIONS - 1);
+ int idx = i * NUM_SUBDIVISIONS + j;
+
+ ComputePoint( s, t, pt[idx], normal[idx], opacity[idx] );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Draws the base ewave
+//-----------------------------------------------------------------------------
+
+#define TRANSITION_REGION_WIDTH 0.5f
+
+void C_EnergyWave::DrawEWavePoints(Vector* pt, Vector* normal, float* opacity)
+{
+ IMesh* pMesh = materials->GetDynamicMesh( true, NULL, NULL, m_pEWaveMat );
+
+ int numTriangles = (NUM_SUBDIVISIONS - 1) * (NUM_SUBDIVISIONS - 1) * 2;
+
+ CMeshBuilder meshBuilder;
+ meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, numTriangles );
+
+ float du = 1.0f / (float)(NUM_SUBDIVISIONS - 1);
+ float dv = du;
+
+ unsigned char color[3];
+ color[0] = 255;
+ color[1] = 255;
+ color[2] = 255;
+
+ for ( int i = 0; i < NUM_SUBDIVISIONS - 1; ++i)
+ {
+ float v = i * dv;
+ for (int j = 0; j < NUM_SUBDIVISIONS - 1; ++j)
+ {
+ int idx = i * NUM_SUBDIVISIONS + j;
+ float u = j * du;
+
+ meshBuilder.Position3fv( pt[idx].Base() );
+ meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx] );
+ meshBuilder.Normal3fv( normal[idx].Base() );
+ meshBuilder.TexCoord2f( 0, u, v );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( pt[idx + NUM_SUBDIVISIONS].Base() );
+ meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+NUM_SUBDIVISIONS] );
+ meshBuilder.Normal3fv( normal[idx + NUM_SUBDIVISIONS].Base() );
+ meshBuilder.TexCoord2f( 0, u, v + dv );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( pt[idx + 1].Base() );
+ meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+1] );
+ meshBuilder.Normal3fv( normal[idx+1].Base() );
+ meshBuilder.TexCoord2f( 0, u + du, v );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( pt[idx + 1].Base() );
+ meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+1] );
+ meshBuilder.Normal3fv( normal[idx+1].Base() );
+ meshBuilder.TexCoord2f( 0, u + du, v );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( pt[idx + NUM_SUBDIVISIONS].Base() );
+ meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+NUM_SUBDIVISIONS] );
+ meshBuilder.Normal3fv( normal[idx + NUM_SUBDIVISIONS].Base() );
+ meshBuilder.TexCoord2f( 0, u, v + dv );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3fv( pt[idx + NUM_SUBDIVISIONS + 1].Base() );
+ meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+NUM_SUBDIVISIONS+1] );
+ meshBuilder.Normal3fv( normal[idx + NUM_SUBDIVISIONS + 1].Base() );
+ meshBuilder.TexCoord2f( 0, u + du, v + dv );
+ meshBuilder.AdvanceVertex();
+ }
+ }
+
+ meshBuilder.End();
+ pMesh->Draw();
+}
+
+//-----------------------------------------------------------------------------
+// Main draw entry point
+//-----------------------------------------------------------------------------
+
+int C_EnergyWave::DrawModel( int flags )
+{
+ if ( !m_bReadyToDraw )
+ return 0;
+
+ // NOTE: We've got a stiff spring case here, we need to simulate at
+ // a fairly fast timestep. A better solution would be to use an
+ // implicit method, which I'm going to not implement for the moment
+
+ float dt = gpGlobals->frametime;
+ m_EWaveEffect.SetPosition( GetAbsOrigin(), GetAbsAngles() );
+ m_EWaveEffect.Simulate(dt);
+
+ Vector pt[NUM_SUBDIVISIONS * NUM_SUBDIVISIONS];
+ Vector normal[NUM_SUBDIVISIONS * NUM_SUBDIVISIONS];
+ float opacity[NUM_SUBDIVISIONS * NUM_SUBDIVISIONS];
+
+ ComputeEWavePoints( pt, normal, opacity );
+
+ DrawEWavePoints( pt, normal, opacity );
+
+ return 1;
+}
+
+
+
+
+
diff --git a/mp/src/game/client/hl2/c_env_alyxtemp.cpp b/mp/src/game/client/hl2/c_env_alyxtemp.cpp
index aa37c277..9e7cd574 100644
--- a/mp/src/game/client/hl2/c_env_alyxtemp.cpp
+++ b/mp/src/game/client/hl2/c_env_alyxtemp.cpp
@@ -1,486 +1,486 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "particles_simple.h"
-#include "citadel_effects_shared.h"
-#include "particles_attractor.h"
-
-class C_AlyxEmpEffect : public C_BaseEntity
-{
- DECLARE_CLASS( C_AlyxEmpEffect, C_BaseEntity );
- DECLARE_CLIENTCLASS();
-
-public:
- void OnDataChanged( DataUpdateType_t updateType );
- RenderGroup_t GetRenderGroup( void );
-
- void ClientThink( void );
- void NotifyShouldTransmit( ShouldTransmitState_t state );
-
- void UpdateIdle( float percentage );
- void UpdateCharging( float percentage );
- void UpdateDischarging( void );
-
-private:
-
- bool SetupEmitters( void );
- inline float GetStateDurationPercentage( void );
-
- int m_nState;
- float m_flDuration;
- float m_flStartTime;
- TimedEvent m_tParticleSpawn;
-
- CSmartPtr<CSimpleEmitter> m_pSimpleEmitter;
- CSmartPtr<CParticleAttractor> m_pAttractorEmitter;
-};
-
-IMPLEMENT_CLIENTCLASS_DT( C_AlyxEmpEffect, DT_AlyxEmpEffect, CAlyxEmpEffect )
- RecvPropInt( RECVINFO(m_nState) ),
- RecvPropFloat( RECVINFO(m_flDuration) ),
- RecvPropFloat( RECVINFO(m_flStartTime) ),
-END_RECV_TABLE()
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : RenderGroup_t
-//-----------------------------------------------------------------------------
-RenderGroup_t C_AlyxEmpEffect::GetRenderGroup( void )
-{
- return RENDER_GROUP_TRANSLUCENT_ENTITY;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : updateType -
-//-----------------------------------------------------------------------------
-void C_AlyxEmpEffect::OnDataChanged( DataUpdateType_t updateType )
-{
- BaseClass::OnDataChanged( updateType );
-
- if ( updateType == DATA_UPDATE_CREATED )
- {
- m_tParticleSpawn.Init( 32 );
- SetNextClientThink( CLIENT_THINK_ALWAYS );
- SetupEmitters();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool C_AlyxEmpEffect::SetupEmitters( void )
-{
- // Setup the basic core emitter
- if ( m_pSimpleEmitter.IsValid() == false )
- {
- m_pSimpleEmitter = CSimpleEmitter::Create( "energycore" );
-
- if ( m_pSimpleEmitter.IsValid() == false )
- return false;
- }
-
- // Setup the attractor emitter
- if ( m_pAttractorEmitter.IsValid() == false )
- {
- m_pAttractorEmitter = CParticleAttractor::Create( GetAbsOrigin(), "energyattractor" );
-
- if ( m_pAttractorEmitter.IsValid() == false )
- return false;
- }
-
- return true;
-}
-
-#define EMP_SCALE 0.5f
-
-#define EMP_PARTICLES "effects/ar2_altfire1b"
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : percentage -
-//-----------------------------------------------------------------------------
-void C_AlyxEmpEffect::UpdateIdle( float percentage )
-{
-#if 0
-
- // Must be active
- if ( percentage >= 1.0f )
- return;
-
- // Emitters must be valid
- if ( SetupEmitters() == false )
- return;
-
- // Reset our sort origin
- m_pSimpleEmitter->SetSortOrigin( GetAbsOrigin() );
-
- SimpleParticle *sParticle;
-
- // Do the charging particles
- m_pAttractorEmitter->SetAttractorOrigin( GetAbsOrigin() );
-
- Vector forward, right, up;
- AngleVectors( GetAbsAngles(), &forward, &right, &up );
-
- Vector offset;
- float dist;
-
- int numParticles = floor( 4.0f * percentage );
-
- float dTime = gpGlobals->frametime;
-
- while ( m_tParticleSpawn.NextEvent( dTime ) )
- {
- for ( int i = 0; i < numParticles; i++ )
- {
- dist = random->RandomFloat( 4.0f * EMP_SCALE * percentage, 64.0f * EMP_SCALE * percentage );
-
- offset = forward * dist;
-
- dist = RemapValClamped( dist, 4.0f * EMP_SCALE * percentage, 64.0f * EMP_SCALE * percentage, 6.0f, 1.0f );
- offset += right * random->RandomFloat( -4.0f * EMP_SCALE * dist, 4.0f * EMP_SCALE * dist );
- offset += up * random->RandomFloat( -4.0f * EMP_SCALE * dist, 4.0f * EMP_SCALE * dist );
-
- offset += GetAbsOrigin();
-
- sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), m_pAttractorEmitter->GetPMaterial( EMP_PARTICLES ), offset );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_vecVelocity = Vector(0,0,8);
- sParticle->m_flDieTime = 0.5f;
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
- sParticle->m_flRollDelta = 0.0f;
-
- float alpha = 255 * percentage;
-
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = 0;
-
- sParticle->m_uchStartSize = random->RandomFloat( 1, 2 );
- sParticle->m_uchEndSize = 0;
- }
- }
-
-#endif
-
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : percentage -
-//-----------------------------------------------------------------------------
-void C_AlyxEmpEffect::UpdateCharging( float percentage )
-{
- // Emitters must be valid
- if ( SetupEmitters() == false )
- return;
-
- if ( percentage <= 0.0f )
- return;
-
- // Reset our sort origin
- m_pSimpleEmitter->SetSortOrigin( GetAbsOrigin() );
-
- float flScale = 4.0f * EMP_SCALE * percentage;
-
- SimpleParticle *sParticle;
-
- float dTime = gpGlobals->frametime;
-
- while ( m_tParticleSpawn.NextEvent( dTime ) )
- {
- // Do the core effects
- sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( EMP_PARTICLES ), GetAbsOrigin() );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_vecVelocity = vec3_origin;
- sParticle->m_flDieTime = 0.1f;
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
- sParticle->m_flRollDelta = 0.0f;
-
- float alpha = 255 * percentage;
-
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = 0;
-
- sParticle->m_uchStartSize = flScale;
- sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
- }
-
-#if 0
-
- // Do the charging particles
- m_pAttractorEmitter->SetAttractorOrigin( GetAbsOrigin() );
-
- Vector forward, right, up;
- AngleVectors( GetAbsAngles(), &forward, &right, &up );
-
- Vector offset;
- float dist;
-
- int numParticles = floor( 4.0f * percentage );
-
- for ( i = 0; i < numParticles; i++ )
- {
- dist = random->RandomFloat( 4.0f * percentage, 64.0f * percentage );
-
- offset = forward * dist;
-
- dist = RemapValClamped( dist, 4.0f * percentage, 64.0f * percentage, 6.0f, 1.0f );
- offset += right * random->RandomFloat( -4.0f * dist, 4.0f * dist );
- offset += up * random->RandomFloat( -4.0f * dist, 4.0f * dist );
-
- offset += GetAbsOrigin();
-
- sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), m_pAttractorEmitter->GetPMaterial( EMP_PARTICLES ), offset );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_vecVelocity = Vector(0,0,8);
- sParticle->m_flDieTime = 0.5f;
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
- sParticle->m_flRollDelta = 0.0f;
-
- float alpha = 255 * percentage;
-
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = 0;
-
- sParticle->m_uchStartSize = random->RandomFloat( 1, 2 );
- sParticle->m_uchEndSize = 0;
- }
-
-#endif
-
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : percentage -
-//-----------------------------------------------------------------------------
-void C_AlyxEmpEffect::UpdateDischarging( void )
-{
- // Emitters must be valid
- if ( SetupEmitters() == false )
- return;
-
- // Reset our sort origin
- m_pSimpleEmitter->SetSortOrigin( GetAbsOrigin() );
-
- float flScale = EMP_SCALE * 8.0f;
-
- Vector forward, right, up;
- AngleVectors( GetAbsAngles(), &forward, &right, &up );
-
- SimpleParticle *sParticle;
-
- float dTime = gpGlobals->frametime;
-
- while ( m_tParticleSpawn.NextEvent( dTime ) )
- {
- // Base of the core effect
- sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( EMP_PARTICLES ), GetAbsOrigin() );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_vecVelocity = vec3_origin;
- sParticle->m_flDieTime = 0.25f;
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
- sParticle->m_flRollDelta = 0.0f;
-
- float alpha = 64;
-
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = 0;
-
- sParticle->m_uchStartSize = flScale * 4.0f;
- sParticle->m_uchEndSize = 0.0f;
-
- // Base of the core effect
- sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( EMP_PARTICLES ), GetAbsOrigin() );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_vecVelocity = vec3_origin;
- sParticle->m_flDieTime = 0.1f;
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
- sParticle->m_flRollDelta = 0.0f;
-
- alpha = 128;
-
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = 0;
-
- sParticle->m_uchStartSize = 0.0f;
- sParticle->m_uchEndSize = flScale * 2.0f;
-
- // Make sure we encompass the complete particle here!
- m_pSimpleEmitter->SetParticleCullRadius( sParticle->m_uchEndSize );
-
- // Do the core effects
- sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( EMP_PARTICLES ), GetAbsOrigin() );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_vecVelocity = RandomVector( -32.0f, 32.0f );
- sParticle->m_flDieTime = 0.2f;
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
- sParticle->m_flRollDelta = 0.0f;
-
- alpha = 255;
-
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = 0;
-
- sParticle->m_uchStartSize = flScale;
- sParticle->m_uchEndSize = 0.0f;
- }
-
-#if 0
-
- // Do the charging particles
- m_pAttractorEmitter->SetAttractorOrigin( GetAbsOrigin() );
-
- Vector offset;
- float dist;
-
- for ( i = 0; i < 4; i++ )
- {
- dist = random->RandomFloat( 4.0f, 64.0f );
-
- offset = forward * dist;
-
- dist = RemapValClamped( dist, 4.0f, 64.0f, 6.0f, 1.0f );
- offset += right * random->RandomFloat( -2.0f * dist, 2.0f * dist );
- offset += up * random->RandomFloat( -2.0f * dist, 2.0f * dist );
-
- offset += GetAbsOrigin();
-
- sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), m_pAttractorEmitter->GetPMaterial( "effects/combinemuzzle2_dark" ), offset );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_vecVelocity = Vector(0,0,2);
- sParticle->m_flDieTime = 0.5f;
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
- sParticle->m_flRollDelta = 0.0f;
-
- float alpha = 255;
-
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = 0;
-
- sParticle->m_uchStartSize = 1;
- sParticle->m_uchEndSize = 0;
- }
-
-#endif
-
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : inline float
-//-----------------------------------------------------------------------------
-inline float C_AlyxEmpEffect::GetStateDurationPercentage( void )
-{
- if ( m_flDuration == 0 )
- return 0.0f;
-
- return RemapValClamped( ( gpGlobals->curtime - m_flStartTime ), 0, m_flDuration, 0, 1.0f );;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_AlyxEmpEffect::NotifyShouldTransmit( ShouldTransmitState_t state )
-{
- BaseClass::NotifyShouldTransmit( state );
-
- // Turn off
- if ( state == SHOULDTRANSMIT_END )
- {
- SetNextClientThink( CLIENT_THINK_NEVER );
- }
-
- // Turn on
- if ( state == SHOULDTRANSMIT_START )
- {
- SetNextClientThink( CLIENT_THINK_ALWAYS );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_AlyxEmpEffect::ClientThink( void )
-{
- if ( gpGlobals->frametime <= 0.0f )
- return;
-
- float flDuration = GetStateDurationPercentage();
-
- switch( m_nState )
- {
- case ENERGYCORE_STATE_OFF:
- UpdateIdle( 1.0f - flDuration );
- break;
-
- case ENERGYCORE_STATE_CHARGING:
- UpdateCharging( flDuration );
- break;
-
- case ENERGYCORE_STATE_DISCHARGING:
- UpdateDischarging( );
- break;
- }
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "particles_simple.h"
+#include "citadel_effects_shared.h"
+#include "particles_attractor.h"
+
+class C_AlyxEmpEffect : public C_BaseEntity
+{
+ DECLARE_CLASS( C_AlyxEmpEffect, C_BaseEntity );
+ DECLARE_CLIENTCLASS();
+
+public:
+ void OnDataChanged( DataUpdateType_t updateType );
+ RenderGroup_t GetRenderGroup( void );
+
+ void ClientThink( void );
+ void NotifyShouldTransmit( ShouldTransmitState_t state );
+
+ void UpdateIdle( float percentage );
+ void UpdateCharging( float percentage );
+ void UpdateDischarging( void );
+
+private:
+
+ bool SetupEmitters( void );
+ inline float GetStateDurationPercentage( void );
+
+ int m_nState;
+ float m_flDuration;
+ float m_flStartTime;
+ TimedEvent m_tParticleSpawn;
+
+ CSmartPtr<CSimpleEmitter> m_pSimpleEmitter;
+ CSmartPtr<CParticleAttractor> m_pAttractorEmitter;
+};
+
+IMPLEMENT_CLIENTCLASS_DT( C_AlyxEmpEffect, DT_AlyxEmpEffect, CAlyxEmpEffect )
+ RecvPropInt( RECVINFO(m_nState) ),
+ RecvPropFloat( RECVINFO(m_flDuration) ),
+ RecvPropFloat( RECVINFO(m_flStartTime) ),
+END_RECV_TABLE()
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : RenderGroup_t
+//-----------------------------------------------------------------------------
+RenderGroup_t C_AlyxEmpEffect::GetRenderGroup( void )
+{
+ return RENDER_GROUP_TRANSLUCENT_ENTITY;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : updateType -
+//-----------------------------------------------------------------------------
+void C_AlyxEmpEffect::OnDataChanged( DataUpdateType_t updateType )
+{
+ BaseClass::OnDataChanged( updateType );
+
+ if ( updateType == DATA_UPDATE_CREATED )
+ {
+ m_tParticleSpawn.Init( 32 );
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+ SetupEmitters();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool C_AlyxEmpEffect::SetupEmitters( void )
+{
+ // Setup the basic core emitter
+ if ( m_pSimpleEmitter.IsValid() == false )
+ {
+ m_pSimpleEmitter = CSimpleEmitter::Create( "energycore" );
+
+ if ( m_pSimpleEmitter.IsValid() == false )
+ return false;
+ }
+
+ // Setup the attractor emitter
+ if ( m_pAttractorEmitter.IsValid() == false )
+ {
+ m_pAttractorEmitter = CParticleAttractor::Create( GetAbsOrigin(), "energyattractor" );
+
+ if ( m_pAttractorEmitter.IsValid() == false )
+ return false;
+ }
+
+ return true;
+}
+
+#define EMP_SCALE 0.5f
+
+#define EMP_PARTICLES "effects/ar2_altfire1b"
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : percentage -
+//-----------------------------------------------------------------------------
+void C_AlyxEmpEffect::UpdateIdle( float percentage )
+{
+#if 0
+
+ // Must be active
+ if ( percentage >= 1.0f )
+ return;
+
+ // Emitters must be valid
+ if ( SetupEmitters() == false )
+ return;
+
+ // Reset our sort origin
+ m_pSimpleEmitter->SetSortOrigin( GetAbsOrigin() );
+
+ SimpleParticle *sParticle;
+
+ // Do the charging particles
+ m_pAttractorEmitter->SetAttractorOrigin( GetAbsOrigin() );
+
+ Vector forward, right, up;
+ AngleVectors( GetAbsAngles(), &forward, &right, &up );
+
+ Vector offset;
+ float dist;
+
+ int numParticles = floor( 4.0f * percentage );
+
+ float dTime = gpGlobals->frametime;
+
+ while ( m_tParticleSpawn.NextEvent( dTime ) )
+ {
+ for ( int i = 0; i < numParticles; i++ )
+ {
+ dist = random->RandomFloat( 4.0f * EMP_SCALE * percentage, 64.0f * EMP_SCALE * percentage );
+
+ offset = forward * dist;
+
+ dist = RemapValClamped( dist, 4.0f * EMP_SCALE * percentage, 64.0f * EMP_SCALE * percentage, 6.0f, 1.0f );
+ offset += right * random->RandomFloat( -4.0f * EMP_SCALE * dist, 4.0f * EMP_SCALE * dist );
+ offset += up * random->RandomFloat( -4.0f * EMP_SCALE * dist, 4.0f * EMP_SCALE * dist );
+
+ offset += GetAbsOrigin();
+
+ sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), m_pAttractorEmitter->GetPMaterial( EMP_PARTICLES ), offset );
+
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_vecVelocity = Vector(0,0,8);
+ sParticle->m_flDieTime = 0.5f;
+ sParticle->m_flLifetime = 0.0f;
+
+ sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = 0.0f;
+
+ float alpha = 255 * percentage;
+
+ sParticle->m_uchColor[0] = alpha;
+ sParticle->m_uchColor[1] = alpha;
+ sParticle->m_uchColor[2] = alpha;
+ sParticle->m_uchStartAlpha = alpha;
+ sParticle->m_uchEndAlpha = 0;
+
+ sParticle->m_uchStartSize = random->RandomFloat( 1, 2 );
+ sParticle->m_uchEndSize = 0;
+ }
+ }
+
+#endif
+
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : percentage -
+//-----------------------------------------------------------------------------
+void C_AlyxEmpEffect::UpdateCharging( float percentage )
+{
+ // Emitters must be valid
+ if ( SetupEmitters() == false )
+ return;
+
+ if ( percentage <= 0.0f )
+ return;
+
+ // Reset our sort origin
+ m_pSimpleEmitter->SetSortOrigin( GetAbsOrigin() );
+
+ float flScale = 4.0f * EMP_SCALE * percentage;
+
+ SimpleParticle *sParticle;
+
+ float dTime = gpGlobals->frametime;
+
+ while ( m_tParticleSpawn.NextEvent( dTime ) )
+ {
+ // Do the core effects
+ sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( EMP_PARTICLES ), GetAbsOrigin() );
+
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_vecVelocity = vec3_origin;
+ sParticle->m_flDieTime = 0.1f;
+ sParticle->m_flLifetime = 0.0f;
+
+ sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = 0.0f;
+
+ float alpha = 255 * percentage;
+
+ sParticle->m_uchColor[0] = alpha;
+ sParticle->m_uchColor[1] = alpha;
+ sParticle->m_uchColor[2] = alpha;
+ sParticle->m_uchStartAlpha = alpha;
+ sParticle->m_uchEndAlpha = 0;
+
+ sParticle->m_uchStartSize = flScale;
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
+ }
+
+#if 0
+
+ // Do the charging particles
+ m_pAttractorEmitter->SetAttractorOrigin( GetAbsOrigin() );
+
+ Vector forward, right, up;
+ AngleVectors( GetAbsAngles(), &forward, &right, &up );
+
+ Vector offset;
+ float dist;
+
+ int numParticles = floor( 4.0f * percentage );
+
+ for ( i = 0; i < numParticles; i++ )
+ {
+ dist = random->RandomFloat( 4.0f * percentage, 64.0f * percentage );
+
+ offset = forward * dist;
+
+ dist = RemapValClamped( dist, 4.0f * percentage, 64.0f * percentage, 6.0f, 1.0f );
+ offset += right * random->RandomFloat( -4.0f * dist, 4.0f * dist );
+ offset += up * random->RandomFloat( -4.0f * dist, 4.0f * dist );
+
+ offset += GetAbsOrigin();
+
+ sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), m_pAttractorEmitter->GetPMaterial( EMP_PARTICLES ), offset );
+
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_vecVelocity = Vector(0,0,8);
+ sParticle->m_flDieTime = 0.5f;
+ sParticle->m_flLifetime = 0.0f;
+
+ sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = 0.0f;
+
+ float alpha = 255 * percentage;
+
+ sParticle->m_uchColor[0] = alpha;
+ sParticle->m_uchColor[1] = alpha;
+ sParticle->m_uchColor[2] = alpha;
+ sParticle->m_uchStartAlpha = alpha;
+ sParticle->m_uchEndAlpha = 0;
+
+ sParticle->m_uchStartSize = random->RandomFloat( 1, 2 );
+ sParticle->m_uchEndSize = 0;
+ }
+
+#endif
+
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : percentage -
+//-----------------------------------------------------------------------------
+void C_AlyxEmpEffect::UpdateDischarging( void )
+{
+ // Emitters must be valid
+ if ( SetupEmitters() == false )
+ return;
+
+ // Reset our sort origin
+ m_pSimpleEmitter->SetSortOrigin( GetAbsOrigin() );
+
+ float flScale = EMP_SCALE * 8.0f;
+
+ Vector forward, right, up;
+ AngleVectors( GetAbsAngles(), &forward, &right, &up );
+
+ SimpleParticle *sParticle;
+
+ float dTime = gpGlobals->frametime;
+
+ while ( m_tParticleSpawn.NextEvent( dTime ) )
+ {
+ // Base of the core effect
+ sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( EMP_PARTICLES ), GetAbsOrigin() );
+
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_vecVelocity = vec3_origin;
+ sParticle->m_flDieTime = 0.25f;
+ sParticle->m_flLifetime = 0.0f;
+
+ sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = 0.0f;
+
+ float alpha = 64;
+
+ sParticle->m_uchColor[0] = alpha;
+ sParticle->m_uchColor[1] = alpha;
+ sParticle->m_uchColor[2] = alpha;
+ sParticle->m_uchStartAlpha = alpha;
+ sParticle->m_uchEndAlpha = 0;
+
+ sParticle->m_uchStartSize = flScale * 4.0f;
+ sParticle->m_uchEndSize = 0.0f;
+
+ // Base of the core effect
+ sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( EMP_PARTICLES ), GetAbsOrigin() );
+
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_vecVelocity = vec3_origin;
+ sParticle->m_flDieTime = 0.1f;
+ sParticle->m_flLifetime = 0.0f;
+
+ sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = 0.0f;
+
+ alpha = 128;
+
+ sParticle->m_uchColor[0] = alpha;
+ sParticle->m_uchColor[1] = alpha;
+ sParticle->m_uchColor[2] = alpha;
+ sParticle->m_uchStartAlpha = alpha;
+ sParticle->m_uchEndAlpha = 0;
+
+ sParticle->m_uchStartSize = 0.0f;
+ sParticle->m_uchEndSize = flScale * 2.0f;
+
+ // Make sure we encompass the complete particle here!
+ m_pSimpleEmitter->SetParticleCullRadius( sParticle->m_uchEndSize );
+
+ // Do the core effects
+ sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( EMP_PARTICLES ), GetAbsOrigin() );
+
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_vecVelocity = RandomVector( -32.0f, 32.0f );
+ sParticle->m_flDieTime = 0.2f;
+ sParticle->m_flLifetime = 0.0f;
+
+ sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = 0.0f;
+
+ alpha = 255;
+
+ sParticle->m_uchColor[0] = alpha;
+ sParticle->m_uchColor[1] = alpha;
+ sParticle->m_uchColor[2] = alpha;
+ sParticle->m_uchStartAlpha = alpha;
+ sParticle->m_uchEndAlpha = 0;
+
+ sParticle->m_uchStartSize = flScale;
+ sParticle->m_uchEndSize = 0.0f;
+ }
+
+#if 0
+
+ // Do the charging particles
+ m_pAttractorEmitter->SetAttractorOrigin( GetAbsOrigin() );
+
+ Vector offset;
+ float dist;
+
+ for ( i = 0; i < 4; i++ )
+ {
+ dist = random->RandomFloat( 4.0f, 64.0f );
+
+ offset = forward * dist;
+
+ dist = RemapValClamped( dist, 4.0f, 64.0f, 6.0f, 1.0f );
+ offset += right * random->RandomFloat( -2.0f * dist, 2.0f * dist );
+ offset += up * random->RandomFloat( -2.0f * dist, 2.0f * dist );
+
+ offset += GetAbsOrigin();
+
+ sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), m_pAttractorEmitter->GetPMaterial( "effects/combinemuzzle2_dark" ), offset );
+
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_vecVelocity = Vector(0,0,2);
+ sParticle->m_flDieTime = 0.5f;
+ sParticle->m_flLifetime = 0.0f;
+
+ sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = 0.0f;
+
+ float alpha = 255;
+
+ sParticle->m_uchColor[0] = alpha;
+ sParticle->m_uchColor[1] = alpha;
+ sParticle->m_uchColor[2] = alpha;
+ sParticle->m_uchStartAlpha = alpha;
+ sParticle->m_uchEndAlpha = 0;
+
+ sParticle->m_uchStartSize = 1;
+ sParticle->m_uchEndSize = 0;
+ }
+
+#endif
+
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : inline float
+//-----------------------------------------------------------------------------
+inline float C_AlyxEmpEffect::GetStateDurationPercentage( void )
+{
+ if ( m_flDuration == 0 )
+ return 0.0f;
+
+ return RemapValClamped( ( gpGlobals->curtime - m_flStartTime ), 0, m_flDuration, 0, 1.0f );;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_AlyxEmpEffect::NotifyShouldTransmit( ShouldTransmitState_t state )
+{
+ BaseClass::NotifyShouldTransmit( state );
+
+ // Turn off
+ if ( state == SHOULDTRANSMIT_END )
+ {
+ SetNextClientThink( CLIENT_THINK_NEVER );
+ }
+
+ // Turn on
+ if ( state == SHOULDTRANSMIT_START )
+ {
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_AlyxEmpEffect::ClientThink( void )
+{
+ if ( gpGlobals->frametime <= 0.0f )
+ return;
+
+ float flDuration = GetStateDurationPercentage();
+
+ switch( m_nState )
+ {
+ case ENERGYCORE_STATE_OFF:
+ UpdateIdle( 1.0f - flDuration );
+ break;
+
+ case ENERGYCORE_STATE_CHARGING:
+ UpdateCharging( flDuration );
+ break;
+
+ case ENERGYCORE_STATE_DISCHARGING:
+ UpdateDischarging( );
+ break;
+ }
+}
diff --git a/mp/src/game/client/hl2/c_env_headcrabcanister.cpp b/mp/src/game/client/hl2/c_env_headcrabcanister.cpp
index 292abc60..fe92ed2f 100644
--- a/mp/src/game/client/hl2/c_env_headcrabcanister.cpp
+++ b/mp/src/game/client/hl2/c_env_headcrabcanister.cpp
@@ -1,97 +1,97 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "fx_explosion.h"
-#include "tempentity.h"
-#include "c_tracer.h"
-#include "env_headcrabcanister_shared.h"
-#include "baseparticleentity.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//-----------------------------------------------------------------------------
-// Headcrab canister Class (Client-side only!)
-//-----------------------------------------------------------------------------
-class C_EnvHeadcrabCanister : public C_BaseAnimating
-{
- DECLARE_CLASS( C_EnvHeadcrabCanister, C_BaseAnimating );
- DECLARE_CLIENTCLASS();
-
-public:
- //-------------------------------------------------------------------------
- // Initialization/Destruction
- //-------------------------------------------------------------------------
- C_EnvHeadcrabCanister();
- ~C_EnvHeadcrabCanister();
-
- virtual void OnDataChanged( DataUpdateType_t updateType );
- virtual void ClientThink();
-
-private:
- C_EnvHeadcrabCanister( const C_EnvHeadcrabCanister & );
-
- CEnvHeadcrabCanisterShared m_Shared;
- CNetworkVar( bool, m_bLanded );
-};
-
-
-EXTERN_RECV_TABLE(DT_EnvHeadcrabCanisterShared);
-
-IMPLEMENT_CLIENTCLASS_DT( C_EnvHeadcrabCanister, DT_EnvHeadcrabCanister, CEnvHeadcrabCanister )
- RecvPropDataTable( RECVINFO_DT( m_Shared ), 0, &REFERENCE_RECV_TABLE(DT_EnvHeadcrabCanisterShared) ),
- RecvPropBool( RECVINFO( m_bLanded ) ),
-END_RECV_TABLE()
-
-
-//-----------------------------------------------------------------------------
-// Constructor
-//-----------------------------------------------------------------------------
-C_EnvHeadcrabCanister::C_EnvHeadcrabCanister()
-{
-}
-
-
-//-----------------------------------------------------------------------------
-// Destructor
-//-----------------------------------------------------------------------------
-C_EnvHeadcrabCanister::~C_EnvHeadcrabCanister()
-{
-}
-
-
-//-----------------------------------------------------------------------------
-// On data update
-//-----------------------------------------------------------------------------
-void C_EnvHeadcrabCanister::OnDataChanged( DataUpdateType_t updateType )
-{
- BaseClass::OnDataChanged( updateType );
- if ( updateType == DATA_UPDATE_CREATED )
- {
- SetNextClientThink( CLIENT_THINK_ALWAYS );
- }
-
- // Stop client-side simulation on landing
- if ( m_bLanded )
- {
- SetNextClientThink( CLIENT_THINK_NEVER );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Compute position
-//-----------------------------------------------------------------------------
-void C_EnvHeadcrabCanister::ClientThink()
-{
- Vector vecEndPosition;
- QAngle vecEndAngles;
- m_Shared.GetPositionAtTime( gpGlobals->curtime, vecEndPosition, vecEndAngles );
- SetAbsOrigin( vecEndPosition );
- SetAbsAngles( vecEndAngles );
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "fx_explosion.h"
+#include "tempentity.h"
+#include "c_tracer.h"
+#include "env_headcrabcanister_shared.h"
+#include "baseparticleentity.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Headcrab canister Class (Client-side only!)
+//-----------------------------------------------------------------------------
+class C_EnvHeadcrabCanister : public C_BaseAnimating
+{
+ DECLARE_CLASS( C_EnvHeadcrabCanister, C_BaseAnimating );
+ DECLARE_CLIENTCLASS();
+
+public:
+ //-------------------------------------------------------------------------
+ // Initialization/Destruction
+ //-------------------------------------------------------------------------
+ C_EnvHeadcrabCanister();
+ ~C_EnvHeadcrabCanister();
+
+ virtual void OnDataChanged( DataUpdateType_t updateType );
+ virtual void ClientThink();
+
+private:
+ C_EnvHeadcrabCanister( const C_EnvHeadcrabCanister & );
+
+ CEnvHeadcrabCanisterShared m_Shared;
+ CNetworkVar( bool, m_bLanded );
+};
+
+
+EXTERN_RECV_TABLE(DT_EnvHeadcrabCanisterShared);
+
+IMPLEMENT_CLIENTCLASS_DT( C_EnvHeadcrabCanister, DT_EnvHeadcrabCanister, CEnvHeadcrabCanister )
+ RecvPropDataTable( RECVINFO_DT( m_Shared ), 0, &REFERENCE_RECV_TABLE(DT_EnvHeadcrabCanisterShared) ),
+ RecvPropBool( RECVINFO( m_bLanded ) ),
+END_RECV_TABLE()
+
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+C_EnvHeadcrabCanister::C_EnvHeadcrabCanister()
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Destructor
+//-----------------------------------------------------------------------------
+C_EnvHeadcrabCanister::~C_EnvHeadcrabCanister()
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// On data update
+//-----------------------------------------------------------------------------
+void C_EnvHeadcrabCanister::OnDataChanged( DataUpdateType_t updateType )
+{
+ BaseClass::OnDataChanged( updateType );
+ if ( updateType == DATA_UPDATE_CREATED )
+ {
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+ }
+
+ // Stop client-side simulation on landing
+ if ( m_bLanded )
+ {
+ SetNextClientThink( CLIENT_THINK_NEVER );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Compute position
+//-----------------------------------------------------------------------------
+void C_EnvHeadcrabCanister::ClientThink()
+{
+ Vector vecEndPosition;
+ QAngle vecEndAngles;
+ m_Shared.GetPositionAtTime( gpGlobals->curtime, vecEndPosition, vecEndAngles );
+ SetAbsOrigin( vecEndPosition );
+ SetAbsAngles( vecEndAngles );
+}
+
diff --git a/mp/src/game/client/hl2/c_env_starfield.cpp b/mp/src/game/client/hl2/c_env_starfield.cpp
index 55e39d7f..632c6f35 100644
--- a/mp/src/game/client/hl2/c_env_starfield.cpp
+++ b/mp/src/game/client/hl2/c_env_starfield.cpp
@@ -1,132 +1,132 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "engine/IEngineTrace.h"
-#include "fx_sparks.h"
-#include "particles_ez.h"
-#include "view.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-ConVar cl_starfield_diameter( "cl_starfield_diameter", "128.0", FCVAR_NONE );
-ConVar cl_starfield_distance( "cl_starfield_distance", "256.0", FCVAR_NONE );
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-class C_EnvStarfield : public C_BaseEntity
-{
- DECLARE_CLASS( C_EnvStarfield, C_BaseEntity );
-public:
- DECLARE_CLIENTCLASS();
-
- C_EnvStarfield();
-
- virtual void OnDataChanged( DataUpdateType_t updateType );
- virtual void ClientThink( void );
-
-private:
- // Emitter
- CSmartPtr<CTrailParticles> m_pEmitter;
- bool m_bOn;
- float m_flDensity;
- float m_flNumParticles;
-
-private:
- C_EnvStarfield( const C_EnvStarfield & );
-};
-
-IMPLEMENT_CLIENTCLASS_DT( C_EnvStarfield, DT_EnvStarfield, CEnvStarfield )
- RecvPropInt( RECVINFO(m_bOn) ),
- RecvPropFloat( RECVINFO(m_flDensity) ),
-END_RECV_TABLE()
-
-// ------------------------------------------------------------------------- //
-// C_EnvStarfield
-// ------------------------------------------------------------------------- //
-C_EnvStarfield::C_EnvStarfield()
-{
- m_bOn = false;
- m_flDensity = 1.0;
- m_flNumParticles = 0;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : updateType -
-//-----------------------------------------------------------------------------
-void C_EnvStarfield::OnDataChanged( DataUpdateType_t updateType )
-{
- if ( updateType == DATA_UPDATE_CREATED )
- {
- m_pEmitter = CTrailParticles::Create( "EnvStarfield" );
- Vector vecCenter = MainViewOrigin() + (MainViewForward() * cl_starfield_distance.GetFloat() );
- m_pEmitter->Setup( (Vector &) vecCenter,
- NULL,
- 0.0,
- 0,
- 64,
- 0,
- 0,
- bitsPARTICLE_TRAIL_VELOCITY_DAMPEN | bitsPARTICLE_TRAIL_FADE | bitsPARTICLE_TRAIL_FADE_IN );
-
- // Start thinking
- SetNextClientThink( CLIENT_THINK_ALWAYS );
- }
-
- BaseClass::OnDataChanged( updateType );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_EnvStarfield::ClientThink( void )
-{
- if ( !m_bOn || !m_flDensity )
- return;
-
- PMaterialHandle hParticleMaterial = m_pEmitter->GetPMaterial( "effects/spark_noz" );
-
- // Find a start & end point for the particle
- // Start particles straight ahead of the client
- Vector vecViewOrigin = MainViewOrigin();
-
- // Determine the number of particles
- m_flNumParticles += 1.0 * (m_flDensity);
- int iNumParticles = floor(m_flNumParticles);
- m_flNumParticles -= iNumParticles;
-
- // Add particles
- for ( int i = 0; i < iNumParticles; i++ )
- {
- float flDiameter = cl_starfield_diameter.GetFloat();
-
- Vector vecStart = vecViewOrigin + (MainViewForward() * cl_starfield_distance.GetFloat() );
- Vector vecEnd = vecViewOrigin + (MainViewRight() * RandomFloat(-flDiameter,flDiameter)) + (MainViewUp() * RandomFloat(-flDiameter,flDiameter));
- Vector vecDir = (vecEnd - vecStart);
- float flDistance = VectorNormalize( vecDir );
- float flTravelTime = 2.0;
-
- // Start a random amount along the path
- vecStart += vecDir * ( RandomFloat(0.1,0.3) * flDistance );
-
- TrailParticle *pParticle = (TrailParticle *) m_pEmitter->AddParticle( sizeof(TrailParticle), hParticleMaterial, vecStart );
- if ( pParticle )
- {
- pParticle->m_vecVelocity = vecDir * (flDistance / flTravelTime);
- pParticle->m_flDieTime = flTravelTime;
- pParticle->m_flLifetime = 0;
- pParticle->m_flWidth = RandomFloat( 1, 3 );
- pParticle->m_flLength = RandomFloat( 0.05, 0.4 );
- pParticle->m_color.r = 255;
- pParticle->m_color.g = 255;
- pParticle->m_color.b = 255;
- pParticle->m_color.a = 255;
- }
- }
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "engine/IEngineTrace.h"
+#include "fx_sparks.h"
+#include "particles_ez.h"
+#include "view.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+ConVar cl_starfield_diameter( "cl_starfield_diameter", "128.0", FCVAR_NONE );
+ConVar cl_starfield_distance( "cl_starfield_distance", "256.0", FCVAR_NONE );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class C_EnvStarfield : public C_BaseEntity
+{
+ DECLARE_CLASS( C_EnvStarfield, C_BaseEntity );
+public:
+ DECLARE_CLIENTCLASS();
+
+ C_EnvStarfield();
+
+ virtual void OnDataChanged( DataUpdateType_t updateType );
+ virtual void ClientThink( void );
+
+private:
+ // Emitter
+ CSmartPtr<CTrailParticles> m_pEmitter;
+ bool m_bOn;
+ float m_flDensity;
+ float m_flNumParticles;
+
+private:
+ C_EnvStarfield( const C_EnvStarfield & );
+};
+
+IMPLEMENT_CLIENTCLASS_DT( C_EnvStarfield, DT_EnvStarfield, CEnvStarfield )
+ RecvPropInt( RECVINFO(m_bOn) ),
+ RecvPropFloat( RECVINFO(m_flDensity) ),
+END_RECV_TABLE()
+
+// ------------------------------------------------------------------------- //
+// C_EnvStarfield
+// ------------------------------------------------------------------------- //
+C_EnvStarfield::C_EnvStarfield()
+{
+ m_bOn = false;
+ m_flDensity = 1.0;
+ m_flNumParticles = 0;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : updateType -
+//-----------------------------------------------------------------------------
+void C_EnvStarfield::OnDataChanged( DataUpdateType_t updateType )
+{
+ if ( updateType == DATA_UPDATE_CREATED )
+ {
+ m_pEmitter = CTrailParticles::Create( "EnvStarfield" );
+ Vector vecCenter = MainViewOrigin() + (MainViewForward() * cl_starfield_distance.GetFloat() );
+ m_pEmitter->Setup( (Vector &) vecCenter,
+ NULL,
+ 0.0,
+ 0,
+ 64,
+ 0,
+ 0,
+ bitsPARTICLE_TRAIL_VELOCITY_DAMPEN | bitsPARTICLE_TRAIL_FADE | bitsPARTICLE_TRAIL_FADE_IN );
+
+ // Start thinking
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+ }
+
+ BaseClass::OnDataChanged( updateType );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_EnvStarfield::ClientThink( void )
+{
+ if ( !m_bOn || !m_flDensity )
+ return;
+
+ PMaterialHandle hParticleMaterial = m_pEmitter->GetPMaterial( "effects/spark_noz" );
+
+ // Find a start & end point for the particle
+ // Start particles straight ahead of the client
+ Vector vecViewOrigin = MainViewOrigin();
+
+ // Determine the number of particles
+ m_flNumParticles += 1.0 * (m_flDensity);
+ int iNumParticles = floor(m_flNumParticles);
+ m_flNumParticles -= iNumParticles;
+
+ // Add particles
+ for ( int i = 0; i < iNumParticles; i++ )
+ {
+ float flDiameter = cl_starfield_diameter.GetFloat();
+
+ Vector vecStart = vecViewOrigin + (MainViewForward() * cl_starfield_distance.GetFloat() );
+ Vector vecEnd = vecViewOrigin + (MainViewRight() * RandomFloat(-flDiameter,flDiameter)) + (MainViewUp() * RandomFloat(-flDiameter,flDiameter));
+ Vector vecDir = (vecEnd - vecStart);
+ float flDistance = VectorNormalize( vecDir );
+ float flTravelTime = 2.0;
+
+ // Start a random amount along the path
+ vecStart += vecDir * ( RandomFloat(0.1,0.3) * flDistance );
+
+ TrailParticle *pParticle = (TrailParticle *) m_pEmitter->AddParticle( sizeof(TrailParticle), hParticleMaterial, vecStart );
+ if ( pParticle )
+ {
+ pParticle->m_vecVelocity = vecDir * (flDistance / flTravelTime);
+ pParticle->m_flDieTime = flTravelTime;
+ pParticle->m_flLifetime = 0;
+ pParticle->m_flWidth = RandomFloat( 1, 3 );
+ pParticle->m_flLength = RandomFloat( 0.05, 0.4 );
+ pParticle->m_color.r = 255;
+ pParticle->m_color.g = 255;
+ pParticle->m_color.b = 255;
+ pParticle->m_color.a = 255;
+ }
+ }
} \ No newline at end of file
diff --git a/mp/src/game/client/hl2/c_extinguisher.cpp b/mp/src/game/client/hl2/c_extinguisher.cpp
index 6715aa53..c5dd0424 100644
--- a/mp/src/game/client/hl2/c_extinguisher.cpp
+++ b/mp/src/game/client/hl2/c_extinguisher.cpp
@@ -1,413 +1,413 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "particles_simple.h"
-#include "baseparticleentity.h"
-#include "iefx.h"
-#include "decals.h"
-#include "beamdraw.h"
-#include "hud.h"
-#include "clienteffectprecachesystem.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-CLIENTEFFECT_REGISTER_BEGIN( PrecacheExtinguisher )
-CLIENTEFFECT_MATERIAL( "particle/particle_smokegrenade" )
-CLIENTEFFECT_REGISTER_END()
-
-class C_ExtinguisherJet : public C_BaseEntity
-{
-public:
- DECLARE_CLIENTCLASS();
- DECLARE_CLASS( C_ExtinguisherJet, C_BaseEntity );
-
- C_ExtinguisherJet();
- ~C_ExtinguisherJet();
-
- void OnDataChanged( DataUpdateType_t updateType );
- void Update( float fTimeDelta );
- void Start( void );
- int DrawModel( int flags );
- bool ShouldDraw( void ) { return m_bEmit; }
-
-protected:
-
- void AddExtinguisherDecal( trace_t &tr );
-
- bool m_bEmit;
- bool m_bUseMuzzlePoint;
- int m_nLength;
- int m_nSize;
-
- PMaterialHandle m_MaterialHandle;
- PMaterialHandle m_EmberMaterialHandle;
- TimedEvent m_ParticleSpawn;
- CSmartPtr<CSimpleEmitter> m_pEmitter;
- CSmartPtr<CEmberEffect> m_pEmberEmitter;
-
-private:
- C_ExtinguisherJet( const C_ExtinguisherJet & );
-};
-
-//Datatable
-IMPLEMENT_CLIENTCLASS_DT( C_ExtinguisherJet, DT_ExtinguisherJet, CExtinguisherJet )
- RecvPropInt(RECVINFO(m_bEmit), 0),
- RecvPropInt(RECVINFO(m_bUseMuzzlePoint), 0),
- RecvPropInt(RECVINFO(m_nLength), 0),
- RecvPropInt(RECVINFO(m_nSize), 0),
-END_RECV_TABLE()
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-C_ExtinguisherJet::C_ExtinguisherJet( void )
-{
- m_bEmit = false;
-
- m_pEmitter = NULL;
- m_pEmberEmitter = NULL;
-}
-
-C_ExtinguisherJet::~C_ExtinguisherJet( void )
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : bnewentity -
-//-----------------------------------------------------------------------------
-void C_ExtinguisherJet::OnDataChanged( DataUpdateType_t updateType )
-{
- C_BaseEntity::OnDataChanged(updateType);
-
- if( updateType == DATA_UPDATE_CREATED )
- {
- Start();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_ExtinguisherJet::Start( void )
-{
- AddToLeafSystem( RENDER_GROUP_TRANSLUCENT_ENTITY );
-
- m_ParticleSpawn.Init( 100 ); //Events per second
-
- //Create the basic emitter
- m_pEmitter = CSimpleEmitter::Create("C_ExtinguisherJet::m_pEmitter");
-
- Assert( m_pEmitter.IsValid() );
- if ( m_pEmitter.IsValid() )
- {
- m_MaterialHandle = g_Mat_DustPuff[0];
- m_pEmitter->SetSortOrigin( GetAbsOrigin() );
- }
-
- //Create the "ember" emitter for the smaller flecks
- m_pEmberEmitter = CEmberEffect::Create( "C_ExtinguisherJet::m_pEmberEmitter" );
-
- Assert( m_pEmberEmitter.IsValid() );
- if ( m_pEmberEmitter.IsValid() )
- {
- m_EmberMaterialHandle = g_Mat_DustPuff[0];
- m_pEmberEmitter->SetSortOrigin( GetAbsOrigin() );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_ExtinguisherJet::AddExtinguisherDecal( trace_t &tr )
-{
- C_BaseEntity *ent = cl_entitylist->GetEnt( 0 );
-
- if ( ent != NULL )
- {
- int index = decalsystem->GetDecalIndexForName( "Extinguish" );
- if ( index >= 0 )
- {
- Vector endpos;
- endpos.Random( -24.0f, 24.0f );
- endpos += tr.endpos;
-
- effects->DecalShoot( index, 0, ent->GetModel(), ent->GetAbsOrigin(), ent->GetAbsAngles(), endpos, 0, 0 );
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : fTimeDelta -
-//-----------------------------------------------------------------------------
-void C_ExtinguisherJet::Update( float fTimeDelta )
-{
- if ( m_bEmit == false )
- return;
-
- C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
-
- if ( m_bUseMuzzlePoint )
- {
- C_BaseViewModel *vm = player ? player->GetViewModel( 0 ) : NULL;
-
- if ( vm )
- {
- int iAttachment = vm->LookupAttachment( "muzzle" );
- Vector origin;
- QAngle angles;
- vm->GetAttachment( iAttachment, origin, angles );
-
- Assert( !GetMoveParent() );
- SetLocalOrigin( origin );
- SetLocalAngles( angles );
- }
- }
-
- trace_t tr;
- Vector shotDir, vRight, vUp;
-
- AngleVectors( GetAbsAngles(), &shotDir, &vRight, &vUp );
-
- //FIXME: Muzzle point is incorrect on the model!
- if ( m_bUseMuzzlePoint )
- {
- shotDir.Negate();
- }
-
- Vector endPoint = GetAbsOrigin() + ( shotDir * 150.0f );
-
- UTIL_TraceLine( GetAbsOrigin(), endPoint, MASK_SHOT, NULL, COLLISION_GROUP_NONE, &tr );
-
- bool hitWall = ( tr.fraction < 1.0f );
-
- //Add normal jet
- if ( m_pEmitter.IsValid() )
- {
- SimpleParticle *pParticle;
-
- m_pEmitter->SetSortOrigin( GetAbsOrigin() );
-
- float tempDelta = fTimeDelta;
-
- //FIXME: All particles need to be within this loop
- while( m_ParticleSpawn.NextEvent( tempDelta ) )
- {
- pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle, GetAbsOrigin() );
-
- if ( pParticle )
- {
- pParticle->m_flDieTime = 0.2f;
- pParticle->m_flLifetime = 0.0f;
-
- pParticle->m_flRoll = random->RandomInt( 0, 360 );
- pParticle->m_flRollDelta= random->RandomFloat( -4.0f, 4.0f );
-
- pParticle->m_uchStartSize = 1;
- pParticle->m_uchEndSize = random->RandomInt( 32, 48 );
- pParticle->m_uchStartAlpha = random->RandomInt( 128, 164 );
- pParticle->m_uchEndAlpha = 0;
-
- int cScale = random->RandomInt( 192, 255 );
- pParticle->m_uchColor[0] = cScale;
- pParticle->m_uchColor[1] = cScale;
- pParticle->m_uchColor[2] = cScale;
-
- Vector dir;
- QAngle ofsAngles;
-
- ofsAngles.Random( -8.0f, 8.0f );
- ofsAngles += GetAbsAngles();
-
- AngleVectors( ofsAngles, &dir );
-
- if ( m_bUseMuzzlePoint )
- {
- dir.Negate();
- }
-
- pParticle->m_vecVelocity = dir * random->RandomInt( 400, 800 );
- }
-
- //Add muzzle effect
- pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle, GetAbsOrigin() );
-
- if ( pParticle )
- {
- pParticle->m_flDieTime = 0.1f;
- pParticle->m_flLifetime = 0.0f;
-
- pParticle->m_flRoll = random->RandomInt( 0, 360 );
- pParticle->m_flRollDelta= random->RandomFloat( -4.0f, 4.0f );
-
- pParticle->m_uchStartSize = 1;
- pParticle->m_uchEndSize = random->RandomInt( 8, 16 );
- pParticle->m_uchStartAlpha = random->RandomInt( 128, 255 );
- pParticle->m_uchEndAlpha = 0;
-
- int cScale = random->RandomInt( 192, 255 );
- pParticle->m_uchColor[0] = cScale;
- pParticle->m_uchColor[1] = cScale;
- pParticle->m_uchColor[2] = cScale;
-
- Vector dir;
- QAngle ofsAngles;
-
- ofsAngles.Random( -64.0f, 64.0f );
- ofsAngles += GetAbsAngles();
-
- AngleVectors( ofsAngles, &dir );
-
- if ( m_bUseMuzzlePoint )
- {
- dir.Negate();
- }
-
- pParticle->m_vecVelocity = dir * random->RandomInt( 32, 64 );
- }
-
- //Add a wall effect if needed
- if ( hitWall )
- {
- AddExtinguisherDecal( tr );
-
- Vector offDir;
-
- offDir.Random( -16.0f, 16.0f );
-
- pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle, ( tr.endpos + ( tr.plane.normal * 8.0f ) ) + offDir );
-
- if ( pParticle )
- {
- pParticle->m_flDieTime = 0.4f;
- pParticle->m_flLifetime = 0.0f;
-
- pParticle->m_flRoll = random->RandomInt( 0, 360 );
- pParticle->m_flRollDelta= random->RandomFloat( -2.0f, 2.0f );
-
- pParticle->m_uchStartSize = random->RandomInt( 8, 16 );
- pParticle->m_uchEndSize = random->RandomInt( 24, 32 );
- pParticle->m_uchStartAlpha = random->RandomInt( 64, 128 );
- pParticle->m_uchEndAlpha = 0;
-
- int cScale = random->RandomInt( 192, 255 );
- pParticle->m_uchColor[0] = cScale;
- pParticle->m_uchColor[1] = cScale;
- pParticle->m_uchColor[2] = cScale;
-
- Vector rDir;
-
- rDir = tr.plane.normal;
- rDir[0] += random->RandomFloat( -0.9f, 0.9f );
- rDir[1] += random->RandomFloat( -0.9f, 0.9f );
- rDir[2] += random->RandomFloat( -0.9f, 0.9f );
-
- pParticle->m_vecVelocity = rDir * random->RandomInt( 32, 64 );
- }
- }
-
- //Add small ember-like particles
- if ( random->RandomInt( 0, 1 ) == 0 )
- {
- m_pEmberEmitter->SetSortOrigin( GetAbsOrigin() );
-
- pParticle = (SimpleParticle *) m_pEmberEmitter->AddParticle( sizeof(SimpleParticle), g_Mat_DustPuff[0], GetAbsOrigin() );
-
- assert(pParticle);
-
- if ( pParticle )
- {
- pParticle->m_flLifetime = 0.0f;
- pParticle->m_flDieTime = 1.0f;
-
- pParticle->m_flRoll = 0;
- pParticle->m_flRollDelta = 0;
-
- pParticle->m_uchColor[0] = 255;
- pParticle->m_uchColor[1] = 255;
- pParticle->m_uchColor[2] = 255;
- pParticle->m_uchStartAlpha = 255;
- pParticle->m_uchEndAlpha = 0;
- pParticle->m_uchStartSize = 1;
- pParticle->m_uchEndSize = 0;
-
- Vector dir;
- QAngle ofsAngles;
-
- ofsAngles.Random( -8.0f, 8.0f );
- ofsAngles += GetAbsAngles();
-
- AngleVectors( ofsAngles, &dir );
-
- if ( m_bUseMuzzlePoint )
- {
- dir.Negate();
- }
-
- pParticle->m_vecVelocity = dir * random->RandomInt( 400, 800 );
- }
- }
- }
- }
-
- // Inner beam
-
- CBeamSegDraw beamDraw;
- CBeamSeg seg;
- const int numPoints = 4;
- Vector beamPoints[numPoints];
-
- beamPoints[0] = GetAbsOrigin();
-
- // Create our beam points
- int i;
- for ( i = 0; i < numPoints; i++ )
- {
- beamPoints[i] = GetAbsOrigin() + ( shotDir * (32*i*i) );
-
- beamPoints[i] += vRight * sin( gpGlobals->curtime * 4.0f ) * (2.0f*i);
- beamPoints[i] += vUp * sin( gpGlobals->curtime * 8.0f ) * (1.0f*i);
- beamPoints[i] += shotDir * sin( gpGlobals->curtime * (16.0f*i) ) * (1.0f*i);
- }
-
- IMaterial *pMat = materials->FindMaterial( "particle/particle_smokegrenade", TEXTURE_GROUP_PARTICLE );
-
- beamDraw.Start( numPoints, pMat );
-
- //Setup and draw those points
- for( i = 0; i < numPoints; i++ )
- {
- float t = (float) i / (numPoints - 1);
- float color = 1.0f * (1.0f - t);
-
- seg.m_vColor = Vector( color, color, color );
- seg.m_vPos = beamPoints[i];
- seg.m_flTexCoord = (float)i/(float)(numPoints-1) - ((gpGlobals->curtime - (int)gpGlobals->curtime) * 4.0f );
- seg.m_flWidth = 4.0f + ( (64.0f*t) * (fabs( sin( gpGlobals->curtime * 16.0f ) )) );
- seg.m_flAlpha = color;
-
- beamDraw.NextSeg( &seg );
- }
-
- beamDraw.End();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : flags -
-//-----------------------------------------------------------------------------
-int C_ExtinguisherJet::DrawModel( int flags )
-{
- if ( m_bEmit == false )
- return 1;
-
- Update( Helper_GetFrameTime() );
-
- return 1;
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "particles_simple.h"
+#include "baseparticleentity.h"
+#include "iefx.h"
+#include "decals.h"
+#include "beamdraw.h"
+#include "hud.h"
+#include "clienteffectprecachesystem.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+CLIENTEFFECT_REGISTER_BEGIN( PrecacheExtinguisher )
+CLIENTEFFECT_MATERIAL( "particle/particle_smokegrenade" )
+CLIENTEFFECT_REGISTER_END()
+
+class C_ExtinguisherJet : public C_BaseEntity
+{
+public:
+ DECLARE_CLIENTCLASS();
+ DECLARE_CLASS( C_ExtinguisherJet, C_BaseEntity );
+
+ C_ExtinguisherJet();
+ ~C_ExtinguisherJet();
+
+ void OnDataChanged( DataUpdateType_t updateType );
+ void Update( float fTimeDelta );
+ void Start( void );
+ int DrawModel( int flags );
+ bool ShouldDraw( void ) { return m_bEmit; }
+
+protected:
+
+ void AddExtinguisherDecal( trace_t &tr );
+
+ bool m_bEmit;
+ bool m_bUseMuzzlePoint;
+ int m_nLength;
+ int m_nSize;
+
+ PMaterialHandle m_MaterialHandle;
+ PMaterialHandle m_EmberMaterialHandle;
+ TimedEvent m_ParticleSpawn;
+ CSmartPtr<CSimpleEmitter> m_pEmitter;
+ CSmartPtr<CEmberEffect> m_pEmberEmitter;
+
+private:
+ C_ExtinguisherJet( const C_ExtinguisherJet & );
+};
+
+//Datatable
+IMPLEMENT_CLIENTCLASS_DT( C_ExtinguisherJet, DT_ExtinguisherJet, CExtinguisherJet )
+ RecvPropInt(RECVINFO(m_bEmit), 0),
+ RecvPropInt(RECVINFO(m_bUseMuzzlePoint), 0),
+ RecvPropInt(RECVINFO(m_nLength), 0),
+ RecvPropInt(RECVINFO(m_nSize), 0),
+END_RECV_TABLE()
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_ExtinguisherJet::C_ExtinguisherJet( void )
+{
+ m_bEmit = false;
+
+ m_pEmitter = NULL;
+ m_pEmberEmitter = NULL;
+}
+
+C_ExtinguisherJet::~C_ExtinguisherJet( void )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : bnewentity -
+//-----------------------------------------------------------------------------
+void C_ExtinguisherJet::OnDataChanged( DataUpdateType_t updateType )
+{
+ C_BaseEntity::OnDataChanged(updateType);
+
+ if( updateType == DATA_UPDATE_CREATED )
+ {
+ Start();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_ExtinguisherJet::Start( void )
+{
+ AddToLeafSystem( RENDER_GROUP_TRANSLUCENT_ENTITY );
+
+ m_ParticleSpawn.Init( 100 ); //Events per second
+
+ //Create the basic emitter
+ m_pEmitter = CSimpleEmitter::Create("C_ExtinguisherJet::m_pEmitter");
+
+ Assert( m_pEmitter.IsValid() );
+ if ( m_pEmitter.IsValid() )
+ {
+ m_MaterialHandle = g_Mat_DustPuff[0];
+ m_pEmitter->SetSortOrigin( GetAbsOrigin() );
+ }
+
+ //Create the "ember" emitter for the smaller flecks
+ m_pEmberEmitter = CEmberEffect::Create( "C_ExtinguisherJet::m_pEmberEmitter" );
+
+ Assert( m_pEmberEmitter.IsValid() );
+ if ( m_pEmberEmitter.IsValid() )
+ {
+ m_EmberMaterialHandle = g_Mat_DustPuff[0];
+ m_pEmberEmitter->SetSortOrigin( GetAbsOrigin() );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_ExtinguisherJet::AddExtinguisherDecal( trace_t &tr )
+{
+ C_BaseEntity *ent = cl_entitylist->GetEnt( 0 );
+
+ if ( ent != NULL )
+ {
+ int index = decalsystem->GetDecalIndexForName( "Extinguish" );
+ if ( index >= 0 )
+ {
+ Vector endpos;
+ endpos.Random( -24.0f, 24.0f );
+ endpos += tr.endpos;
+
+ effects->DecalShoot( index, 0, ent->GetModel(), ent->GetAbsOrigin(), ent->GetAbsAngles(), endpos, 0, 0 );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : fTimeDelta -
+//-----------------------------------------------------------------------------
+void C_ExtinguisherJet::Update( float fTimeDelta )
+{
+ if ( m_bEmit == false )
+ return;
+
+ C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
+
+ if ( m_bUseMuzzlePoint )
+ {
+ C_BaseViewModel *vm = player ? player->GetViewModel( 0 ) : NULL;
+
+ if ( vm )
+ {
+ int iAttachment = vm->LookupAttachment( "muzzle" );
+ Vector origin;
+ QAngle angles;
+ vm->GetAttachment( iAttachment, origin, angles );
+
+ Assert( !GetMoveParent() );
+ SetLocalOrigin( origin );
+ SetLocalAngles( angles );
+ }
+ }
+
+ trace_t tr;
+ Vector shotDir, vRight, vUp;
+
+ AngleVectors( GetAbsAngles(), &shotDir, &vRight, &vUp );
+
+ //FIXME: Muzzle point is incorrect on the model!
+ if ( m_bUseMuzzlePoint )
+ {
+ shotDir.Negate();
+ }
+
+ Vector endPoint = GetAbsOrigin() + ( shotDir * 150.0f );
+
+ UTIL_TraceLine( GetAbsOrigin(), endPoint, MASK_SHOT, NULL, COLLISION_GROUP_NONE, &tr );
+
+ bool hitWall = ( tr.fraction < 1.0f );
+
+ //Add normal jet
+ if ( m_pEmitter.IsValid() )
+ {
+ SimpleParticle *pParticle;
+
+ m_pEmitter->SetSortOrigin( GetAbsOrigin() );
+
+ float tempDelta = fTimeDelta;
+
+ //FIXME: All particles need to be within this loop
+ while( m_ParticleSpawn.NextEvent( tempDelta ) )
+ {
+ pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle, GetAbsOrigin() );
+
+ if ( pParticle )
+ {
+ pParticle->m_flDieTime = 0.2f;
+ pParticle->m_flLifetime = 0.0f;
+
+ pParticle->m_flRoll = random->RandomInt( 0, 360 );
+ pParticle->m_flRollDelta= random->RandomFloat( -4.0f, 4.0f );
+
+ pParticle->m_uchStartSize = 1;
+ pParticle->m_uchEndSize = random->RandomInt( 32, 48 );
+ pParticle->m_uchStartAlpha = random->RandomInt( 128, 164 );
+ pParticle->m_uchEndAlpha = 0;
+
+ int cScale = random->RandomInt( 192, 255 );
+ pParticle->m_uchColor[0] = cScale;
+ pParticle->m_uchColor[1] = cScale;
+ pParticle->m_uchColor[2] = cScale;
+
+ Vector dir;
+ QAngle ofsAngles;
+
+ ofsAngles.Random( -8.0f, 8.0f );
+ ofsAngles += GetAbsAngles();
+
+ AngleVectors( ofsAngles, &dir );
+
+ if ( m_bUseMuzzlePoint )
+ {
+ dir.Negate();
+ }
+
+ pParticle->m_vecVelocity = dir * random->RandomInt( 400, 800 );
+ }
+
+ //Add muzzle effect
+ pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle, GetAbsOrigin() );
+
+ if ( pParticle )
+ {
+ pParticle->m_flDieTime = 0.1f;
+ pParticle->m_flLifetime = 0.0f;
+
+ pParticle->m_flRoll = random->RandomInt( 0, 360 );
+ pParticle->m_flRollDelta= random->RandomFloat( -4.0f, 4.0f );
+
+ pParticle->m_uchStartSize = 1;
+ pParticle->m_uchEndSize = random->RandomInt( 8, 16 );
+ pParticle->m_uchStartAlpha = random->RandomInt( 128, 255 );
+ pParticle->m_uchEndAlpha = 0;
+
+ int cScale = random->RandomInt( 192, 255 );
+ pParticle->m_uchColor[0] = cScale;
+ pParticle->m_uchColor[1] = cScale;
+ pParticle->m_uchColor[2] = cScale;
+
+ Vector dir;
+ QAngle ofsAngles;
+
+ ofsAngles.Random( -64.0f, 64.0f );
+ ofsAngles += GetAbsAngles();
+
+ AngleVectors( ofsAngles, &dir );
+
+ if ( m_bUseMuzzlePoint )
+ {
+ dir.Negate();
+ }
+
+ pParticle->m_vecVelocity = dir * random->RandomInt( 32, 64 );
+ }
+
+ //Add a wall effect if needed
+ if ( hitWall )
+ {
+ AddExtinguisherDecal( tr );
+
+ Vector offDir;
+
+ offDir.Random( -16.0f, 16.0f );
+
+ pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle, ( tr.endpos + ( tr.plane.normal * 8.0f ) ) + offDir );
+
+ if ( pParticle )
+ {
+ pParticle->m_flDieTime = 0.4f;
+ pParticle->m_flLifetime = 0.0f;
+
+ pParticle->m_flRoll = random->RandomInt( 0, 360 );
+ pParticle->m_flRollDelta= random->RandomFloat( -2.0f, 2.0f );
+
+ pParticle->m_uchStartSize = random->RandomInt( 8, 16 );
+ pParticle->m_uchEndSize = random->RandomInt( 24, 32 );
+ pParticle->m_uchStartAlpha = random->RandomInt( 64, 128 );
+ pParticle->m_uchEndAlpha = 0;
+
+ int cScale = random->RandomInt( 192, 255 );
+ pParticle->m_uchColor[0] = cScale;
+ pParticle->m_uchColor[1] = cScale;
+ pParticle->m_uchColor[2] = cScale;
+
+ Vector rDir;
+
+ rDir = tr.plane.normal;
+ rDir[0] += random->RandomFloat( -0.9f, 0.9f );
+ rDir[1] += random->RandomFloat( -0.9f, 0.9f );
+ rDir[2] += random->RandomFloat( -0.9f, 0.9f );
+
+ pParticle->m_vecVelocity = rDir * random->RandomInt( 32, 64 );
+ }
+ }
+
+ //Add small ember-like particles
+ if ( random->RandomInt( 0, 1 ) == 0 )
+ {
+ m_pEmberEmitter->SetSortOrigin( GetAbsOrigin() );
+
+ pParticle = (SimpleParticle *) m_pEmberEmitter->AddParticle( sizeof(SimpleParticle), g_Mat_DustPuff[0], GetAbsOrigin() );
+
+ assert(pParticle);
+
+ if ( pParticle )
+ {
+ pParticle->m_flLifetime = 0.0f;
+ pParticle->m_flDieTime = 1.0f;
+
+ pParticle->m_flRoll = 0;
+ pParticle->m_flRollDelta = 0;
+
+ pParticle->m_uchColor[0] = 255;
+ pParticle->m_uchColor[1] = 255;
+ pParticle->m_uchColor[2] = 255;
+ pParticle->m_uchStartAlpha = 255;
+ pParticle->m_uchEndAlpha = 0;
+ pParticle->m_uchStartSize = 1;
+ pParticle->m_uchEndSize = 0;
+
+ Vector dir;
+ QAngle ofsAngles;
+
+ ofsAngles.Random( -8.0f, 8.0f );
+ ofsAngles += GetAbsAngles();
+
+ AngleVectors( ofsAngles, &dir );
+
+ if ( m_bUseMuzzlePoint )
+ {
+ dir.Negate();
+ }
+
+ pParticle->m_vecVelocity = dir * random->RandomInt( 400, 800 );
+ }
+ }
+ }
+ }
+
+ // Inner beam
+
+ CBeamSegDraw beamDraw;
+ CBeamSeg seg;
+ const int numPoints = 4;
+ Vector beamPoints[numPoints];
+
+ beamPoints[0] = GetAbsOrigin();
+
+ // Create our beam points
+ int i;
+ for ( i = 0; i < numPoints; i++ )
+ {
+ beamPoints[i] = GetAbsOrigin() + ( shotDir * (32*i*i) );
+
+ beamPoints[i] += vRight * sin( gpGlobals->curtime * 4.0f ) * (2.0f*i);
+ beamPoints[i] += vUp * sin( gpGlobals->curtime * 8.0f ) * (1.0f*i);
+ beamPoints[i] += shotDir * sin( gpGlobals->curtime * (16.0f*i) ) * (1.0f*i);
+ }
+
+ IMaterial *pMat = materials->FindMaterial( "particle/particle_smokegrenade", TEXTURE_GROUP_PARTICLE );
+
+ beamDraw.Start( numPoints, pMat );
+
+ //Setup and draw those points
+ for( i = 0; i < numPoints; i++ )
+ {
+ float t = (float) i / (numPoints - 1);
+ float color = 1.0f * (1.0f - t);
+
+ seg.m_vColor = Vector( color, color, color );
+ seg.m_vPos = beamPoints[i];
+ seg.m_flTexCoord = (float)i/(float)(numPoints-1) - ((gpGlobals->curtime - (int)gpGlobals->curtime) * 4.0f );
+ seg.m_flWidth = 4.0f + ( (64.0f*t) * (fabs( sin( gpGlobals->curtime * 16.0f ) )) );
+ seg.m_flAlpha = color;
+
+ beamDraw.NextSeg( &seg );
+ }
+
+ beamDraw.End();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : flags -
+//-----------------------------------------------------------------------------
+int C_ExtinguisherJet::DrawModel( int flags )
+{
+ if ( m_bEmit == false )
+ return 1;
+
+ Update( Helper_GetFrameTime() );
+
+ return 1;
+}
diff --git a/mp/src/game/client/hl2/c_func_tankmortar.cpp b/mp/src/game/client/hl2/c_func_tankmortar.cpp
index 5d23995d..09987aaf 100644
--- a/mp/src/game/client/hl2/c_func_tankmortar.cpp
+++ b/mp/src/game/client/hl2/c_func_tankmortar.cpp
@@ -1,249 +1,249 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "fx_quad.h"
-#include "fx.h"
-
-class C_MortarShell : public C_BaseEntity
-{
-public:
-
- DECLARE_CLASS( C_MortarShell, C_BaseEntity );
- DECLARE_CLIENTCLASS();
-
- void OnDataChanged( DataUpdateType_t updateType );
- int DrawModel( int flags );
-
- RenderGroup_t GetRenderGroup( void ) { return RENDER_GROUP_TRANSLUCENT_ENTITY; }
-
-private:
-
- void AddRisingParticles( float flPerc );
- void AddExplodingParticles( float flPerc );
-
- inline float GetStartPerc( void );
- inline float GetEndPerc( void );
-
- CSmartPtr<CSimpleEmitter> m_pEmitter;
- TimedEvent m_ParticleEvent;
-
- float m_flLifespan;
- float m_flRadius;
- float m_flStarttime;
- Vector m_vecSurfaceNormal;
-};
-
-IMPLEMENT_CLIENTCLASS_DT( C_MortarShell, DT_MortarShell, CMortarShell )
- RecvPropFloat( RECVINFO( m_flLifespan ) ),
- RecvPropFloat( RECVINFO( m_flRadius ) ),
- RecvPropVector( RECVINFO( m_vecSurfaceNormal ) ),
-END_RECV_TABLE()
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : updateType -
-//-----------------------------------------------------------------------------
-void C_MortarShell::OnDataChanged( DataUpdateType_t updateType )
-{
- BaseClass::OnDataChanged( updateType );
-
- if ( updateType == DATA_UPDATE_CREATED )
- {
- m_flStarttime = gpGlobals->curtime;
- AddToLeafSystem( RENDER_GROUP_TRANSLUCENT_ENTITY );
-
- m_pEmitter = CSimpleEmitter::Create( "C_EntityDissolve" );
- m_pEmitter->SetSortOrigin( GetAbsOrigin() );
-
- m_ParticleEvent.Init( 128 );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : flPerc -
-//-----------------------------------------------------------------------------
-void C_MortarShell::AddRisingParticles( float flPerc )
-{
- SimpleParticle *sParticle;
-
- Vector offset;
- float radius = m_flRadius * 0.25f * flPerc;
-
- float val = RemapValClamped( gpGlobals->curtime, m_flStarttime, m_flStarttime + m_flLifespan, 0.0f, 1.0f );
-
- float flCur = gpGlobals->frametime;
-
- // Anime ground effects
- while ( m_ParticleEvent.NextEvent( flCur ) )
- {
- offset.x = random->RandomFloat( -radius, radius );
- offset.y = random->RandomFloat( -radius, radius );
- offset.z = random->RandomFloat( -8.0f, 8.0f );
-
- offset += GetAbsOrigin();
-
- sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_pEmitter->GetPMaterial( "effects/spark" ), offset );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_vecVelocity = Vector( Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( 32.0f, 256.0f ) * Bias( val, 0.25f ) );
-
- sParticle->m_uchStartSize = random->RandomFloat( 4, 8 ) * flPerc;
-
- sParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.0f );
-
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
-
- float alpha = 255 * flPerc;
-
- sParticle->m_flRollDelta = Helper_RandomFloat( -8.0f * flPerc, 8.0f * flPerc );
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = 0;
- sParticle->m_uchEndSize = 0;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : flPerc -
-//-----------------------------------------------------------------------------
-void C_MortarShell::AddExplodingParticles( float flPerc )
-{
- SimpleParticle *sParticle;
-
- Vector offset;
- float radius = 48.0f * flPerc;
-
- float flCur = gpGlobals->frametime;
-
- // Anime ground effects
- while ( m_ParticleEvent.NextEvent( flCur ) )
- {
- offset.x = random->RandomFloat( -radius, radius );
- offset.y = random->RandomFloat( -radius, radius );
- offset.z = random->RandomFloat( -8.0f, 8.0f );
-
- offset += GetAbsOrigin();
-
- sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_pEmitter->GetPMaterial( "effects/spark" ), offset );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_vecVelocity = RandomVector( -1.0f, 1.0f ) + Vector( 0, 0, 1 );
- sParticle->m_vecVelocity *= ( 750.0f * flPerc );
-
- sParticle->m_uchStartSize = random->RandomFloat( 2, 4 ) * flPerc;
-
- sParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f );
-
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
-
- float alpha = 255 * flPerc;
-
- sParticle->m_flRollDelta = Helper_RandomFloat( -8.0f * flPerc, 8.0f * flPerc );
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = 0;
- sParticle->m_uchEndSize = 0;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : inline float
-//-----------------------------------------------------------------------------
-inline float C_MortarShell::GetStartPerc( void )
-{
- float val = RemapValClamped( gpGlobals->curtime, m_flStarttime, m_flStarttime + m_flLifespan, 0.0f, 1.0f );
-
- return ( Gain( val, 0.2f ) );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : inline float
-//-----------------------------------------------------------------------------
-inline float C_MortarShell::GetEndPerc( void )
-{
- float val = RemapValClamped( gpGlobals->curtime, m_flStarttime + m_flLifespan, m_flStarttime + m_flLifespan + 1.0f, 1.0f, 0.0f );
-
- return ( Gain( val, 0.75f ) );
-}
-
-#define ALPHA_MIN 0.0f
-#define ALPHA_MAX 1.0f
-
-#define SCALE_MIN 8
-#define SCALE_MAX 200
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-int C_MortarShell::DrawModel( int flags )
-{
- if ( gpGlobals->frametime <= 0.0f )
- return 0;
-
- float flPerc;
- bool ending;
-
- // See if we're in the beginning phase
- if ( gpGlobals->curtime < ( m_flStarttime + m_flLifespan ) )
- {
- flPerc = GetStartPerc();
- ending = false;
- }
- else
- {
- flPerc = GetEndPerc();
- ending = true;
- }
-
- float flAlpha = ALPHA_MIN + ( ( ALPHA_MAX - ALPHA_MIN ) * flPerc );
- float flScale = ( ending ) ? m_flRadius : ( (m_flRadius*0.1f)+ ( ( m_flRadius - (m_flRadius*0.1f) ) * flPerc ) );
-
- // Do the ground effect
- FX_AddQuad( GetAbsOrigin() + ( m_vecSurfaceNormal * 2.0f ),
- m_vecSurfaceNormal,
- flScale,
- flScale,
- 1.0f,
- flAlpha,
- flAlpha,
- 1.0f,
- 0,
- 0,
- Vector( 1.0f, 1.0f, 1.0f ),
- 0.0001f,
- "effects/combinemuzzle2_nocull",
- 0 );
-
- if ( !ending )
- {
- // Add extra effects on startup
- AddRisingParticles( flPerc );
- }
- else
- {
- // Add exploding particles after the impact
- AddExplodingParticles( flPerc );
- }
-
- return 1;
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "fx_quad.h"
+#include "fx.h"
+
+class C_MortarShell : public C_BaseEntity
+{
+public:
+
+ DECLARE_CLASS( C_MortarShell, C_BaseEntity );
+ DECLARE_CLIENTCLASS();
+
+ void OnDataChanged( DataUpdateType_t updateType );
+ int DrawModel( int flags );
+
+ RenderGroup_t GetRenderGroup( void ) { return RENDER_GROUP_TRANSLUCENT_ENTITY; }
+
+private:
+
+ void AddRisingParticles( float flPerc );
+ void AddExplodingParticles( float flPerc );
+
+ inline float GetStartPerc( void );
+ inline float GetEndPerc( void );
+
+ CSmartPtr<CSimpleEmitter> m_pEmitter;
+ TimedEvent m_ParticleEvent;
+
+ float m_flLifespan;
+ float m_flRadius;
+ float m_flStarttime;
+ Vector m_vecSurfaceNormal;
+};
+
+IMPLEMENT_CLIENTCLASS_DT( C_MortarShell, DT_MortarShell, CMortarShell )
+ RecvPropFloat( RECVINFO( m_flLifespan ) ),
+ RecvPropFloat( RECVINFO( m_flRadius ) ),
+ RecvPropVector( RECVINFO( m_vecSurfaceNormal ) ),
+END_RECV_TABLE()
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : updateType -
+//-----------------------------------------------------------------------------
+void C_MortarShell::OnDataChanged( DataUpdateType_t updateType )
+{
+ BaseClass::OnDataChanged( updateType );
+
+ if ( updateType == DATA_UPDATE_CREATED )
+ {
+ m_flStarttime = gpGlobals->curtime;
+ AddToLeafSystem( RENDER_GROUP_TRANSLUCENT_ENTITY );
+
+ m_pEmitter = CSimpleEmitter::Create( "C_EntityDissolve" );
+ m_pEmitter->SetSortOrigin( GetAbsOrigin() );
+
+ m_ParticleEvent.Init( 128 );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : flPerc -
+//-----------------------------------------------------------------------------
+void C_MortarShell::AddRisingParticles( float flPerc )
+{
+ SimpleParticle *sParticle;
+
+ Vector offset;
+ float radius = m_flRadius * 0.25f * flPerc;
+
+ float val = RemapValClamped( gpGlobals->curtime, m_flStarttime, m_flStarttime + m_flLifespan, 0.0f, 1.0f );
+
+ float flCur = gpGlobals->frametime;
+
+ // Anime ground effects
+ while ( m_ParticleEvent.NextEvent( flCur ) )
+ {
+ offset.x = random->RandomFloat( -radius, radius );
+ offset.y = random->RandomFloat( -radius, radius );
+ offset.z = random->RandomFloat( -8.0f, 8.0f );
+
+ offset += GetAbsOrigin();
+
+ sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_pEmitter->GetPMaterial( "effects/spark" ), offset );
+
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_vecVelocity = Vector( Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( 32.0f, 256.0f ) * Bias( val, 0.25f ) );
+
+ sParticle->m_uchStartSize = random->RandomFloat( 4, 8 ) * flPerc;
+
+ sParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.0f );
+
+ sParticle->m_flLifetime = 0.0f;
+
+ sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
+
+ float alpha = 255 * flPerc;
+
+ sParticle->m_flRollDelta = Helper_RandomFloat( -8.0f * flPerc, 8.0f * flPerc );
+ sParticle->m_uchColor[0] = alpha;
+ sParticle->m_uchColor[1] = alpha;
+ sParticle->m_uchColor[2] = alpha;
+ sParticle->m_uchStartAlpha = alpha;
+ sParticle->m_uchEndAlpha = 0;
+ sParticle->m_uchEndSize = 0;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : flPerc -
+//-----------------------------------------------------------------------------
+void C_MortarShell::AddExplodingParticles( float flPerc )
+{
+ SimpleParticle *sParticle;
+
+ Vector offset;
+ float radius = 48.0f * flPerc;
+
+ float flCur = gpGlobals->frametime;
+
+ // Anime ground effects
+ while ( m_ParticleEvent.NextEvent( flCur ) )
+ {
+ offset.x = random->RandomFloat( -radius, radius );
+ offset.y = random->RandomFloat( -radius, radius );
+ offset.z = random->RandomFloat( -8.0f, 8.0f );
+
+ offset += GetAbsOrigin();
+
+ sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_pEmitter->GetPMaterial( "effects/spark" ), offset );
+
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_vecVelocity = RandomVector( -1.0f, 1.0f ) + Vector( 0, 0, 1 );
+ sParticle->m_vecVelocity *= ( 750.0f * flPerc );
+
+ sParticle->m_uchStartSize = random->RandomFloat( 2, 4 ) * flPerc;
+
+ sParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f );
+
+ sParticle->m_flLifetime = 0.0f;
+
+ sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
+
+ float alpha = 255 * flPerc;
+
+ sParticle->m_flRollDelta = Helper_RandomFloat( -8.0f * flPerc, 8.0f * flPerc );
+ sParticle->m_uchColor[0] = alpha;
+ sParticle->m_uchColor[1] = alpha;
+ sParticle->m_uchColor[2] = alpha;
+ sParticle->m_uchStartAlpha = alpha;
+ sParticle->m_uchEndAlpha = 0;
+ sParticle->m_uchEndSize = 0;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : inline float
+//-----------------------------------------------------------------------------
+inline float C_MortarShell::GetStartPerc( void )
+{
+ float val = RemapValClamped( gpGlobals->curtime, m_flStarttime, m_flStarttime + m_flLifespan, 0.0f, 1.0f );
+
+ return ( Gain( val, 0.2f ) );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : inline float
+//-----------------------------------------------------------------------------
+inline float C_MortarShell::GetEndPerc( void )
+{
+ float val = RemapValClamped( gpGlobals->curtime, m_flStarttime + m_flLifespan, m_flStarttime + m_flLifespan + 1.0f, 1.0f, 0.0f );
+
+ return ( Gain( val, 0.75f ) );
+}
+
+#define ALPHA_MIN 0.0f
+#define ALPHA_MAX 1.0f
+
+#define SCALE_MIN 8
+#define SCALE_MAX 200
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int C_MortarShell::DrawModel( int flags )
+{
+ if ( gpGlobals->frametime <= 0.0f )
+ return 0;
+
+ float flPerc;
+ bool ending;
+
+ // See if we're in the beginning phase
+ if ( gpGlobals->curtime < ( m_flStarttime + m_flLifespan ) )
+ {
+ flPerc = GetStartPerc();
+ ending = false;
+ }
+ else
+ {
+ flPerc = GetEndPerc();
+ ending = true;
+ }
+
+ float flAlpha = ALPHA_MIN + ( ( ALPHA_MAX - ALPHA_MIN ) * flPerc );
+ float flScale = ( ending ) ? m_flRadius : ( (m_flRadius*0.1f)+ ( ( m_flRadius - (m_flRadius*0.1f) ) * flPerc ) );
+
+ // Do the ground effect
+ FX_AddQuad( GetAbsOrigin() + ( m_vecSurfaceNormal * 2.0f ),
+ m_vecSurfaceNormal,
+ flScale,
+ flScale,
+ 1.0f,
+ flAlpha,
+ flAlpha,
+ 1.0f,
+ 0,
+ 0,
+ Vector( 1.0f, 1.0f, 1.0f ),
+ 0.0001f,
+ "effects/combinemuzzle2_nocull",
+ 0 );
+
+ if ( !ending )
+ {
+ // Add extra effects on startup
+ AddRisingParticles( flPerc );
+ }
+ else
+ {
+ // Add exploding particles after the impact
+ AddExplodingParticles( flPerc );
+ }
+
+ return 1;
+}
diff --git a/mp/src/game/client/hl2/c_hl2_playerlocaldata.cpp b/mp/src/game/client/hl2/c_hl2_playerlocaldata.cpp
index a28cce3d..469bd4ec 100644
--- a/mp/src/game/client/hl2/c_hl2_playerlocaldata.cpp
+++ b/mp/src/game/client/hl2/c_hl2_playerlocaldata.cpp
@@ -1,52 +1,52 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "c_hl2_playerlocaldata.h"
-#include "dt_recv.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-BEGIN_RECV_TABLE_NOBASE( C_HL2PlayerLocalData, DT_HL2Local )
- RecvPropFloat( RECVINFO(m_flSuitPower) ),
- RecvPropInt( RECVINFO(m_bZooming) ),
- RecvPropInt( RECVINFO(m_bitsActiveDevices) ),
- RecvPropInt( RECVINFO(m_iSquadMemberCount) ),
- RecvPropInt( RECVINFO(m_iSquadMedicCount) ),
- RecvPropBool( RECVINFO(m_fSquadInFollowMode) ),
- RecvPropBool( RECVINFO(m_bWeaponLowered) ),
- RecvPropEHandle( RECVINFO(m_hAutoAimTarget) ),
- RecvPropVector( RECVINFO(m_vecAutoAimPoint) ),
- RecvPropEHandle( RECVINFO(m_hLadder) ),
- RecvPropBool( RECVINFO(m_bDisplayReticle) ),
- RecvPropBool( RECVINFO(m_bStickyAutoAim) ),
- RecvPropBool( RECVINFO(m_bAutoAimTarget) ),
-#ifdef HL2_EPISODIC
- RecvPropFloat( RECVINFO(m_flFlashBattery) ),
- RecvPropVector( RECVINFO(m_vecLocatorOrigin) ),
-#endif
-END_RECV_TABLE()
-
-BEGIN_PREDICTION_DATA_NO_BASE( C_HL2PlayerLocalData )
- DEFINE_PRED_FIELD( m_hLadder, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),
-END_PREDICTION_DATA()
-
-C_HL2PlayerLocalData::C_HL2PlayerLocalData()
-{
- m_flSuitPower = 0.0;
- m_bZooming = false;
- m_iSquadMemberCount = 0;
- m_iSquadMedicCount = 0;
- m_fSquadInFollowMode = false;
- m_bWeaponLowered = false;
- m_hLadder = NULL;
-#ifdef HL2_EPISODIC
- m_flFlashBattery = 0.0f;
- m_vecLocatorOrigin = vec3_origin;
-#endif
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "c_hl2_playerlocaldata.h"
+#include "dt_recv.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+BEGIN_RECV_TABLE_NOBASE( C_HL2PlayerLocalData, DT_HL2Local )
+ RecvPropFloat( RECVINFO(m_flSuitPower) ),
+ RecvPropInt( RECVINFO(m_bZooming) ),
+ RecvPropInt( RECVINFO(m_bitsActiveDevices) ),
+ RecvPropInt( RECVINFO(m_iSquadMemberCount) ),
+ RecvPropInt( RECVINFO(m_iSquadMedicCount) ),
+ RecvPropBool( RECVINFO(m_fSquadInFollowMode) ),
+ RecvPropBool( RECVINFO(m_bWeaponLowered) ),
+ RecvPropEHandle( RECVINFO(m_hAutoAimTarget) ),
+ RecvPropVector( RECVINFO(m_vecAutoAimPoint) ),
+ RecvPropEHandle( RECVINFO(m_hLadder) ),
+ RecvPropBool( RECVINFO(m_bDisplayReticle) ),
+ RecvPropBool( RECVINFO(m_bStickyAutoAim) ),
+ RecvPropBool( RECVINFO(m_bAutoAimTarget) ),
+#ifdef HL2_EPISODIC
+ RecvPropFloat( RECVINFO(m_flFlashBattery) ),
+ RecvPropVector( RECVINFO(m_vecLocatorOrigin) ),
+#endif
+END_RECV_TABLE()
+
+BEGIN_PREDICTION_DATA_NO_BASE( C_HL2PlayerLocalData )
+ DEFINE_PRED_FIELD( m_hLadder, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),
+END_PREDICTION_DATA()
+
+C_HL2PlayerLocalData::C_HL2PlayerLocalData()
+{
+ m_flSuitPower = 0.0;
+ m_bZooming = false;
+ m_iSquadMemberCount = 0;
+ m_iSquadMedicCount = 0;
+ m_fSquadInFollowMode = false;
+ m_bWeaponLowered = false;
+ m_hLadder = NULL;
+#ifdef HL2_EPISODIC
+ m_flFlashBattery = 0.0f;
+ m_vecLocatorOrigin = vec3_origin;
+#endif
+}
+
diff --git a/mp/src/game/client/hl2/c_hl2_playerlocaldata.h b/mp/src/game/client/hl2/c_hl2_playerlocaldata.h
index 9c862368..80019915 100644
--- a/mp/src/game/client/hl2/c_hl2_playerlocaldata.h
+++ b/mp/src/game/client/hl2/c_hl2_playerlocaldata.h
@@ -1,55 +1,55 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $Workfile: $
-// $NoKeywords: $
-//=============================================================================//
-
-#if !defined( C_HL2_PLAYERLOCALDATA_H )
-#define C_HL2_PLAYERLOCALDATA_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-
-#include "dt_recv.h"
-
-#include "hl2/hl_movedata.h"
-
-EXTERN_RECV_TABLE( DT_HL2Local );
-
-
-class C_HL2PlayerLocalData
-{
-public:
- DECLARE_PREDICTABLE();
- DECLARE_CLASS_NOBASE( C_HL2PlayerLocalData );
- DECLARE_EMBEDDED_NETWORKVAR();
-
- C_HL2PlayerLocalData();
-
- float m_flSuitPower;
- bool m_bZooming;
- int m_bitsActiveDevices;
- int m_iSquadMemberCount;
- int m_iSquadMedicCount;
- bool m_fSquadInFollowMode;
- bool m_bWeaponLowered;
- EHANDLE m_hAutoAimTarget;
- Vector m_vecAutoAimPoint;
- bool m_bDisplayReticle;
- bool m_bStickyAutoAim;
- bool m_bAutoAimTarget;
-#ifdef HL2_EPISODIC
- float m_flFlashBattery;
- Vector m_vecLocatorOrigin;
-#endif
-
- // Ladder related data
- EHANDLE m_hLadder;
- LadderMove_t m_LadderMove;
-};
-
-
-#endif
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $Workfile: $
+// $NoKeywords: $
+//=============================================================================//
+
+#if !defined( C_HL2_PLAYERLOCALDATA_H )
+#define C_HL2_PLAYERLOCALDATA_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "dt_recv.h"
+
+#include "hl2/hl_movedata.h"
+
+EXTERN_RECV_TABLE( DT_HL2Local );
+
+
+class C_HL2PlayerLocalData
+{
+public:
+ DECLARE_PREDICTABLE();
+ DECLARE_CLASS_NOBASE( C_HL2PlayerLocalData );
+ DECLARE_EMBEDDED_NETWORKVAR();
+
+ C_HL2PlayerLocalData();
+
+ float m_flSuitPower;
+ bool m_bZooming;
+ int m_bitsActiveDevices;
+ int m_iSquadMemberCount;
+ int m_iSquadMedicCount;
+ bool m_fSquadInFollowMode;
+ bool m_bWeaponLowered;
+ EHANDLE m_hAutoAimTarget;
+ Vector m_vecAutoAimPoint;
+ bool m_bDisplayReticle;
+ bool m_bStickyAutoAim;
+ bool m_bAutoAimTarget;
+#ifdef HL2_EPISODIC
+ float m_flFlashBattery;
+ Vector m_vecLocatorOrigin;
+#endif
+
+ // Ladder related data
+ EHANDLE m_hLadder;
+ LadderMove_t m_LadderMove;
+};
+
+
+#endif
diff --git a/mp/src/game/client/hl2/c_info_teleporter_countdown.cpp b/mp/src/game/client/hl2/c_info_teleporter_countdown.cpp
index 1cb9ae6f..e99277c9 100644
--- a/mp/src/game/client/hl2/c_info_teleporter_countdown.cpp
+++ b/mp/src/game/client/hl2/c_info_teleporter_countdown.cpp
@@ -1,194 +1,194 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-
-#include "c_vguiscreen.h"
-#include <vgui/IVGui.h>
-#include <vgui_controls/Controls.h>
-#include <vgui_controls/Label.h>
-#include "clientmode_hlnormal.h"
-#include "tier1/utllinkedlist.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-
-//-----------------------------------------------------------------------------
-// Amount of time before breen teleports away
-//-----------------------------------------------------------------------------
-class C_InfoTeleporterCountdown : public C_BaseEntity
-{
-public:
- DECLARE_CLASS( C_InfoTeleporterCountdown, C_BaseEntity );
- DECLARE_CLIENTCLASS();
-
-public:
- C_InfoTeleporterCountdown();
- ~C_InfoTeleporterCountdown();
-
- virtual bool ShouldDraw() { return false; }
-
-private:
- bool m_bCountdownStarted;
- bool m_bDisabled;
- float m_flStartTime;
- float m_flTimeRemaining;
-
- friend class CTeleportCountdownScreen;
-};
-
-
-//-----------------------------------------------------------------------------
-// Global list of teleporters
-//-----------------------------------------------------------------------------
-CUtlFixedLinkedList<C_InfoTeleporterCountdown *> g_InfoTeleporterCountdownList;
-
-
-//-----------------------------------------------------------------------------
-// Networking
-//-----------------------------------------------------------------------------
-IMPLEMENT_CLIENTCLASS_DT( C_InfoTeleporterCountdown, DT_InfoTeleporterCountdown, CInfoTeleporterCountdown )
- RecvPropInt( RECVINFO( m_bCountdownStarted ) ),
- RecvPropInt( RECVINFO( m_bDisabled ) ),
- RecvPropTime( RECVINFO( m_flStartTime ) ),
- RecvPropFloat( RECVINFO( m_flTimeRemaining ) ),
-END_RECV_TABLE()
-
-
-//-----------------------------------------------------------------------------
-// Constructor, destructor
-//-----------------------------------------------------------------------------
-C_InfoTeleporterCountdown::C_InfoTeleporterCountdown()
-{
- g_InfoTeleporterCountdownList.AddToTail( this );
-}
-
-C_InfoTeleporterCountdown::~C_InfoTeleporterCountdown()
-{
- g_InfoTeleporterCountdownList.FindAndRemove( this );
-}
-
-
-//-----------------------------------------------------------------------------
-//
-// In-game vgui panel which shows the teleporter countdown
-//
-//-----------------------------------------------------------------------------
-class CTeleportCountdownScreen : public CVGuiScreenPanel
-{
- DECLARE_CLASS( CTeleportCountdownScreen, CVGuiScreenPanel );
-
-public:
- CTeleportCountdownScreen( vgui::Panel *parent, const char *panelName );
-
- virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
- virtual void OnTick();
-
-private:
- vgui::Label *m_pTimeRemainingTitleLabel;
- vgui::Label *m_pTimeRemainingLabel;
- vgui::Label *m_pMalfunctionLabel;
-};
-
-
-//-----------------------------------------------------------------------------
-// Standard VGUI panel for objects
-//-----------------------------------------------------------------------------
-DECLARE_VGUI_SCREEN_FACTORY( CTeleportCountdownScreen, "teleport_countdown_screen" );
-
-
-//-----------------------------------------------------------------------------
-// Constructor:
-//-----------------------------------------------------------------------------
-CTeleportCountdownScreen::CTeleportCountdownScreen( vgui::Panel *parent, const char *panelName )
- : BaseClass( parent, panelName, g_hVGuiCombineScheme )
-{
-}
-
-
-//-----------------------------------------------------------------------------
-// Initialization
-//-----------------------------------------------------------------------------
-bool CTeleportCountdownScreen::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
-{
- // Load all of the controls in
- if ( !BaseClass::Init(pKeyValues, pInitData) )
- return false;
-
- // Make sure we get ticked...
- vgui::ivgui()->AddTickSignal( GetVPanel() );
-
- // Grab ahold of certain well-known controls
- // NOTE: it is valid for these controls to not exist!
- m_pTimeRemainingTitleLabel = dynamic_cast<vgui::Label*>(FindChildByName( "TimeRemainingTitle" ));
- m_pTimeRemainingLabel = dynamic_cast<vgui::Label*>(FindChildByName( "TimeRemaining" ));
- m_pMalfunctionLabel = dynamic_cast<vgui::Label*>( FindChildByName( "MalfunctionLabel" ) );
-
- return true;
-}
-
-
-//-----------------------------------------------------------------------------
-// Frame-based update
-//-----------------------------------------------------------------------------
-void CTeleportCountdownScreen::OnTick()
-{
- BaseClass::OnTick();
-
- // Find the active info teleporter countdown
- C_InfoTeleporterCountdown *pActiveCountdown = NULL;
- for ( int i = g_InfoTeleporterCountdownList.Head(); i != g_InfoTeleporterCountdownList.InvalidIndex();
- i = g_InfoTeleporterCountdownList.Next(i) )
- {
- if ( g_InfoTeleporterCountdownList[i]->m_bCountdownStarted )
- {
- pActiveCountdown = g_InfoTeleporterCountdownList[i];
- break;
- }
- }
-
- if ( !GetEntity() || !pActiveCountdown )
- {
- m_pTimeRemainingTitleLabel->SetVisible( false );
- m_pTimeRemainingLabel->SetVisible( false );
- m_pMalfunctionLabel->SetVisible( false );
-
- return;
- }
-
- // Make the appropriate labels visible
- bool bMalfunction = pActiveCountdown->m_bDisabled;
- m_pTimeRemainingTitleLabel->SetVisible( !bMalfunction );
- m_pTimeRemainingLabel->SetVisible( !bMalfunction );
-
- // This will make it flash
- m_pMalfunctionLabel->SetVisible( bMalfunction && (((int)(gpGlobals->curtime) & 0x1) == 0x1) );
-
- // Update the time remaining
- if ( !bMalfunction )
- {
- char buf[32];
- if (m_pTimeRemainingLabel)
- {
- float dt = gpGlobals->curtime - pActiveCountdown->m_flStartTime;
- if ( dt < 0.0f )
- {
- dt = 0.0f;
- }
-
- int nTimeRemaining = (int)(pActiveCountdown->m_flTimeRemaining - dt + 0.5f);
- if ( nTimeRemaining < 0 )
- {
- nTimeRemaining = 0;
- }
-
- Q_snprintf( buf, sizeof( buf ), "%d", nTimeRemaining );
- m_pTimeRemainingLabel->SetText( buf );
- }
- }
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+
+#include "c_vguiscreen.h"
+#include <vgui/IVGui.h>
+#include <vgui_controls/Controls.h>
+#include <vgui_controls/Label.h>
+#include "clientmode_hlnormal.h"
+#include "tier1/utllinkedlist.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+//-----------------------------------------------------------------------------
+// Amount of time before breen teleports away
+//-----------------------------------------------------------------------------
+class C_InfoTeleporterCountdown : public C_BaseEntity
+{
+public:
+ DECLARE_CLASS( C_InfoTeleporterCountdown, C_BaseEntity );
+ DECLARE_CLIENTCLASS();
+
+public:
+ C_InfoTeleporterCountdown();
+ ~C_InfoTeleporterCountdown();
+
+ virtual bool ShouldDraw() { return false; }
+
+private:
+ bool m_bCountdownStarted;
+ bool m_bDisabled;
+ float m_flStartTime;
+ float m_flTimeRemaining;
+
+ friend class CTeleportCountdownScreen;
+};
+
+
+//-----------------------------------------------------------------------------
+// Global list of teleporters
+//-----------------------------------------------------------------------------
+CUtlFixedLinkedList<C_InfoTeleporterCountdown *> g_InfoTeleporterCountdownList;
+
+
+//-----------------------------------------------------------------------------
+// Networking
+//-----------------------------------------------------------------------------
+IMPLEMENT_CLIENTCLASS_DT( C_InfoTeleporterCountdown, DT_InfoTeleporterCountdown, CInfoTeleporterCountdown )
+ RecvPropInt( RECVINFO( m_bCountdownStarted ) ),
+ RecvPropInt( RECVINFO( m_bDisabled ) ),
+ RecvPropTime( RECVINFO( m_flStartTime ) ),
+ RecvPropFloat( RECVINFO( m_flTimeRemaining ) ),
+END_RECV_TABLE()
+
+
+//-----------------------------------------------------------------------------
+// Constructor, destructor
+//-----------------------------------------------------------------------------
+C_InfoTeleporterCountdown::C_InfoTeleporterCountdown()
+{
+ g_InfoTeleporterCountdownList.AddToTail( this );
+}
+
+C_InfoTeleporterCountdown::~C_InfoTeleporterCountdown()
+{
+ g_InfoTeleporterCountdownList.FindAndRemove( this );
+}
+
+
+//-----------------------------------------------------------------------------
+//
+// In-game vgui panel which shows the teleporter countdown
+//
+//-----------------------------------------------------------------------------
+class CTeleportCountdownScreen : public CVGuiScreenPanel
+{
+ DECLARE_CLASS( CTeleportCountdownScreen, CVGuiScreenPanel );
+
+public:
+ CTeleportCountdownScreen( vgui::Panel *parent, const char *panelName );
+
+ virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
+ virtual void OnTick();
+
+private:
+ vgui::Label *m_pTimeRemainingTitleLabel;
+ vgui::Label *m_pTimeRemainingLabel;
+ vgui::Label *m_pMalfunctionLabel;
+};
+
+
+//-----------------------------------------------------------------------------
+// Standard VGUI panel for objects
+//-----------------------------------------------------------------------------
+DECLARE_VGUI_SCREEN_FACTORY( CTeleportCountdownScreen, "teleport_countdown_screen" );
+
+
+//-----------------------------------------------------------------------------
+// Constructor:
+//-----------------------------------------------------------------------------
+CTeleportCountdownScreen::CTeleportCountdownScreen( vgui::Panel *parent, const char *panelName )
+ : BaseClass( parent, panelName, g_hVGuiCombineScheme )
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Initialization
+//-----------------------------------------------------------------------------
+bool CTeleportCountdownScreen::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
+{
+ // Load all of the controls in
+ if ( !BaseClass::Init(pKeyValues, pInitData) )
+ return false;
+
+ // Make sure we get ticked...
+ vgui::ivgui()->AddTickSignal( GetVPanel() );
+
+ // Grab ahold of certain well-known controls
+ // NOTE: it is valid for these controls to not exist!
+ m_pTimeRemainingTitleLabel = dynamic_cast<vgui::Label*>(FindChildByName( "TimeRemainingTitle" ));
+ m_pTimeRemainingLabel = dynamic_cast<vgui::Label*>(FindChildByName( "TimeRemaining" ));
+ m_pMalfunctionLabel = dynamic_cast<vgui::Label*>( FindChildByName( "MalfunctionLabel" ) );
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Frame-based update
+//-----------------------------------------------------------------------------
+void CTeleportCountdownScreen::OnTick()
+{
+ BaseClass::OnTick();
+
+ // Find the active info teleporter countdown
+ C_InfoTeleporterCountdown *pActiveCountdown = NULL;
+ for ( int i = g_InfoTeleporterCountdownList.Head(); i != g_InfoTeleporterCountdownList.InvalidIndex();
+ i = g_InfoTeleporterCountdownList.Next(i) )
+ {
+ if ( g_InfoTeleporterCountdownList[i]->m_bCountdownStarted )
+ {
+ pActiveCountdown = g_InfoTeleporterCountdownList[i];
+ break;
+ }
+ }
+
+ if ( !GetEntity() || !pActiveCountdown )
+ {
+ m_pTimeRemainingTitleLabel->SetVisible( false );
+ m_pTimeRemainingLabel->SetVisible( false );
+ m_pMalfunctionLabel->SetVisible( false );
+
+ return;
+ }
+
+ // Make the appropriate labels visible
+ bool bMalfunction = pActiveCountdown->m_bDisabled;
+ m_pTimeRemainingTitleLabel->SetVisible( !bMalfunction );
+ m_pTimeRemainingLabel->SetVisible( !bMalfunction );
+
+ // This will make it flash
+ m_pMalfunctionLabel->SetVisible( bMalfunction && (((int)(gpGlobals->curtime) & 0x1) == 0x1) );
+
+ // Update the time remaining
+ if ( !bMalfunction )
+ {
+ char buf[32];
+ if (m_pTimeRemainingLabel)
+ {
+ float dt = gpGlobals->curtime - pActiveCountdown->m_flStartTime;
+ if ( dt < 0.0f )
+ {
+ dt = 0.0f;
+ }
+
+ int nTimeRemaining = (int)(pActiveCountdown->m_flTimeRemaining - dt + 0.5f);
+ if ( nTimeRemaining < 0 )
+ {
+ nTimeRemaining = 0;
+ }
+
+ Q_snprintf( buf, sizeof( buf ), "%d", nTimeRemaining );
+ m_pTimeRemainingLabel->SetText( buf );
+ }
+ }
+}
+
diff --git a/mp/src/game/client/hl2/c_npc_antlionguard.cpp b/mp/src/game/client/hl2/c_npc_antlionguard.cpp
index 0448468f..e2c7232a 100644
--- a/mp/src/game/client/hl2/c_npc_antlionguard.cpp
+++ b/mp/src/game/client/hl2/c_npc_antlionguard.cpp
@@ -1,160 +1,160 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Client side antlion guard. Used to create dlight for the cave guard.
-//
-//=============================================================================
-
-#include "cbase.h"
-#include "c_ai_basenpc.h"
-#include "dlight.h"
-#include "iefx.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-
-#if HL2_EPISODIC
-// When enabled, add code to have the antlion bleed profusely as it is badly injured.
-#define ANTLIONGUARD_BLOOD_EFFECTS 2
-#endif
-
-
-class C_NPC_AntlionGuard : public C_AI_BaseNPC
-{
-public:
- C_NPC_AntlionGuard() {}
-
- DECLARE_CLASS( C_NPC_AntlionGuard, C_AI_BaseNPC );
- DECLARE_CLIENTCLASS();
- DECLARE_DATADESC();
-
- virtual void OnDataChanged( DataUpdateType_t type );
- virtual void ClientThink();
-
-private:
-
- bool m_bCavernBreed;
- bool m_bInCavern;
- dlight_t *m_dlight;
-
-#if HL2_EPISODIC
- unsigned char m_iBleedingLevel; //< the version coming from the server
- unsigned char m_iPerformingBleedingLevel; //< the version we're currently performing (for comparison to one above)
- CNewParticleEffect *m_pBleedingFX;
-
- /// update the hemorrhage particle effect
- virtual void UpdateBleedingPerformance( void );
-#endif
-
- C_NPC_AntlionGuard( const C_NPC_AntlionGuard & );
-};
-
-
-//-----------------------------------------------------------------------------
-// Save/restore
-//-----------------------------------------------------------------------------
-BEGIN_DATADESC( C_NPC_AntlionGuard )
-END_DATADESC()
-
-
-//-----------------------------------------------------------------------------
-// Networking
-//-----------------------------------------------------------------------------
-IMPLEMENT_CLIENTCLASS_DT(C_NPC_AntlionGuard, DT_NPC_AntlionGuard, CNPC_AntlionGuard)
- RecvPropBool( RECVINFO( m_bCavernBreed ) ),
- RecvPropBool( RECVINFO( m_bInCavern ) ),
-
-#if ANTLIONGUARD_BLOOD_EFFECTS
- RecvPropInt( RECVINFO( m_iBleedingLevel ) ),
-#endif
-END_RECV_TABLE()
-
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void C_NPC_AntlionGuard::OnDataChanged( DataUpdateType_t type )
-{
- BaseClass::OnDataChanged( type );
-
- if ( (type == DATA_UPDATE_CREATED) && m_bCavernBreed && m_bInCavern )
- {
- SetNextClientThink( CLIENT_THINK_ALWAYS );
- }
-
-
-#if HL2_EPISODIC
- if (m_iBleedingLevel != m_iPerformingBleedingLevel)
- {
- UpdateBleedingPerformance();
- }
-#endif
-
-}
-
-#if HL2_EPISODIC
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void C_NPC_AntlionGuard::UpdateBleedingPerformance()
-{
- // get my particles
- CParticleProperty * pProp = ParticleProp();
-
- // squelch the prior effect if it exists
- if (m_pBleedingFX)
- {
- pProp->StopEmission(m_pBleedingFX);
- m_pBleedingFX = NULL;
- }
-
- // kick off a new effect
- switch (m_iBleedingLevel)
- {
- case 1: // light bleeding
- {
- m_pBleedingFX = pProp->Create( "blood_antlionguard_injured_light", PATTACH_ABSORIGIN_FOLLOW );
- AssertMsg1( m_pBleedingFX, "Particle system couldn't make %s", "blood_antlionguard_injured_light" );
- if ( m_pBleedingFX )
- {
- pProp->AddControlPoint( m_pBleedingFX, 1, this, PATTACH_ABSORIGIN_FOLLOW );
- }
- }
- break;
-
- case 2: // severe bleeding
- {
- m_pBleedingFX = pProp->Create( "blood_antlionguard_injured_heavy", PATTACH_ABSORIGIN_FOLLOW );
- AssertMsg1( m_pBleedingFX, "Particle system couldn't make %s", "blood_antlionguard_injured_heavy" );
- if ( m_pBleedingFX )
- {
- pProp->AddControlPoint( m_pBleedingFX, 1, this, PATTACH_ABSORIGIN_FOLLOW );
- }
-
- }
- break;
- }
-
- m_iPerformingBleedingLevel = m_iBleedingLevel;
-}
-#endif
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void C_NPC_AntlionGuard::ClientThink()
-{
- // update the dlight. (always done because clienthink only exists for cavernguard)
- if (!m_dlight)
- {
- m_dlight = effects->CL_AllocDlight( index );
- m_dlight->color.r = 220;
- m_dlight->color.g = 255;
- m_dlight->color.b = 80;
- m_dlight->radius = 180;
- m_dlight->minlight = 128.0 / 256.0f;
- m_dlight->flags = DLIGHT_NO_MODEL_ILLUMINATION;
- }
-
- m_dlight->origin = GetAbsOrigin();
- // dl->die = gpGlobals->curtime + 0.1f;
-
- BaseClass::ClientThink();
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Client side antlion guard. Used to create dlight for the cave guard.
+//
+//=============================================================================
+
+#include "cbase.h"
+#include "c_ai_basenpc.h"
+#include "dlight.h"
+#include "iefx.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+#if HL2_EPISODIC
+// When enabled, add code to have the antlion bleed profusely as it is badly injured.
+#define ANTLIONGUARD_BLOOD_EFFECTS 2
+#endif
+
+
+class C_NPC_AntlionGuard : public C_AI_BaseNPC
+{
+public:
+ C_NPC_AntlionGuard() {}
+
+ DECLARE_CLASS( C_NPC_AntlionGuard, C_AI_BaseNPC );
+ DECLARE_CLIENTCLASS();
+ DECLARE_DATADESC();
+
+ virtual void OnDataChanged( DataUpdateType_t type );
+ virtual void ClientThink();
+
+private:
+
+ bool m_bCavernBreed;
+ bool m_bInCavern;
+ dlight_t *m_dlight;
+
+#if HL2_EPISODIC
+ unsigned char m_iBleedingLevel; //< the version coming from the server
+ unsigned char m_iPerformingBleedingLevel; //< the version we're currently performing (for comparison to one above)
+ CNewParticleEffect *m_pBleedingFX;
+
+ /// update the hemorrhage particle effect
+ virtual void UpdateBleedingPerformance( void );
+#endif
+
+ C_NPC_AntlionGuard( const C_NPC_AntlionGuard & );
+};
+
+
+//-----------------------------------------------------------------------------
+// Save/restore
+//-----------------------------------------------------------------------------
+BEGIN_DATADESC( C_NPC_AntlionGuard )
+END_DATADESC()
+
+
+//-----------------------------------------------------------------------------
+// Networking
+//-----------------------------------------------------------------------------
+IMPLEMENT_CLIENTCLASS_DT(C_NPC_AntlionGuard, DT_NPC_AntlionGuard, CNPC_AntlionGuard)
+ RecvPropBool( RECVINFO( m_bCavernBreed ) ),
+ RecvPropBool( RECVINFO( m_bInCavern ) ),
+
+#if ANTLIONGUARD_BLOOD_EFFECTS
+ RecvPropInt( RECVINFO( m_iBleedingLevel ) ),
+#endif
+END_RECV_TABLE()
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void C_NPC_AntlionGuard::OnDataChanged( DataUpdateType_t type )
+{
+ BaseClass::OnDataChanged( type );
+
+ if ( (type == DATA_UPDATE_CREATED) && m_bCavernBreed && m_bInCavern )
+ {
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+ }
+
+
+#if HL2_EPISODIC
+ if (m_iBleedingLevel != m_iPerformingBleedingLevel)
+ {
+ UpdateBleedingPerformance();
+ }
+#endif
+
+}
+
+#if HL2_EPISODIC
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void C_NPC_AntlionGuard::UpdateBleedingPerformance()
+{
+ // get my particles
+ CParticleProperty * pProp = ParticleProp();
+
+ // squelch the prior effect if it exists
+ if (m_pBleedingFX)
+ {
+ pProp->StopEmission(m_pBleedingFX);
+ m_pBleedingFX = NULL;
+ }
+
+ // kick off a new effect
+ switch (m_iBleedingLevel)
+ {
+ case 1: // light bleeding
+ {
+ m_pBleedingFX = pProp->Create( "blood_antlionguard_injured_light", PATTACH_ABSORIGIN_FOLLOW );
+ AssertMsg1( m_pBleedingFX, "Particle system couldn't make %s", "blood_antlionguard_injured_light" );
+ if ( m_pBleedingFX )
+ {
+ pProp->AddControlPoint( m_pBleedingFX, 1, this, PATTACH_ABSORIGIN_FOLLOW );
+ }
+ }
+ break;
+
+ case 2: // severe bleeding
+ {
+ m_pBleedingFX = pProp->Create( "blood_antlionguard_injured_heavy", PATTACH_ABSORIGIN_FOLLOW );
+ AssertMsg1( m_pBleedingFX, "Particle system couldn't make %s", "blood_antlionguard_injured_heavy" );
+ if ( m_pBleedingFX )
+ {
+ pProp->AddControlPoint( m_pBleedingFX, 1, this, PATTACH_ABSORIGIN_FOLLOW );
+ }
+
+ }
+ break;
+ }
+
+ m_iPerformingBleedingLevel = m_iBleedingLevel;
+}
+#endif
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void C_NPC_AntlionGuard::ClientThink()
+{
+ // update the dlight. (always done because clienthink only exists for cavernguard)
+ if (!m_dlight)
+ {
+ m_dlight = effects->CL_AllocDlight( index );
+ m_dlight->color.r = 220;
+ m_dlight->color.g = 255;
+ m_dlight->color.b = 80;
+ m_dlight->radius = 180;
+ m_dlight->minlight = 128.0 / 256.0f;
+ m_dlight->flags = DLIGHT_NO_MODEL_ILLUMINATION;
+ }
+
+ m_dlight->origin = GetAbsOrigin();
+ // dl->die = gpGlobals->curtime + 0.1f;
+
+ BaseClass::ClientThink();
+}
diff --git a/mp/src/game/client/hl2/c_npc_combinegunship.cpp b/mp/src/game/client/hl2/c_npc_combinegunship.cpp
index c3e1e930..b42ca04f 100644
--- a/mp/src/game/client/hl2/c_npc_combinegunship.cpp
+++ b/mp/src/game/client/hl2/c_npc_combinegunship.cpp
@@ -1,476 +1,476 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "c_basehelicopter.h"
-#include "fx_impact.h"
-#include "IEffects.h"
-#include "simple_keys.h"
-#include "fx_envelope.h"
-#include "fx_line.h"
-#include "iefx.h"
-#include "dlight.h"
-#include "c_sprite.h"
-#include "clienteffectprecachesystem.h"
-#include <bitbuf.h>
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-#define GUNSHIP_MSG_BIG_SHOT 1
-#define GUNSHIP_MSG_STREAKS 2
-#define GUNSHIP_MSG_DEAD 3
-
-#define GUNSHIPFX_BIG_SHOT_TIME 3.0f
-
-CLIENTEFFECT_REGISTER_BEGIN( PrecacheGunshipFX )
-CLIENTEFFECT_MATERIAL( "sprites/bluelaser1" )
-CLIENTEFFECT_REGISTER_END()
-
-//-----------------------------------------------------------------------------
-// Big belly shot FX
-//-----------------------------------------------------------------------------
-
-class C_GunshipFX : public C_EnvelopeFX
-{
-public:
- typedef C_EnvelopeFX BaseClass;
-
- C_GunshipFX();
- void Update( C_BaseEntity *pOwner, const Vector &targetPos );
-
- // Returns the bounds relative to the origin (render bounds)
- virtual void GetRenderBounds( Vector& mins, Vector& maxs )
- {
- ClearBounds( mins, maxs );
- AddPointToBounds( m_worldPosition, mins, maxs );
- AddPointToBounds( m_targetPosition, mins, maxs );
- mins -= GetRenderOrigin();
- maxs -= GetRenderOrigin();
- }
-
- virtual int DrawModel( int flags );
-
- C_BaseEntity *m_pOwner;
- Vector m_targetPosition;
- Vector m_beamEndPosition;
-};
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-C_GunshipFX::C_GunshipFX( void )
-{
- m_pOwner = NULL;
-}
-
-enum
-{
- GUNSHIPFX_WARP_SCALE = 0,
- GUNSHIPFX_DARKNESS,
- GUNSHIPFX_FLARE_COLOR,
- GUNSHIPFX_FLARE_SIZE,
-
- GUNSHIPFX_NARROW_BEAM_COLOR,
- GUNSHIPFX_NARROW_BEAM_SIZE,
-
- GUNSHIPFX_WIDE_BEAM_COLOR,
- GUNSHIPFX_WIDE_BEAM_SIZE,
-
- GUNSHIPFX_AFTERGLOW_COLOR,
-
- GUNSHIPFX_WIDE_BEAM_LENGTH,
-
- // must be last
- GUNSHIPFX_PARAMETERS,
-};
-
-class CGunshipFXEnvelope
-{
-public:
- CGunshipFXEnvelope();
-
- void AddKey( int parameterIndex, const CSimpleKeyInterp &key )
- {
- Assert( parameterIndex >= 0 && parameterIndex < GUNSHIPFX_PARAMETERS );
-
- if ( parameterIndex >= 0 && parameterIndex < GUNSHIPFX_PARAMETERS )
- {
- m_parameters[parameterIndex].Insert( key );
- }
-
- }
-
- CSimpleKeyList m_parameters[GUNSHIPFX_PARAMETERS];
-};
-
-// NOTE: Beam widths are half-widths or radii, so this is a beam that represents a cylinder with 2" radius
-const float NARROW_BEAM_WIDTH = 32;
-const float WIDE_BEAM_WIDTH = 2;
-const float FLARE_SIZE = 128;
-const float DARK_SIZE = 16;
-const float AFTERGLOW_SIZE = 64;
-
-CGunshipFXEnvelope::CGunshipFXEnvelope()
-{
- // Glow flare
- AddKey( GUNSHIPFX_FLARE_COLOR, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
- AddKey( GUNSHIPFX_FLARE_COLOR, CSimpleKeyInterp( 0.5, KEY_SPLINE, 1 ) );
- AddKey( GUNSHIPFX_FLARE_COLOR, CSimpleKeyInterp( 2.9, KEY_LINEAR, 1 ) );
- AddKey( GUNSHIPFX_FLARE_COLOR, CSimpleKeyInterp( 3.2, KEY_DECELERATE, 0 ) );
-
- AddKey( GUNSHIPFX_FLARE_SIZE, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
- AddKey( GUNSHIPFX_FLARE_SIZE, CSimpleKeyInterp( 2.9, KEY_ACCELERATE, 1 ) );
- AddKey( GUNSHIPFX_FLARE_SIZE, CSimpleKeyInterp( 5.0, KEY_LINEAR, 1 ) );
-
- // Ground beam
- AddKey( GUNSHIPFX_NARROW_BEAM_COLOR, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0.0 ) );
- AddKey( GUNSHIPFX_NARROW_BEAM_COLOR, CSimpleKeyInterp( 2.5, KEY_SPLINE, 1.0 ) );
- AddKey( GUNSHIPFX_NARROW_BEAM_COLOR, CSimpleKeyInterp( 3.0, KEY_LINEAR, 1 ) );
- AddKey( GUNSHIPFX_NARROW_BEAM_COLOR, CSimpleKeyInterp( 3.2, KEY_ACCELERATE, 0 ) );
-
- AddKey( GUNSHIPFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
- AddKey( GUNSHIPFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 2.5, KEY_SPLINE, 0.25 ) );
- AddKey( GUNSHIPFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 2.8, KEY_ACCELERATE, 1 ) );
- AddKey( GUNSHIPFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 3.0, KEY_ACCELERATE, 4 ) );
- AddKey( GUNSHIPFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 3.2, KEY_DECELERATE, 0 ) );
-
- // Glow color on the ship
- AddKey( GUNSHIPFX_AFTERGLOW_COLOR, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
- AddKey( GUNSHIPFX_AFTERGLOW_COLOR, CSimpleKeyInterp( 3.0, KEY_LINEAR, 1 ) );
- AddKey( GUNSHIPFX_AFTERGLOW_COLOR, CSimpleKeyInterp( 5.0, KEY_SPLINE, 0 ) );
-}
-
-CGunshipFXEnvelope g_GunshipCannonEnvelope;
-
-static void ScaleColor( color32 &out, const color32 &in, float scale )
-{
- out.r = (byte)(int)((float)in.r * scale);
- out.g = (byte)(int)((float)in.g * scale);
- out.b = (byte)(int)((float)in.b * scale);
- out.a = (byte)(int)((float)in.a * scale);
-}
-
-static void DrawSpriteTangentSpace( const Vector &vecOrigin, float flWidth, float flHeight, color32 color )
-{
- unsigned char pColor[4] = { color.r, color.g, color.b, color.a };
-
- // Generate half-widths
- flWidth *= 0.5f;
- flHeight *= 0.5f;
-
- // Compute direction vectors for the sprite
- Vector fwd, right( 1, 0, 0 ), up( 0, 1, 0 );
- VectorSubtract( CurrentViewOrigin(), vecOrigin, fwd );
- float flDist = VectorNormalize( fwd );
- if (flDist >= 1e-3)
- {
- CrossProduct( CurrentViewUp(), fwd, right );
- flDist = VectorNormalize( right );
- if (flDist >= 1e-3)
- {
- CrossProduct( fwd, right, up );
- }
- else
- {
- // In this case, fwd == g_vecVUp, it's right above or
- // below us in screen space
- CrossProduct( fwd, CurrentViewRight(), up );
- VectorNormalize( up );
- CrossProduct( up, fwd, right );
- }
- }
-
- Vector left = -right;
- Vector down = -up;
- Vector back = -fwd;
-
- CMatRenderContextPtr pRenderContext( materials );
-
- CMeshBuilder meshBuilder;
- Vector point;
- IMesh* pMesh = pRenderContext->GetDynamicMesh( );
-
- meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
-
- meshBuilder.Color4ubv (pColor);
- meshBuilder.TexCoord2f (0, 0, 1);
- VectorMA (vecOrigin, -flHeight, up, point);
- VectorMA (point, -flWidth, right, point);
- meshBuilder.TangentS3fv( left.Base() );
- meshBuilder.TangentT3fv( down.Base() );
- meshBuilder.Normal3fv( back.Base() );
- meshBuilder.Position3fv (point.Base());
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color4ubv (pColor);
- meshBuilder.TexCoord2f (0, 0, 0);
- VectorMA (vecOrigin, flHeight, up, point);
- VectorMA (point, -flWidth, right, point);
- meshBuilder.TangentS3fv( left.Base() );
- meshBuilder.TangentT3fv( down.Base() );
- meshBuilder.Normal3fv( back.Base() );
- meshBuilder.Position3fv (point.Base());
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color4ubv (pColor);
- meshBuilder.TexCoord2f (0, 1, 0);
- VectorMA (vecOrigin, flHeight, up, point);
- VectorMA (point, flWidth, right, point);
- meshBuilder.TangentS3fv( left.Base() );
- meshBuilder.TangentT3fv( down.Base() );
- meshBuilder.Normal3fv( back.Base() );
- meshBuilder.Position3fv (point.Base());
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color4ubv (pColor);
- meshBuilder.TexCoord2f (0, 1, 1);
- VectorMA (vecOrigin, -flHeight, up, point);
- VectorMA (point, flWidth, right, point);
- meshBuilder.TangentS3fv( left.Base() );
- meshBuilder.TangentT3fv( down.Base() );
- meshBuilder.Normal3fv( back.Base() );
- meshBuilder.Position3fv (point.Base());
- meshBuilder.AdvanceVertex();
-
- meshBuilder.End();
- pMesh->Draw();
-}
-
-
-void Gunship_DrawSprite( const Vector &vecOrigin, float size, const color32 &color, bool glow )
-{
- if ( glow )
- {
- pixelvis_queryparams_t params;
- params.Init( vecOrigin );
- if ( PixelVisibility_FractionVisible( params, NULL ) <= 0.0f )
- return;
- }
-
- DrawSpriteTangentSpace( vecOrigin, size, size, color );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : int -
-//-----------------------------------------------------------------------------
-int C_GunshipFX::DrawModel( int )
-{
- static color32 white = {255,255,255,255};
- Vector params[GUNSHIPFX_PARAMETERS];
- bool hasParam[GUNSHIPFX_PARAMETERS];
-
- if ( !m_active )
- return 1;
-
- C_BaseEntity *ent = cl_entitylist->GetEnt( m_entityIndex );
- if ( ent )
- {
- QAngle angles;
- ent->GetAttachment( m_attachment, m_worldPosition, angles );
- }
-
- Vector test;
- m_t += gpGlobals->frametime;
- if ( m_tMax > 0 )
- {
- m_t = clamp( m_t, 0, m_tMax );
- m_beamEndPosition = m_worldPosition;
- }
- float t = m_t;
-
- bool hasAny = false;
- memset( hasParam, 0, sizeof(hasParam) );
- for ( int i = 0; i < GUNSHIPFX_PARAMETERS; i++ )
- {
- hasParam[i] = g_GunshipCannonEnvelope.m_parameters[i].Interp( params[i], t );
- hasAny = hasAny || hasParam[i];
- }
-
- // draw the narrow beam
- if ( hasParam[GUNSHIPFX_NARROW_BEAM_COLOR] && hasParam[GUNSHIPFX_NARROW_BEAM_SIZE] )
- {
- IMaterial *pMat = materials->FindMaterial( "sprites/bluelaser1", TEXTURE_GROUP_CLIENT_EFFECTS );
- float width = NARROW_BEAM_WIDTH * params[GUNSHIPFX_NARROW_BEAM_SIZE].x;
- color32 color;
- float bright = params[GUNSHIPFX_NARROW_BEAM_COLOR].x;
- ScaleColor( color, white, bright );
-
- //Gunship_DrawLine( m_beamEndPosition, m_targetPosition, width, pMat, color );
- FX_DrawLine( m_beamEndPosition, m_targetPosition, width, pMat, color );
- }
-
- // glowy blue flare sprite
- if ( hasParam[GUNSHIPFX_FLARE_COLOR] && hasParam[GUNSHIPFX_FLARE_SIZE] )
- {
- IMaterial *pMat = materials->FindMaterial( "effects/blueblackflash", TEXTURE_GROUP_CLIENT_EFFECTS );
- float size = FLARE_SIZE * params[GUNSHIPFX_FLARE_SIZE].x;
- color32 color;
- float bright = params[GUNSHIPFX_FLARE_COLOR].x;
- ScaleColor( color, white, bright );
- color.a = (int)(255 * params[GUNSHIPFX_DARKNESS].x);
- CMatRenderContextPtr pRenderContext( materials );
- pRenderContext->Bind( pMat, (IClientRenderable*)this );
- Gunship_DrawSprite( m_worldPosition, size, color, true );
- }
-
- if ( hasParam[GUNSHIPFX_AFTERGLOW_COLOR] )
- {
- // Muzzle effect
- dlight_t *dl = effects->CL_AllocDlight( m_entityIndex );
- dl->origin = m_worldPosition;
- dl->color.r = 40*params[GUNSHIPFX_AFTERGLOW_COLOR].x;
- dl->color.g = 60*params[GUNSHIPFX_AFTERGLOW_COLOR].x;
- dl->color.b = 255*params[GUNSHIPFX_AFTERGLOW_COLOR].x;
- dl->color.exponent = 5;
- dl->radius = 128.0f;
- dl->die = gpGlobals->curtime + 0.001;
- }
-
- if ( m_t >= 4.0 && !hasAny )
- {
- EffectShutdown();
- }
-
- return 1;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pOwner -
-// &targetPos -
-//-----------------------------------------------------------------------------
-void C_GunshipFX::Update( C_BaseEntity *pOwner, const Vector &targetPos )
-{
- BaseClass::Update();
-
- m_pOwner = pOwner;
-
- if ( m_active )
- {
- m_targetPosition = targetPos;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Gunship
-//-----------------------------------------------------------------------------
-
-class C_CombineGunship : public C_BaseHelicopter
-{
- DECLARE_CLASS( C_CombineGunship, C_BaseHelicopter );
-public:
- DECLARE_CLIENTCLASS();
-
- C_CombineGunship( void ) {}
-
- virtual ~C_CombineGunship( void )
- {
- m_cannonFX.EffectShutdown();
- }
-
- C_GunshipFX m_cannonFX;
- Vector m_vecHitPos;
-
- //-----------------------------------------------------------------------------
- // Purpose:
- // Input : length -
- // *data -
- // Output : void
- //-----------------------------------------------------------------------------
- void ReceiveMessage( int classID, bf_read &msg )
- {
- if ( classID != GetClientClass()->m_ClassID )
- {
- // message is for subclass
- BaseClass::ReceiveMessage( classID, msg );
- return;
- }
-
- int messageType = msg.ReadByte();
- switch( messageType )
- {
- case GUNSHIP_MSG_STREAKS:
- {
- Vector pos;
- msg.ReadBitVec3Coord( pos );
- m_cannonFX.SetRenderOrigin( pos );
- m_cannonFX.EffectInit( entindex(), LookupAttachment( "BellyGun" ) );
- m_cannonFX.LimitTime( GUNSHIPFX_BIG_SHOT_TIME );
- }
- break;
-
- case GUNSHIP_MSG_BIG_SHOT:
- {
- Vector tmp;
- msg.ReadBitVec3Coord( tmp );
- m_cannonFX.SetTime( GUNSHIPFX_BIG_SHOT_TIME );
- m_cannonFX.LimitTime( 0 );
- }
- break;
-
- case GUNSHIP_MSG_DEAD:
- {
- m_cannonFX.EffectShutdown();
- }
- break;
- }
- }
-
- void OnDataChanged( DataUpdateType_t updateType )
- {
- BaseClass::OnDataChanged( updateType );
-
- m_cannonFX.Update( this, m_vecHitPos );
- }
-
- virtual RenderGroup_t GetRenderGroup()
- {
- if ( hl2_episodic.GetBool() == true )
- {
- return RENDER_GROUP_TWOPASS;
- }
- else
- {
- return BaseClass::GetRenderGroup();
- }
- }
-
-private:
- C_CombineGunship( const C_CombineGunship & ) {}
-};
-
-IMPLEMENT_CLIENTCLASS_DT( C_CombineGunship, DT_CombineGunship, CNPC_CombineGunship )
- RecvPropVector(RECVINFO(m_vecHitPos)),
-END_RECV_TABLE()
-
-//-----------------------------------------------------------------------------
-// Purpose: Handle gunship impacts
-//-----------------------------------------------------------------------------
-void ImpactGunshipCallback( 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, 3 );
- }
-
- PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
-}
-
-DECLARE_CLIENT_EFFECT( "ImpactGunship", ImpactGunshipCallback );
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "c_basehelicopter.h"
+#include "fx_impact.h"
+#include "IEffects.h"
+#include "simple_keys.h"
+#include "fx_envelope.h"
+#include "fx_line.h"
+#include "iefx.h"
+#include "dlight.h"
+#include "c_sprite.h"
+#include "clienteffectprecachesystem.h"
+#include <bitbuf.h>
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#define GUNSHIP_MSG_BIG_SHOT 1
+#define GUNSHIP_MSG_STREAKS 2
+#define GUNSHIP_MSG_DEAD 3
+
+#define GUNSHIPFX_BIG_SHOT_TIME 3.0f
+
+CLIENTEFFECT_REGISTER_BEGIN( PrecacheGunshipFX )
+CLIENTEFFECT_MATERIAL( "sprites/bluelaser1" )
+CLIENTEFFECT_REGISTER_END()
+
+//-----------------------------------------------------------------------------
+// Big belly shot FX
+//-----------------------------------------------------------------------------
+
+class C_GunshipFX : public C_EnvelopeFX
+{
+public:
+ typedef C_EnvelopeFX BaseClass;
+
+ C_GunshipFX();
+ void Update( C_BaseEntity *pOwner, const Vector &targetPos );
+
+ // Returns the bounds relative to the origin (render bounds)
+ virtual void GetRenderBounds( Vector& mins, Vector& maxs )
+ {
+ ClearBounds( mins, maxs );
+ AddPointToBounds( m_worldPosition, mins, maxs );
+ AddPointToBounds( m_targetPosition, mins, maxs );
+ mins -= GetRenderOrigin();
+ maxs -= GetRenderOrigin();
+ }
+
+ virtual int DrawModel( int flags );
+
+ C_BaseEntity *m_pOwner;
+ Vector m_targetPosition;
+ Vector m_beamEndPosition;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_GunshipFX::C_GunshipFX( void )
+{
+ m_pOwner = NULL;
+}
+
+enum
+{
+ GUNSHIPFX_WARP_SCALE = 0,
+ GUNSHIPFX_DARKNESS,
+ GUNSHIPFX_FLARE_COLOR,
+ GUNSHIPFX_FLARE_SIZE,
+
+ GUNSHIPFX_NARROW_BEAM_COLOR,
+ GUNSHIPFX_NARROW_BEAM_SIZE,
+
+ GUNSHIPFX_WIDE_BEAM_COLOR,
+ GUNSHIPFX_WIDE_BEAM_SIZE,
+
+ GUNSHIPFX_AFTERGLOW_COLOR,
+
+ GUNSHIPFX_WIDE_BEAM_LENGTH,
+
+ // must be last
+ GUNSHIPFX_PARAMETERS,
+};
+
+class CGunshipFXEnvelope
+{
+public:
+ CGunshipFXEnvelope();
+
+ void AddKey( int parameterIndex, const CSimpleKeyInterp &key )
+ {
+ Assert( parameterIndex >= 0 && parameterIndex < GUNSHIPFX_PARAMETERS );
+
+ if ( parameterIndex >= 0 && parameterIndex < GUNSHIPFX_PARAMETERS )
+ {
+ m_parameters[parameterIndex].Insert( key );
+ }
+
+ }
+
+ CSimpleKeyList m_parameters[GUNSHIPFX_PARAMETERS];
+};
+
+// NOTE: Beam widths are half-widths or radii, so this is a beam that represents a cylinder with 2" radius
+const float NARROW_BEAM_WIDTH = 32;
+const float WIDE_BEAM_WIDTH = 2;
+const float FLARE_SIZE = 128;
+const float DARK_SIZE = 16;
+const float AFTERGLOW_SIZE = 64;
+
+CGunshipFXEnvelope::CGunshipFXEnvelope()
+{
+ // Glow flare
+ AddKey( GUNSHIPFX_FLARE_COLOR, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
+ AddKey( GUNSHIPFX_FLARE_COLOR, CSimpleKeyInterp( 0.5, KEY_SPLINE, 1 ) );
+ AddKey( GUNSHIPFX_FLARE_COLOR, CSimpleKeyInterp( 2.9, KEY_LINEAR, 1 ) );
+ AddKey( GUNSHIPFX_FLARE_COLOR, CSimpleKeyInterp( 3.2, KEY_DECELERATE, 0 ) );
+
+ AddKey( GUNSHIPFX_FLARE_SIZE, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
+ AddKey( GUNSHIPFX_FLARE_SIZE, CSimpleKeyInterp( 2.9, KEY_ACCELERATE, 1 ) );
+ AddKey( GUNSHIPFX_FLARE_SIZE, CSimpleKeyInterp( 5.0, KEY_LINEAR, 1 ) );
+
+ // Ground beam
+ AddKey( GUNSHIPFX_NARROW_BEAM_COLOR, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0.0 ) );
+ AddKey( GUNSHIPFX_NARROW_BEAM_COLOR, CSimpleKeyInterp( 2.5, KEY_SPLINE, 1.0 ) );
+ AddKey( GUNSHIPFX_NARROW_BEAM_COLOR, CSimpleKeyInterp( 3.0, KEY_LINEAR, 1 ) );
+ AddKey( GUNSHIPFX_NARROW_BEAM_COLOR, CSimpleKeyInterp( 3.2, KEY_ACCELERATE, 0 ) );
+
+ AddKey( GUNSHIPFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
+ AddKey( GUNSHIPFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 2.5, KEY_SPLINE, 0.25 ) );
+ AddKey( GUNSHIPFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 2.8, KEY_ACCELERATE, 1 ) );
+ AddKey( GUNSHIPFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 3.0, KEY_ACCELERATE, 4 ) );
+ AddKey( GUNSHIPFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 3.2, KEY_DECELERATE, 0 ) );
+
+ // Glow color on the ship
+ AddKey( GUNSHIPFX_AFTERGLOW_COLOR, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
+ AddKey( GUNSHIPFX_AFTERGLOW_COLOR, CSimpleKeyInterp( 3.0, KEY_LINEAR, 1 ) );
+ AddKey( GUNSHIPFX_AFTERGLOW_COLOR, CSimpleKeyInterp( 5.0, KEY_SPLINE, 0 ) );
+}
+
+CGunshipFXEnvelope g_GunshipCannonEnvelope;
+
+static void ScaleColor( color32 &out, const color32 &in, float scale )
+{
+ out.r = (byte)(int)((float)in.r * scale);
+ out.g = (byte)(int)((float)in.g * scale);
+ out.b = (byte)(int)((float)in.b * scale);
+ out.a = (byte)(int)((float)in.a * scale);
+}
+
+static void DrawSpriteTangentSpace( const Vector &vecOrigin, float flWidth, float flHeight, color32 color )
+{
+ unsigned char pColor[4] = { color.r, color.g, color.b, color.a };
+
+ // Generate half-widths
+ flWidth *= 0.5f;
+ flHeight *= 0.5f;
+
+ // Compute direction vectors for the sprite
+ Vector fwd, right( 1, 0, 0 ), up( 0, 1, 0 );
+ VectorSubtract( CurrentViewOrigin(), vecOrigin, fwd );
+ float flDist = VectorNormalize( fwd );
+ if (flDist >= 1e-3)
+ {
+ CrossProduct( CurrentViewUp(), fwd, right );
+ flDist = VectorNormalize( right );
+ if (flDist >= 1e-3)
+ {
+ CrossProduct( fwd, right, up );
+ }
+ else
+ {
+ // In this case, fwd == g_vecVUp, it's right above or
+ // below us in screen space
+ CrossProduct( fwd, CurrentViewRight(), up );
+ VectorNormalize( up );
+ CrossProduct( up, fwd, right );
+ }
+ }
+
+ Vector left = -right;
+ Vector down = -up;
+ Vector back = -fwd;
+
+ CMatRenderContextPtr pRenderContext( materials );
+
+ CMeshBuilder meshBuilder;
+ Vector point;
+ IMesh* pMesh = pRenderContext->GetDynamicMesh( );
+
+ meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
+
+ meshBuilder.Color4ubv (pColor);
+ meshBuilder.TexCoord2f (0, 0, 1);
+ VectorMA (vecOrigin, -flHeight, up, point);
+ VectorMA (point, -flWidth, right, point);
+ meshBuilder.TangentS3fv( left.Base() );
+ meshBuilder.TangentT3fv( down.Base() );
+ meshBuilder.Normal3fv( back.Base() );
+ meshBuilder.Position3fv (point.Base());
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ubv (pColor);
+ meshBuilder.TexCoord2f (0, 0, 0);
+ VectorMA (vecOrigin, flHeight, up, point);
+ VectorMA (point, -flWidth, right, point);
+ meshBuilder.TangentS3fv( left.Base() );
+ meshBuilder.TangentT3fv( down.Base() );
+ meshBuilder.Normal3fv( back.Base() );
+ meshBuilder.Position3fv (point.Base());
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ubv (pColor);
+ meshBuilder.TexCoord2f (0, 1, 0);
+ VectorMA (vecOrigin, flHeight, up, point);
+ VectorMA (point, flWidth, right, point);
+ meshBuilder.TangentS3fv( left.Base() );
+ meshBuilder.TangentT3fv( down.Base() );
+ meshBuilder.Normal3fv( back.Base() );
+ meshBuilder.Position3fv (point.Base());
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ubv (pColor);
+ meshBuilder.TexCoord2f (0, 1, 1);
+ VectorMA (vecOrigin, -flHeight, up, point);
+ VectorMA (point, flWidth, right, point);
+ meshBuilder.TangentS3fv( left.Base() );
+ meshBuilder.TangentT3fv( down.Base() );
+ meshBuilder.Normal3fv( back.Base() );
+ meshBuilder.Position3fv (point.Base());
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.End();
+ pMesh->Draw();
+}
+
+
+void Gunship_DrawSprite( const Vector &vecOrigin, float size, const color32 &color, bool glow )
+{
+ if ( glow )
+ {
+ pixelvis_queryparams_t params;
+ params.Init( vecOrigin );
+ if ( PixelVisibility_FractionVisible( params, NULL ) <= 0.0f )
+ return;
+ }
+
+ DrawSpriteTangentSpace( vecOrigin, size, size, color );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : int -
+//-----------------------------------------------------------------------------
+int C_GunshipFX::DrawModel( int )
+{
+ static color32 white = {255,255,255,255};
+ Vector params[GUNSHIPFX_PARAMETERS];
+ bool hasParam[GUNSHIPFX_PARAMETERS];
+
+ if ( !m_active )
+ return 1;
+
+ C_BaseEntity *ent = cl_entitylist->GetEnt( m_entityIndex );
+ if ( ent )
+ {
+ QAngle angles;
+ ent->GetAttachment( m_attachment, m_worldPosition, angles );
+ }
+
+ Vector test;
+ m_t += gpGlobals->frametime;
+ if ( m_tMax > 0 )
+ {
+ m_t = clamp( m_t, 0, m_tMax );
+ m_beamEndPosition = m_worldPosition;
+ }
+ float t = m_t;
+
+ bool hasAny = false;
+ memset( hasParam, 0, sizeof(hasParam) );
+ for ( int i = 0; i < GUNSHIPFX_PARAMETERS; i++ )
+ {
+ hasParam[i] = g_GunshipCannonEnvelope.m_parameters[i].Interp( params[i], t );
+ hasAny = hasAny || hasParam[i];
+ }
+
+ // draw the narrow beam
+ if ( hasParam[GUNSHIPFX_NARROW_BEAM_COLOR] && hasParam[GUNSHIPFX_NARROW_BEAM_SIZE] )
+ {
+ IMaterial *pMat = materials->FindMaterial( "sprites/bluelaser1", TEXTURE_GROUP_CLIENT_EFFECTS );
+ float width = NARROW_BEAM_WIDTH * params[GUNSHIPFX_NARROW_BEAM_SIZE].x;
+ color32 color;
+ float bright = params[GUNSHIPFX_NARROW_BEAM_COLOR].x;
+ ScaleColor( color, white, bright );
+
+ //Gunship_DrawLine( m_beamEndPosition, m_targetPosition, width, pMat, color );
+ FX_DrawLine( m_beamEndPosition, m_targetPosition, width, pMat, color );
+ }
+
+ // glowy blue flare sprite
+ if ( hasParam[GUNSHIPFX_FLARE_COLOR] && hasParam[GUNSHIPFX_FLARE_SIZE] )
+ {
+ IMaterial *pMat = materials->FindMaterial( "effects/blueblackflash", TEXTURE_GROUP_CLIENT_EFFECTS );
+ float size = FLARE_SIZE * params[GUNSHIPFX_FLARE_SIZE].x;
+ color32 color;
+ float bright = params[GUNSHIPFX_FLARE_COLOR].x;
+ ScaleColor( color, white, bright );
+ color.a = (int)(255 * params[GUNSHIPFX_DARKNESS].x);
+ CMatRenderContextPtr pRenderContext( materials );
+ pRenderContext->Bind( pMat, (IClientRenderable*)this );
+ Gunship_DrawSprite( m_worldPosition, size, color, true );
+ }
+
+ if ( hasParam[GUNSHIPFX_AFTERGLOW_COLOR] )
+ {
+ // Muzzle effect
+ dlight_t *dl = effects->CL_AllocDlight( m_entityIndex );
+ dl->origin = m_worldPosition;
+ dl->color.r = 40*params[GUNSHIPFX_AFTERGLOW_COLOR].x;
+ dl->color.g = 60*params[GUNSHIPFX_AFTERGLOW_COLOR].x;
+ dl->color.b = 255*params[GUNSHIPFX_AFTERGLOW_COLOR].x;
+ dl->color.exponent = 5;
+ dl->radius = 128.0f;
+ dl->die = gpGlobals->curtime + 0.001;
+ }
+
+ if ( m_t >= 4.0 && !hasAny )
+ {
+ EffectShutdown();
+ }
+
+ return 1;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pOwner -
+// &targetPos -
+//-----------------------------------------------------------------------------
+void C_GunshipFX::Update( C_BaseEntity *pOwner, const Vector &targetPos )
+{
+ BaseClass::Update();
+
+ m_pOwner = pOwner;
+
+ if ( m_active )
+ {
+ m_targetPosition = targetPos;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Gunship
+//-----------------------------------------------------------------------------
+
+class C_CombineGunship : public C_BaseHelicopter
+{
+ DECLARE_CLASS( C_CombineGunship, C_BaseHelicopter );
+public:
+ DECLARE_CLIENTCLASS();
+
+ C_CombineGunship( void ) {}
+
+ virtual ~C_CombineGunship( void )
+ {
+ m_cannonFX.EffectShutdown();
+ }
+
+ C_GunshipFX m_cannonFX;
+ Vector m_vecHitPos;
+
+ //-----------------------------------------------------------------------------
+ // Purpose:
+ // Input : length -
+ // *data -
+ // Output : void
+ //-----------------------------------------------------------------------------
+ void ReceiveMessage( int classID, bf_read &msg )
+ {
+ if ( classID != GetClientClass()->m_ClassID )
+ {
+ // message is for subclass
+ BaseClass::ReceiveMessage( classID, msg );
+ return;
+ }
+
+ int messageType = msg.ReadByte();
+ switch( messageType )
+ {
+ case GUNSHIP_MSG_STREAKS:
+ {
+ Vector pos;
+ msg.ReadBitVec3Coord( pos );
+ m_cannonFX.SetRenderOrigin( pos );
+ m_cannonFX.EffectInit( entindex(), LookupAttachment( "BellyGun" ) );
+ m_cannonFX.LimitTime( GUNSHIPFX_BIG_SHOT_TIME );
+ }
+ break;
+
+ case GUNSHIP_MSG_BIG_SHOT:
+ {
+ Vector tmp;
+ msg.ReadBitVec3Coord( tmp );
+ m_cannonFX.SetTime( GUNSHIPFX_BIG_SHOT_TIME );
+ m_cannonFX.LimitTime( 0 );
+ }
+ break;
+
+ case GUNSHIP_MSG_DEAD:
+ {
+ m_cannonFX.EffectShutdown();
+ }
+ break;
+ }
+ }
+
+ void OnDataChanged( DataUpdateType_t updateType )
+ {
+ BaseClass::OnDataChanged( updateType );
+
+ m_cannonFX.Update( this, m_vecHitPos );
+ }
+
+ virtual RenderGroup_t GetRenderGroup()
+ {
+ if ( hl2_episodic.GetBool() == true )
+ {
+ return RENDER_GROUP_TWOPASS;
+ }
+ else
+ {
+ return BaseClass::GetRenderGroup();
+ }
+ }
+
+private:
+ C_CombineGunship( const C_CombineGunship & ) {}
+};
+
+IMPLEMENT_CLIENTCLASS_DT( C_CombineGunship, DT_CombineGunship, CNPC_CombineGunship )
+ RecvPropVector(RECVINFO(m_vecHitPos)),
+END_RECV_TABLE()
+
+//-----------------------------------------------------------------------------
+// Purpose: Handle gunship impacts
+//-----------------------------------------------------------------------------
+void ImpactGunshipCallback( 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, 3 );
+ }
+
+ PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
+}
+
+DECLARE_CLIENT_EFFECT( "ImpactGunship", ImpactGunshipCallback );
+
diff --git a/mp/src/game/client/hl2/c_npc_hydra.cpp b/mp/src/game/client/hl2/c_npc_hydra.cpp
index a0cf2b80..271c7752 100644
--- a/mp/src/game/client/hl2/c_npc_hydra.cpp
+++ b/mp/src/game/client/hl2/c_npc_hydra.cpp
@@ -1,386 +1,386 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "bone_setup.h"
-#include "c_ai_basenpc.h"
-#include "engine/ivdebugoverlay.h"
-#include "tier0/vprof.h"
-#include "soundinfo.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-class C_NPC_Hydra : public C_AI_BaseNPC
-{
-public:
- DECLARE_CLASS( C_NPC_Hydra, C_AI_BaseNPC );
- DECLARE_CLIENTCLASS();
- DECLARE_INTERPOLATION();
-
- C_NPC_Hydra();
- virtual ~C_NPC_Hydra();
-
- // model specific
- virtual void OnLatchInterpolatedVariables( int flags );
- virtual bool SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime );
- virtual void StandardBlendingRules( Vector pos[], Quaternion q[], float currentTime, int boneMask );
-
- void CalcBoneChain( Vector pos[], const Vector chain[] );
- void CalcBoneAngles( const Vector pos[], Quaternion q[] );
-
- virtual bool GetSoundSpatialization( SpatializationInfo_t& info );
-
- virtual void ResetLatched();
-
-#define CHAIN_LINKS 32
-
- bool m_bNewChain;
- int m_fLatchFlags;
- Vector m_vecChain[CHAIN_LINKS];
-
- Vector m_vecHeadDir;
- CInterpolatedVar< Vector > m_iv_vecHeadDir;
-
- //Vector m_vecInterpHeadDir;
-
- float m_flRelaxedLength;
-
- Vector *m_vecPos; // current animation
- CInterpolatedVar< Vector > *m_iv_vecPos;
-
- int m_numHydraBones;
- float *m_boneLength;
-
- float m_maxPossibleLength;
-
-private:
- C_NPC_Hydra( const C_NPC_Hydra & ); // not defined, not accessible
-};
-
-IMPLEMENT_CLIENTCLASS_DT(C_NPC_Hydra, DT_NPC_Hydra, CNPC_Hydra)
- RecvPropVector ( RECVINFO( m_vecChain[0] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[1] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[2] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[3] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[4] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[5] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[6] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[7] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[8] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[9] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[10] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[11] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[12] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[13] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[14] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[15] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[16] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[17] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[18] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[19] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[20] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[21] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[22] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[23] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[24] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[25] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[26] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[27] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[28] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[29] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[30] ) ),
- RecvPropVector ( RECVINFO( m_vecChain[31] ) ),
- RecvPropVector ( RECVINFO( m_vecHeadDir ) ),
- RecvPropFloat ( RECVINFO( m_flRelaxedLength ) ),
-END_RECV_TABLE()
-
-C_NPC_Hydra::C_NPC_Hydra() : m_iv_vecHeadDir( "C_NPC_Hydra::m_iv_vecHeadDir" )
-{
- AddVar( &m_vecHeadDir, &m_iv_vecHeadDir, LATCH_ANIMATION_VAR );
-
- m_numHydraBones = 0;
- m_boneLength = NULL;
- m_maxPossibleLength = 1;
- m_vecPos = NULL;
- m_iv_vecPos = NULL;
-}
-
-
-C_NPC_Hydra::~C_NPC_Hydra()
-{
- delete m_boneLength;
- delete m_vecPos;
- delete[] m_iv_vecPos;
- m_iv_vecPos = NULL;
-}
-
-void C_NPC_Hydra::OnLatchInterpolatedVariables( int flags )
-{
- m_bNewChain = true;
- m_fLatchFlags = flags;
-
- BaseClass::OnLatchInterpolatedVariables( flags );
-}
-
-void C_NPC_Hydra::ResetLatched()
-{
- for (int i = 0; i < m_numHydraBones; i++)
- {
- m_iv_vecPos[i].Reset();
- }
-
- BaseClass::ResetLatched();
-}
-
-bool C_NPC_Hydra::SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime )
-{
- return BaseClass::SetupBones( pBoneToWorldOut, nMaxBones, boneMask, currentTime );
-}
-
-
-void C_NPC_Hydra::StandardBlendingRules( Vector pos[], Quaternion q[], float currentTime, int boneMask )
-{
- VPROF( "C_NPC_Hydra::StandardBlendingRules" );
-
- studiohdr_t *hdr = GetModelPtr();
- if ( !hdr )
- {
- return;
- }
-
- int i;
-
- // check for changing model memory requirements
- bool bNewlyInited = false;
- if (m_numHydraBones != hdr->numbones)
- {
- m_numHydraBones = hdr->numbones;
-
- // build root animation
- float poseparam[MAXSTUDIOPOSEPARAM];
- for (i = 0; i < hdr->GetNumPoseParameters(); i++)
- {
- poseparam[i] = 0;
- }
- CalcPose( hdr, NULL, pos, q, 0.0f, 0.0f, poseparam, BONE_USED_BY_ANYTHING );
-
- // allocate arrays
- if (m_boneLength)
- {
- delete[] m_boneLength;
- }
- m_boneLength = new float [m_numHydraBones];
-
- if (m_vecPos)
- {
- delete[] m_vecPos;
- }
- m_vecPos = new Vector [m_numHydraBones];
-
- if (m_iv_vecPos)
- {
- delete m_iv_vecPos;
- }
- m_iv_vecPos = new CInterpolatedVar< Vector >[m_numHydraBones];
- for ( i = 0; i < m_numHydraBones; i++ )
- {
- m_iv_vecPos[ i ].Setup( &m_vecPos[ i ], LATCH_SIMULATION_VAR | EXCLUDE_AUTO_LATCH | EXCLUDE_AUTO_INTERPOLATE );
- }
-
- // calc models bone lengths
- m_maxPossibleLength = 0;
- for (i = 0; i < m_numHydraBones-1; i++)
- {
- m_boneLength[i] = (pos[i+1] - pos[i]).Length();
- m_maxPossibleLength += m_boneLength[i];
- }
- m_boneLength[i] = 0.0f;
-
- bNewlyInited = true;
- }
-
- // calc new bone setup if networked.
- if (m_bNewChain)
- {
- CalcBoneChain( m_vecPos, m_vecChain );
- for (i = 0; i < m_numHydraBones; i++)
- {
- // debugoverlay->AddLineOverlay( m_vecPos[i], m_vecPos[i<m_numHydraBones-1?i+1:m_numHydraBones-1], 0, 255, 0, false, 0.1 );
- m_vecPos[i] = m_vecPos[i] - GetAbsOrigin();
-
- if ( m_fLatchFlags & LATCH_SIMULATION_VAR )
- {
- m_iv_vecPos[i].NoteChanged( currentTime, true );
- }
- }
- m_bNewChain = false;
- }
-
- // if just allocated, initialize bones
- if (bNewlyInited)
- {
-
- for (i = 0; i < m_numHydraBones; i++)
- {
- m_iv_vecPos[i].Reset();
- }
- }
-
- for (i = 0; i < m_numHydraBones; i++)
- {
- m_iv_vecPos[i].Interpolate( currentTime );
- pos[ i ] = m_vecPos[ i ];
- }
-
- // calculate bone angles
- CalcBoneAngles( pos, q );
-
- // rotate the last bone of the hydra 90 degrees since it's oriented differently than the others
- Quaternion qTmp;
- AngleQuaternion( QAngle( 0, -90, 0) , qTmp );
- QuaternionMult( q[m_numHydraBones - 1], qTmp, q[m_numHydraBones - 1] );
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Fits skeleton of hydra to the variable segment length "chain" array
-// Adjusts overall hydra so that "m_flRelaxedLength" of texture fits over
-// the actual length of the chain
-//-----------------------------------------------------------------------------
-
-void C_NPC_Hydra::CalcBoneChain( Vector pos[], const Vector chain[] )
-{
- int i, j;
-
- // Find the dist chain link that's not zero length
- i = CHAIN_LINKS-1;
- while (i > 0)
- {
- if ((chain[i] - chain[i-1]).LengthSqr() > 0.0)
- {
- break;
- }
- i--;
- }
-
- // initialize the last bone to the last bone
- j = m_numHydraBones - 1;
-
- // clamp length
- float totalLength = 0;
- for (int k = i; k > 0; k--)
- {
- // debugoverlay->AddLineOverlay( chain[k], chain[k-1], 255, 255, 255, false, 0 );
- totalLength += (chain[k] - chain[k-1]).Length();
- }
- totalLength = clamp( totalLength, 1.0, m_maxPossibleLength );
- float scale = m_flRelaxedLength / totalLength;
-
- // starting from the head, fit the hydra skeleton onto the chain spline
- float dist = -16;
- while (j >= 0 && i > 0)
- {
- // debugoverlay->AddLineOverlay( chain[i], chain[i-1], 255, 255, 255, false, 0 );
- float dt = (chain[i] - chain[i-1]).Length() * scale;
- float dx = dt;
- while (j >= 0 && dist + dt >= m_boneLength[j])
- {
- float s = (dx - (dt - (m_boneLength[j] - dist))) / dx;
-
- if (s < 0 || s > 1.)
- s = 0;
- // pos[j] = chain[i] * (1 - s) + chain[i-1] * s;
- Catmull_Rom_Spline( chain[(i<CHAIN_LINKS-1)?i+1:CHAIN_LINKS-1], chain[i], chain[(i>0)?i-1:0], chain[(i>1)?i-2:0], s, pos[j] );
- // debugoverlay->AddLineOverlay( pos[j], chain[i], 0, 255, 0, false, 0 );
- // debugoverlay->AddLineOverlay( pos[j], chain[i-1], 0, 255, 0, false, 0 );
-
- dt = dt - (m_boneLength[j] - dist);
- j--;
- dist = 0;
- }
- dist += dt;
- i--;
- }
-
- while (j >= 0)
- {
- pos[j] = chain[0];
- j--;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Minimize the amount of twist between bone segments
-//-----------------------------------------------------------------------------
-
-void C_NPC_Hydra::CalcBoneAngles( const Vector pos[], Quaternion q[] )
-{
- int i;
- matrix3x4_t bonematrix;
-
- for (i = m_numHydraBones - 1; i >= 0; i--)
- {
- Vector forward;
- Vector left2;
-
- if (i != m_numHydraBones - 1)
- {
- QuaternionMatrix( q[i+1], bonematrix );
- MatrixGetColumn( bonematrix, 1, left2 );
-
- forward = (pos[i+1] - pos[i]) /* + (pos[i] - pos[i-1])*/;
- float length = VectorNormalize( forward );
- if (length == 0.0)
- {
- q[i] = q[i+1];
- continue;
- }
- }
- else
- {
- forward = m_vecHeadDir;
- VectorNormalize( forward );
-
- VectorMatrix( forward, bonematrix );
- MatrixGetColumn( bonematrix, 1, left2 );
- }
-
- Vector up = CrossProduct( forward, left2 );
- VectorNormalize( up );
-
- Vector left = CrossProduct( up, forward );
-
- MatrixSetColumn( forward, 0, bonematrix );
- MatrixSetColumn( left, 1, bonematrix );
- MatrixSetColumn( up, 2, bonematrix );
-
- // MatrixQuaternion( bonematrix, q[i] );
- QAngle angles;
- MatrixAngles( bonematrix, angles );
- AngleQuaternion( angles, q[i] );
- }
-}
-
-bool C_NPC_Hydra::GetSoundSpatialization( SpatializationInfo_t& info )
-{
- bool bret = BaseClass::GetSoundSpatialization( info );
- // Default things it's audible, put it at a better spot?
- if ( bret )
- {
- // TODO: Note, this is where you could override the sound position and orientation and use
- // an attachment points position as the sound source
- // You might have to issue C_BaseAnimating::AllowBoneAccess( true, false ); to allow
- // bone setup during sound spatialization if you run into asserts...
- }
-
- return bret;
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "bone_setup.h"
+#include "c_ai_basenpc.h"
+#include "engine/ivdebugoverlay.h"
+#include "tier0/vprof.h"
+#include "soundinfo.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class C_NPC_Hydra : public C_AI_BaseNPC
+{
+public:
+ DECLARE_CLASS( C_NPC_Hydra, C_AI_BaseNPC );
+ DECLARE_CLIENTCLASS();
+ DECLARE_INTERPOLATION();
+
+ C_NPC_Hydra();
+ virtual ~C_NPC_Hydra();
+
+ // model specific
+ virtual void OnLatchInterpolatedVariables( int flags );
+ virtual bool SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime );
+ virtual void StandardBlendingRules( Vector pos[], Quaternion q[], float currentTime, int boneMask );
+
+ void CalcBoneChain( Vector pos[], const Vector chain[] );
+ void CalcBoneAngles( const Vector pos[], Quaternion q[] );
+
+ virtual bool GetSoundSpatialization( SpatializationInfo_t& info );
+
+ virtual void ResetLatched();
+
+#define CHAIN_LINKS 32
+
+ bool m_bNewChain;
+ int m_fLatchFlags;
+ Vector m_vecChain[CHAIN_LINKS];
+
+ Vector m_vecHeadDir;
+ CInterpolatedVar< Vector > m_iv_vecHeadDir;
+
+ //Vector m_vecInterpHeadDir;
+
+ float m_flRelaxedLength;
+
+ Vector *m_vecPos; // current animation
+ CInterpolatedVar< Vector > *m_iv_vecPos;
+
+ int m_numHydraBones;
+ float *m_boneLength;
+
+ float m_maxPossibleLength;
+
+private:
+ C_NPC_Hydra( const C_NPC_Hydra & ); // not defined, not accessible
+};
+
+IMPLEMENT_CLIENTCLASS_DT(C_NPC_Hydra, DT_NPC_Hydra, CNPC_Hydra)
+ RecvPropVector ( RECVINFO( m_vecChain[0] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[1] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[2] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[3] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[4] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[5] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[6] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[7] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[8] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[9] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[10] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[11] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[12] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[13] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[14] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[15] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[16] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[17] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[18] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[19] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[20] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[21] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[22] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[23] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[24] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[25] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[26] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[27] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[28] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[29] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[30] ) ),
+ RecvPropVector ( RECVINFO( m_vecChain[31] ) ),
+ RecvPropVector ( RECVINFO( m_vecHeadDir ) ),
+ RecvPropFloat ( RECVINFO( m_flRelaxedLength ) ),
+END_RECV_TABLE()
+
+C_NPC_Hydra::C_NPC_Hydra() : m_iv_vecHeadDir( "C_NPC_Hydra::m_iv_vecHeadDir" )
+{
+ AddVar( &m_vecHeadDir, &m_iv_vecHeadDir, LATCH_ANIMATION_VAR );
+
+ m_numHydraBones = 0;
+ m_boneLength = NULL;
+ m_maxPossibleLength = 1;
+ m_vecPos = NULL;
+ m_iv_vecPos = NULL;
+}
+
+
+C_NPC_Hydra::~C_NPC_Hydra()
+{
+ delete m_boneLength;
+ delete m_vecPos;
+ delete[] m_iv_vecPos;
+ m_iv_vecPos = NULL;
+}
+
+void C_NPC_Hydra::OnLatchInterpolatedVariables( int flags )
+{
+ m_bNewChain = true;
+ m_fLatchFlags = flags;
+
+ BaseClass::OnLatchInterpolatedVariables( flags );
+}
+
+void C_NPC_Hydra::ResetLatched()
+{
+ for (int i = 0; i < m_numHydraBones; i++)
+ {
+ m_iv_vecPos[i].Reset();
+ }
+
+ BaseClass::ResetLatched();
+}
+
+bool C_NPC_Hydra::SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime )
+{
+ return BaseClass::SetupBones( pBoneToWorldOut, nMaxBones, boneMask, currentTime );
+}
+
+
+void C_NPC_Hydra::StandardBlendingRules( Vector pos[], Quaternion q[], float currentTime, int boneMask )
+{
+ VPROF( "C_NPC_Hydra::StandardBlendingRules" );
+
+ studiohdr_t *hdr = GetModelPtr();
+ if ( !hdr )
+ {
+ return;
+ }
+
+ int i;
+
+ // check for changing model memory requirements
+ bool bNewlyInited = false;
+ if (m_numHydraBones != hdr->numbones)
+ {
+ m_numHydraBones = hdr->numbones;
+
+ // build root animation
+ float poseparam[MAXSTUDIOPOSEPARAM];
+ for (i = 0; i < hdr->GetNumPoseParameters(); i++)
+ {
+ poseparam[i] = 0;
+ }
+ CalcPose( hdr, NULL, pos, q, 0.0f, 0.0f, poseparam, BONE_USED_BY_ANYTHING );
+
+ // allocate arrays
+ if (m_boneLength)
+ {
+ delete[] m_boneLength;
+ }
+ m_boneLength = new float [m_numHydraBones];
+
+ if (m_vecPos)
+ {
+ delete[] m_vecPos;
+ }
+ m_vecPos = new Vector [m_numHydraBones];
+
+ if (m_iv_vecPos)
+ {
+ delete m_iv_vecPos;
+ }
+ m_iv_vecPos = new CInterpolatedVar< Vector >[m_numHydraBones];
+ for ( i = 0; i < m_numHydraBones; i++ )
+ {
+ m_iv_vecPos[ i ].Setup( &m_vecPos[ i ], LATCH_SIMULATION_VAR | EXCLUDE_AUTO_LATCH | EXCLUDE_AUTO_INTERPOLATE );
+ }
+
+ // calc models bone lengths
+ m_maxPossibleLength = 0;
+ for (i = 0; i < m_numHydraBones-1; i++)
+ {
+ m_boneLength[i] = (pos[i+1] - pos[i]).Length();
+ m_maxPossibleLength += m_boneLength[i];
+ }
+ m_boneLength[i] = 0.0f;
+
+ bNewlyInited = true;
+ }
+
+ // calc new bone setup if networked.
+ if (m_bNewChain)
+ {
+ CalcBoneChain( m_vecPos, m_vecChain );
+ for (i = 0; i < m_numHydraBones; i++)
+ {
+ // debugoverlay->AddLineOverlay( m_vecPos[i], m_vecPos[i<m_numHydraBones-1?i+1:m_numHydraBones-1], 0, 255, 0, false, 0.1 );
+ m_vecPos[i] = m_vecPos[i] - GetAbsOrigin();
+
+ if ( m_fLatchFlags & LATCH_SIMULATION_VAR )
+ {
+ m_iv_vecPos[i].NoteChanged( currentTime, true );
+ }
+ }
+ m_bNewChain = false;
+ }
+
+ // if just allocated, initialize bones
+ if (bNewlyInited)
+ {
+
+ for (i = 0; i < m_numHydraBones; i++)
+ {
+ m_iv_vecPos[i].Reset();
+ }
+ }
+
+ for (i = 0; i < m_numHydraBones; i++)
+ {
+ m_iv_vecPos[i].Interpolate( currentTime );
+ pos[ i ] = m_vecPos[ i ];
+ }
+
+ // calculate bone angles
+ CalcBoneAngles( pos, q );
+
+ // rotate the last bone of the hydra 90 degrees since it's oriented differently than the others
+ Quaternion qTmp;
+ AngleQuaternion( QAngle( 0, -90, 0) , qTmp );
+ QuaternionMult( q[m_numHydraBones - 1], qTmp, q[m_numHydraBones - 1] );
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Fits skeleton of hydra to the variable segment length "chain" array
+// Adjusts overall hydra so that "m_flRelaxedLength" of texture fits over
+// the actual length of the chain
+//-----------------------------------------------------------------------------
+
+void C_NPC_Hydra::CalcBoneChain( Vector pos[], const Vector chain[] )
+{
+ int i, j;
+
+ // Find the dist chain link that's not zero length
+ i = CHAIN_LINKS-1;
+ while (i > 0)
+ {
+ if ((chain[i] - chain[i-1]).LengthSqr() > 0.0)
+ {
+ break;
+ }
+ i--;
+ }
+
+ // initialize the last bone to the last bone
+ j = m_numHydraBones - 1;
+
+ // clamp length
+ float totalLength = 0;
+ for (int k = i; k > 0; k--)
+ {
+ // debugoverlay->AddLineOverlay( chain[k], chain[k-1], 255, 255, 255, false, 0 );
+ totalLength += (chain[k] - chain[k-1]).Length();
+ }
+ totalLength = clamp( totalLength, 1.0, m_maxPossibleLength );
+ float scale = m_flRelaxedLength / totalLength;
+
+ // starting from the head, fit the hydra skeleton onto the chain spline
+ float dist = -16;
+ while (j >= 0 && i > 0)
+ {
+ // debugoverlay->AddLineOverlay( chain[i], chain[i-1], 255, 255, 255, false, 0 );
+ float dt = (chain[i] - chain[i-1]).Length() * scale;
+ float dx = dt;
+ while (j >= 0 && dist + dt >= m_boneLength[j])
+ {
+ float s = (dx - (dt - (m_boneLength[j] - dist))) / dx;
+
+ if (s < 0 || s > 1.)
+ s = 0;
+ // pos[j] = chain[i] * (1 - s) + chain[i-1] * s;
+ Catmull_Rom_Spline( chain[(i<CHAIN_LINKS-1)?i+1:CHAIN_LINKS-1], chain[i], chain[(i>0)?i-1:0], chain[(i>1)?i-2:0], s, pos[j] );
+ // debugoverlay->AddLineOverlay( pos[j], chain[i], 0, 255, 0, false, 0 );
+ // debugoverlay->AddLineOverlay( pos[j], chain[i-1], 0, 255, 0, false, 0 );
+
+ dt = dt - (m_boneLength[j] - dist);
+ j--;
+ dist = 0;
+ }
+ dist += dt;
+ i--;
+ }
+
+ while (j >= 0)
+ {
+ pos[j] = chain[0];
+ j--;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Minimize the amount of twist between bone segments
+//-----------------------------------------------------------------------------
+
+void C_NPC_Hydra::CalcBoneAngles( const Vector pos[], Quaternion q[] )
+{
+ int i;
+ matrix3x4_t bonematrix;
+
+ for (i = m_numHydraBones - 1; i >= 0; i--)
+ {
+ Vector forward;
+ Vector left2;
+
+ if (i != m_numHydraBones - 1)
+ {
+ QuaternionMatrix( q[i+1], bonematrix );
+ MatrixGetColumn( bonematrix, 1, left2 );
+
+ forward = (pos[i+1] - pos[i]) /* + (pos[i] - pos[i-1])*/;
+ float length = VectorNormalize( forward );
+ if (length == 0.0)
+ {
+ q[i] = q[i+1];
+ continue;
+ }
+ }
+ else
+ {
+ forward = m_vecHeadDir;
+ VectorNormalize( forward );
+
+ VectorMatrix( forward, bonematrix );
+ MatrixGetColumn( bonematrix, 1, left2 );
+ }
+
+ Vector up = CrossProduct( forward, left2 );
+ VectorNormalize( up );
+
+ Vector left = CrossProduct( up, forward );
+
+ MatrixSetColumn( forward, 0, bonematrix );
+ MatrixSetColumn( left, 1, bonematrix );
+ MatrixSetColumn( up, 2, bonematrix );
+
+ // MatrixQuaternion( bonematrix, q[i] );
+ QAngle angles;
+ MatrixAngles( bonematrix, angles );
+ AngleQuaternion( angles, q[i] );
+ }
+}
+
+bool C_NPC_Hydra::GetSoundSpatialization( SpatializationInfo_t& info )
+{
+ bool bret = BaseClass::GetSoundSpatialization( info );
+ // Default things it's audible, put it at a better spot?
+ if ( bret )
+ {
+ // TODO: Note, this is where you could override the sound position and orientation and use
+ // an attachment points position as the sound source
+ // You might have to issue C_BaseAnimating::AllowBoneAccess( true, false ); to allow
+ // bone setup during sound spatialization if you run into asserts...
+ }
+
+ return bret;
+}
+
diff --git a/mp/src/game/client/hl2/c_npc_manhack.cpp b/mp/src/game/client/hl2/c_npc_manhack.cpp
index a6679412..a804fcff 100644
--- a/mp/src/game/client/hl2/c_npc_manhack.cpp
+++ b/mp/src/game/client/hl2/c_npc_manhack.cpp
@@ -1,182 +1,182 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#include "cbase.h"
-#include "c_ai_basenpc.h"
-#include "soundenvelope.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-class C_NPC_Manhack : public C_AI_BaseNPC
-{
-public:
- C_NPC_Manhack() {}
-
- DECLARE_CLASS( C_NPC_Manhack, C_AI_BaseNPC );
- DECLARE_CLIENTCLASS();
- DECLARE_DATADESC();
-
- // Purpose: Start the manhack's engine sound.
- virtual void OnDataChanged( DataUpdateType_t type );
- virtual void UpdateOnRemove( void );
- virtual void OnRestore();
-
-private:
- C_NPC_Manhack( const C_NPC_Manhack & );
-
- // Purpose: Start + stop the manhack's engine sound.
- void SoundInit( void );
- void SoundShutdown( void );
-
- CSoundPatch *m_pEngineSound1;
- CSoundPatch *m_pEngineSound2;
- CSoundPatch *m_pBladeSound;
-
- int m_nEnginePitch1;
- int m_nEnginePitch2;
- float m_flEnginePitch1Time;
- float m_flEnginePitch2Time;
-};
-
-
-//-----------------------------------------------------------------------------
-// Save/restore
-//-----------------------------------------------------------------------------
-BEGIN_DATADESC( C_NPC_Manhack )
-
-// DEFINE_SOUNDPATCH( m_pEngineSound1 ),
-// DEFINE_SOUNDPATCH( m_pEngineSound2 ),
-// DEFINE_SOUNDPATCH( m_pBladeSound ),
-
-// DEFINE_FIELD( m_nEnginePitch1, FIELD_INTEGER ),
-// DEFINE_FIELD( m_nEnginePitch2, FIELD_INTEGER ),
-// DEFINE_FIELD( m_flEnginePitch1Time, FIELD_FLOAT ),
-// DEFINE_FIELD( m_flEnginePitch2Time, FIELD_FLOAT ),
-
-END_DATADESC()
-
-
-//-----------------------------------------------------------------------------
-// Networking
-//-----------------------------------------------------------------------------
-IMPLEMENT_CLIENTCLASS_DT(C_NPC_Manhack, DT_NPC_Manhack, CNPC_Manhack)
- RecvPropIntWithMinusOneFlag(RECVINFO(m_nEnginePitch1)),
- RecvPropFloat(RECVINFO(m_flEnginePitch1Time)),
- RecvPropIntWithMinusOneFlag(RECVINFO(m_nEnginePitch2)),
- RecvPropFloat(RECVINFO(m_flEnginePitch2Time)),
-END_RECV_TABLE()
-
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Start the manhack's engine sound.
-//-----------------------------------------------------------------------------
-void C_NPC_Manhack::OnDataChanged( DataUpdateType_t type )
-{
- BaseClass::OnDataChanged( type );
-
- if (( m_nEnginePitch1 < 0 ) || ( m_nEnginePitch2 < 0 ) )
- {
- SoundShutdown();
- }
- else
- {
- SoundInit();
- if ( m_pEngineSound1 && m_pEngineSound2 )
- {
- float dt = ( m_flEnginePitch1Time >= gpGlobals->curtime ) ? m_flEnginePitch1Time - gpGlobals->curtime : 0.0f;
- CSoundEnvelopeController::GetController().SoundChangePitch( m_pEngineSound1, m_nEnginePitch1, dt );
- dt = ( m_flEnginePitch2Time >= gpGlobals->curtime ) ? m_flEnginePitch2Time - gpGlobals->curtime : 0.0f;
- CSoundEnvelopeController::GetController().SoundChangePitch( m_pEngineSound2, m_nEnginePitch2, dt );
- }
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Restore
-//-----------------------------------------------------------------------------
-void C_NPC_Manhack::OnRestore()
-{
- BaseClass::OnRestore();
- SoundInit();
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Start the manhack's engine sound.
-//-----------------------------------------------------------------------------
-void C_NPC_Manhack::UpdateOnRemove( void )
-{
- BaseClass::UpdateOnRemove();
- SoundShutdown();
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Start the manhack's engine sound.
-//-----------------------------------------------------------------------------
-void C_NPC_Manhack::SoundInit( void )
-{
- if (( m_nEnginePitch1 < 0 ) || ( m_nEnginePitch2 < 0 ) )
- return;
-
- // play an engine start sound!!
- CPASAttenuationFilter filter( this );
-
- // Bring up the engine looping sound.
- if( !m_pEngineSound1 )
- {
- m_pEngineSound1 = CSoundEnvelopeController::GetController().SoundCreate( filter, entindex(), "NPC_Manhack.EngineSound1" );
- CSoundEnvelopeController::GetController().Play( m_pEngineSound1, 0.0, m_nEnginePitch1 );
- CSoundEnvelopeController::GetController().SoundChangeVolume( m_pEngineSound1, 0.7, 2.0 );
- }
-
- if( !m_pEngineSound2 )
- {
- m_pEngineSound2 = CSoundEnvelopeController::GetController().SoundCreate( filter, entindex(), "NPC_Manhack.EngineSound2" );
- CSoundEnvelopeController::GetController().Play( m_pEngineSound2, 0.0, m_nEnginePitch2 );
- CSoundEnvelopeController::GetController().SoundChangeVolume( m_pEngineSound2, 0.7, 2.0 );
- }
-
- if( !m_pBladeSound )
- {
- m_pBladeSound = CSoundEnvelopeController::GetController().SoundCreate( filter, entindex(), "NPC_Manhack.BladeSound" );
- CSoundEnvelopeController::GetController().Play( m_pBladeSound, 0.0, m_nEnginePitch1 );
- CSoundEnvelopeController::GetController().SoundChangeVolume( m_pBladeSound, 0.7, 2.0 );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_NPC_Manhack::SoundShutdown(void)
-{
- // Kill the engine!
- if ( m_pEngineSound1 )
- {
- CSoundEnvelopeController::GetController().SoundDestroy( m_pEngineSound1 );
- m_pEngineSound1 = NULL;
- }
-
- // Kill the engine!
- if ( m_pEngineSound2 )
- {
- CSoundEnvelopeController::GetController().SoundDestroy( m_pEngineSound2 );
- m_pEngineSound2 = NULL;
- }
-
- // Kill the blade!
- if ( m_pBladeSound )
- {
- CSoundEnvelopeController::GetController().SoundDestroy( m_pBladeSound );
- m_pBladeSound = NULL;
- }
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "c_ai_basenpc.h"
+#include "soundenvelope.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+class C_NPC_Manhack : public C_AI_BaseNPC
+{
+public:
+ C_NPC_Manhack() {}
+
+ DECLARE_CLASS( C_NPC_Manhack, C_AI_BaseNPC );
+ DECLARE_CLIENTCLASS();
+ DECLARE_DATADESC();
+
+ // Purpose: Start the manhack's engine sound.
+ virtual void OnDataChanged( DataUpdateType_t type );
+ virtual void UpdateOnRemove( void );
+ virtual void OnRestore();
+
+private:
+ C_NPC_Manhack( const C_NPC_Manhack & );
+
+ // Purpose: Start + stop the manhack's engine sound.
+ void SoundInit( void );
+ void SoundShutdown( void );
+
+ CSoundPatch *m_pEngineSound1;
+ CSoundPatch *m_pEngineSound2;
+ CSoundPatch *m_pBladeSound;
+
+ int m_nEnginePitch1;
+ int m_nEnginePitch2;
+ float m_flEnginePitch1Time;
+ float m_flEnginePitch2Time;
+};
+
+
+//-----------------------------------------------------------------------------
+// Save/restore
+//-----------------------------------------------------------------------------
+BEGIN_DATADESC( C_NPC_Manhack )
+
+// DEFINE_SOUNDPATCH( m_pEngineSound1 ),
+// DEFINE_SOUNDPATCH( m_pEngineSound2 ),
+// DEFINE_SOUNDPATCH( m_pBladeSound ),
+
+// DEFINE_FIELD( m_nEnginePitch1, FIELD_INTEGER ),
+// DEFINE_FIELD( m_nEnginePitch2, FIELD_INTEGER ),
+// DEFINE_FIELD( m_flEnginePitch1Time, FIELD_FLOAT ),
+// DEFINE_FIELD( m_flEnginePitch2Time, FIELD_FLOAT ),
+
+END_DATADESC()
+
+
+//-----------------------------------------------------------------------------
+// Networking
+//-----------------------------------------------------------------------------
+IMPLEMENT_CLIENTCLASS_DT(C_NPC_Manhack, DT_NPC_Manhack, CNPC_Manhack)
+ RecvPropIntWithMinusOneFlag(RECVINFO(m_nEnginePitch1)),
+ RecvPropFloat(RECVINFO(m_flEnginePitch1Time)),
+ RecvPropIntWithMinusOneFlag(RECVINFO(m_nEnginePitch2)),
+ RecvPropFloat(RECVINFO(m_flEnginePitch2Time)),
+END_RECV_TABLE()
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Start the manhack's engine sound.
+//-----------------------------------------------------------------------------
+void C_NPC_Manhack::OnDataChanged( DataUpdateType_t type )
+{
+ BaseClass::OnDataChanged( type );
+
+ if (( m_nEnginePitch1 < 0 ) || ( m_nEnginePitch2 < 0 ) )
+ {
+ SoundShutdown();
+ }
+ else
+ {
+ SoundInit();
+ if ( m_pEngineSound1 && m_pEngineSound2 )
+ {
+ float dt = ( m_flEnginePitch1Time >= gpGlobals->curtime ) ? m_flEnginePitch1Time - gpGlobals->curtime : 0.0f;
+ CSoundEnvelopeController::GetController().SoundChangePitch( m_pEngineSound1, m_nEnginePitch1, dt );
+ dt = ( m_flEnginePitch2Time >= gpGlobals->curtime ) ? m_flEnginePitch2Time - gpGlobals->curtime : 0.0f;
+ CSoundEnvelopeController::GetController().SoundChangePitch( m_pEngineSound2, m_nEnginePitch2, dt );
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Restore
+//-----------------------------------------------------------------------------
+void C_NPC_Manhack::OnRestore()
+{
+ BaseClass::OnRestore();
+ SoundInit();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Start the manhack's engine sound.
+//-----------------------------------------------------------------------------
+void C_NPC_Manhack::UpdateOnRemove( void )
+{
+ BaseClass::UpdateOnRemove();
+ SoundShutdown();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Start the manhack's engine sound.
+//-----------------------------------------------------------------------------
+void C_NPC_Manhack::SoundInit( void )
+{
+ if (( m_nEnginePitch1 < 0 ) || ( m_nEnginePitch2 < 0 ) )
+ return;
+
+ // play an engine start sound!!
+ CPASAttenuationFilter filter( this );
+
+ // Bring up the engine looping sound.
+ if( !m_pEngineSound1 )
+ {
+ m_pEngineSound1 = CSoundEnvelopeController::GetController().SoundCreate( filter, entindex(), "NPC_Manhack.EngineSound1" );
+ CSoundEnvelopeController::GetController().Play( m_pEngineSound1, 0.0, m_nEnginePitch1 );
+ CSoundEnvelopeController::GetController().SoundChangeVolume( m_pEngineSound1, 0.7, 2.0 );
+ }
+
+ if( !m_pEngineSound2 )
+ {
+ m_pEngineSound2 = CSoundEnvelopeController::GetController().SoundCreate( filter, entindex(), "NPC_Manhack.EngineSound2" );
+ CSoundEnvelopeController::GetController().Play( m_pEngineSound2, 0.0, m_nEnginePitch2 );
+ CSoundEnvelopeController::GetController().SoundChangeVolume( m_pEngineSound2, 0.7, 2.0 );
+ }
+
+ if( !m_pBladeSound )
+ {
+ m_pBladeSound = CSoundEnvelopeController::GetController().SoundCreate( filter, entindex(), "NPC_Manhack.BladeSound" );
+ CSoundEnvelopeController::GetController().Play( m_pBladeSound, 0.0, m_nEnginePitch1 );
+ CSoundEnvelopeController::GetController().SoundChangeVolume( m_pBladeSound, 0.7, 2.0 );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_NPC_Manhack::SoundShutdown(void)
+{
+ // Kill the engine!
+ if ( m_pEngineSound1 )
+ {
+ CSoundEnvelopeController::GetController().SoundDestroy( m_pEngineSound1 );
+ m_pEngineSound1 = NULL;
+ }
+
+ // Kill the engine!
+ if ( m_pEngineSound2 )
+ {
+ CSoundEnvelopeController::GetController().SoundDestroy( m_pEngineSound2 );
+ m_pEngineSound2 = NULL;
+ }
+
+ // Kill the blade!
+ if ( m_pBladeSound )
+ {
+ CSoundEnvelopeController::GetController().SoundDestroy( m_pBladeSound );
+ m_pBladeSound = NULL;
+ }
+}
+
diff --git a/mp/src/game/client/hl2/c_npc_rollermine.cpp b/mp/src/game/client/hl2/c_npc_rollermine.cpp
index bf91c1ce..a8b7ed0f 100644
--- a/mp/src/game/client/hl2/c_npc_rollermine.cpp
+++ b/mp/src/game/client/hl2/c_npc_rollermine.cpp
@@ -1,174 +1,174 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "c_ai_basenpc.h"
-#include "iviewrender_beams.h"
-#include "beam_shared.h"
-#include "materialsystem/imaterial.h"
-#include "model_types.h"
-#include "clienteffectprecachesystem.h"
-#include "beamdraw.h"
-
-class C_RollerMine : public C_AI_BaseNPC
-{
- DECLARE_CLASS( C_RollerMine, C_AI_BaseNPC );
-public:
- DECLARE_CLIENTCLASS();
-
- C_RollerMine( void ) {}
-
- int DrawModel( int flags );
-
- RenderGroup_t GetRenderGroup( void )
- {
- if ( m_bIsOpen )
- return RENDER_GROUP_TRANSLUCENT_ENTITY;
- else
- return RENDER_GROUP_OPAQUE_ENTITY;
- }
-
-private:
- C_RollerMine( const C_RollerMine & ) {}
-
- bool m_bIsOpen;
- float m_flActiveTime;
- bool m_bHackedByAlyx;
- bool m_bPowerDown;
-};
-
-IMPLEMENT_CLIENTCLASS_DT( C_RollerMine, DT_RollerMine, CNPC_RollerMine )
- RecvPropInt( RECVINFO( m_bIsOpen ) ),
- RecvPropFloat( RECVINFO( m_flActiveTime ) ),
- RecvPropInt( RECVINFO( m_bHackedByAlyx ) ),
- RecvPropInt( RECVINFO( m_bPowerDown ) ),
-END_RECV_TABLE()
-
-#define NUM_ATTACHMENTS 11
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : flags -
-// Output : int
-//-----------------------------------------------------------------------------
-int C_RollerMine::DrawModel( int flags )
-{
- if ( m_bIsOpen && m_flActiveTime <= gpGlobals->curtime )
- {
- float scale = random->RandomFloat( 4.0f, 6.0f );
-
- if ( gpGlobals->frametime != 0 )
- {
- // Inner beams
- BeamInfo_t beamInfo;
-
- beamInfo.m_vecStart = GetAbsOrigin();
- Vector offset = RandomVector( -6*scale, 2*scale );
-
- offset += Vector(2,2,2) * scale;
- beamInfo.m_vecEnd = GetAbsOrigin() + offset;
-
- beamInfo.m_pStartEnt= cl_entitylist->GetEnt( BEAMENT_ENTITY( entindex() ) );
- beamInfo.m_pEndEnt = beamInfo.m_pStartEnt;
- beamInfo.m_nStartAttachment = random->RandomInt( 0, NUM_ATTACHMENTS );
- beamInfo.m_nEndAttachment = random->RandomInt( 0, NUM_ATTACHMENTS );
-
- // Ensure we're not the same point
- if ( beamInfo.m_nStartAttachment == beamInfo.m_nEndAttachment )
- {
- int nextStep = ( random->RandomInt( 0, 1 ) ) ? 1 : -1;
-
- beamInfo.m_nEndAttachment = ( beamInfo.m_nStartAttachment + nextStep ) % NUM_ATTACHMENTS;
- }
-
- beamInfo.m_nType = TE_BEAMTESLA;
- beamInfo.m_pszModelName = "sprites/lgtning.vmt";
- beamInfo.m_flHaloScale = 0.0f;
- beamInfo.m_flLife = 0.1f;
- beamInfo.m_flWidth = random->RandomFloat( 2.0f, 4.0f );
- beamInfo.m_flEndWidth = random->RandomFloat( 0.0f, 1.0f );
- beamInfo.m_flFadeLength = 0.0f;
- beamInfo.m_flAmplitude = random->RandomFloat( 16, 32 );
- beamInfo.m_flBrightness = 255.0;
- beamInfo.m_flSpeed = 0.0;
- beamInfo.m_nStartFrame = 0.0;
- beamInfo.m_flFrameRate = 1.0f;
-
- if ( m_bPowerDown )
- {
- beamInfo.m_flRed = 255.0f;;
- beamInfo.m_flGreen = 64.0f;
- beamInfo.m_flBlue = 64.0f;
- }
- else if ( m_bHackedByAlyx )
- {
- beamInfo.m_flRed = 240.0f;;
- beamInfo.m_flGreen = 200.0f;
- beamInfo.m_flBlue = 80.0f;
- }
- else
- {
- beamInfo.m_flRed = 255.0f;;
- beamInfo.m_flGreen = 255.0f;
- beamInfo.m_flBlue = 255.0f;
- }
-
- beamInfo.m_nSegments = 4;
- beamInfo.m_bRenderable = true;
- beamInfo.m_nFlags = 0;
-
- beams->CreateBeamEntPoint( beamInfo );
-
- // Draw the halo
- float color[3];
-
- if ( m_bHackedByAlyx )
- {
- color[0] = 0.25f;
- color[1] = 0.05f;
- color[2] = 0.0f;
- }
- else
- {
- color[0] = color[1] = color[2] = 0.15f;
- }
-
- IMaterial *pMaterial = materials->FindMaterial( "effects/rollerglow", NULL, false );
-
- CMatRenderContextPtr pRenderContext( materials );
- pRenderContext->Bind( pMaterial );
- DrawHalo( pMaterial, GetAbsOrigin(), random->RandomFloat( 6.0f*scale, 6.5f*scale ), color );
-
- if ( m_bPowerDown )
- {
- color[0] = random->RandomFloat( 0.80f, 1.00f );
- color[1] = random->RandomFloat( 0.10f, 0.25f );
- color[2] = 0.0f;
- }
- else if ( m_bHackedByAlyx )
- {
- color[0] = random->RandomFloat( 0.25f, 0.75f );
- color[1] = random->RandomFloat( 0.10f, 0.25f );
- color[2] = 0.0f;
- }
- else
- {
- color[0] = color[1] = color[2] = random->RandomFloat( 0.25f, 0.5f );
- }
-
- Vector attachOrigin;
- QAngle attachAngles;
-
- GetAttachment( beamInfo.m_nEndAttachment, attachOrigin, attachAngles );
- DrawHalo( pMaterial, attachOrigin, random->RandomFloat( 1.0f*scale, 1.5f*scale ), color );
-
- GetAttachment( beamInfo.m_nStartAttachment, attachOrigin, attachAngles );
- DrawHalo( pMaterial, attachOrigin, random->RandomFloat( 1.0f*scale, 1.5f*scale ), color );
- }
- }
-
- return BaseClass::DrawModel( flags );
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "c_ai_basenpc.h"
+#include "iviewrender_beams.h"
+#include "beam_shared.h"
+#include "materialsystem/imaterial.h"
+#include "model_types.h"
+#include "clienteffectprecachesystem.h"
+#include "beamdraw.h"
+
+class C_RollerMine : public C_AI_BaseNPC
+{
+ DECLARE_CLASS( C_RollerMine, C_AI_BaseNPC );
+public:
+ DECLARE_CLIENTCLASS();
+
+ C_RollerMine( void ) {}
+
+ int DrawModel( int flags );
+
+ RenderGroup_t GetRenderGroup( void )
+ {
+ if ( m_bIsOpen )
+ return RENDER_GROUP_TRANSLUCENT_ENTITY;
+ else
+ return RENDER_GROUP_OPAQUE_ENTITY;
+ }
+
+private:
+ C_RollerMine( const C_RollerMine & ) {}
+
+ bool m_bIsOpen;
+ float m_flActiveTime;
+ bool m_bHackedByAlyx;
+ bool m_bPowerDown;
+};
+
+IMPLEMENT_CLIENTCLASS_DT( C_RollerMine, DT_RollerMine, CNPC_RollerMine )
+ RecvPropInt( RECVINFO( m_bIsOpen ) ),
+ RecvPropFloat( RECVINFO( m_flActiveTime ) ),
+ RecvPropInt( RECVINFO( m_bHackedByAlyx ) ),
+ RecvPropInt( RECVINFO( m_bPowerDown ) ),
+END_RECV_TABLE()
+
+#define NUM_ATTACHMENTS 11
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : flags -
+// Output : int
+//-----------------------------------------------------------------------------
+int C_RollerMine::DrawModel( int flags )
+{
+ if ( m_bIsOpen && m_flActiveTime <= gpGlobals->curtime )
+ {
+ float scale = random->RandomFloat( 4.0f, 6.0f );
+
+ if ( gpGlobals->frametime != 0 )
+ {
+ // Inner beams
+ BeamInfo_t beamInfo;
+
+ beamInfo.m_vecStart = GetAbsOrigin();
+ Vector offset = RandomVector( -6*scale, 2*scale );
+
+ offset += Vector(2,2,2) * scale;
+ beamInfo.m_vecEnd = GetAbsOrigin() + offset;
+
+ beamInfo.m_pStartEnt= cl_entitylist->GetEnt( BEAMENT_ENTITY( entindex() ) );
+ beamInfo.m_pEndEnt = beamInfo.m_pStartEnt;
+ beamInfo.m_nStartAttachment = random->RandomInt( 0, NUM_ATTACHMENTS );
+ beamInfo.m_nEndAttachment = random->RandomInt( 0, NUM_ATTACHMENTS );
+
+ // Ensure we're not the same point
+ if ( beamInfo.m_nStartAttachment == beamInfo.m_nEndAttachment )
+ {
+ int nextStep = ( random->RandomInt( 0, 1 ) ) ? 1 : -1;
+
+ beamInfo.m_nEndAttachment = ( beamInfo.m_nStartAttachment + nextStep ) % NUM_ATTACHMENTS;
+ }
+
+ beamInfo.m_nType = TE_BEAMTESLA;
+ beamInfo.m_pszModelName = "sprites/lgtning.vmt";
+ beamInfo.m_flHaloScale = 0.0f;
+ beamInfo.m_flLife = 0.1f;
+ beamInfo.m_flWidth = random->RandomFloat( 2.0f, 4.0f );
+ beamInfo.m_flEndWidth = random->RandomFloat( 0.0f, 1.0f );
+ beamInfo.m_flFadeLength = 0.0f;
+ beamInfo.m_flAmplitude = random->RandomFloat( 16, 32 );
+ beamInfo.m_flBrightness = 255.0;
+ beamInfo.m_flSpeed = 0.0;
+ beamInfo.m_nStartFrame = 0.0;
+ beamInfo.m_flFrameRate = 1.0f;
+
+ if ( m_bPowerDown )
+ {
+ beamInfo.m_flRed = 255.0f;;
+ beamInfo.m_flGreen = 64.0f;
+ beamInfo.m_flBlue = 64.0f;
+ }
+ else if ( m_bHackedByAlyx )
+ {
+ beamInfo.m_flRed = 240.0f;;
+ beamInfo.m_flGreen = 200.0f;
+ beamInfo.m_flBlue = 80.0f;
+ }
+ else
+ {
+ beamInfo.m_flRed = 255.0f;;
+ beamInfo.m_flGreen = 255.0f;
+ beamInfo.m_flBlue = 255.0f;
+ }
+
+ beamInfo.m_nSegments = 4;
+ beamInfo.m_bRenderable = true;
+ beamInfo.m_nFlags = 0;
+
+ beams->CreateBeamEntPoint( beamInfo );
+
+ // Draw the halo
+ float color[3];
+
+ if ( m_bHackedByAlyx )
+ {
+ color[0] = 0.25f;
+ color[1] = 0.05f;
+ color[2] = 0.0f;
+ }
+ else
+ {
+ color[0] = color[1] = color[2] = 0.15f;
+ }
+
+ IMaterial *pMaterial = materials->FindMaterial( "effects/rollerglow", NULL, false );
+
+ CMatRenderContextPtr pRenderContext( materials );
+ pRenderContext->Bind( pMaterial );
+ DrawHalo( pMaterial, GetAbsOrigin(), random->RandomFloat( 6.0f*scale, 6.5f*scale ), color );
+
+ if ( m_bPowerDown )
+ {
+ color[0] = random->RandomFloat( 0.80f, 1.00f );
+ color[1] = random->RandomFloat( 0.10f, 0.25f );
+ color[2] = 0.0f;
+ }
+ else if ( m_bHackedByAlyx )
+ {
+ color[0] = random->RandomFloat( 0.25f, 0.75f );
+ color[1] = random->RandomFloat( 0.10f, 0.25f );
+ color[2] = 0.0f;
+ }
+ else
+ {
+ color[0] = color[1] = color[2] = random->RandomFloat( 0.25f, 0.5f );
+ }
+
+ Vector attachOrigin;
+ QAngle attachAngles;
+
+ GetAttachment( beamInfo.m_nEndAttachment, attachOrigin, attachAngles );
+ DrawHalo( pMaterial, attachOrigin, random->RandomFloat( 1.0f*scale, 1.5f*scale ), color );
+
+ GetAttachment( beamInfo.m_nStartAttachment, attachOrigin, attachAngles );
+ DrawHalo( pMaterial, attachOrigin, random->RandomFloat( 1.0f*scale, 1.5f*scale ), color );
+ }
+ }
+
+ return BaseClass::DrawModel( flags );
} \ No newline at end of file
diff --git a/mp/src/game/client/hl2/c_plasma_beam_node.cpp b/mp/src/game/client/hl2/c_plasma_beam_node.cpp
index 6f979c50..68cbc70a 100644
--- a/mp/src/game/client/hl2/c_plasma_beam_node.cpp
+++ b/mp/src/game/client/hl2/c_plasma_beam_node.cpp
@@ -1,279 +1,279 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#include "cbase.h"
-#include "particles_simple.h"
-#include "c_tracer.h"
-#include "particle_collision.h"
-#include "view.h"
-#include "clienteffectprecachesystem.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-#define PLASMASPARK_LIFETIME 0.5
-#define SPRAYS_PER_THINK 12
-
-CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectPlasmaBeam )
-CLIENTEFFECT_MATERIAL( "sprites/plasmaember" )
-CLIENTEFFECT_REGISTER_END()
-
-class C_PlasmaBeamNode;
-
-//##################################################################
-//
-// > CPlasmaSpray
-//
-//##################################################################
-class CPlasmaSpray : public CSimpleEmitter
-{
-public:
- CPlasmaSpray( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
-
- static CSmartPtr<CPlasmaSpray> Create( const char *pDebugName );
- void Think( void );
- void UpdateVelocity( SimpleParticle *pParticle, float timeDelta );
- virtual void RenderParticles( CParticleRenderIterator *pIterator );
- virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
- EHANDLE m_pOwner;
- CParticleCollision m_ParticleCollision;
-
-private:
- CPlasmaSpray( const CPlasmaSpray & );
-};
-
-//##################################################################
-//
-// PlasmaBeamNode - generates plasma spray
-//
-//##################################################################
-class C_PlasmaBeamNode : public C_BaseEntity
-{
-public:
- DECLARE_CLASS( C_PlasmaBeamNode, C_BaseEntity );
- DECLARE_CLIENTCLASS();
-
- C_PlasmaBeamNode();
- ~C_PlasmaBeamNode(void);
-
-public:
- void ClientThink(void);
- void AddEntity( void );
- void OnDataChanged(DataUpdateType_t updateType);
- bool ShouldDraw();
- bool m_bSprayOn;
- CSmartPtr<CPlasmaSpray> m_pFirePlasmaSpray;
-};
-
-//##################################################################
-//
-// > CPlasmaSpray
-//
-//##################################################################
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pParticle -
-// timeDelta -
-// Output : float
-//-----------------------------------------------------------------------------
-CSmartPtr<CPlasmaSpray> CPlasmaSpray::Create( const char *pDebugName )
-{
- CPlasmaSpray *pRet = new CPlasmaSpray( pDebugName );
- return pRet;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : fTimeDelta -
-// Output : Vector
-//-----------------------------------------------------------------------------
-void CPlasmaSpray::UpdateVelocity( SimpleParticle *pParticle, float timeDelta )
-{
- Vector vGravity = Vector(0,0,-1000);
- float flFrametime = gpGlobals->frametime;
- vGravity = flFrametime * vGravity;
- pParticle->m_vecVelocity += vGravity;
-}
-
-
-void CPlasmaSpray::SimulateParticles( CParticleSimulateIterator *pIterator )
-{
- float timeDelta = pIterator->GetTimeDelta();
-
- SimpleParticle *pParticle = (SimpleParticle*)pIterator->GetFirst();
- while ( pParticle )
- {
- //Should this particle die?
- pParticle->m_flLifetime += timeDelta;
-
- C_PlasmaBeamNode* pNode = (C_PlasmaBeamNode*)((C_BaseEntity*)m_pOwner);
- if ( pParticle->m_flLifetime >= pParticle->m_flDieTime )
- {
- pIterator->RemoveParticle( pParticle );
- }
- // If owner is gone or spray off remove me
- else if (pNode == NULL || !pNode->m_bSprayOn)
- {
- pIterator->RemoveParticle( pParticle );
- }
-
- //Simulate the movement with collision
- trace_t trace;
- m_ParticleCollision.MoveParticle( pParticle->m_Pos, pParticle->m_vecVelocity, NULL, timeDelta, &trace );
-
- pParticle = (SimpleParticle*)pIterator->GetNext();
- }
-}
-
-
-void CPlasmaSpray::RenderParticles( CParticleRenderIterator *pIterator )
-{
- const SimpleParticle *pParticle = (const SimpleParticle *)pIterator->GetFirst();
- while ( pParticle )
- {
- float scale = random->RandomFloat( 0.02, 0.08 );
-
- // NOTE: We need to do everything in screen space
- Vector delta;
- Vector start;
- TransformParticle(ParticleMgr()->GetModelView(), pParticle->m_Pos, start);
- float sortKey = start.z;
-
- Vector3DMultiply( CurrentWorldToViewMatrix(), pParticle->m_vecVelocity, delta );
-
- delta[0] *= scale;
- delta[1] *= scale;
- delta[2] *= scale;
-
- // See c_tracer.* for this method
- Tracer_Draw( pIterator->GetParticleDraw(), start, delta, random->RandomInt( 2, 8 ), 0 );
-
- pParticle = (const SimpleParticle *)pIterator->GetNext( sortKey );
- }
-}
-
-
-//##################################################################
-//
-// PlasmaBeamNode - generates plasma spray
-//
-//##################################################################
-
-//------------------------------------------------------------------------------
-// Purpose :
-// Input :
-// Output :
-//------------------------------------------------------------------------------
-C_PlasmaBeamNode::C_PlasmaBeamNode(void)
-{
- m_bSprayOn = false;
- m_pFirePlasmaSpray = CPlasmaSpray::Create( "C_PlasmaBeamNode" );
-}
-
-//------------------------------------------------------------------------------
-// Purpose :
-// Input :
-// Output :
-//------------------------------------------------------------------------------
-C_PlasmaBeamNode::~C_PlasmaBeamNode(void)
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_PlasmaBeamNode::AddEntity( void )
-{
- m_pFirePlasmaSpray->SetSortOrigin( GetAbsOrigin() );
-}
-
-//------------------------------------------------------------------------------
-// Purpose :
-// Input :
-// Output :
-//------------------------------------------------------------------------------
-void C_PlasmaBeamNode::OnDataChanged(DataUpdateType_t updateType)
-{
- if (updateType == DATA_UPDATE_CREATED)
- {
- Vector vMoveDir = GetAbsVelocity();
- float flVel = VectorNormalize(vMoveDir);
- m_pFirePlasmaSpray->m_ParticleCollision.Setup( GetAbsOrigin(), &vMoveDir, 0.3,
- flVel-50, flVel+50, 800, 0.5 );
- SetNextClientThink(gpGlobals->curtime + 0.01);
- }
- C_BaseEntity::OnDataChanged(updateType);
-}
-
-//------------------------------------------------------------------------------
-// Purpose :
-// Input :
-// Output :
-//------------------------------------------------------------------------------
-bool C_PlasmaBeamNode::ShouldDraw()
-{
- return false;
-}
-
-//------------------------------------------------------------------------------
-// Purpose :
-// Input :
-// Output :
-//------------------------------------------------------------------------------
-void C_PlasmaBeamNode::ClientThink(void)
-{
- if (!m_bSprayOn)
- {
- return;
- }
-
- trace_t trace;
- Vector vEndTrace = GetAbsOrigin() + (0.3*GetAbsVelocity());
- UTIL_TraceLine( GetAbsOrigin(), vEndTrace, MASK_SHOT, NULL, COLLISION_GROUP_NONE, &trace );
- if ( trace.fraction != 1.0f || trace.startsolid)
- {
- m_bSprayOn = false;
- return;
- }
-
- PMaterialHandle handle = m_pFirePlasmaSpray->GetPMaterial( "sprites/plasmaember" );
- for (int i=0;i<SPRAYS_PER_THINK;i++)
- {
- SimpleParticle *sParticle;
-
- //Make a new particle
- if ( random->RandomInt( 0, 2 ) == 0 )
- {
- float ranx = random->RandomFloat( -28.0f, 28.0f );
- float rany = random->RandomFloat( -28.0f, 28.0f );
- float ranz = random->RandomFloat( -28.0f, 28.0f );
-
- Vector vNewPos = GetAbsOrigin();
- Vector vAdd = Vector(GetAbsAngles().x,GetAbsAngles().y,GetAbsAngles().z)*random->RandomFloat(-60,120);
- vNewPos += vAdd;
-
- sParticle = (SimpleParticle *) m_pFirePlasmaSpray->AddParticle( sizeof(SimpleParticle), handle, vNewPos );
-
- sParticle->m_flLifetime = 0.0f;
- sParticle->m_flDieTime = PLASMASPARK_LIFETIME;
-
- sParticle->m_vecVelocity = GetAbsVelocity();
- sParticle->m_vecVelocity.x += ranx;
- sParticle->m_vecVelocity.y += rany;
- sParticle->m_vecVelocity.z += ranz;
- m_pFirePlasmaSpray->m_pOwner = this;
- }
- }
-
- SetNextClientThink(gpGlobals->curtime + 0.05);
-}
-
-IMPLEMENT_CLIENTCLASS_DT(C_PlasmaBeamNode, DT_PlasmaBeamNode, CPlasmaBeamNode )
- RecvPropVector (RECVINFO(m_vecVelocity), 0, RecvProxy_LocalVelocity),
- RecvPropInt (RECVINFO(m_bSprayOn)),
-END_RECV_TABLE()
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "particles_simple.h"
+#include "c_tracer.h"
+#include "particle_collision.h"
+#include "view.h"
+#include "clienteffectprecachesystem.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#define PLASMASPARK_LIFETIME 0.5
+#define SPRAYS_PER_THINK 12
+
+CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectPlasmaBeam )
+CLIENTEFFECT_MATERIAL( "sprites/plasmaember" )
+CLIENTEFFECT_REGISTER_END()
+
+class C_PlasmaBeamNode;
+
+//##################################################################
+//
+// > CPlasmaSpray
+//
+//##################################################################
+class CPlasmaSpray : public CSimpleEmitter
+{
+public:
+ CPlasmaSpray( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
+
+ static CSmartPtr<CPlasmaSpray> Create( const char *pDebugName );
+ void Think( void );
+ void UpdateVelocity( SimpleParticle *pParticle, float timeDelta );
+ virtual void RenderParticles( CParticleRenderIterator *pIterator );
+ virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
+ EHANDLE m_pOwner;
+ CParticleCollision m_ParticleCollision;
+
+private:
+ CPlasmaSpray( const CPlasmaSpray & );
+};
+
+//##################################################################
+//
+// PlasmaBeamNode - generates plasma spray
+//
+//##################################################################
+class C_PlasmaBeamNode : public C_BaseEntity
+{
+public:
+ DECLARE_CLASS( C_PlasmaBeamNode, C_BaseEntity );
+ DECLARE_CLIENTCLASS();
+
+ C_PlasmaBeamNode();
+ ~C_PlasmaBeamNode(void);
+
+public:
+ void ClientThink(void);
+ void AddEntity( void );
+ void OnDataChanged(DataUpdateType_t updateType);
+ bool ShouldDraw();
+ bool m_bSprayOn;
+ CSmartPtr<CPlasmaSpray> m_pFirePlasmaSpray;
+};
+
+//##################################################################
+//
+// > CPlasmaSpray
+//
+//##################################################################
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pParticle -
+// timeDelta -
+// Output : float
+//-----------------------------------------------------------------------------
+CSmartPtr<CPlasmaSpray> CPlasmaSpray::Create( const char *pDebugName )
+{
+ CPlasmaSpray *pRet = new CPlasmaSpray( pDebugName );
+ return pRet;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : fTimeDelta -
+// Output : Vector
+//-----------------------------------------------------------------------------
+void CPlasmaSpray::UpdateVelocity( SimpleParticle *pParticle, float timeDelta )
+{
+ Vector vGravity = Vector(0,0,-1000);
+ float flFrametime = gpGlobals->frametime;
+ vGravity = flFrametime * vGravity;
+ pParticle->m_vecVelocity += vGravity;
+}
+
+
+void CPlasmaSpray::SimulateParticles( CParticleSimulateIterator *pIterator )
+{
+ float timeDelta = pIterator->GetTimeDelta();
+
+ SimpleParticle *pParticle = (SimpleParticle*)pIterator->GetFirst();
+ while ( pParticle )
+ {
+ //Should this particle die?
+ pParticle->m_flLifetime += timeDelta;
+
+ C_PlasmaBeamNode* pNode = (C_PlasmaBeamNode*)((C_BaseEntity*)m_pOwner);
+ if ( pParticle->m_flLifetime >= pParticle->m_flDieTime )
+ {
+ pIterator->RemoveParticle( pParticle );
+ }
+ // If owner is gone or spray off remove me
+ else if (pNode == NULL || !pNode->m_bSprayOn)
+ {
+ pIterator->RemoveParticle( pParticle );
+ }
+
+ //Simulate the movement with collision
+ trace_t trace;
+ m_ParticleCollision.MoveParticle( pParticle->m_Pos, pParticle->m_vecVelocity, NULL, timeDelta, &trace );
+
+ pParticle = (SimpleParticle*)pIterator->GetNext();
+ }
+}
+
+
+void CPlasmaSpray::RenderParticles( CParticleRenderIterator *pIterator )
+{
+ const SimpleParticle *pParticle = (const SimpleParticle *)pIterator->GetFirst();
+ while ( pParticle )
+ {
+ float scale = random->RandomFloat( 0.02, 0.08 );
+
+ // NOTE: We need to do everything in screen space
+ Vector delta;
+ Vector start;
+ TransformParticle(ParticleMgr()->GetModelView(), pParticle->m_Pos, start);
+ float sortKey = start.z;
+
+ Vector3DMultiply( CurrentWorldToViewMatrix(), pParticle->m_vecVelocity, delta );
+
+ delta[0] *= scale;
+ delta[1] *= scale;
+ delta[2] *= scale;
+
+ // See c_tracer.* for this method
+ Tracer_Draw( pIterator->GetParticleDraw(), start, delta, random->RandomInt( 2, 8 ), 0 );
+
+ pParticle = (const SimpleParticle *)pIterator->GetNext( sortKey );
+ }
+}
+
+
+//##################################################################
+//
+// PlasmaBeamNode - generates plasma spray
+//
+//##################################################################
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+C_PlasmaBeamNode::C_PlasmaBeamNode(void)
+{
+ m_bSprayOn = false;
+ m_pFirePlasmaSpray = CPlasmaSpray::Create( "C_PlasmaBeamNode" );
+}
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+C_PlasmaBeamNode::~C_PlasmaBeamNode(void)
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_PlasmaBeamNode::AddEntity( void )
+{
+ m_pFirePlasmaSpray->SetSortOrigin( GetAbsOrigin() );
+}
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+void C_PlasmaBeamNode::OnDataChanged(DataUpdateType_t updateType)
+{
+ if (updateType == DATA_UPDATE_CREATED)
+ {
+ Vector vMoveDir = GetAbsVelocity();
+ float flVel = VectorNormalize(vMoveDir);
+ m_pFirePlasmaSpray->m_ParticleCollision.Setup( GetAbsOrigin(), &vMoveDir, 0.3,
+ flVel-50, flVel+50, 800, 0.5 );
+ SetNextClientThink(gpGlobals->curtime + 0.01);
+ }
+ C_BaseEntity::OnDataChanged(updateType);
+}
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+bool C_PlasmaBeamNode::ShouldDraw()
+{
+ return false;
+}
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+void C_PlasmaBeamNode::ClientThink(void)
+{
+ if (!m_bSprayOn)
+ {
+ return;
+ }
+
+ trace_t trace;
+ Vector vEndTrace = GetAbsOrigin() + (0.3*GetAbsVelocity());
+ UTIL_TraceLine( GetAbsOrigin(), vEndTrace, MASK_SHOT, NULL, COLLISION_GROUP_NONE, &trace );
+ if ( trace.fraction != 1.0f || trace.startsolid)
+ {
+ m_bSprayOn = false;
+ return;
+ }
+
+ PMaterialHandle handle = m_pFirePlasmaSpray->GetPMaterial( "sprites/plasmaember" );
+ for (int i=0;i<SPRAYS_PER_THINK;i++)
+ {
+ SimpleParticle *sParticle;
+
+ //Make a new particle
+ if ( random->RandomInt( 0, 2 ) == 0 )
+ {
+ float ranx = random->RandomFloat( -28.0f, 28.0f );
+ float rany = random->RandomFloat( -28.0f, 28.0f );
+ float ranz = random->RandomFloat( -28.0f, 28.0f );
+
+ Vector vNewPos = GetAbsOrigin();
+ Vector vAdd = Vector(GetAbsAngles().x,GetAbsAngles().y,GetAbsAngles().z)*random->RandomFloat(-60,120);
+ vNewPos += vAdd;
+
+ sParticle = (SimpleParticle *) m_pFirePlasmaSpray->AddParticle( sizeof(SimpleParticle), handle, vNewPos );
+
+ sParticle->m_flLifetime = 0.0f;
+ sParticle->m_flDieTime = PLASMASPARK_LIFETIME;
+
+ sParticle->m_vecVelocity = GetAbsVelocity();
+ sParticle->m_vecVelocity.x += ranx;
+ sParticle->m_vecVelocity.y += rany;
+ sParticle->m_vecVelocity.z += ranz;
+ m_pFirePlasmaSpray->m_pOwner = this;
+ }
+ }
+
+ SetNextClientThink(gpGlobals->curtime + 0.05);
+}
+
+IMPLEMENT_CLIENTCLASS_DT(C_PlasmaBeamNode, DT_PlasmaBeamNode, CPlasmaBeamNode )
+ RecvPropVector (RECVINFO(m_vecVelocity), 0, RecvProxy_LocalVelocity),
+ RecvPropInt (RECVINFO(m_bSprayOn)),
+END_RECV_TABLE()
diff --git a/mp/src/game/client/hl2/c_prop_combine_ball.cpp b/mp/src/game/client/hl2/c_prop_combine_ball.cpp
index d1a912d7..2e318064 100644
--- a/mp/src/game/client/hl2/c_prop_combine_ball.cpp
+++ b/mp/src/game/client/hl2/c_prop_combine_ball.cpp
@@ -1,340 +1,340 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "c_prop_combine_ball.h"
-#include "materialsystem/imaterial.h"
-#include "model_types.h"
-#include "c_physicsprop.h"
-#include "c_te_effect_dispatch.h"
-#include "fx_quad.h"
-#include "fx.h"
-#include "clienteffectprecachesystem.h"
-#include "view.h"
-#include "view_scene.h"
-#include "beamdraw.h"
-
-// Precache our effects
-CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectCombineBall )
-CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1" )
-CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1b" )
-CLIENTEFFECT_MATERIAL( "effects/combinemuzzle1_nocull" )
-CLIENTEFFECT_MATERIAL( "effects/combinemuzzle2_nocull" )
-CLIENTEFFECT_MATERIAL( "effects/combinemuzzle1" )
-CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1" )
-CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1b" )
-CLIENTEFFECT_REGISTER_END()
-
-IMPLEMENT_CLIENTCLASS_DT( C_PropCombineBall, DT_PropCombineBall, CPropCombineBall )
- RecvPropBool( RECVINFO( m_bEmit ) ),
- RecvPropFloat( RECVINFO( m_flRadius ) ),
- RecvPropBool( RECVINFO( m_bHeld ) ),
- RecvPropBool( RECVINFO( m_bLaunched ) ),
-END_RECV_TABLE()
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-C_PropCombineBall::C_PropCombineBall( void )
-{
- m_pFlickerMaterial = NULL;
- m_pBodyMaterial = NULL;
- m_pBlurMaterial = NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : updateType -
-//-----------------------------------------------------------------------------
-void C_PropCombineBall::OnDataChanged( DataUpdateType_t updateType )
-{
- BaseClass::OnDataChanged( updateType );
-
- if ( updateType == DATA_UPDATE_CREATED )
- {
- m_vecLastOrigin = GetAbsOrigin();
- InitMaterials();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : RenderGroup_t
-//-----------------------------------------------------------------------------
-RenderGroup_t C_PropCombineBall::GetRenderGroup( void )
-{
- return RENDER_GROUP_TRANSLUCENT_ENTITY;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Cache the material handles
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool C_PropCombineBall::InitMaterials( void )
-{
- // Motion blur
- if ( m_pBlurMaterial == NULL )
- {
- m_pBlurMaterial = materials->FindMaterial( "effects/ar2_altfire1b", NULL, false );
-
- if ( m_pBlurMaterial == NULL )
- return false;
- }
-
- // Main body of the ball
- if ( m_pBodyMaterial == NULL )
- {
- m_pBodyMaterial = materials->FindMaterial( "effects/ar2_altfire1", NULL, false );
-
- if ( m_pBodyMaterial == NULL )
- return false;
- }
-
- // Flicker material
- if ( m_pFlickerMaterial == NULL )
- {
- m_pFlickerMaterial = materials->FindMaterial( "effects/combinemuzzle1", NULL, false );
-
- if ( m_pFlickerMaterial == NULL )
- return false;
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_PropCombineBall::DrawMotionBlur( void )
-{
- float color[3];
-
- Vector vecDir = GetAbsOrigin() - m_vecLastOrigin;
- float speed = VectorNormalize( vecDir );
-
- speed = clamp( speed, 0, 32 );
-
- float stepSize = MIN( ( speed * 0.5f ), 4.0f );
-
- Vector spawnPos = GetAbsOrigin();
- Vector spawnStep = -vecDir * stepSize;
-
- float base = RemapValClamped( speed, 4, 32, 0.0f, 1.0f );
-
- CMatRenderContextPtr pRenderContext( materials );
- pRenderContext->Bind( m_pBlurMaterial );
-
- // Draw the motion blurred trail
- for ( int i = 0; i < 8; i++ )
- {
- spawnPos += spawnStep;
-
- color[0] = color[1] = color[2] = base * ( 1.0f - ( (float) i / 12.0f ) );
-
- DrawHalo( m_pBlurMaterial, spawnPos, m_flRadius, color );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_PropCombineBall::DrawFlicker( void )
-{
- float rand1 = random->RandomFloat( 0.2f, 0.3f );
- float rand2 = random->RandomFloat( 1.5f, 2.5f );
-
- if ( gpGlobals->frametime == 0.0f )
- {
- rand1 = 0.2f;
- rand2 = 1.5f;
- }
-
- float color[3];
- color[0] = color[1] = color[2] = rand1;
-
- // Draw the flickering glow
- CMatRenderContextPtr pRenderContext( materials );
- pRenderContext->Bind( m_pFlickerMaterial );
- DrawHalo( m_pFlickerMaterial, GetAbsOrigin(), m_flRadius * rand2, color );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : pMaterial -
-// source -
-// color -
-//-----------------------------------------------------------------------------
-void DrawHaloOriented( const Vector& source, float scale, float const *color, float roll )
-{
- Vector point, screen;
-
- CMatRenderContextPtr pRenderContext( materials );
- IMesh* pMesh = pRenderContext->GetDynamicMesh();
-
- CMeshBuilder meshBuilder;
- meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
-
- // Transform source into screen space
- ScreenTransform( source, screen );
-
- Vector right, up;
- float sr, cr;
-
- SinCos( roll, &sr, &cr );
-
- for ( int i = 0; i < 3; i++ )
- {
- right[i] = CurrentViewRight()[i] * cr + CurrentViewUp()[i] * sr;
- up[i] = CurrentViewRight()[i] * -sr + CurrentViewUp()[i] * cr;
- }
-
- meshBuilder.Color3fv (color);
- meshBuilder.TexCoord2f (0, 0, 1);
- VectorMA (source, -scale, up, point);
- VectorMA (point, -scale, right, point);
- meshBuilder.Position3fv (point.Base());
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color3fv (color);
- meshBuilder.TexCoord2f (0, 0, 0);
- VectorMA (source, scale, up, point);
- VectorMA (point, -scale, right, point);
- meshBuilder.Position3fv (point.Base());
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color3fv (color);
- meshBuilder.TexCoord2f (0, 1, 0);
- VectorMA (source, scale, up, point);
- VectorMA (point, scale, right, point);
- meshBuilder.Position3fv (point.Base());
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color3fv (color);
- meshBuilder.TexCoord2f (0, 1, 1);
- VectorMA (source, -scale, up, point);
- VectorMA (point, scale, right, point);
- meshBuilder.Position3fv (point.Base());
- meshBuilder.AdvanceVertex();
-
- meshBuilder.End();
- pMesh->Draw();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : flags -
-// Output : int
-//-----------------------------------------------------------------------------
-int C_PropCombineBall::DrawModel( int flags )
-{
- if ( !m_bEmit )
- return 0;
-
- // Make sure our materials are cached
- if ( !InitMaterials() )
- {
- //NOTENOTE: This means that a material was not found for the combine ball, so it may not render!
- AssertOnce( 0 );
- return 0;
- }
-
- // Draw the flickering overlay
- DrawFlicker();
-
- // Draw the motion blur from movement
- if ( m_bHeld || m_bLaunched )
- {
- DrawMotionBlur();
- }
-
- // Draw the model if we're being held
- if ( m_bHeld )
- {
- QAngle angles;
- VectorAngles( -CurrentViewForward(), angles );
-
- // Always orient towards the camera!
- SetAbsAngles( angles );
-
- BaseClass::DrawModel( flags );
- }
- else
- {
- float color[3];
- color[0] = color[1] = color[2] = 1.0f;
-
- float sinOffs = 1.0f * sin( gpGlobals->curtime * 25 );
-
- float roll = SpawnTime();
-
- // Draw the main ball body
- CMatRenderContextPtr pRenderContext( materials );
- pRenderContext->Bind( m_pBodyMaterial, (C_BaseEntity*) this );
- DrawHaloOriented( GetAbsOrigin(), m_flRadius + sinOffs, color, roll );
- }
-
- m_vecLastOrigin = GetAbsOrigin();
-
- return 1;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : &data -
-//-----------------------------------------------------------------------------
-void CombineBallImpactCallback( const CEffectData &data )
-{
- // Quick flash
- FX_AddQuad( data.m_vOrigin,
- data.m_vNormal,
- data.m_flRadius * 10.0f,
- 0,
- 0.75f,
- 1.0f,
- 0.0f,
- 0.4f,
- random->RandomInt( 0, 360 ),
- 0,
- Vector( 1.0f, 1.0f, 1.0f ),
- 0.25f,
- "effects/combinemuzzle1_nocull",
- (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
-
- // Lingering burn
- FX_AddQuad( data.m_vOrigin,
- data.m_vNormal,
- data.m_flRadius * 2.0f,
- data.m_flRadius * 4.0f,
- 0.75f,
- 1.0f,
- 0.0f,
- 0.4f,
- random->RandomInt( 0, 360 ),
- 0,
- Vector( 1.0f, 1.0f, 1.0f ),
- 0.5f,
- "effects/combinemuzzle2_nocull",
- (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
-
- // Throw sparks
- FX_ElectricSpark( data.m_vOrigin, 2, 1, &data.m_vNormal );
-}
-
-DECLARE_CLIENT_EFFECT( "cball_bounce", CombineBallImpactCallback );
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : &data -
-//-----------------------------------------------------------------------------
-void CombineBallExplosionCallback( const CEffectData &data )
-{
- Vector normal(0,0,1);
-
- // Throw sparks
- FX_ElectricSpark( data.m_vOrigin, 4, 1, &normal );
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "c_prop_combine_ball.h"
+#include "materialsystem/imaterial.h"
+#include "model_types.h"
+#include "c_physicsprop.h"
+#include "c_te_effect_dispatch.h"
+#include "fx_quad.h"
+#include "fx.h"
+#include "clienteffectprecachesystem.h"
+#include "view.h"
+#include "view_scene.h"
+#include "beamdraw.h"
+
+// Precache our effects
+CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectCombineBall )
+CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1" )
+CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1b" )
+CLIENTEFFECT_MATERIAL( "effects/combinemuzzle1_nocull" )
+CLIENTEFFECT_MATERIAL( "effects/combinemuzzle2_nocull" )
+CLIENTEFFECT_MATERIAL( "effects/combinemuzzle1" )
+CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1" )
+CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1b" )
+CLIENTEFFECT_REGISTER_END()
+
+IMPLEMENT_CLIENTCLASS_DT( C_PropCombineBall, DT_PropCombineBall, CPropCombineBall )
+ RecvPropBool( RECVINFO( m_bEmit ) ),
+ RecvPropFloat( RECVINFO( m_flRadius ) ),
+ RecvPropBool( RECVINFO( m_bHeld ) ),
+ RecvPropBool( RECVINFO( m_bLaunched ) ),
+END_RECV_TABLE()
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_PropCombineBall::C_PropCombineBall( void )
+{
+ m_pFlickerMaterial = NULL;
+ m_pBodyMaterial = NULL;
+ m_pBlurMaterial = NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : updateType -
+//-----------------------------------------------------------------------------
+void C_PropCombineBall::OnDataChanged( DataUpdateType_t updateType )
+{
+ BaseClass::OnDataChanged( updateType );
+
+ if ( updateType == DATA_UPDATE_CREATED )
+ {
+ m_vecLastOrigin = GetAbsOrigin();
+ InitMaterials();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : RenderGroup_t
+//-----------------------------------------------------------------------------
+RenderGroup_t C_PropCombineBall::GetRenderGroup( void )
+{
+ return RENDER_GROUP_TRANSLUCENT_ENTITY;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Cache the material handles
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool C_PropCombineBall::InitMaterials( void )
+{
+ // Motion blur
+ if ( m_pBlurMaterial == NULL )
+ {
+ m_pBlurMaterial = materials->FindMaterial( "effects/ar2_altfire1b", NULL, false );
+
+ if ( m_pBlurMaterial == NULL )
+ return false;
+ }
+
+ // Main body of the ball
+ if ( m_pBodyMaterial == NULL )
+ {
+ m_pBodyMaterial = materials->FindMaterial( "effects/ar2_altfire1", NULL, false );
+
+ if ( m_pBodyMaterial == NULL )
+ return false;
+ }
+
+ // Flicker material
+ if ( m_pFlickerMaterial == NULL )
+ {
+ m_pFlickerMaterial = materials->FindMaterial( "effects/combinemuzzle1", NULL, false );
+
+ if ( m_pFlickerMaterial == NULL )
+ return false;
+ }
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_PropCombineBall::DrawMotionBlur( void )
+{
+ float color[3];
+
+ Vector vecDir = GetAbsOrigin() - m_vecLastOrigin;
+ float speed = VectorNormalize( vecDir );
+
+ speed = clamp( speed, 0, 32 );
+
+ float stepSize = MIN( ( speed * 0.5f ), 4.0f );
+
+ Vector spawnPos = GetAbsOrigin();
+ Vector spawnStep = -vecDir * stepSize;
+
+ float base = RemapValClamped( speed, 4, 32, 0.0f, 1.0f );
+
+ CMatRenderContextPtr pRenderContext( materials );
+ pRenderContext->Bind( m_pBlurMaterial );
+
+ // Draw the motion blurred trail
+ for ( int i = 0; i < 8; i++ )
+ {
+ spawnPos += spawnStep;
+
+ color[0] = color[1] = color[2] = base * ( 1.0f - ( (float) i / 12.0f ) );
+
+ DrawHalo( m_pBlurMaterial, spawnPos, m_flRadius, color );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_PropCombineBall::DrawFlicker( void )
+{
+ float rand1 = random->RandomFloat( 0.2f, 0.3f );
+ float rand2 = random->RandomFloat( 1.5f, 2.5f );
+
+ if ( gpGlobals->frametime == 0.0f )
+ {
+ rand1 = 0.2f;
+ rand2 = 1.5f;
+ }
+
+ float color[3];
+ color[0] = color[1] = color[2] = rand1;
+
+ // Draw the flickering glow
+ CMatRenderContextPtr pRenderContext( materials );
+ pRenderContext->Bind( m_pFlickerMaterial );
+ DrawHalo( m_pFlickerMaterial, GetAbsOrigin(), m_flRadius * rand2, color );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pMaterial -
+// source -
+// color -
+//-----------------------------------------------------------------------------
+void DrawHaloOriented( const Vector& source, float scale, float const *color, float roll )
+{
+ Vector point, screen;
+
+ CMatRenderContextPtr pRenderContext( materials );
+ IMesh* pMesh = pRenderContext->GetDynamicMesh();
+
+ CMeshBuilder meshBuilder;
+ meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
+
+ // Transform source into screen space
+ ScreenTransform( source, screen );
+
+ Vector right, up;
+ float sr, cr;
+
+ SinCos( roll, &sr, &cr );
+
+ for ( int i = 0; i < 3; i++ )
+ {
+ right[i] = CurrentViewRight()[i] * cr + CurrentViewUp()[i] * sr;
+ up[i] = CurrentViewRight()[i] * -sr + CurrentViewUp()[i] * cr;
+ }
+
+ meshBuilder.Color3fv (color);
+ meshBuilder.TexCoord2f (0, 0, 1);
+ VectorMA (source, -scale, up, point);
+ VectorMA (point, -scale, right, point);
+ meshBuilder.Position3fv (point.Base());
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color3fv (color);
+ meshBuilder.TexCoord2f (0, 0, 0);
+ VectorMA (source, scale, up, point);
+ VectorMA (point, -scale, right, point);
+ meshBuilder.Position3fv (point.Base());
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color3fv (color);
+ meshBuilder.TexCoord2f (0, 1, 0);
+ VectorMA (source, scale, up, point);
+ VectorMA (point, scale, right, point);
+ meshBuilder.Position3fv (point.Base());
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color3fv (color);
+ meshBuilder.TexCoord2f (0, 1, 1);
+ VectorMA (source, -scale, up, point);
+ VectorMA (point, scale, right, point);
+ meshBuilder.Position3fv (point.Base());
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.End();
+ pMesh->Draw();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : flags -
+// Output : int
+//-----------------------------------------------------------------------------
+int C_PropCombineBall::DrawModel( int flags )
+{
+ if ( !m_bEmit )
+ return 0;
+
+ // Make sure our materials are cached
+ if ( !InitMaterials() )
+ {
+ //NOTENOTE: This means that a material was not found for the combine ball, so it may not render!
+ AssertOnce( 0 );
+ return 0;
+ }
+
+ // Draw the flickering overlay
+ DrawFlicker();
+
+ // Draw the motion blur from movement
+ if ( m_bHeld || m_bLaunched )
+ {
+ DrawMotionBlur();
+ }
+
+ // Draw the model if we're being held
+ if ( m_bHeld )
+ {
+ QAngle angles;
+ VectorAngles( -CurrentViewForward(), angles );
+
+ // Always orient towards the camera!
+ SetAbsAngles( angles );
+
+ BaseClass::DrawModel( flags );
+ }
+ else
+ {
+ float color[3];
+ color[0] = color[1] = color[2] = 1.0f;
+
+ float sinOffs = 1.0f * sin( gpGlobals->curtime * 25 );
+
+ float roll = SpawnTime();
+
+ // Draw the main ball body
+ CMatRenderContextPtr pRenderContext( materials );
+ pRenderContext->Bind( m_pBodyMaterial, (C_BaseEntity*) this );
+ DrawHaloOriented( GetAbsOrigin(), m_flRadius + sinOffs, color, roll );
+ }
+
+ m_vecLastOrigin = GetAbsOrigin();
+
+ return 1;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &data -
+//-----------------------------------------------------------------------------
+void CombineBallImpactCallback( const CEffectData &data )
+{
+ // Quick flash
+ FX_AddQuad( data.m_vOrigin,
+ data.m_vNormal,
+ data.m_flRadius * 10.0f,
+ 0,
+ 0.75f,
+ 1.0f,
+ 0.0f,
+ 0.4f,
+ random->RandomInt( 0, 360 ),
+ 0,
+ Vector( 1.0f, 1.0f, 1.0f ),
+ 0.25f,
+ "effects/combinemuzzle1_nocull",
+ (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
+
+ // Lingering burn
+ FX_AddQuad( data.m_vOrigin,
+ data.m_vNormal,
+ data.m_flRadius * 2.0f,
+ data.m_flRadius * 4.0f,
+ 0.75f,
+ 1.0f,
+ 0.0f,
+ 0.4f,
+ random->RandomInt( 0, 360 ),
+ 0,
+ Vector( 1.0f, 1.0f, 1.0f ),
+ 0.5f,
+ "effects/combinemuzzle2_nocull",
+ (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
+
+ // Throw sparks
+ FX_ElectricSpark( data.m_vOrigin, 2, 1, &data.m_vNormal );
+}
+
+DECLARE_CLIENT_EFFECT( "cball_bounce", CombineBallImpactCallback );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &data -
+//-----------------------------------------------------------------------------
+void CombineBallExplosionCallback( const CEffectData &data )
+{
+ Vector normal(0,0,1);
+
+ // Throw sparks
+ FX_ElectricSpark( data.m_vOrigin, 4, 1, &normal );
+}
+
DECLARE_CLIENT_EFFECT( "cball_explode", CombineBallExplosionCallback ); \ No newline at end of file
diff --git a/mp/src/game/client/hl2/c_prop_combine_ball.h b/mp/src/game/client/hl2/c_prop_combine_ball.h
index 234fdda8..04e8e47d 100644
--- a/mp/src/game/client/hl2/c_prop_combine_ball.h
+++ b/mp/src/game/client/hl2/c_prop_combine_ball.h
@@ -1,45 +1,45 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#ifndef CPROPCOMBINEBALL_H_
-#define CPROPCOMBINEBALL_H_
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-class C_PropCombineBall : public C_BaseAnimating
-{
- DECLARE_CLASS( C_PropCombineBall, C_BaseAnimating );
- DECLARE_CLIENTCLASS();
-public:
-
- C_PropCombineBall( void );
-
- virtual RenderGroup_t GetRenderGroup( void );
-
- virtual void OnDataChanged( DataUpdateType_t updateType );
- virtual int DrawModel( int flags );
-
-protected:
-
- void DrawMotionBlur( void );
- void DrawFlicker( void );
- virtual bool InitMaterials( void );
-
- Vector m_vecLastOrigin;
- bool m_bEmit;
- float m_flRadius;
- bool m_bHeld;
- bool m_bLaunched;
-
- IMaterial *m_pFlickerMaterial;
- IMaterial *m_pBodyMaterial;
- IMaterial *m_pBlurMaterial;
-};
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef CPROPCOMBINEBALL_H_
+#define CPROPCOMBINEBALL_H_
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+class C_PropCombineBall : public C_BaseAnimating
+{
+ DECLARE_CLASS( C_PropCombineBall, C_BaseAnimating );
+ DECLARE_CLIENTCLASS();
+public:
+
+ C_PropCombineBall( void );
+
+ virtual RenderGroup_t GetRenderGroup( void );
+
+ virtual void OnDataChanged( DataUpdateType_t updateType );
+ virtual int DrawModel( int flags );
+
+protected:
+
+ void DrawMotionBlur( void );
+ void DrawFlicker( void );
+ virtual bool InitMaterials( void );
+
+ Vector m_vecLastOrigin;
+ bool m_bEmit;
+ float m_flRadius;
+ bool m_bHeld;
+ bool m_bLaunched;
+
+ IMaterial *m_pFlickerMaterial;
+ IMaterial *m_pBodyMaterial;
+ IMaterial *m_pBlurMaterial;
+};
+
+
#endif \ No newline at end of file
diff --git a/mp/src/game/client/hl2/c_rotorwash.cpp b/mp/src/game/client/hl2/c_rotorwash.cpp
index 18655ea7..439f18a3 100644
--- a/mp/src/game/client/hl2/c_rotorwash.cpp
+++ b/mp/src/game/client/hl2/c_rotorwash.cpp
@@ -1,306 +1,306 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "particlemgr.h"
-#include "particle_prototype.h"
-#include "particle_util.h"
-#include "c_te_particlesystem.h"
-#include "fx.h"
-#include "fx_quad.h"
-#include "clienteffectprecachesystem.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-// ==============================================
-// Rotorwash particle emitter
-// ==============================================
-
-#ifndef _XBOX
-
-class WashEmitter : public CSimpleEmitter
-{
-public:
-
- WashEmitter( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
-
- static WashEmitter *Create( const char *pDebugName )
- {
- return new WashEmitter( pDebugName );
- }
-
- void UpdateVelocity( SimpleParticle *pParticle, float timeDelta )
- {
- // Float up when lifetime is half gone.
- pParticle->m_vecVelocity[ 2 ] += 64 * timeDelta;
-
- // FIXME: optimize this....
- pParticle->m_vecVelocity *= ExponentialDecay( 0.8, 0.05, timeDelta );
- }
-
- virtual float UpdateRoll( SimpleParticle *pParticle, float timeDelta )
- {
- pParticle->m_flRoll += pParticle->m_flRollDelta * timeDelta;
-
- pParticle->m_flRollDelta += pParticle->m_flRollDelta * ( timeDelta * -2.0f );
-
- //Cap the minimum roll
- if ( fabs( pParticle->m_flRollDelta ) < 0.5f )
- {
- pParticle->m_flRollDelta = ( pParticle->m_flRollDelta > 0.0f ) ? 0.5f : -0.5f;
- }
-
- return pParticle->m_flRoll;
- }
-
- virtual float UpdateAlpha( const SimpleParticle *pParticle )
- {
- return ( ((float)pParticle->m_uchStartAlpha/255.0f) * sin( M_PI * (pParticle->m_flLifetime / pParticle->m_flDieTime) ) );
- }
-
-private:
- WashEmitter( const WashEmitter & );
-};
-
-#endif // !_XBOX
-
-// ==============================================
-// Rotorwash entity
-// ==============================================
-
-#define ROTORWASH_THINK_INTERVAL 0.1f
-
-class C_RotorWashEmitter : public C_BaseEntity
-{
-public:
-
- DECLARE_CLASS( C_RotorWashEmitter, C_BaseEntity );
- DECLARE_CLIENTCLASS();
-
- C_RotorWashEmitter( void );
-
- virtual void OnDataChanged( DataUpdateType_t updateType );
- virtual void ClientThink( void );
-
-protected:
-
- float m_flAltitude;
-
- PMaterialHandle m_hWaterMaterial[2];
-
-#ifndef _XBOX
- void InitSpawner( void );
- CSmartPtr<WashEmitter> m_pSimple;
-#endif // !XBOX
-};
-
-IMPLEMENT_CLIENTCLASS_DT( C_RotorWashEmitter, DT_RotorWashEmitter, CRotorWashEmitter)
- RecvPropFloat(RECVINFO(m_flAltitude)),
-END_RECV_TABLE()
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-C_RotorWashEmitter::C_RotorWashEmitter( void )
-{
-#ifndef _XBOX
- m_pSimple = NULL;
- m_hWaterMaterial[0] = NULL;
- m_hWaterMaterial[1] = NULL;
-#endif // !_XBOX
-}
-
-#ifndef _XBOX
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_RotorWashEmitter::InitSpawner( void )
-{
- if ( m_pSimple.IsValid() )
- return;
-
- m_pSimple = WashEmitter::Create( "wash" );
- m_pSimple->SetNearClip( 128, 256 );
-}
-#endif // !XBOX
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : updateType -
-//-----------------------------------------------------------------------------
-void C_RotorWashEmitter::OnDataChanged( DataUpdateType_t updateType )
-{
- BaseClass::OnDataChanged( updateType );
-
- if ( updateType == DATA_UPDATE_CREATED )
- {
- SetNextClientThink( gpGlobals->curtime + ROTORWASH_THINK_INTERVAL );
-
-#ifndef _XBOX
- InitSpawner();
-#endif // !XBOX
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_RotorWashEmitter::ClientThink( void )
-{
- SetNextClientThink( gpGlobals->curtime + ROTORWASH_THINK_INTERVAL );
-
- trace_t tr;
- UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin()+(Vector(0, 0, -1024)), (MASK_SOLID_BRUSHONLY|CONTENTS_WATER|CONTENTS_SLIME), NULL, COLLISION_GROUP_NONE, &tr );
-
- if ( /*!m_bIgnoreSolid && */(tr.fraction == 1.0f || tr.startsolid || tr.allsolid) )
- return;
-
- // If we hit the skybox, don't do it either
- if ( tr.surface.flags & SURF_SKY )
- return;
-
- float heightScale = RemapValClamped( tr.fraction * 1024, 512, 1024, 1.0f, 0.0f );
-
- Vector vecDustColor;
-
- if ( tr.contents & CONTENTS_WATER )
- {
- vecDustColor.x = 0.8f;
- vecDustColor.y = 0.8f;
- vecDustColor.z = 0.75f;
- }
- else if ( tr.contents & CONTENTS_SLIME )
- {
- vecDustColor.x = 0.6f;
- vecDustColor.y = 0.5f;
- vecDustColor.z = 0.15f;
- }
- else
- {
- vecDustColor.x = 0.35f;
- vecDustColor.y = 0.3f;
- vecDustColor.z = 0.25f;
- }
-
-#ifndef _XBOX
-
- InitSpawner();
-
- if ( m_pSimple.IsValid() == false )
- return;
-
- m_pSimple->SetSortOrigin( GetAbsOrigin() );
-
- PMaterialHandle *hMaterial;
-
- // Cache and set our material based on the surface we're over (ie. water)
- if ( tr.contents & (CONTENTS_WATER|CONTENTS_SLIME) )
- {
- if ( m_hWaterMaterial[0] == NULL )
- {
- m_hWaterMaterial[0] = m_pSimple->GetPMaterial("effects/splash1");
- m_hWaterMaterial[1] = m_pSimple->GetPMaterial("effects/splash2");
- }
- hMaterial = m_hWaterMaterial;
- }
- else
- {
- hMaterial = g_Mat_DustPuff;
- }
-
-#endif // !XBOX
-
- // If we're above water, make ripples
- if ( tr.contents & (CONTENTS_WATER|CONTENTS_SLIME) )
- {
- float flScale = random->RandomFloat( 7.5f, 8.5f );
-
- Vector color = Vector( 0.8f, 0.8f, 0.75f );
- Vector startPos = tr.endpos + Vector(0,0,8);
- Vector endPos = tr.endpos + Vector(0,0,-64);
-
- if ( tr.fraction < 1.0f )
- {
- //Add a ripple quad to the surface
- FX_AddQuad( tr.endpos + ( tr.plane.normal * 0.5f ),
- tr.plane.normal,
- 64.0f * flScale,
- 128.0f * flScale,
- 0.8f,
- 0.75f * heightScale,
- 0.0f,
- 0.75f,
- random->RandomFloat( 0, 360 ),
- random->RandomFloat( -2.0f, 2.0f ),
- vecDustColor,
- 0.2f,
- "effects/splashwake3",
- (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
- }
- }
-
-#ifndef _XBOX
- int numRingSprites = 32;
- float yaw = random->RandomFloat( 0, 2*M_PI ); // Randomly placed on the unit circle
- float yawIncr = (2*M_PI) / numRingSprites;
- Vector vecForward;
- Vector offset;
- SimpleParticle *pParticle;
-
- // Draw the rings
- for ( int i = 0; i < numRingSprites; i++ )
- {
- // Get our x,y on the unit circle
- SinCos( yaw, &vecForward.y, &vecForward.x );
-
- // Increment ahead
- yaw += yawIncr;
-
- // @NOTE toml (3-28-07): broke out following expression because vc2005 optimizer was screwing up in presence of SinCos inline assembly. Would also
- // go away if offset were referenced below as in the AddLineOverlay()
- //offset = ( RandomVector( -4.0f, 4.0f ) + tr.endpos ) + ( vecForward * 128.0f );
-
- offset = vecForward * 128.0f;
- offset += tr.endpos + RandomVector( -4.0f, 4.0f );
-
-
- pParticle = (SimpleParticle *) m_pSimple->AddParticle( sizeof(SimpleParticle), hMaterial[random->RandomInt(0,1)], offset );
-
- if ( pParticle != NULL )
- {
- pParticle->m_flLifetime = 0.0f;
- pParticle->m_flDieTime = random->RandomFloat( 0.25f, 1.0f );
-
- pParticle->m_vecVelocity = vecForward * random->RandomFloat( 1000, 1500 );
-
- #if __EXPLOSION_DEBUG
- debugoverlay->AddLineOverlay( m_vecOrigin, m_vecOrigin + pParticle->m_vecVelocity, 255, 0, 0, false, 3 );
- #endif
-
- if ( tr.contents & CONTENTS_SLIME )
- {
- vecDustColor.x = random->RandomFloat( 0.4f, 0.6f );
- vecDustColor.y = random->RandomFloat( 0.3f, 0.5f );
- vecDustColor.z = random->RandomFloat( 0.1f, 0.2f );
- }
-
- pParticle->m_uchColor[0] = vecDustColor.x * 255.0f;
- pParticle->m_uchColor[1] = vecDustColor.y * 255.0f;
- pParticle->m_uchColor[2] = vecDustColor.z * 255.0f;
-
- pParticle->m_uchStartSize = random->RandomInt( 16, 64 );
- pParticle->m_uchEndSize = pParticle->m_uchStartSize * 4;
-
- pParticle->m_uchStartAlpha = random->RandomFloat( 16, 32 ) * heightScale;
- pParticle->m_uchEndAlpha = 0;
-
- pParticle->m_flRoll = random->RandomInt( 0, 360 );
- pParticle->m_flRollDelta = random->RandomFloat( -16.0f, 16.0f );
- }
- }
-#endif // !XBOX
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "particlemgr.h"
+#include "particle_prototype.h"
+#include "particle_util.h"
+#include "c_te_particlesystem.h"
+#include "fx.h"
+#include "fx_quad.h"
+#include "clienteffectprecachesystem.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+// ==============================================
+// Rotorwash particle emitter
+// ==============================================
+
+#ifndef _XBOX
+
+class WashEmitter : public CSimpleEmitter
+{
+public:
+
+ WashEmitter( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
+
+ static WashEmitter *Create( const char *pDebugName )
+ {
+ return new WashEmitter( pDebugName );
+ }
+
+ void UpdateVelocity( SimpleParticle *pParticle, float timeDelta )
+ {
+ // Float up when lifetime is half gone.
+ pParticle->m_vecVelocity[ 2 ] += 64 * timeDelta;
+
+ // FIXME: optimize this....
+ pParticle->m_vecVelocity *= ExponentialDecay( 0.8, 0.05, timeDelta );
+ }
+
+ virtual float UpdateRoll( SimpleParticle *pParticle, float timeDelta )
+ {
+ pParticle->m_flRoll += pParticle->m_flRollDelta * timeDelta;
+
+ pParticle->m_flRollDelta += pParticle->m_flRollDelta * ( timeDelta * -2.0f );
+
+ //Cap the minimum roll
+ if ( fabs( pParticle->m_flRollDelta ) < 0.5f )
+ {
+ pParticle->m_flRollDelta = ( pParticle->m_flRollDelta > 0.0f ) ? 0.5f : -0.5f;
+ }
+
+ return pParticle->m_flRoll;
+ }
+
+ virtual float UpdateAlpha( const SimpleParticle *pParticle )
+ {
+ return ( ((float)pParticle->m_uchStartAlpha/255.0f) * sin( M_PI * (pParticle->m_flLifetime / pParticle->m_flDieTime) ) );
+ }
+
+private:
+ WashEmitter( const WashEmitter & );
+};
+
+#endif // !_XBOX
+
+// ==============================================
+// Rotorwash entity
+// ==============================================
+
+#define ROTORWASH_THINK_INTERVAL 0.1f
+
+class C_RotorWashEmitter : public C_BaseEntity
+{
+public:
+
+ DECLARE_CLASS( C_RotorWashEmitter, C_BaseEntity );
+ DECLARE_CLIENTCLASS();
+
+ C_RotorWashEmitter( void );
+
+ virtual void OnDataChanged( DataUpdateType_t updateType );
+ virtual void ClientThink( void );
+
+protected:
+
+ float m_flAltitude;
+
+ PMaterialHandle m_hWaterMaterial[2];
+
+#ifndef _XBOX
+ void InitSpawner( void );
+ CSmartPtr<WashEmitter> m_pSimple;
+#endif // !XBOX
+};
+
+IMPLEMENT_CLIENTCLASS_DT( C_RotorWashEmitter, DT_RotorWashEmitter, CRotorWashEmitter)
+ RecvPropFloat(RECVINFO(m_flAltitude)),
+END_RECV_TABLE()
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_RotorWashEmitter::C_RotorWashEmitter( void )
+{
+#ifndef _XBOX
+ m_pSimple = NULL;
+ m_hWaterMaterial[0] = NULL;
+ m_hWaterMaterial[1] = NULL;
+#endif // !_XBOX
+}
+
+#ifndef _XBOX
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_RotorWashEmitter::InitSpawner( void )
+{
+ if ( m_pSimple.IsValid() )
+ return;
+
+ m_pSimple = WashEmitter::Create( "wash" );
+ m_pSimple->SetNearClip( 128, 256 );
+}
+#endif // !XBOX
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : updateType -
+//-----------------------------------------------------------------------------
+void C_RotorWashEmitter::OnDataChanged( DataUpdateType_t updateType )
+{
+ BaseClass::OnDataChanged( updateType );
+
+ if ( updateType == DATA_UPDATE_CREATED )
+ {
+ SetNextClientThink( gpGlobals->curtime + ROTORWASH_THINK_INTERVAL );
+
+#ifndef _XBOX
+ InitSpawner();
+#endif // !XBOX
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_RotorWashEmitter::ClientThink( void )
+{
+ SetNextClientThink( gpGlobals->curtime + ROTORWASH_THINK_INTERVAL );
+
+ trace_t tr;
+ UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin()+(Vector(0, 0, -1024)), (MASK_SOLID_BRUSHONLY|CONTENTS_WATER|CONTENTS_SLIME), NULL, COLLISION_GROUP_NONE, &tr );
+
+ if ( /*!m_bIgnoreSolid && */(tr.fraction == 1.0f || tr.startsolid || tr.allsolid) )
+ return;
+
+ // If we hit the skybox, don't do it either
+ if ( tr.surface.flags & SURF_SKY )
+ return;
+
+ float heightScale = RemapValClamped( tr.fraction * 1024, 512, 1024, 1.0f, 0.0f );
+
+ Vector vecDustColor;
+
+ if ( tr.contents & CONTENTS_WATER )
+ {
+ vecDustColor.x = 0.8f;
+ vecDustColor.y = 0.8f;
+ vecDustColor.z = 0.75f;
+ }
+ else if ( tr.contents & CONTENTS_SLIME )
+ {
+ vecDustColor.x = 0.6f;
+ vecDustColor.y = 0.5f;
+ vecDustColor.z = 0.15f;
+ }
+ else
+ {
+ vecDustColor.x = 0.35f;
+ vecDustColor.y = 0.3f;
+ vecDustColor.z = 0.25f;
+ }
+
+#ifndef _XBOX
+
+ InitSpawner();
+
+ if ( m_pSimple.IsValid() == false )
+ return;
+
+ m_pSimple->SetSortOrigin( GetAbsOrigin() );
+
+ PMaterialHandle *hMaterial;
+
+ // Cache and set our material based on the surface we're over (ie. water)
+ if ( tr.contents & (CONTENTS_WATER|CONTENTS_SLIME) )
+ {
+ if ( m_hWaterMaterial[0] == NULL )
+ {
+ m_hWaterMaterial[0] = m_pSimple->GetPMaterial("effects/splash1");
+ m_hWaterMaterial[1] = m_pSimple->GetPMaterial("effects/splash2");
+ }
+ hMaterial = m_hWaterMaterial;
+ }
+ else
+ {
+ hMaterial = g_Mat_DustPuff;
+ }
+
+#endif // !XBOX
+
+ // If we're above water, make ripples
+ if ( tr.contents & (CONTENTS_WATER|CONTENTS_SLIME) )
+ {
+ float flScale = random->RandomFloat( 7.5f, 8.5f );
+
+ Vector color = Vector( 0.8f, 0.8f, 0.75f );
+ Vector startPos = tr.endpos + Vector(0,0,8);
+ Vector endPos = tr.endpos + Vector(0,0,-64);
+
+ if ( tr.fraction < 1.0f )
+ {
+ //Add a ripple quad to the surface
+ FX_AddQuad( tr.endpos + ( tr.plane.normal * 0.5f ),
+ tr.plane.normal,
+ 64.0f * flScale,
+ 128.0f * flScale,
+ 0.8f,
+ 0.75f * heightScale,
+ 0.0f,
+ 0.75f,
+ random->RandomFloat( 0, 360 ),
+ random->RandomFloat( -2.0f, 2.0f ),
+ vecDustColor,
+ 0.2f,
+ "effects/splashwake3",
+ (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
+ }
+ }
+
+#ifndef _XBOX
+ int numRingSprites = 32;
+ float yaw = random->RandomFloat( 0, 2*M_PI ); // Randomly placed on the unit circle
+ float yawIncr = (2*M_PI) / numRingSprites;
+ Vector vecForward;
+ Vector offset;
+ SimpleParticle *pParticle;
+
+ // Draw the rings
+ for ( int i = 0; i < numRingSprites; i++ )
+ {
+ // Get our x,y on the unit circle
+ SinCos( yaw, &vecForward.y, &vecForward.x );
+
+ // Increment ahead
+ yaw += yawIncr;
+
+ // @NOTE toml (3-28-07): broke out following expression because vc2005 optimizer was screwing up in presence of SinCos inline assembly. Would also
+ // go away if offset were referenced below as in the AddLineOverlay()
+ //offset = ( RandomVector( -4.0f, 4.0f ) + tr.endpos ) + ( vecForward * 128.0f );
+
+ offset = vecForward * 128.0f;
+ offset += tr.endpos + RandomVector( -4.0f, 4.0f );
+
+
+ pParticle = (SimpleParticle *) m_pSimple->AddParticle( sizeof(SimpleParticle), hMaterial[random->RandomInt(0,1)], offset );
+
+ if ( pParticle != NULL )
+ {
+ pParticle->m_flLifetime = 0.0f;
+ pParticle->m_flDieTime = random->RandomFloat( 0.25f, 1.0f );
+
+ pParticle->m_vecVelocity = vecForward * random->RandomFloat( 1000, 1500 );
+
+ #if __EXPLOSION_DEBUG
+ debugoverlay->AddLineOverlay( m_vecOrigin, m_vecOrigin + pParticle->m_vecVelocity, 255, 0, 0, false, 3 );
+ #endif
+
+ if ( tr.contents & CONTENTS_SLIME )
+ {
+ vecDustColor.x = random->RandomFloat( 0.4f, 0.6f );
+ vecDustColor.y = random->RandomFloat( 0.3f, 0.5f );
+ vecDustColor.z = random->RandomFloat( 0.1f, 0.2f );
+ }
+
+ pParticle->m_uchColor[0] = vecDustColor.x * 255.0f;
+ pParticle->m_uchColor[1] = vecDustColor.y * 255.0f;
+ pParticle->m_uchColor[2] = vecDustColor.z * 255.0f;
+
+ pParticle->m_uchStartSize = random->RandomInt( 16, 64 );
+ pParticle->m_uchEndSize = pParticle->m_uchStartSize * 4;
+
+ pParticle->m_uchStartAlpha = random->RandomFloat( 16, 32 ) * heightScale;
+ pParticle->m_uchEndAlpha = 0;
+
+ pParticle->m_flRoll = random->RandomInt( 0, 360 );
+ pParticle->m_flRollDelta = random->RandomFloat( -16.0f, 16.0f );
+ }
+ }
+#endif // !XBOX
+}
diff --git a/mp/src/game/client/hl2/c_script_intro.cpp b/mp/src/game/client/hl2/c_script_intro.cpp
index de82e70b..eb97cb4f 100644
--- a/mp/src/game/client/hl2/c_script_intro.cpp
+++ b/mp/src/game/client/hl2/c_script_intro.cpp
@@ -1,327 +1,327 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-#include "cbase.h"
-#include "shareddefs.h"
-#include "materialsystem/imesh.h"
-#include "view.h"
-#include "iviewrender.h"
-#include "view_shared.h"
-#include "viewrender.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-extern IntroData_t *g_pIntroData;
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-class C_ScriptIntro : public C_BaseEntity
-{
- DECLARE_CLASS( C_ScriptIntro, C_BaseEntity );
-public:
- DECLARE_CLIENTCLASS();
-
- C_ScriptIntro( void );
- ~C_ScriptIntro( void );
- void PostDataUpdate( DataUpdateType_t updateType );
- void ClientThink( void );
- void CalculateFOV( void );
- void CalculateAlpha( void );
-
-public:
- int m_iNextFOV;
- int m_iFOV;
- int m_iPrevFOV;
- int m_iStartFOV;
- float m_flNextFOVBlendTime;
- float m_flFOVBlendStartTime;
- bool m_bAlternateFOV;
-
- // Our intro data block
- IntroData_t m_IntroData;
-
-private:
- Vector m_vecCameraView;
- QAngle m_vecCameraViewAngles;
- int m_iBlendMode;
- int m_iNextBlendMode;
- float m_flNextBlendTime;
- float m_flBlendStartTime;
- bool m_bActive;
- EHANDLE m_hCameraEntity;
-
- // Fades
- float m_flFadeColor[3]; // Server's desired fade color
- float m_flFadeAlpha; // Server's desired fade alpha
- float m_flPrevServerFadeAlpha; // Previous server's desired fade alpha
- float m_flFadeDuration; // Time it should take to reach the server's new fade alpha
- float m_flFadeTimeStartedAt; // Time at which we last recieved a new desired fade alpha
- float m_flFadeAlphaStartedAt; // Alpha at which we last received a new desired fade alpha
-};
-
-IMPLEMENT_CLIENTCLASS_DT( C_ScriptIntro, DT_ScriptIntro, CScriptIntro )
- RecvPropVector( RECVINFO( m_vecCameraView ) ),
- RecvPropVector( RECVINFO( m_vecCameraViewAngles ) ),
- RecvPropInt( RECVINFO( m_iBlendMode ) ),
- RecvPropInt( RECVINFO( m_iNextBlendMode ) ),
- RecvPropFloat( RECVINFO( m_flNextBlendTime ) ),
- RecvPropFloat( RECVINFO( m_flBlendStartTime ) ),
- RecvPropBool( RECVINFO( m_bActive ) ),
-
- // Fov & fov blends
- RecvPropInt( RECVINFO( m_iFOV ) ),
- RecvPropInt( RECVINFO( m_iNextFOV ) ),
- RecvPropInt( RECVINFO( m_iStartFOV ) ),
- RecvPropFloat( RECVINFO( m_flNextFOVBlendTime ) ),
- RecvPropFloat( RECVINFO( m_flFOVBlendStartTime ) ),
- RecvPropBool( RECVINFO( m_bAlternateFOV ) ),
-
- // Fades
- RecvPropFloat( RECVINFO( m_flFadeAlpha ) ),
- RecvPropArray( RecvPropFloat( RECVINFO( m_flFadeColor[0] ) ), m_flFadeColor ),
- RecvPropFloat( RECVINFO( m_flFadeDuration ) ),
- RecvPropEHandle(RECVINFO(m_hCameraEntity)),
-END_RECV_TABLE()
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-C_ScriptIntro::C_ScriptIntro( void )
-{
- m_bActive = false;
- m_vecCameraView = vec3_origin;
- m_vecCameraViewAngles = vec3_angle;
- m_iBlendMode = 0;
- m_iNextBlendMode = 0;
- m_flNextBlendTime = 0;
- m_flBlendStartTime = 0;
- m_IntroData.m_playerViewFOV = 0;
- m_flFadeAlpha = 0;
- m_flPrevServerFadeAlpha = 0;
- m_flFadeDuration = 0;
- m_flFadeTimeStartedAt = 0;
- m_flFadeAlphaStartedAt = 0;
- m_hCameraEntity = NULL;
- m_iPrevFOV = 0;
- m_iStartFOV = 0;
-
- g_pIntroData = NULL;
-
- // Setup fade colors
- m_IntroData.m_flCurrentFadeColor[0] = m_flFadeColor[0];
- m_IntroData.m_flCurrentFadeColor[1] = m_flFadeColor[1];
- m_IntroData.m_flCurrentFadeColor[2] = m_flFadeColor[2];
- m_IntroData.m_flCurrentFadeColor[3] = m_flFadeAlpha;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-C_ScriptIntro::~C_ScriptIntro( void )
-{
- g_pIntroData = NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_ScriptIntro::PostDataUpdate( DataUpdateType_t updateType )
-{
- BaseClass::PostDataUpdate( updateType );
-
- SetNextClientThink( CLIENT_THINK_ALWAYS );
-
- // Fill out the intro data
- m_IntroData.m_vecCameraView = m_vecCameraView;
- m_IntroData.m_vecCameraViewAngles = m_vecCameraViewAngles;
- m_IntroData.m_Passes.SetCount( 0 );
-
- // Find/Create our first pass
- IntroDataBlendPass_t *pass1;
- if ( m_IntroData.m_Passes.Count() == 0 )
- {
- pass1 = &m_IntroData.m_Passes[m_IntroData.m_Passes.AddToTail()];
- }
- else
- {
- pass1 = &m_IntroData.m_Passes[0];
- }
- Assert(pass1);
- pass1->m_BlendMode = m_iBlendMode;
- pass1->m_Alpha = 1.0f;
-
- if ( m_vecCameraView == vec3_origin )
- {
- m_IntroData.m_bDrawPrimary = false;
- }
- else
- {
- m_IntroData.m_bDrawPrimary = true;
- }
-
- // If we're currently blending to a new mode, set the second pass
- if ( m_flNextBlendTime > gpGlobals->curtime )
- {
- IntroDataBlendPass_t *pass2;
- if ( m_IntroData.m_Passes.Count() < 2 )
- {
- pass2 = &m_IntroData.m_Passes[m_IntroData.m_Passes.AddToTail()];
-
- //Msg("STARTED BLEND: Mode %d to %d.\n", m_IntroData.m_Passes[0].m_BlendMode, m_iNextBlendMode );
- }
- else
- {
- pass2 = &m_IntroData.m_Passes[1];
-
- Assert( pass2->m_BlendMode == m_iNextBlendMode );
- }
- Assert(pass2);
- pass2->m_BlendMode = m_iNextBlendMode;
- pass2->m_Alpha = 0.0f;
- }
- else if ( m_IntroData.m_Passes.Count() == 2 )
- {
- C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
- if ( !player )
- return;
-
- //Msg("FINISHED BLEND.\n");
- m_IntroData.m_Passes.Remove(1);
- }
-
- // Set the introdata our data chunk
- if ( m_bActive )
- {
- g_pIntroData = &m_IntroData;
- }
- else if ( g_pIntroData == &m_IntroData )
- {
- g_pIntroData = NULL;
- }
-
- // Update the fade color
- m_IntroData.m_flCurrentFadeColor[0] = m_flFadeColor[0];
- m_IntroData.m_flCurrentFadeColor[1] = m_flFadeColor[1];
- m_IntroData.m_flCurrentFadeColor[2] = m_flFadeColor[2];
-
- // Started fading?
- if ( m_flFadeAlpha != m_flPrevServerFadeAlpha )
- {
- m_flFadeTimeStartedAt = gpGlobals->curtime;
- m_flFadeAlphaStartedAt = m_IntroData.m_flCurrentFadeColor[3];
- m_flPrevServerFadeAlpha = m_flFadeAlpha;
-
- if ( !m_flFadeDuration )
- {
- m_flFadeDuration = 0.01;
- }
-
- //Msg("STARTING NEW FADE: alpha %.2f, duration %.2f.\n", m_flFadeAlpha, m_flFadeDuration );
- }
-
- if ( m_iPrevFOV != m_iFOV )
- {
- m_IntroData.m_playerViewFOV = m_iFOV;
- m_iPrevFOV = m_iFOV;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_ScriptIntro::ClientThink( void )
-{
- Assert( m_IntroData.m_Passes.Count() <= 2 );
-
- if ( m_hCameraEntity )
- {
- m_IntroData.m_vecCameraView = m_hCameraEntity->GetAbsOrigin();
- m_IntroData.m_vecCameraViewAngles = m_hCameraEntity->GetAbsAngles();
- }
-
- CalculateFOV();
- CalculateAlpha();
-
- // Calculate the blend levels of each pass
- float flPerc = 1.0;
- if ( (m_flNextBlendTime - m_flBlendStartTime) != 0 )
- {
- flPerc = clamp( (gpGlobals->curtime - m_flBlendStartTime) / (m_flNextBlendTime - m_flBlendStartTime), 0, 1 );
- }
-
- // Detect when we're finished blending
- if ( flPerc >= 1.0 )
- {
- if ( m_IntroData.m_Passes.Count() == 2 )
- {
- // We're done blending
- m_IntroData.m_Passes[0].m_BlendMode = m_IntroData.m_Passes[1].m_BlendMode;
- m_IntroData.m_Passes[0].m_Alpha = 1.0;
- m_IntroData.m_Passes.Remove(1);
-
- //Msg("FINISHED BLEND.\n");
- }
- else
- {
- m_IntroData.m_Passes[0].m_Alpha = 1.0f;
- }
- return;
- }
-
- /*
- if ( m_flNextBlendTime >= gpGlobals->curtime )
- {
- Msg("INTRO BLENDING: Blending from mode %d to %d.\n", m_IntroData.m_Passes[0].m_BlendMode, m_IntroData.m_Passes[1].m_BlendMode );
- Msg(" curtime %.2f StartedAt %.2f FinishAt: %.2f\n", gpGlobals->curtime, m_flBlendStartTime, m_flNextBlendTime );
- Msg(" Perc: %.2f\n", flPerc );
- }
- */
-
- if ( m_IntroData.m_Passes.Count() == 2 )
- {
- m_IntroData.m_Passes[0].m_Alpha = 1.0 - flPerc;
- m_IntroData.m_Passes[1].m_Alpha = flPerc;
- }
- else
- {
- m_IntroData.m_Passes[0].m_Alpha = 1.0 - flPerc;
- }
-}
-
-extern float ScriptInfo_CalculateFOV( float flFOVBlendStartTime, float flNextFOVBlendTime, int nFOV, int nNextFOV, bool bSplineRamp );
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_ScriptIntro::CalculateFOV( void )
-{
- // We're past our blending time so we're at our target
- if ( m_flNextFOVBlendTime >= gpGlobals->curtime )
- {
- // Calculate where we're at
- m_IntroData.m_playerViewFOV = ScriptInfo_CalculateFOV( m_flFOVBlendStartTime, m_flNextFOVBlendTime, m_iStartFOV, m_iNextFOV, m_bAlternateFOV );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_ScriptIntro::CalculateAlpha( void )
-{
- // Fill out the fade alpha
- float flNewAlpha = RemapValClamped( gpGlobals->curtime, m_flFadeTimeStartedAt, m_flFadeTimeStartedAt + m_flFadeDuration, m_flFadeAlphaStartedAt, m_flFadeAlpha );
- /*
- if ( m_IntroData.m_flCurrentFadeColor[3] != flNewAlpha )
- {
- Msg("INTRO FADING: curtime %.2f StartedAt %.2f Duration: %.2f\n", gpGlobals->curtime, m_flFadeTimeStartedAt, m_flFadeDuration );
- Msg(" TimePassed %.2f Alpha: %.2f\n", RemapValClamped( gpGlobals->curtime, m_flFadeTimeStartedAt, m_flFadeTimeStartedAt + m_flFadeDuration, 0.0, 1.0 ), m_IntroData.m_flCurrentFadeColor[3] );
- }
- */
-
- m_IntroData.m_flCurrentFadeColor[3] = flNewAlpha;
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+#include "cbase.h"
+#include "shareddefs.h"
+#include "materialsystem/imesh.h"
+#include "view.h"
+#include "iviewrender.h"
+#include "view_shared.h"
+#include "viewrender.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+extern IntroData_t *g_pIntroData;
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class C_ScriptIntro : public C_BaseEntity
+{
+ DECLARE_CLASS( C_ScriptIntro, C_BaseEntity );
+public:
+ DECLARE_CLIENTCLASS();
+
+ C_ScriptIntro( void );
+ ~C_ScriptIntro( void );
+ void PostDataUpdate( DataUpdateType_t updateType );
+ void ClientThink( void );
+ void CalculateFOV( void );
+ void CalculateAlpha( void );
+
+public:
+ int m_iNextFOV;
+ int m_iFOV;
+ int m_iPrevFOV;
+ int m_iStartFOV;
+ float m_flNextFOVBlendTime;
+ float m_flFOVBlendStartTime;
+ bool m_bAlternateFOV;
+
+ // Our intro data block
+ IntroData_t m_IntroData;
+
+private:
+ Vector m_vecCameraView;
+ QAngle m_vecCameraViewAngles;
+ int m_iBlendMode;
+ int m_iNextBlendMode;
+ float m_flNextBlendTime;
+ float m_flBlendStartTime;
+ bool m_bActive;
+ EHANDLE m_hCameraEntity;
+
+ // Fades
+ float m_flFadeColor[3]; // Server's desired fade color
+ float m_flFadeAlpha; // Server's desired fade alpha
+ float m_flPrevServerFadeAlpha; // Previous server's desired fade alpha
+ float m_flFadeDuration; // Time it should take to reach the server's new fade alpha
+ float m_flFadeTimeStartedAt; // Time at which we last recieved a new desired fade alpha
+ float m_flFadeAlphaStartedAt; // Alpha at which we last received a new desired fade alpha
+};
+
+IMPLEMENT_CLIENTCLASS_DT( C_ScriptIntro, DT_ScriptIntro, CScriptIntro )
+ RecvPropVector( RECVINFO( m_vecCameraView ) ),
+ RecvPropVector( RECVINFO( m_vecCameraViewAngles ) ),
+ RecvPropInt( RECVINFO( m_iBlendMode ) ),
+ RecvPropInt( RECVINFO( m_iNextBlendMode ) ),
+ RecvPropFloat( RECVINFO( m_flNextBlendTime ) ),
+ RecvPropFloat( RECVINFO( m_flBlendStartTime ) ),
+ RecvPropBool( RECVINFO( m_bActive ) ),
+
+ // Fov & fov blends
+ RecvPropInt( RECVINFO( m_iFOV ) ),
+ RecvPropInt( RECVINFO( m_iNextFOV ) ),
+ RecvPropInt( RECVINFO( m_iStartFOV ) ),
+ RecvPropFloat( RECVINFO( m_flNextFOVBlendTime ) ),
+ RecvPropFloat( RECVINFO( m_flFOVBlendStartTime ) ),
+ RecvPropBool( RECVINFO( m_bAlternateFOV ) ),
+
+ // Fades
+ RecvPropFloat( RECVINFO( m_flFadeAlpha ) ),
+ RecvPropArray( RecvPropFloat( RECVINFO( m_flFadeColor[0] ) ), m_flFadeColor ),
+ RecvPropFloat( RECVINFO( m_flFadeDuration ) ),
+ RecvPropEHandle(RECVINFO(m_hCameraEntity)),
+END_RECV_TABLE()
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_ScriptIntro::C_ScriptIntro( void )
+{
+ m_bActive = false;
+ m_vecCameraView = vec3_origin;
+ m_vecCameraViewAngles = vec3_angle;
+ m_iBlendMode = 0;
+ m_iNextBlendMode = 0;
+ m_flNextBlendTime = 0;
+ m_flBlendStartTime = 0;
+ m_IntroData.m_playerViewFOV = 0;
+ m_flFadeAlpha = 0;
+ m_flPrevServerFadeAlpha = 0;
+ m_flFadeDuration = 0;
+ m_flFadeTimeStartedAt = 0;
+ m_flFadeAlphaStartedAt = 0;
+ m_hCameraEntity = NULL;
+ m_iPrevFOV = 0;
+ m_iStartFOV = 0;
+
+ g_pIntroData = NULL;
+
+ // Setup fade colors
+ m_IntroData.m_flCurrentFadeColor[0] = m_flFadeColor[0];
+ m_IntroData.m_flCurrentFadeColor[1] = m_flFadeColor[1];
+ m_IntroData.m_flCurrentFadeColor[2] = m_flFadeColor[2];
+ m_IntroData.m_flCurrentFadeColor[3] = m_flFadeAlpha;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_ScriptIntro::~C_ScriptIntro( void )
+{
+ g_pIntroData = NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_ScriptIntro::PostDataUpdate( DataUpdateType_t updateType )
+{
+ BaseClass::PostDataUpdate( updateType );
+
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+
+ // Fill out the intro data
+ m_IntroData.m_vecCameraView = m_vecCameraView;
+ m_IntroData.m_vecCameraViewAngles = m_vecCameraViewAngles;
+ m_IntroData.m_Passes.SetCount( 0 );
+
+ // Find/Create our first pass
+ IntroDataBlendPass_t *pass1;
+ if ( m_IntroData.m_Passes.Count() == 0 )
+ {
+ pass1 = &m_IntroData.m_Passes[m_IntroData.m_Passes.AddToTail()];
+ }
+ else
+ {
+ pass1 = &m_IntroData.m_Passes[0];
+ }
+ Assert(pass1);
+ pass1->m_BlendMode = m_iBlendMode;
+ pass1->m_Alpha = 1.0f;
+
+ if ( m_vecCameraView == vec3_origin )
+ {
+ m_IntroData.m_bDrawPrimary = false;
+ }
+ else
+ {
+ m_IntroData.m_bDrawPrimary = true;
+ }
+
+ // If we're currently blending to a new mode, set the second pass
+ if ( m_flNextBlendTime > gpGlobals->curtime )
+ {
+ IntroDataBlendPass_t *pass2;
+ if ( m_IntroData.m_Passes.Count() < 2 )
+ {
+ pass2 = &m_IntroData.m_Passes[m_IntroData.m_Passes.AddToTail()];
+
+ //Msg("STARTED BLEND: Mode %d to %d.\n", m_IntroData.m_Passes[0].m_BlendMode, m_iNextBlendMode );
+ }
+ else
+ {
+ pass2 = &m_IntroData.m_Passes[1];
+
+ Assert( pass2->m_BlendMode == m_iNextBlendMode );
+ }
+ Assert(pass2);
+ pass2->m_BlendMode = m_iNextBlendMode;
+ pass2->m_Alpha = 0.0f;
+ }
+ else if ( m_IntroData.m_Passes.Count() == 2 )
+ {
+ C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
+ if ( !player )
+ return;
+
+ //Msg("FINISHED BLEND.\n");
+ m_IntroData.m_Passes.Remove(1);
+ }
+
+ // Set the introdata our data chunk
+ if ( m_bActive )
+ {
+ g_pIntroData = &m_IntroData;
+ }
+ else if ( g_pIntroData == &m_IntroData )
+ {
+ g_pIntroData = NULL;
+ }
+
+ // Update the fade color
+ m_IntroData.m_flCurrentFadeColor[0] = m_flFadeColor[0];
+ m_IntroData.m_flCurrentFadeColor[1] = m_flFadeColor[1];
+ m_IntroData.m_flCurrentFadeColor[2] = m_flFadeColor[2];
+
+ // Started fading?
+ if ( m_flFadeAlpha != m_flPrevServerFadeAlpha )
+ {
+ m_flFadeTimeStartedAt = gpGlobals->curtime;
+ m_flFadeAlphaStartedAt = m_IntroData.m_flCurrentFadeColor[3];
+ m_flPrevServerFadeAlpha = m_flFadeAlpha;
+
+ if ( !m_flFadeDuration )
+ {
+ m_flFadeDuration = 0.01;
+ }
+
+ //Msg("STARTING NEW FADE: alpha %.2f, duration %.2f.\n", m_flFadeAlpha, m_flFadeDuration );
+ }
+
+ if ( m_iPrevFOV != m_iFOV )
+ {
+ m_IntroData.m_playerViewFOV = m_iFOV;
+ m_iPrevFOV = m_iFOV;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_ScriptIntro::ClientThink( void )
+{
+ Assert( m_IntroData.m_Passes.Count() <= 2 );
+
+ if ( m_hCameraEntity )
+ {
+ m_IntroData.m_vecCameraView = m_hCameraEntity->GetAbsOrigin();
+ m_IntroData.m_vecCameraViewAngles = m_hCameraEntity->GetAbsAngles();
+ }
+
+ CalculateFOV();
+ CalculateAlpha();
+
+ // Calculate the blend levels of each pass
+ float flPerc = 1.0;
+ if ( (m_flNextBlendTime - m_flBlendStartTime) != 0 )
+ {
+ flPerc = clamp( (gpGlobals->curtime - m_flBlendStartTime) / (m_flNextBlendTime - m_flBlendStartTime), 0, 1 );
+ }
+
+ // Detect when we're finished blending
+ if ( flPerc >= 1.0 )
+ {
+ if ( m_IntroData.m_Passes.Count() == 2 )
+ {
+ // We're done blending
+ m_IntroData.m_Passes[0].m_BlendMode = m_IntroData.m_Passes[1].m_BlendMode;
+ m_IntroData.m_Passes[0].m_Alpha = 1.0;
+ m_IntroData.m_Passes.Remove(1);
+
+ //Msg("FINISHED BLEND.\n");
+ }
+ else
+ {
+ m_IntroData.m_Passes[0].m_Alpha = 1.0f;
+ }
+ return;
+ }
+
+ /*
+ if ( m_flNextBlendTime >= gpGlobals->curtime )
+ {
+ Msg("INTRO BLENDING: Blending from mode %d to %d.\n", m_IntroData.m_Passes[0].m_BlendMode, m_IntroData.m_Passes[1].m_BlendMode );
+ Msg(" curtime %.2f StartedAt %.2f FinishAt: %.2f\n", gpGlobals->curtime, m_flBlendStartTime, m_flNextBlendTime );
+ Msg(" Perc: %.2f\n", flPerc );
+ }
+ */
+
+ if ( m_IntroData.m_Passes.Count() == 2 )
+ {
+ m_IntroData.m_Passes[0].m_Alpha = 1.0 - flPerc;
+ m_IntroData.m_Passes[1].m_Alpha = flPerc;
+ }
+ else
+ {
+ m_IntroData.m_Passes[0].m_Alpha = 1.0 - flPerc;
+ }
+}
+
+extern float ScriptInfo_CalculateFOV( float flFOVBlendStartTime, float flNextFOVBlendTime, int nFOV, int nNextFOV, bool bSplineRamp );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_ScriptIntro::CalculateFOV( void )
+{
+ // We're past our blending time so we're at our target
+ if ( m_flNextFOVBlendTime >= gpGlobals->curtime )
+ {
+ // Calculate where we're at
+ m_IntroData.m_playerViewFOV = ScriptInfo_CalculateFOV( m_flFOVBlendStartTime, m_flNextFOVBlendTime, m_iStartFOV, m_iNextFOV, m_bAlternateFOV );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_ScriptIntro::CalculateAlpha( void )
+{
+ // Fill out the fade alpha
+ float flNewAlpha = RemapValClamped( gpGlobals->curtime, m_flFadeTimeStartedAt, m_flFadeTimeStartedAt + m_flFadeDuration, m_flFadeAlphaStartedAt, m_flFadeAlpha );
+ /*
+ if ( m_IntroData.m_flCurrentFadeColor[3] != flNewAlpha )
+ {
+ Msg("INTRO FADING: curtime %.2f StartedAt %.2f Duration: %.2f\n", gpGlobals->curtime, m_flFadeTimeStartedAt, m_flFadeDuration );
+ Msg(" TimePassed %.2f Alpha: %.2f\n", RemapValClamped( gpGlobals->curtime, m_flFadeTimeStartedAt, m_flFadeTimeStartedAt + m_flFadeDuration, 0.0, 1.0 ), m_IntroData.m_flCurrentFadeColor[3] );
+ }
+ */
+
+ m_IntroData.m_flCurrentFadeColor[3] = flNewAlpha;
+}
+
diff --git a/mp/src/game/client/hl2/c_strider.cpp b/mp/src/game/client/hl2/c_strider.cpp
index f05f335a..3ea3f733 100644
--- a/mp/src/game/client/hl2/c_strider.cpp
+++ b/mp/src/game/client/hl2/c_strider.cpp
@@ -1,1048 +1,1048 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "c_ai_basenpc.h"
-#include "c_te_particlesystem.h"
-#include "fx.h"
-#include "fx_sparks.h"
-#include "c_tracer.h"
-#include "clientsideeffects.h"
-#include "iefx.h"
-#include "dlight.h"
-#include "bone_setup.h"
-#include "c_rope.h"
-#include "fx_line.h"
-#include "c_sprite.h"
-#include "view.h"
-#include "view_scene.h"
-#include "materialsystem/imaterialvar.h"
-#include "simple_keys.h"
-#include "fx_envelope.h"
-#include "iclientvehicle.h"
-#include "engine/ivdebugoverlay.h"
-#include "particles_localspace.h"
-#include "dlight.h"
-#include "iefx.h"
-#include "c_te_effect_dispatch.h"
-#include "tier0/vprof.h"
-#include "clienteffectprecachesystem.h"
-#include <bitbuf.h>
-#include "fx_water.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-#define STRIDER_MSG_BIG_SHOT 1
-#define STRIDER_MSG_STREAKS 2
-#define STRIDER_MSG_DEAD 3
-
-#define STOMP_IK_SLOT 11
-const int NUM_STRIDER_IK_TARGETS = 6;
-
-const float STRIDERFX_BIG_SHOT_TIME = 1.25f;
-const float STRIDERFX_END_ALL_TIME = 4.0f;
-
-class C_StriderFX : public C_EnvelopeFX
-{
-public:
- typedef C_EnvelopeFX BaseClass;
-
- C_StriderFX();
- ~C_StriderFX()
- {
- EffectShutdown();
- }
-
-
- void Update( C_BaseEntity *pOwner, const Vector &targetPos );
-
- // Returns the bounds relative to the origin (render bounds)
- virtual void GetRenderBounds( Vector& mins, Vector& maxs )
- {
- ClearBounds( mins, maxs );
- AddPointToBounds( m_worldPosition, mins, maxs );
- AddPointToBounds( m_targetPosition, mins, maxs );
- mins -= GetRenderOrigin();
- maxs -= GetRenderOrigin();
- }
-
- virtual void EffectInit( int entityIndex, int attachment )
- {
- m_limitHitTime = 0;
- BaseClass::EffectInit( entityIndex, attachment );
- }
- virtual void EffectShutdown( void )
- {
- m_limitHitTime = 0;
- BaseClass::EffectShutdown();
- }
-
- virtual int DrawModel( int flags );
- virtual void LimitTime( float tmax )
- {
- float dt = tmax - m_t;
- if ( dt < 0 )
- {
- dt = 0;
- }
- m_limitHitTime = gpGlobals->curtime + dt;
- BaseClass::LimitTime( tmax );
- }
-
- C_BaseEntity *m_pOwner;
- Vector m_targetPosition;
- Vector m_beamEndPosition;
- pixelvis_handle_t m_queryHandleGun;
- pixelvis_handle_t m_queryHandleBeamEnd;
- float m_limitHitTime;
-};
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-class C_Strider : public C_AI_BaseNPC
-{
- DECLARE_CLASS( C_Strider, C_AI_BaseNPC );
-public:
- DECLARE_CLIENTCLASS();
- DECLARE_INTERPOLATION();
-
-
- C_Strider();
- virtual ~C_Strider();
-
- // model specific
- virtual void ReceiveMessage( int classID, bf_read &msg );
- virtual void CalculateIKLocks( float currentTime )
- {
- // NOTE: All strider IK is solved on the server, enable this to do it client-side
- //BaseClass::CalculateIKLocks( currentTime );
- if ( m_pIk && m_pIk->m_target.Count() )
- {
- Assert(m_pIk->m_target.Count() > STOMP_IK_SLOT);
- // HACKHACK: Hardcoded 11??? Not a cleaner way to do this
- CIKTarget &target = m_pIk->m_target[STOMP_IK_SLOT];
- target.SetPos( m_vecHitPos );
- // target.latched.pos = m_vecHitPos;
-
- for ( int i = 0; i < NUM_STRIDER_IK_TARGETS; i++ )
- {
- CIKTarget &target = m_pIk->m_target[i];
- target.SetPos( m_vecIKTarget[i] );
-#if 0
- debugoverlay->AddBoxOverlay( m_vecIKTarget[i], Vector( -2, -2, -2 ), Vector( 2, 2, 2), QAngle( 0, 0, 0 ), (int)255*m_pIk->m_target[i].est.latched, 0, 0, 0, 0 );
-#endif
- }
- }
- }
-
- virtual void OnDataChanged( DataUpdateType_t updateType );
- virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
- virtual void ClientThink();
-
-private:
- C_Strider( const C_Strider & );
- C_StriderFX m_cannonFX;
- Vector m_vecHitPos;
- Vector m_vecIKTarget[NUM_STRIDER_IK_TARGETS];
- CInterpolatedVar< Vector > m_iv_vecHitPos;
- CInterpolatedVarArray< Vector, NUM_STRIDER_IK_TARGETS > m_iv_vecIKTarget;
- Vector m_vecRenderMins;
- Vector m_vecRenderMaxs;
-
- float m_flNextRopeCutTime;
-};
-
-IMPLEMENT_CLIENTCLASS_DT(C_Strider, DT_NPC_Strider, CNPC_Strider)
- RecvPropVector(RECVINFO(m_vecHitPos)),
- RecvPropVector(RECVINFO(m_vecIKTarget[0])),
- RecvPropVector(RECVINFO(m_vecIKTarget[1])),
- RecvPropVector(RECVINFO(m_vecIKTarget[2])),
- RecvPropVector(RECVINFO(m_vecIKTarget[3])),
- RecvPropVector(RECVINFO(m_vecIKTarget[4])),
- RecvPropVector(RECVINFO(m_vecIKTarget[5])),
-END_RECV_TABLE()
-
-C_StriderFX::C_StriderFX()
-{
- m_pOwner = NULL;
- m_active = false;
-}
-
-void C_StriderFX::Update( C_BaseEntity *pOwner, const Vector &targetPos )
-{
- BaseClass::Update();
-
- m_pOwner = pOwner;
-
- if ( m_active )
- {
- m_targetPosition = targetPos;
- }
-}
-
-// --on gun
-// warpy sprite bit
-// darkening sprite
-// glowy blue flare sprite
-// bubble warpy sprite
-// after glow sprite
-
-// --on line of sight
-// narrow beam
-// wide beam
-
-// --on impact point
-// sparkly white bits
-// sparkly white streaks
-// pale blue particle steam
-
-enum
-{
- STRIDERFX_WARP_SCALE = 0,
- STRIDERFX_DARKNESS,
- STRIDERFX_FLARE_COLOR,
- STRIDERFX_FLARE_SIZE,
- STRIDERFX_BUBBLE_SIZE,
- STRIDERFX_BUBBLE_REFRACT,
-
- STRIDERFX_NARROW_BEAM_COLOR,
- STRIDERFX_NARROW_BEAM_SIZE,
-
- STRIDERFX_WIDE_BEAM_COLOR,
- STRIDERFX_WIDE_BEAM_SIZE,
-
- STRIDERFX_AFTERGLOW_COLOR,
-
- STRIDERFX_WIDE_BEAM_LENGTH,
-
- STRIDERFX_SPARK_COUNT,
- STRIDERFX_STREAK_COUNT,
- STRIDERFX_STEAM_COUNT,
-
-
- // must be last
- STRIDERFX_PARAMETERS,
-};
-
-class CStriderFXEnvelope
-{
-public:
- CStriderFXEnvelope();
-
- void AddKey( int parameterIndex, const CSimpleKeyInterp &key )
- {
- Assert( parameterIndex >= 0 && parameterIndex < STRIDERFX_PARAMETERS );
-
- if ( parameterIndex >= 0 && parameterIndex < STRIDERFX_PARAMETERS )
- {
- m_parameters[parameterIndex].Insert( key );
- }
-
- }
-
- CSimpleKeyList m_parameters[STRIDERFX_PARAMETERS];
-};
-
-// NOTE: Beam widths are half-widths or radii, so this is a beam that represents a cylinder with 2" radius
-const float NARROW_BEAM_WIDTH = 2;
-const float WIDE_BEAM_WIDTH = 16;
-const float FLARE_SIZE = 128;
-const float DARK_SIZE = 64;
-const float AFTERGLOW_SIZE = 64;
-
-const float WARP_SIZE = 512;
-const float WARP_REFRACT = 0.075f;
-const float WARP_BUBBLE_SIZE = 256;
-const float WARP_BUBBLE_REFRACT = 1.0f;
-
-CStriderFXEnvelope::CStriderFXEnvelope()
-{
- AddKey( STRIDERFX_WARP_SCALE, CSimpleKeyInterp( 0, KEY_LINEAR, 0 ) );
- AddKey( STRIDERFX_WARP_SCALE, CSimpleKeyInterp( 1.25, KEY_ACCELERATE, 1 ) );
- AddKey( STRIDERFX_WARP_SCALE, CSimpleKeyInterp( 1.25, KEY_LINEAR, 1 ) );
- AddKey( STRIDERFX_WARP_SCALE, CSimpleKeyInterp( 1.3, KEY_LINEAR, 0 ) );
-
- AddKey( STRIDERFX_DARKNESS, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
- AddKey( STRIDERFX_DARKNESS, CSimpleKeyInterp( 0.5, KEY_SPLINE, 1 ) );
- AddKey( STRIDERFX_DARKNESS, CSimpleKeyInterp( 1.0, KEY_LINEAR, 1 ) );
- AddKey( STRIDERFX_DARKNESS, CSimpleKeyInterp( 1.25, KEY_SPLINE, 0 ) );
- AddKey( STRIDERFX_DARKNESS, CSimpleKeyInterp( 2.0, KEY_SPLINE, 0 ) );
-
- AddKey( STRIDERFX_FLARE_COLOR, CSimpleKeyInterp( 0, KEY_LINEAR, 0 ) );
- AddKey( STRIDERFX_FLARE_COLOR, CSimpleKeyInterp( 0.5, KEY_LINEAR, 0 ) );
- AddKey( STRIDERFX_FLARE_COLOR, CSimpleKeyInterp( 1.25, KEY_ACCELERATE, 1 ) );
- AddKey( STRIDERFX_FLARE_COLOR, CSimpleKeyInterp( 1.5, KEY_LINEAR, 1 ) );
- AddKey( STRIDERFX_FLARE_COLOR, CSimpleKeyInterp( 2.0, KEY_SPLINE, 0 ) );
-
- AddKey( STRIDERFX_FLARE_SIZE, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
- AddKey( STRIDERFX_FLARE_SIZE, CSimpleKeyInterp( 1.0, KEY_LINEAR, 1 ) );
- AddKey( STRIDERFX_FLARE_SIZE, CSimpleKeyInterp( 2.0, KEY_LINEAR, 1 ) );
-
- AddKey( STRIDERFX_BUBBLE_SIZE, CSimpleKeyInterp( 1.3, KEY_LINEAR, 0.5 ) );
- AddKey( STRIDERFX_BUBBLE_SIZE, CSimpleKeyInterp( 2.0, KEY_DECELERATE, 2 ) );
-
- AddKey( STRIDERFX_BUBBLE_REFRACT, CSimpleKeyInterp( 1.3, KEY_LINEAR, 1 ) );
- AddKey( STRIDERFX_BUBBLE_REFRACT, CSimpleKeyInterp( 2.0, KEY_LINEAR, 0 ) );
-
- AddKey( STRIDERFX_NARROW_BEAM_COLOR, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
- AddKey( STRIDERFX_NARROW_BEAM_COLOR, CSimpleKeyInterp( 1.25, KEY_ACCELERATE, 1.0 ) );
- AddKey( STRIDERFX_NARROW_BEAM_COLOR, CSimpleKeyInterp( 1.5, KEY_SPLINE, 0 ) );
-
- AddKey( STRIDERFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
- AddKey( STRIDERFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 0.5, KEY_ACCELERATE, 1 ) );
- AddKey( STRIDERFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 1.25, KEY_LINEAR, 1 ) );
- AddKey( STRIDERFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 1.5, KEY_DECELERATE, 2 ) );
-
- AddKey( STRIDERFX_WIDE_BEAM_COLOR, CSimpleKeyInterp( 1.25, KEY_LINEAR, 0 ) );
- AddKey( STRIDERFX_WIDE_BEAM_COLOR, CSimpleKeyInterp( 1.5, KEY_SPLINE, 1 ) );
- AddKey( STRIDERFX_WIDE_BEAM_COLOR, CSimpleKeyInterp( 1.75, KEY_LINEAR, 1 ) );
- AddKey( STRIDERFX_WIDE_BEAM_COLOR, CSimpleKeyInterp( 2.1, KEY_SPLINE, 0 ) );
-
- AddKey( STRIDERFX_WIDE_BEAM_SIZE, CSimpleKeyInterp( 1.25, KEY_LINEAR, 1 ) );
- AddKey( STRIDERFX_WIDE_BEAM_SIZE, CSimpleKeyInterp( 2.1, KEY_LINEAR, 1 ) );
-
- AddKey( STRIDERFX_AFTERGLOW_COLOR, CSimpleKeyInterp( 1.0, KEY_LINEAR, 0 ) );
- AddKey( STRIDERFX_AFTERGLOW_COLOR, CSimpleKeyInterp( 1.25, KEY_SPLINE, 1 ) );
- AddKey( STRIDERFX_AFTERGLOW_COLOR, CSimpleKeyInterp( 3.0, KEY_LINEAR, 1 ) );
- AddKey( STRIDERFX_AFTERGLOW_COLOR, CSimpleKeyInterp( 3.5, KEY_ACCELERATE, 0 ) );
-
- AddKey( STRIDERFX_WIDE_BEAM_LENGTH, CSimpleKeyInterp( 1.25, KEY_LINEAR, 1.0 ) );
- AddKey( STRIDERFX_WIDE_BEAM_LENGTH, CSimpleKeyInterp( 1.5, KEY_ACCELERATE, 0.0 ) );
- AddKey( STRIDERFX_WIDE_BEAM_LENGTH, CSimpleKeyInterp( 2.1, KEY_LINEAR, 0 ) );
-
- //AddKey( STRIDERFX_SPARK_COUNT,
- //AddKey( STRIDERFX_STREAK_COUNT,
- //AddKey( STRIDERFX_STEAM_COUNT,
-}
-
-CStriderFXEnvelope g_StriderCannonEnvelope;
-
-void ScaleColor( color32 &out, const color32 &in, float scale )
-{
- out.r = (byte)(int)((float)in.r * scale);
- out.g = (byte)(int)((float)in.g * scale);
- out.b = (byte)(int)((float)in.b * scale);
- out.a = (byte)(int)((float)in.a * scale);
-}
-
-void DrawSpriteTangentSpace( const Vector &vecOrigin, float flWidth, float flHeight, color32 color )
-{
- unsigned char pColor[4] = { color.r, color.g, color.b, color.a };
-
- // Generate half-widths
- flWidth *= 0.5f;
- flHeight *= 0.5f;
-
- // Compute direction vectors for the sprite
- Vector fwd, right( 1, 0, 0 ), up( 0, 1, 0 );
- VectorSubtract( CurrentViewOrigin(), vecOrigin, fwd );
- float flDist = VectorNormalize( fwd );
- if (flDist >= 1e-3)
- {
- CrossProduct( CurrentViewUp(), fwd, right );
- flDist = VectorNormalize( right );
- if (flDist >= 1e-3)
- {
- CrossProduct( fwd, right, up );
- }
- else
- {
- // In this case, fwd == g_vecVUp, it's right above or
- // below us in screen space
- CrossProduct( fwd, CurrentViewRight(), up );
- VectorNormalize( up );
- CrossProduct( up, fwd, right );
- }
- }
-
- Vector left = -right;
- Vector down = -up;
- Vector back = -fwd;
-
- CMeshBuilder meshBuilder;
- Vector point;
- CMatRenderContextPtr pRenderContext( materials );
- IMesh* pMesh = pRenderContext->GetDynamicMesh( );
-
- meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
-
- meshBuilder.Color4ubv (pColor);
- meshBuilder.TexCoord2f (0, 0, 1);
- VectorMA (vecOrigin, -flHeight, up, point);
- VectorMA (point, -flWidth, right, point);
- meshBuilder.TangentS3fv( left.Base() );
- meshBuilder.TangentT3fv( down.Base() );
- meshBuilder.Normal3fv( back.Base() );
- meshBuilder.Position3fv (point.Base());
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color4ubv (pColor);
- meshBuilder.TexCoord2f (0, 0, 0);
- VectorMA (vecOrigin, flHeight, up, point);
- VectorMA (point, -flWidth, right, point);
- meshBuilder.TangentS3fv( left.Base() );
- meshBuilder.TangentT3fv( down.Base() );
- meshBuilder.Normal3fv( back.Base() );
- meshBuilder.Position3fv (point.Base());
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color4ubv (pColor);
- meshBuilder.TexCoord2f (0, 1, 0);
- VectorMA (vecOrigin, flHeight, up, point);
- VectorMA (point, flWidth, right, point);
- meshBuilder.TangentS3fv( left.Base() );
- meshBuilder.TangentT3fv( down.Base() );
- meshBuilder.Normal3fv( back.Base() );
- meshBuilder.Position3fv (point.Base());
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color4ubv (pColor);
- meshBuilder.TexCoord2f (0, 1, 1);
- VectorMA (vecOrigin, -flHeight, up, point);
- VectorMA (point, flWidth, right, point);
- meshBuilder.TangentS3fv( left.Base() );
- meshBuilder.TangentT3fv( down.Base() );
- meshBuilder.Normal3fv( back.Base() );
- meshBuilder.Position3fv (point.Base());
- meshBuilder.AdvanceVertex();
-
- meshBuilder.End();
- pMesh->Draw();
-}
-
-
-void Strider_DrawSprite( const Vector &vecOrigin, float size, const color32 &color )
-{
- DrawSpriteTangentSpace( vecOrigin, size, size, color );
-}
-
-
-void Strider_DrawLine( const Vector &start, const Vector &end, float width, IMaterial *pMaterial, const color32 &color )
-{
- FX_DrawLineFade( start, end, width, pMaterial, color, 8.0f );
-}
-
-int C_StriderFX::DrawModel( int )
-{
- static color32 white = {255,255,255,255};
- Vector params[STRIDERFX_PARAMETERS];
- bool hasParam[STRIDERFX_PARAMETERS];
-
- if ( !m_active )
- return 1;
-
- C_BaseEntity *ent = cl_entitylist->GetEnt( m_entityIndex );
- if ( ent )
- {
- QAngle angles;
- ent->GetAttachment( m_attachment, m_worldPosition, angles );
- }
-
- // This forces time to drive from the main clock instead of being integrated per-draw below
- // that way the effect moves on even when culled for visibility
- if ( m_limitHitTime > 0 && m_tMax > 0 )
- {
- float dt = m_limitHitTime - gpGlobals->curtime;
- if ( dt < 0 )
- {
- dt = 0;
- }
- // if the clock needs to move, update it.
- if ( m_tMax - dt > m_t )
- {
- m_t = m_tMax - dt;
- m_beamEndPosition = m_worldPosition;
- }
- }
- else
- {
- // don't have enough info to derive the time, integrate current frame time
- m_t += gpGlobals->frametime;
- if ( m_tMax > 0 )
- {
- m_t = clamp( m_t, 0, m_tMax );
- m_beamEndPosition = m_worldPosition;
- }
- }
- float t = m_t;
-
- bool hasAny = false;
- memset( hasParam, 0, sizeof(hasParam) );
- for ( int i = 0; i < STRIDERFX_PARAMETERS; i++ )
- {
- hasParam[i] = g_StriderCannonEnvelope.m_parameters[i].Interp( params[i], t );
- hasAny = hasAny || hasParam[i];
- }
-
- pixelvis_queryparams_t gunParams;
- gunParams.Init(m_worldPosition, 4.0f);
- float gunFractionVisible = PixelVisibility_FractionVisible( gunParams, &m_queryHandleGun );
- bool gunVisible = gunFractionVisible > 0.0f ? true : false;
-
- // draw the narrow beam
- if ( hasParam[STRIDERFX_NARROW_BEAM_COLOR] && hasParam[STRIDERFX_NARROW_BEAM_SIZE] )
- {
- IMaterial *pMat = materials->FindMaterial( "sprites/bluelaser1", TEXTURE_GROUP_CLIENT_EFFECTS );
- float width = NARROW_BEAM_WIDTH * params[STRIDERFX_NARROW_BEAM_SIZE].x;
- color32 color;
- float bright = params[STRIDERFX_NARROW_BEAM_COLOR].x;
- ScaleColor( color, white, bright );
-
- Strider_DrawLine( m_beamEndPosition, m_targetPosition, width, pMat, color );
- }
-
- // draw the wide beam
- if ( hasParam[STRIDERFX_WIDE_BEAM_COLOR] && hasParam[STRIDERFX_WIDE_BEAM_SIZE] )
- {
- IMaterial *pMat = materials->FindMaterial( "effects/blueblacklargebeam", TEXTURE_GROUP_CLIENT_EFFECTS );
- float width = WIDE_BEAM_WIDTH * params[STRIDERFX_WIDE_BEAM_SIZE].x;
- color32 color;
- float bright = params[STRIDERFX_WIDE_BEAM_COLOR].x;
- ScaleColor( color, white, bright );
- Vector wideBeamEnd = m_beamEndPosition;
- if ( hasParam[STRIDERFX_WIDE_BEAM_LENGTH] )
- {
- float amt = params[STRIDERFX_WIDE_BEAM_LENGTH].x;
- wideBeamEnd = m_beamEndPosition * amt + m_targetPosition * (1-amt);
- }
-
- Strider_DrawLine( wideBeamEnd, m_targetPosition, width, pMat, color );
- }
-
-// after glow sprite
- bool updated = false;
- CMatRenderContextPtr pRenderContext( materials );
-// warpy sprite bit
- if ( hasParam[STRIDERFX_WARP_SCALE] && !hasParam[STRIDERFX_BUBBLE_SIZE] && gunVisible )
- {
- if ( !updated )
- {
- updated = true;
- pRenderContext->Flush();
- UpdateRefractTexture();
- }
-
- IMaterial *pMat = materials->FindMaterial( "effects/strider_pinch_dudv", TEXTURE_GROUP_CLIENT_EFFECTS );
- float size = WARP_SIZE;
- float refract = params[STRIDERFX_WARP_SCALE].x * WARP_REFRACT * gunFractionVisible;
-
- pRenderContext->Bind( pMat, (IClientRenderable*)this );
- IMaterialVar *pVar = pMat->FindVar( "$refractamount", NULL );
- pVar->SetFloatValue( refract );
- Strider_DrawSprite( m_worldPosition, size, white );
- }
-// darkening sprite
-// glowy blue flare sprite
- if ( hasParam[STRIDERFX_FLARE_COLOR] && hasParam[STRIDERFX_FLARE_SIZE] && hasParam[STRIDERFX_DARKNESS] && gunVisible )
- {
- IMaterial *pMat = materials->FindMaterial( "effects/blueblackflash", TEXTURE_GROUP_CLIENT_EFFECTS );
- float size = FLARE_SIZE * params[STRIDERFX_FLARE_SIZE].x;
- color32 color;
- float bright = params[STRIDERFX_FLARE_COLOR].x * gunFractionVisible;
- ScaleColor( color, white, bright );
- color.a = (int)(255 * params[STRIDERFX_DARKNESS].x);
- pRenderContext->Bind( pMat, (IClientRenderable*)this );
- Strider_DrawSprite( m_worldPosition, size, color );
- }
-// bubble warpy sprite
- if ( hasParam[STRIDERFX_BUBBLE_SIZE] )
- {
- Vector wideBeamEnd = m_beamEndPosition;
- if ( hasParam[STRIDERFX_WIDE_BEAM_LENGTH] )
- {
- float amt = params[STRIDERFX_WIDE_BEAM_LENGTH].x;
- wideBeamEnd = m_beamEndPosition * amt + m_targetPosition * (1-amt);
- }
- pixelvis_queryparams_t endParams;
- endParams.Init(wideBeamEnd, 4.0f, 0.001f);
- float endFractionVisible = PixelVisibility_FractionVisible( endParams, &m_queryHandleBeamEnd );
- bool endVisible = endFractionVisible > 0.0f ? true : false;
-
- if ( endVisible )
- {
- if ( !updated )
- {
- updated = true;
- pRenderContext->Flush();
- UpdateRefractTexture();
- }
- IMaterial *pMat = materials->FindMaterial( "effects/strider_bulge_dudv", TEXTURE_GROUP_CLIENT_EFFECTS );
- float refract = endFractionVisible * WARP_BUBBLE_REFRACT * params[STRIDERFX_BUBBLE_REFRACT].x;
- float size = WARP_BUBBLE_SIZE * params[STRIDERFX_BUBBLE_SIZE].x;
- IMaterialVar *pVar = pMat->FindVar( "$refractamount", NULL );
- pVar->SetFloatValue( refract );
-
- pRenderContext->Bind( pMat, (IClientRenderable*)this );
- Strider_DrawSprite( wideBeamEnd, size, white );
- }
- }
- else
- {
- // call this to have the check ready on the first frame
- pixelvis_queryparams_t endParams;
- endParams.Init(m_beamEndPosition, 4.0f, 0.001f);
- PixelVisibility_FractionVisible( endParams, &m_queryHandleBeamEnd );
- }
- if ( hasParam[STRIDERFX_AFTERGLOW_COLOR] && gunVisible )
- {
- IMaterial *pMat = materials->FindMaterial( "effects/blueblackflash", TEXTURE_GROUP_CLIENT_EFFECTS );
- float size = AFTERGLOW_SIZE;// * params[STRIDERFX_FLARE_SIZE].x;
- color32 color;
- float bright = params[STRIDERFX_AFTERGLOW_COLOR].x * gunFractionVisible;
- ScaleColor( color, white, bright );
-
- pRenderContext->Bind( pMat, (IClientRenderable*)this );
- Strider_DrawSprite( m_worldPosition, size, color );
-
- dlight_t *dl = effects->CL_AllocDlight( m_entityIndex );
- dl->origin = m_worldPosition;
- dl->color.r = 40;
- dl->color.g = 60;
- dl->color.b = 255;
- dl->color.exponent = 5;
- dl->radius = bright * 128;
- dl->die = gpGlobals->curtime + 0.001;
- }
-
- if ( m_t >= STRIDERFX_END_ALL_TIME && !hasAny )
- {
- EffectShutdown();
- }
- return 1;
-}
-
-
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Strider class implementation
-//-----------------------------------------------------------------------------
-C_Strider::C_Strider() :
- m_iv_vecHitPos("C_Strider::m_iv_vecHitPos"),
- m_iv_vecIKTarget("C_Strider::m_iv_vecIKTarget")
-{
- AddVar( &m_vecHitPos, &m_iv_vecHitPos, LATCH_ANIMATION_VAR );
-
- memset(m_vecIKTarget, 0, sizeof(m_vecIKTarget));
- AddVar( &m_vecIKTarget, &m_iv_vecIKTarget, LATCH_ANIMATION_VAR );
-
- m_flNextRopeCutTime = 0;
-}
-
-C_Strider::~C_Strider()
-{
-}
-
-void C_Strider::ReceiveMessage( int classID, bf_read &msg )
-{
- if ( classID != GetClientClass()->m_ClassID )
- {
- // message is for subclass
- BaseClass::ReceiveMessage( classID, msg );
- return;
- }
-
- int messageType = msg.ReadByte();
- switch( messageType )
- {
- case STRIDER_MSG_STREAKS:
- {
- Vector pos;
- msg.ReadBitVec3Coord( pos );
- m_cannonFX.SetRenderOrigin( pos );
- m_cannonFX.EffectInit( entindex(), LookupAttachment( "BigGun" ) );
- m_cannonFX.LimitTime( STRIDERFX_BIG_SHOT_TIME );
- }
- break;
-
- case STRIDER_MSG_BIG_SHOT:
- {
- Vector tmp;
- msg.ReadBitVec3Coord( tmp );
- m_cannonFX.SetTime( STRIDERFX_BIG_SHOT_TIME );
- m_cannonFX.LimitTime( STRIDERFX_END_ALL_TIME );
- }
- break;
-
- case STRIDER_MSG_DEAD:
- {
- m_cannonFX.EffectShutdown();
- }
- break;
- }
-}
-
-
-void C_Strider::OnDataChanged( DataUpdateType_t updateType )
-{
- if ( updateType == DATA_UPDATE_CREATED )
- {
- // We need to have our render bounds defined or shadow creation won't work correctly
- ClientThink();
- ClientThinkList()->SetNextClientThink( GetClientHandle(), CLIENT_THINK_ALWAYS );
- }
-
- BaseClass::OnDataChanged( updateType );
-
- m_cannonFX.Update( this, m_vecHitPos );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Recompute my rendering box
-//-----------------------------------------------------------------------------
-void C_Strider::ClientThink()
-{
- // The reason why this is here, as opposed to in SetObjectCollisionBox,
- // is because of IK. The code below recomputes bones so as to get at the hitboxes,
- // which causes IK to trigger, which causes raycasts against the other entities to occur,
- // which is illegal to do while in the Relink phase.
-
- ComputeEntitySpaceHitboxSurroundingBox( &m_vecRenderMins, &m_vecRenderMaxs );
- // UNDONE: Disabled this until we can get closer to a final map and tune
-#if 0
- // Cut ropes.
- if ( gpGlobals->curtime >= m_flNextRopeCutTime )
- {
- // Blow the bbox out a little.
- Vector vExtendedMins = vecMins - Vector( 50, 50, 50 );
- Vector vExtendedMaxs = vecMaxs + Vector( 50, 50, 50 );
-
- C_RopeKeyframe *ropes[512];
- int nRopes = C_RopeKeyframe::GetRopesIntersectingAABB( ropes, ARRAYSIZE( ropes ), GetAbsOrigin() + vExtendedMins, GetAbsOrigin() + vExtendedMaxs );
- for ( int i=0; i < nRopes; i++ )
- {
- C_RopeKeyframe *pRope = ropes[i];
-
- if ( pRope->GetEndEntity() )
- {
- Vector vPos;
- if ( pRope->GetEndPointPos( 1, vPos ) )
- {
- // Detach the endpoint.
- pRope->SetEndEntity( NULL );
-
- // Make some spark effect here..
- g_pEffects->Sparks( vPos );
- }
- }
- }
-
- m_flNextRopeCutTime = gpGlobals->curtime + 0.5;
- }
-#endif
-
- // True argument because the origin may have stayed the same, but the size is expected to always change
- g_pClientShadowMgr->AddToDirtyShadowList( this, true );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Recompute my rendering box
-//-----------------------------------------------------------------------------
-void C_Strider::GetRenderBounds( Vector& theMins, Vector& theMaxs )
-{
- theMins = m_vecRenderMins;
- theMaxs = m_vecRenderMaxs;
-}
-
-
-//-----------------------------------------------------------------------------
-// Strider muzzle flashes
-//-----------------------------------------------------------------------------
-void MuzzleFlash_Strider( ClientEntityHandle_t hEntity, int attachmentIndex )
-{
- VPROF_BUDGET( "MuzzleFlash_Strider", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
-
- // If the client hasn't seen this entity yet, bail.
- matrix3x4_t matAttachment;
- if ( !FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) )
- return;
-
- CSmartPtr<CLocalSpaceEmitter> pSimple = CLocalSpaceEmitter::Create( "MuzzleFlash_Strider", hEntity, attachmentIndex );
-
- SimpleParticle *pParticle;
- Vector forward(1,0,0), offset; //NOTENOTE: All coords are in local space
-
- float flScale = random->RandomFloat( 3.0f, 4.0f );
-
- float burstSpeed = random->RandomFloat( 400.0f, 600.0f );
-
-#define FRONT_LENGTH 12
-
- // Front flash
- for ( int i = 1; i < FRONT_LENGTH; i++ )
- {
- offset = (forward * (i*2.0f*flScale));
-
- pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( VarArgs( "effects/combinemuzzle%d", random->RandomInt(1,2) ) ), offset );
-
- if ( pParticle == NULL )
- return;
-
- pParticle->m_flLifetime = 0.0f;
- pParticle->m_flDieTime = 0.1f;
-
- pParticle->m_vecVelocity = forward * burstSpeed;
-
- pParticle->m_uchColor[0] = 255;
- pParticle->m_uchColor[1] = 255;
- pParticle->m_uchColor[2] = 255;
-
- pParticle->m_uchStartAlpha = 255.0f;
- pParticle->m_uchEndAlpha = 0;
-
- pParticle->m_uchStartSize = ( (random->RandomFloat( 6.0f, 8.0f ) * (FRONT_LENGTH-(i))/(FRONT_LENGTH*0.75f)) * flScale );
- pParticle->m_uchEndSize = pParticle->m_uchStartSize;
- pParticle->m_flRoll = random->RandomInt( 0, 360 );
- pParticle->m_flRollDelta = 0.0f;
- }
-
- Vector right(0,1,0), up(0,0,1);
- Vector dir = right - up;
-
-#define SIDE_LENGTH 8
-
- burstSpeed = random->RandomFloat( 400.0f, 600.0f );
-
- // Diagonal flash
- for ( int i = 1; i < SIDE_LENGTH; i++ )
- {
- offset = (dir * (i*flScale));
-
- pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( VarArgs( "effects/combinemuzzle%d", random->RandomInt(1,2) ) ), offset );
-
- if ( pParticle == NULL )
- return;
-
- pParticle->m_flLifetime = 0.0f;
- pParticle->m_flDieTime = 0.2f;
-
- pParticle->m_vecVelocity = dir * burstSpeed * 0.25f;
-
- pParticle->m_uchColor[0] = 255;
- pParticle->m_uchColor[1] = 255;
- pParticle->m_uchColor[2] = 255;
-
- pParticle->m_uchStartAlpha = 255;
- pParticle->m_uchEndAlpha = 0;
-
- pParticle->m_uchStartSize = ( (random->RandomFloat( 2.0f, 4.0f ) * (SIDE_LENGTH-(i))/(SIDE_LENGTH*0.5f)) * flScale );
- pParticle->m_uchEndSize = pParticle->m_uchStartSize;
- pParticle->m_flRoll = random->RandomInt( 0, 360 );
- pParticle->m_flRollDelta = 0.0f;
- }
-
- dir = right + up;
- burstSpeed = random->RandomFloat( 400.0f, 600.0f );
-
- // Diagonal flash
- for ( int i = 1; i < SIDE_LENGTH; i++ )
- {
- offset = (-dir * (i*flScale));
-
- pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( VarArgs( "effects/combinemuzzle%d", random->RandomInt(1,2) ) ), offset );
-
- if ( pParticle == NULL )
- return;
-
- pParticle->m_flLifetime = 0.0f;
- pParticle->m_flDieTime = 0.2f;
-
- pParticle->m_vecVelocity = dir * -burstSpeed * 0.25f;
-
- pParticle->m_uchColor[0] = 255;
- pParticle->m_uchColor[1] = 255;
- pParticle->m_uchColor[2] = 255;
-
- pParticle->m_uchStartAlpha = 255;
- pParticle->m_uchEndAlpha = 0;
-
- pParticle->m_uchStartSize = ( (random->RandomFloat( 2.0f, 4.0f ) * (SIDE_LENGTH-(i))/(SIDE_LENGTH*0.5f)) * flScale );
- pParticle->m_uchEndSize = pParticle->m_uchStartSize;
- pParticle->m_flRoll = random->RandomInt( 0, 360 );
- pParticle->m_flRollDelta = 0.0f;
- }
-
- dir = up;
- burstSpeed = random->RandomFloat( 400.0f, 600.0f );
-
- // Top flash
- for ( int i = 1; i < SIDE_LENGTH; i++ )
- {
- offset = (dir * (i*flScale));
-
- pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( VarArgs( "effects/combinemuzzle%d", random->RandomInt(1,2) ) ), offset );
-
- if ( pParticle == NULL )
- return;
-
- pParticle->m_flLifetime = 0.0f;
- pParticle->m_flDieTime = 0.2f;
-
- pParticle->m_vecVelocity = dir * burstSpeed * 0.25f;
-
- pParticle->m_uchColor[0] = 255;
- pParticle->m_uchColor[1] = 255;
- pParticle->m_uchColor[2] = 255;
-
- pParticle->m_uchStartAlpha = 255;
- pParticle->m_uchEndAlpha = 0;
-
- pParticle->m_uchStartSize = ( (random->RandomFloat( 2.0f, 4.0f ) * (SIDE_LENGTH-(i))/(SIDE_LENGTH*0.5f)) * flScale );
- pParticle->m_uchEndSize = pParticle->m_uchStartSize;
- pParticle->m_flRoll = random->RandomInt( 0, 360 );
- pParticle->m_flRollDelta = 0.0f;
- }
-
- pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/strider_muzzle" ), vec3_origin );
-
- if ( pParticle == NULL )
- return;
-
- pParticle->m_flLifetime = 0.0f;
- pParticle->m_flDieTime = random->RandomFloat( 0.3f, 0.4f );
-
- pParticle->m_vecVelocity.Init();
-
- pParticle->m_uchColor[0] = 255;
- pParticle->m_uchColor[1] = 255;
- pParticle->m_uchColor[2] = 255;
-
- pParticle->m_uchStartAlpha = 255;
- pParticle->m_uchEndAlpha = 0;
-
- pParticle->m_uchStartSize = flScale * random->RandomFloat( 12.0f, 16.0f );
- pParticle->m_uchEndSize = 0.0f;
- pParticle->m_flRoll = random->RandomInt( 0, 360 );
- pParticle->m_flRollDelta = 0.0f;
-
- Vector origin;
- MatrixGetColumn( matAttachment, 3, &origin );
-
- int entityIndex = ClientEntityList().HandleToEntIndex( hEntity );
- if ( entityIndex >= 0 )
- {
- dlight_t *el = effects->CL_AllocElight( LIGHT_INDEX_MUZZLEFLASH + entityIndex );
-
- el->origin = origin;
-
- el->color.r = 64;
- el->color.g = 128;
- el->color.b = 255;
- el->color.exponent = 5;
-
- el->radius = random->RandomInt( 100, 150 );
- el->decay = el->radius / 0.05f;
- el->die = gpGlobals->curtime + 0.1f;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : &data -
-//-----------------------------------------------------------------------------
-void StriderMuzzleFlashCallback( const CEffectData &data )
-{
- MuzzleFlash_Strider( data.m_hEntity, data.m_nAttachmentIndex );
-}
-
-DECLARE_CLIENT_EFFECT( "StriderMuzzleFlash", StriderMuzzleFlashCallback );
-
-#define BLOOD_MIN_SPEED 64.0f*2.0f
-#define BLOOD_MAX_SPEED 256.0f*8.0f
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : &origin -
-// &normal -
-// scale -
-//-----------------------------------------------------------------------------
-void StriderBlood( const Vector &origin, const Vector &normal, float scale )
-{
- VPROF_BUDGET( "StriderBlood", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
-
- //Find area ambient light color and use it to tint smoke
- Vector worldLight = WorldGetLightForPoint( origin, true );
- Vector tint;
- float luminosity;
- UTIL_GetNormalizedColorTintAndLuminosity( worldLight, &tint, &luminosity );
-
- // We only take a portion of the tint
- tint = (tint * 0.25f)+(Vector(0.75f,0.75f,0.75f));
-
- // Rescale to a character range
- luminosity = MAX( 200, luminosity*255 );
-
- CSmartPtr<CSplashParticle> pSimple = CSplashParticle::Create( "splish" );
- pSimple->SetSortOrigin( origin );
-
- int i;
- float flScale = scale / 8.0f;
-
- PMaterialHandle hMaterial = ParticleMgr()->GetPMaterial( "effects/slime1" );
-
- float length = 0.2f;
- Vector vForward, vRight, vUp;
- Vector offDir;
-
- TrailParticle *tParticle;
-
- CSmartPtr<CTrailParticles> sparkEmitter = CTrailParticles::Create( "splash" );
-
- if ( !sparkEmitter )
- return;
-
- sparkEmitter->SetSortOrigin( origin );
- sparkEmitter->m_ParticleCollision.SetGravity( 600.0f );
- sparkEmitter->SetFlag( bitsPARTICLE_TRAIL_VELOCITY_DAMPEN );
- sparkEmitter->SetVelocityDampen( 2.0f );
-
- //Dump out drops
- Vector offset;
- for ( i = 0; i < 64; i++ )
- {
- offset = origin;
- offset[0] += random->RandomFloat( -8.0f, 8.0f ) * flScale;
- offset[1] += random->RandomFloat( -8.0f, 8.0f ) * flScale;
- offset[2] += random->RandomFloat( -8.0f, 8.0f ) * flScale;
-
- tParticle = (TrailParticle *) sparkEmitter->AddParticle( sizeof(TrailParticle), hMaterial, offset );
-
- if ( tParticle == NULL )
- break;
-
- tParticle->m_flLifetime = 0.0f;
- tParticle->m_flDieTime = 1.0f;
-
- offDir = normal + RandomVector( -1.0f, 1.0f );
-
- tParticle->m_vecVelocity = offDir * random->RandomFloat( BLOOD_MIN_SPEED * flScale * 2.0f, BLOOD_MAX_SPEED * flScale * 2.0f );
- tParticle->m_vecVelocity[2] += random->RandomFloat( 8.0f, 32.0f ) * flScale;
-
- tParticle->m_flWidth = random->RandomFloat( 20.0f, 26.0f ) * flScale;
- tParticle->m_flLength = random->RandomFloat( length*0.5f, length ) * flScale;
-
- int nColor = random->RandomInt( luminosity*0.75f, luminosity );
- tParticle->m_color.r = nColor * tint.x;
- tParticle->m_color.g = nColor * tint.y;
- tParticle->m_color.b = nColor * tint.z;
- tParticle->m_color.a = 255;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : &data -
-//-----------------------------------------------------------------------------
-void StriderBloodCallback( const CEffectData &data )
-{
- StriderBlood( data.m_vOrigin, data.m_vNormal, data.m_flScale );
-}
-
-DECLARE_CLIENT_EFFECT( "StriderBlood", StriderBloodCallback );
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "c_ai_basenpc.h"
+#include "c_te_particlesystem.h"
+#include "fx.h"
+#include "fx_sparks.h"
+#include "c_tracer.h"
+#include "clientsideeffects.h"
+#include "iefx.h"
+#include "dlight.h"
+#include "bone_setup.h"
+#include "c_rope.h"
+#include "fx_line.h"
+#include "c_sprite.h"
+#include "view.h"
+#include "view_scene.h"
+#include "materialsystem/imaterialvar.h"
+#include "simple_keys.h"
+#include "fx_envelope.h"
+#include "iclientvehicle.h"
+#include "engine/ivdebugoverlay.h"
+#include "particles_localspace.h"
+#include "dlight.h"
+#include "iefx.h"
+#include "c_te_effect_dispatch.h"
+#include "tier0/vprof.h"
+#include "clienteffectprecachesystem.h"
+#include <bitbuf.h>
+#include "fx_water.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#define STRIDER_MSG_BIG_SHOT 1
+#define STRIDER_MSG_STREAKS 2
+#define STRIDER_MSG_DEAD 3
+
+#define STOMP_IK_SLOT 11
+const int NUM_STRIDER_IK_TARGETS = 6;
+
+const float STRIDERFX_BIG_SHOT_TIME = 1.25f;
+const float STRIDERFX_END_ALL_TIME = 4.0f;
+
+class C_StriderFX : public C_EnvelopeFX
+{
+public:
+ typedef C_EnvelopeFX BaseClass;
+
+ C_StriderFX();
+ ~C_StriderFX()
+ {
+ EffectShutdown();
+ }
+
+
+ void Update( C_BaseEntity *pOwner, const Vector &targetPos );
+
+ // Returns the bounds relative to the origin (render bounds)
+ virtual void GetRenderBounds( Vector& mins, Vector& maxs )
+ {
+ ClearBounds( mins, maxs );
+ AddPointToBounds( m_worldPosition, mins, maxs );
+ AddPointToBounds( m_targetPosition, mins, maxs );
+ mins -= GetRenderOrigin();
+ maxs -= GetRenderOrigin();
+ }
+
+ virtual void EffectInit( int entityIndex, int attachment )
+ {
+ m_limitHitTime = 0;
+ BaseClass::EffectInit( entityIndex, attachment );
+ }
+ virtual void EffectShutdown( void )
+ {
+ m_limitHitTime = 0;
+ BaseClass::EffectShutdown();
+ }
+
+ virtual int DrawModel( int flags );
+ virtual void LimitTime( float tmax )
+ {
+ float dt = tmax - m_t;
+ if ( dt < 0 )
+ {
+ dt = 0;
+ }
+ m_limitHitTime = gpGlobals->curtime + dt;
+ BaseClass::LimitTime( tmax );
+ }
+
+ C_BaseEntity *m_pOwner;
+ Vector m_targetPosition;
+ Vector m_beamEndPosition;
+ pixelvis_handle_t m_queryHandleGun;
+ pixelvis_handle_t m_queryHandleBeamEnd;
+ float m_limitHitTime;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class C_Strider : public C_AI_BaseNPC
+{
+ DECLARE_CLASS( C_Strider, C_AI_BaseNPC );
+public:
+ DECLARE_CLIENTCLASS();
+ DECLARE_INTERPOLATION();
+
+
+ C_Strider();
+ virtual ~C_Strider();
+
+ // model specific
+ virtual void ReceiveMessage( int classID, bf_read &msg );
+ virtual void CalculateIKLocks( float currentTime )
+ {
+ // NOTE: All strider IK is solved on the server, enable this to do it client-side
+ //BaseClass::CalculateIKLocks( currentTime );
+ if ( m_pIk && m_pIk->m_target.Count() )
+ {
+ Assert(m_pIk->m_target.Count() > STOMP_IK_SLOT);
+ // HACKHACK: Hardcoded 11??? Not a cleaner way to do this
+ CIKTarget &target = m_pIk->m_target[STOMP_IK_SLOT];
+ target.SetPos( m_vecHitPos );
+ // target.latched.pos = m_vecHitPos;
+
+ for ( int i = 0; i < NUM_STRIDER_IK_TARGETS; i++ )
+ {
+ CIKTarget &target = m_pIk->m_target[i];
+ target.SetPos( m_vecIKTarget[i] );
+#if 0
+ debugoverlay->AddBoxOverlay( m_vecIKTarget[i], Vector( -2, -2, -2 ), Vector( 2, 2, 2), QAngle( 0, 0, 0 ), (int)255*m_pIk->m_target[i].est.latched, 0, 0, 0, 0 );
+#endif
+ }
+ }
+ }
+
+ virtual void OnDataChanged( DataUpdateType_t updateType );
+ virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
+ virtual void ClientThink();
+
+private:
+ C_Strider( const C_Strider & );
+ C_StriderFX m_cannonFX;
+ Vector m_vecHitPos;
+ Vector m_vecIKTarget[NUM_STRIDER_IK_TARGETS];
+ CInterpolatedVar< Vector > m_iv_vecHitPos;
+ CInterpolatedVarArray< Vector, NUM_STRIDER_IK_TARGETS > m_iv_vecIKTarget;
+ Vector m_vecRenderMins;
+ Vector m_vecRenderMaxs;
+
+ float m_flNextRopeCutTime;
+};
+
+IMPLEMENT_CLIENTCLASS_DT(C_Strider, DT_NPC_Strider, CNPC_Strider)
+ RecvPropVector(RECVINFO(m_vecHitPos)),
+ RecvPropVector(RECVINFO(m_vecIKTarget[0])),
+ RecvPropVector(RECVINFO(m_vecIKTarget[1])),
+ RecvPropVector(RECVINFO(m_vecIKTarget[2])),
+ RecvPropVector(RECVINFO(m_vecIKTarget[3])),
+ RecvPropVector(RECVINFO(m_vecIKTarget[4])),
+ RecvPropVector(RECVINFO(m_vecIKTarget[5])),
+END_RECV_TABLE()
+
+C_StriderFX::C_StriderFX()
+{
+ m_pOwner = NULL;
+ m_active = false;
+}
+
+void C_StriderFX::Update( C_BaseEntity *pOwner, const Vector &targetPos )
+{
+ BaseClass::Update();
+
+ m_pOwner = pOwner;
+
+ if ( m_active )
+ {
+ m_targetPosition = targetPos;
+ }
+}
+
+// --on gun
+// warpy sprite bit
+// darkening sprite
+// glowy blue flare sprite
+// bubble warpy sprite
+// after glow sprite
+
+// --on line of sight
+// narrow beam
+// wide beam
+
+// --on impact point
+// sparkly white bits
+// sparkly white streaks
+// pale blue particle steam
+
+enum
+{
+ STRIDERFX_WARP_SCALE = 0,
+ STRIDERFX_DARKNESS,
+ STRIDERFX_FLARE_COLOR,
+ STRIDERFX_FLARE_SIZE,
+ STRIDERFX_BUBBLE_SIZE,
+ STRIDERFX_BUBBLE_REFRACT,
+
+ STRIDERFX_NARROW_BEAM_COLOR,
+ STRIDERFX_NARROW_BEAM_SIZE,
+
+ STRIDERFX_WIDE_BEAM_COLOR,
+ STRIDERFX_WIDE_BEAM_SIZE,
+
+ STRIDERFX_AFTERGLOW_COLOR,
+
+ STRIDERFX_WIDE_BEAM_LENGTH,
+
+ STRIDERFX_SPARK_COUNT,
+ STRIDERFX_STREAK_COUNT,
+ STRIDERFX_STEAM_COUNT,
+
+
+ // must be last
+ STRIDERFX_PARAMETERS,
+};
+
+class CStriderFXEnvelope
+{
+public:
+ CStriderFXEnvelope();
+
+ void AddKey( int parameterIndex, const CSimpleKeyInterp &key )
+ {
+ Assert( parameterIndex >= 0 && parameterIndex < STRIDERFX_PARAMETERS );
+
+ if ( parameterIndex >= 0 && parameterIndex < STRIDERFX_PARAMETERS )
+ {
+ m_parameters[parameterIndex].Insert( key );
+ }
+
+ }
+
+ CSimpleKeyList m_parameters[STRIDERFX_PARAMETERS];
+};
+
+// NOTE: Beam widths are half-widths or radii, so this is a beam that represents a cylinder with 2" radius
+const float NARROW_BEAM_WIDTH = 2;
+const float WIDE_BEAM_WIDTH = 16;
+const float FLARE_SIZE = 128;
+const float DARK_SIZE = 64;
+const float AFTERGLOW_SIZE = 64;
+
+const float WARP_SIZE = 512;
+const float WARP_REFRACT = 0.075f;
+const float WARP_BUBBLE_SIZE = 256;
+const float WARP_BUBBLE_REFRACT = 1.0f;
+
+CStriderFXEnvelope::CStriderFXEnvelope()
+{
+ AddKey( STRIDERFX_WARP_SCALE, CSimpleKeyInterp( 0, KEY_LINEAR, 0 ) );
+ AddKey( STRIDERFX_WARP_SCALE, CSimpleKeyInterp( 1.25, KEY_ACCELERATE, 1 ) );
+ AddKey( STRIDERFX_WARP_SCALE, CSimpleKeyInterp( 1.25, KEY_LINEAR, 1 ) );
+ AddKey( STRIDERFX_WARP_SCALE, CSimpleKeyInterp( 1.3, KEY_LINEAR, 0 ) );
+
+ AddKey( STRIDERFX_DARKNESS, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
+ AddKey( STRIDERFX_DARKNESS, CSimpleKeyInterp( 0.5, KEY_SPLINE, 1 ) );
+ AddKey( STRIDERFX_DARKNESS, CSimpleKeyInterp( 1.0, KEY_LINEAR, 1 ) );
+ AddKey( STRIDERFX_DARKNESS, CSimpleKeyInterp( 1.25, KEY_SPLINE, 0 ) );
+ AddKey( STRIDERFX_DARKNESS, CSimpleKeyInterp( 2.0, KEY_SPLINE, 0 ) );
+
+ AddKey( STRIDERFX_FLARE_COLOR, CSimpleKeyInterp( 0, KEY_LINEAR, 0 ) );
+ AddKey( STRIDERFX_FLARE_COLOR, CSimpleKeyInterp( 0.5, KEY_LINEAR, 0 ) );
+ AddKey( STRIDERFX_FLARE_COLOR, CSimpleKeyInterp( 1.25, KEY_ACCELERATE, 1 ) );
+ AddKey( STRIDERFX_FLARE_COLOR, CSimpleKeyInterp( 1.5, KEY_LINEAR, 1 ) );
+ AddKey( STRIDERFX_FLARE_COLOR, CSimpleKeyInterp( 2.0, KEY_SPLINE, 0 ) );
+
+ AddKey( STRIDERFX_FLARE_SIZE, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
+ AddKey( STRIDERFX_FLARE_SIZE, CSimpleKeyInterp( 1.0, KEY_LINEAR, 1 ) );
+ AddKey( STRIDERFX_FLARE_SIZE, CSimpleKeyInterp( 2.0, KEY_LINEAR, 1 ) );
+
+ AddKey( STRIDERFX_BUBBLE_SIZE, CSimpleKeyInterp( 1.3, KEY_LINEAR, 0.5 ) );
+ AddKey( STRIDERFX_BUBBLE_SIZE, CSimpleKeyInterp( 2.0, KEY_DECELERATE, 2 ) );
+
+ AddKey( STRIDERFX_BUBBLE_REFRACT, CSimpleKeyInterp( 1.3, KEY_LINEAR, 1 ) );
+ AddKey( STRIDERFX_BUBBLE_REFRACT, CSimpleKeyInterp( 2.0, KEY_LINEAR, 0 ) );
+
+ AddKey( STRIDERFX_NARROW_BEAM_COLOR, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
+ AddKey( STRIDERFX_NARROW_BEAM_COLOR, CSimpleKeyInterp( 1.25, KEY_ACCELERATE, 1.0 ) );
+ AddKey( STRIDERFX_NARROW_BEAM_COLOR, CSimpleKeyInterp( 1.5, KEY_SPLINE, 0 ) );
+
+ AddKey( STRIDERFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
+ AddKey( STRIDERFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 0.5, KEY_ACCELERATE, 1 ) );
+ AddKey( STRIDERFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 1.25, KEY_LINEAR, 1 ) );
+ AddKey( STRIDERFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 1.5, KEY_DECELERATE, 2 ) );
+
+ AddKey( STRIDERFX_WIDE_BEAM_COLOR, CSimpleKeyInterp( 1.25, KEY_LINEAR, 0 ) );
+ AddKey( STRIDERFX_WIDE_BEAM_COLOR, CSimpleKeyInterp( 1.5, KEY_SPLINE, 1 ) );
+ AddKey( STRIDERFX_WIDE_BEAM_COLOR, CSimpleKeyInterp( 1.75, KEY_LINEAR, 1 ) );
+ AddKey( STRIDERFX_WIDE_BEAM_COLOR, CSimpleKeyInterp( 2.1, KEY_SPLINE, 0 ) );
+
+ AddKey( STRIDERFX_WIDE_BEAM_SIZE, CSimpleKeyInterp( 1.25, KEY_LINEAR, 1 ) );
+ AddKey( STRIDERFX_WIDE_BEAM_SIZE, CSimpleKeyInterp( 2.1, KEY_LINEAR, 1 ) );
+
+ AddKey( STRIDERFX_AFTERGLOW_COLOR, CSimpleKeyInterp( 1.0, KEY_LINEAR, 0 ) );
+ AddKey( STRIDERFX_AFTERGLOW_COLOR, CSimpleKeyInterp( 1.25, KEY_SPLINE, 1 ) );
+ AddKey( STRIDERFX_AFTERGLOW_COLOR, CSimpleKeyInterp( 3.0, KEY_LINEAR, 1 ) );
+ AddKey( STRIDERFX_AFTERGLOW_COLOR, CSimpleKeyInterp( 3.5, KEY_ACCELERATE, 0 ) );
+
+ AddKey( STRIDERFX_WIDE_BEAM_LENGTH, CSimpleKeyInterp( 1.25, KEY_LINEAR, 1.0 ) );
+ AddKey( STRIDERFX_WIDE_BEAM_LENGTH, CSimpleKeyInterp( 1.5, KEY_ACCELERATE, 0.0 ) );
+ AddKey( STRIDERFX_WIDE_BEAM_LENGTH, CSimpleKeyInterp( 2.1, KEY_LINEAR, 0 ) );
+
+ //AddKey( STRIDERFX_SPARK_COUNT,
+ //AddKey( STRIDERFX_STREAK_COUNT,
+ //AddKey( STRIDERFX_STEAM_COUNT,
+}
+
+CStriderFXEnvelope g_StriderCannonEnvelope;
+
+void ScaleColor( color32 &out, const color32 &in, float scale )
+{
+ out.r = (byte)(int)((float)in.r * scale);
+ out.g = (byte)(int)((float)in.g * scale);
+ out.b = (byte)(int)((float)in.b * scale);
+ out.a = (byte)(int)((float)in.a * scale);
+}
+
+void DrawSpriteTangentSpace( const Vector &vecOrigin, float flWidth, float flHeight, color32 color )
+{
+ unsigned char pColor[4] = { color.r, color.g, color.b, color.a };
+
+ // Generate half-widths
+ flWidth *= 0.5f;
+ flHeight *= 0.5f;
+
+ // Compute direction vectors for the sprite
+ Vector fwd, right( 1, 0, 0 ), up( 0, 1, 0 );
+ VectorSubtract( CurrentViewOrigin(), vecOrigin, fwd );
+ float flDist = VectorNormalize( fwd );
+ if (flDist >= 1e-3)
+ {
+ CrossProduct( CurrentViewUp(), fwd, right );
+ flDist = VectorNormalize( right );
+ if (flDist >= 1e-3)
+ {
+ CrossProduct( fwd, right, up );
+ }
+ else
+ {
+ // In this case, fwd == g_vecVUp, it's right above or
+ // below us in screen space
+ CrossProduct( fwd, CurrentViewRight(), up );
+ VectorNormalize( up );
+ CrossProduct( up, fwd, right );
+ }
+ }
+
+ Vector left = -right;
+ Vector down = -up;
+ Vector back = -fwd;
+
+ CMeshBuilder meshBuilder;
+ Vector point;
+ CMatRenderContextPtr pRenderContext( materials );
+ IMesh* pMesh = pRenderContext->GetDynamicMesh( );
+
+ meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
+
+ meshBuilder.Color4ubv (pColor);
+ meshBuilder.TexCoord2f (0, 0, 1);
+ VectorMA (vecOrigin, -flHeight, up, point);
+ VectorMA (point, -flWidth, right, point);
+ meshBuilder.TangentS3fv( left.Base() );
+ meshBuilder.TangentT3fv( down.Base() );
+ meshBuilder.Normal3fv( back.Base() );
+ meshBuilder.Position3fv (point.Base());
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ubv (pColor);
+ meshBuilder.TexCoord2f (0, 0, 0);
+ VectorMA (vecOrigin, flHeight, up, point);
+ VectorMA (point, -flWidth, right, point);
+ meshBuilder.TangentS3fv( left.Base() );
+ meshBuilder.TangentT3fv( down.Base() );
+ meshBuilder.Normal3fv( back.Base() );
+ meshBuilder.Position3fv (point.Base());
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ubv (pColor);
+ meshBuilder.TexCoord2f (0, 1, 0);
+ VectorMA (vecOrigin, flHeight, up, point);
+ VectorMA (point, flWidth, right, point);
+ meshBuilder.TangentS3fv( left.Base() );
+ meshBuilder.TangentT3fv( down.Base() );
+ meshBuilder.Normal3fv( back.Base() );
+ meshBuilder.Position3fv (point.Base());
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ubv (pColor);
+ meshBuilder.TexCoord2f (0, 1, 1);
+ VectorMA (vecOrigin, -flHeight, up, point);
+ VectorMA (point, flWidth, right, point);
+ meshBuilder.TangentS3fv( left.Base() );
+ meshBuilder.TangentT3fv( down.Base() );
+ meshBuilder.Normal3fv( back.Base() );
+ meshBuilder.Position3fv (point.Base());
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.End();
+ pMesh->Draw();
+}
+
+
+void Strider_DrawSprite( const Vector &vecOrigin, float size, const color32 &color )
+{
+ DrawSpriteTangentSpace( vecOrigin, size, size, color );
+}
+
+
+void Strider_DrawLine( const Vector &start, const Vector &end, float width, IMaterial *pMaterial, const color32 &color )
+{
+ FX_DrawLineFade( start, end, width, pMaterial, color, 8.0f );
+}
+
+int C_StriderFX::DrawModel( int )
+{
+ static color32 white = {255,255,255,255};
+ Vector params[STRIDERFX_PARAMETERS];
+ bool hasParam[STRIDERFX_PARAMETERS];
+
+ if ( !m_active )
+ return 1;
+
+ C_BaseEntity *ent = cl_entitylist->GetEnt( m_entityIndex );
+ if ( ent )
+ {
+ QAngle angles;
+ ent->GetAttachment( m_attachment, m_worldPosition, angles );
+ }
+
+ // This forces time to drive from the main clock instead of being integrated per-draw below
+ // that way the effect moves on even when culled for visibility
+ if ( m_limitHitTime > 0 && m_tMax > 0 )
+ {
+ float dt = m_limitHitTime - gpGlobals->curtime;
+ if ( dt < 0 )
+ {
+ dt = 0;
+ }
+ // if the clock needs to move, update it.
+ if ( m_tMax - dt > m_t )
+ {
+ m_t = m_tMax - dt;
+ m_beamEndPosition = m_worldPosition;
+ }
+ }
+ else
+ {
+ // don't have enough info to derive the time, integrate current frame time
+ m_t += gpGlobals->frametime;
+ if ( m_tMax > 0 )
+ {
+ m_t = clamp( m_t, 0, m_tMax );
+ m_beamEndPosition = m_worldPosition;
+ }
+ }
+ float t = m_t;
+
+ bool hasAny = false;
+ memset( hasParam, 0, sizeof(hasParam) );
+ for ( int i = 0; i < STRIDERFX_PARAMETERS; i++ )
+ {
+ hasParam[i] = g_StriderCannonEnvelope.m_parameters[i].Interp( params[i], t );
+ hasAny = hasAny || hasParam[i];
+ }
+
+ pixelvis_queryparams_t gunParams;
+ gunParams.Init(m_worldPosition, 4.0f);
+ float gunFractionVisible = PixelVisibility_FractionVisible( gunParams, &m_queryHandleGun );
+ bool gunVisible = gunFractionVisible > 0.0f ? true : false;
+
+ // draw the narrow beam
+ if ( hasParam[STRIDERFX_NARROW_BEAM_COLOR] && hasParam[STRIDERFX_NARROW_BEAM_SIZE] )
+ {
+ IMaterial *pMat = materials->FindMaterial( "sprites/bluelaser1", TEXTURE_GROUP_CLIENT_EFFECTS );
+ float width = NARROW_BEAM_WIDTH * params[STRIDERFX_NARROW_BEAM_SIZE].x;
+ color32 color;
+ float bright = params[STRIDERFX_NARROW_BEAM_COLOR].x;
+ ScaleColor( color, white, bright );
+
+ Strider_DrawLine( m_beamEndPosition, m_targetPosition, width, pMat, color );
+ }
+
+ // draw the wide beam
+ if ( hasParam[STRIDERFX_WIDE_BEAM_COLOR] && hasParam[STRIDERFX_WIDE_BEAM_SIZE] )
+ {
+ IMaterial *pMat = materials->FindMaterial( "effects/blueblacklargebeam", TEXTURE_GROUP_CLIENT_EFFECTS );
+ float width = WIDE_BEAM_WIDTH * params[STRIDERFX_WIDE_BEAM_SIZE].x;
+ color32 color;
+ float bright = params[STRIDERFX_WIDE_BEAM_COLOR].x;
+ ScaleColor( color, white, bright );
+ Vector wideBeamEnd = m_beamEndPosition;
+ if ( hasParam[STRIDERFX_WIDE_BEAM_LENGTH] )
+ {
+ float amt = params[STRIDERFX_WIDE_BEAM_LENGTH].x;
+ wideBeamEnd = m_beamEndPosition * amt + m_targetPosition * (1-amt);
+ }
+
+ Strider_DrawLine( wideBeamEnd, m_targetPosition, width, pMat, color );
+ }
+
+// after glow sprite
+ bool updated = false;
+ CMatRenderContextPtr pRenderContext( materials );
+// warpy sprite bit
+ if ( hasParam[STRIDERFX_WARP_SCALE] && !hasParam[STRIDERFX_BUBBLE_SIZE] && gunVisible )
+ {
+ if ( !updated )
+ {
+ updated = true;
+ pRenderContext->Flush();
+ UpdateRefractTexture();
+ }
+
+ IMaterial *pMat = materials->FindMaterial( "effects/strider_pinch_dudv", TEXTURE_GROUP_CLIENT_EFFECTS );
+ float size = WARP_SIZE;
+ float refract = params[STRIDERFX_WARP_SCALE].x * WARP_REFRACT * gunFractionVisible;
+
+ pRenderContext->Bind( pMat, (IClientRenderable*)this );
+ IMaterialVar *pVar = pMat->FindVar( "$refractamount", NULL );
+ pVar->SetFloatValue( refract );
+ Strider_DrawSprite( m_worldPosition, size, white );
+ }
+// darkening sprite
+// glowy blue flare sprite
+ if ( hasParam[STRIDERFX_FLARE_COLOR] && hasParam[STRIDERFX_FLARE_SIZE] && hasParam[STRIDERFX_DARKNESS] && gunVisible )
+ {
+ IMaterial *pMat = materials->FindMaterial( "effects/blueblackflash", TEXTURE_GROUP_CLIENT_EFFECTS );
+ float size = FLARE_SIZE * params[STRIDERFX_FLARE_SIZE].x;
+ color32 color;
+ float bright = params[STRIDERFX_FLARE_COLOR].x * gunFractionVisible;
+ ScaleColor( color, white, bright );
+ color.a = (int)(255 * params[STRIDERFX_DARKNESS].x);
+ pRenderContext->Bind( pMat, (IClientRenderable*)this );
+ Strider_DrawSprite( m_worldPosition, size, color );
+ }
+// bubble warpy sprite
+ if ( hasParam[STRIDERFX_BUBBLE_SIZE] )
+ {
+ Vector wideBeamEnd = m_beamEndPosition;
+ if ( hasParam[STRIDERFX_WIDE_BEAM_LENGTH] )
+ {
+ float amt = params[STRIDERFX_WIDE_BEAM_LENGTH].x;
+ wideBeamEnd = m_beamEndPosition * amt + m_targetPosition * (1-amt);
+ }
+ pixelvis_queryparams_t endParams;
+ endParams.Init(wideBeamEnd, 4.0f, 0.001f);
+ float endFractionVisible = PixelVisibility_FractionVisible( endParams, &m_queryHandleBeamEnd );
+ bool endVisible = endFractionVisible > 0.0f ? true : false;
+
+ if ( endVisible )
+ {
+ if ( !updated )
+ {
+ updated = true;
+ pRenderContext->Flush();
+ UpdateRefractTexture();
+ }
+ IMaterial *pMat = materials->FindMaterial( "effects/strider_bulge_dudv", TEXTURE_GROUP_CLIENT_EFFECTS );
+ float refract = endFractionVisible * WARP_BUBBLE_REFRACT * params[STRIDERFX_BUBBLE_REFRACT].x;
+ float size = WARP_BUBBLE_SIZE * params[STRIDERFX_BUBBLE_SIZE].x;
+ IMaterialVar *pVar = pMat->FindVar( "$refractamount", NULL );
+ pVar->SetFloatValue( refract );
+
+ pRenderContext->Bind( pMat, (IClientRenderable*)this );
+ Strider_DrawSprite( wideBeamEnd, size, white );
+ }
+ }
+ else
+ {
+ // call this to have the check ready on the first frame
+ pixelvis_queryparams_t endParams;
+ endParams.Init(m_beamEndPosition, 4.0f, 0.001f);
+ PixelVisibility_FractionVisible( endParams, &m_queryHandleBeamEnd );
+ }
+ if ( hasParam[STRIDERFX_AFTERGLOW_COLOR] && gunVisible )
+ {
+ IMaterial *pMat = materials->FindMaterial( "effects/blueblackflash", TEXTURE_GROUP_CLIENT_EFFECTS );
+ float size = AFTERGLOW_SIZE;// * params[STRIDERFX_FLARE_SIZE].x;
+ color32 color;
+ float bright = params[STRIDERFX_AFTERGLOW_COLOR].x * gunFractionVisible;
+ ScaleColor( color, white, bright );
+
+ pRenderContext->Bind( pMat, (IClientRenderable*)this );
+ Strider_DrawSprite( m_worldPosition, size, color );
+
+ dlight_t *dl = effects->CL_AllocDlight( m_entityIndex );
+ dl->origin = m_worldPosition;
+ dl->color.r = 40;
+ dl->color.g = 60;
+ dl->color.b = 255;
+ dl->color.exponent = 5;
+ dl->radius = bright * 128;
+ dl->die = gpGlobals->curtime + 0.001;
+ }
+
+ if ( m_t >= STRIDERFX_END_ALL_TIME && !hasAny )
+ {
+ EffectShutdown();
+ }
+ return 1;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Strider class implementation
+//-----------------------------------------------------------------------------
+C_Strider::C_Strider() :
+ m_iv_vecHitPos("C_Strider::m_iv_vecHitPos"),
+ m_iv_vecIKTarget("C_Strider::m_iv_vecIKTarget")
+{
+ AddVar( &m_vecHitPos, &m_iv_vecHitPos, LATCH_ANIMATION_VAR );
+
+ memset(m_vecIKTarget, 0, sizeof(m_vecIKTarget));
+ AddVar( &m_vecIKTarget, &m_iv_vecIKTarget, LATCH_ANIMATION_VAR );
+
+ m_flNextRopeCutTime = 0;
+}
+
+C_Strider::~C_Strider()
+{
+}
+
+void C_Strider::ReceiveMessage( int classID, bf_read &msg )
+{
+ if ( classID != GetClientClass()->m_ClassID )
+ {
+ // message is for subclass
+ BaseClass::ReceiveMessage( classID, msg );
+ return;
+ }
+
+ int messageType = msg.ReadByte();
+ switch( messageType )
+ {
+ case STRIDER_MSG_STREAKS:
+ {
+ Vector pos;
+ msg.ReadBitVec3Coord( pos );
+ m_cannonFX.SetRenderOrigin( pos );
+ m_cannonFX.EffectInit( entindex(), LookupAttachment( "BigGun" ) );
+ m_cannonFX.LimitTime( STRIDERFX_BIG_SHOT_TIME );
+ }
+ break;
+
+ case STRIDER_MSG_BIG_SHOT:
+ {
+ Vector tmp;
+ msg.ReadBitVec3Coord( tmp );
+ m_cannonFX.SetTime( STRIDERFX_BIG_SHOT_TIME );
+ m_cannonFX.LimitTime( STRIDERFX_END_ALL_TIME );
+ }
+ break;
+
+ case STRIDER_MSG_DEAD:
+ {
+ m_cannonFX.EffectShutdown();
+ }
+ break;
+ }
+}
+
+
+void C_Strider::OnDataChanged( DataUpdateType_t updateType )
+{
+ if ( updateType == DATA_UPDATE_CREATED )
+ {
+ // We need to have our render bounds defined or shadow creation won't work correctly
+ ClientThink();
+ ClientThinkList()->SetNextClientThink( GetClientHandle(), CLIENT_THINK_ALWAYS );
+ }
+
+ BaseClass::OnDataChanged( updateType );
+
+ m_cannonFX.Update( this, m_vecHitPos );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Recompute my rendering box
+//-----------------------------------------------------------------------------
+void C_Strider::ClientThink()
+{
+ // The reason why this is here, as opposed to in SetObjectCollisionBox,
+ // is because of IK. The code below recomputes bones so as to get at the hitboxes,
+ // which causes IK to trigger, which causes raycasts against the other entities to occur,
+ // which is illegal to do while in the Relink phase.
+
+ ComputeEntitySpaceHitboxSurroundingBox( &m_vecRenderMins, &m_vecRenderMaxs );
+ // UNDONE: Disabled this until we can get closer to a final map and tune
+#if 0
+ // Cut ropes.
+ if ( gpGlobals->curtime >= m_flNextRopeCutTime )
+ {
+ // Blow the bbox out a little.
+ Vector vExtendedMins = vecMins - Vector( 50, 50, 50 );
+ Vector vExtendedMaxs = vecMaxs + Vector( 50, 50, 50 );
+
+ C_RopeKeyframe *ropes[512];
+ int nRopes = C_RopeKeyframe::GetRopesIntersectingAABB( ropes, ARRAYSIZE( ropes ), GetAbsOrigin() + vExtendedMins, GetAbsOrigin() + vExtendedMaxs );
+ for ( int i=0; i < nRopes; i++ )
+ {
+ C_RopeKeyframe *pRope = ropes[i];
+
+ if ( pRope->GetEndEntity() )
+ {
+ Vector vPos;
+ if ( pRope->GetEndPointPos( 1, vPos ) )
+ {
+ // Detach the endpoint.
+ pRope->SetEndEntity( NULL );
+
+ // Make some spark effect here..
+ g_pEffects->Sparks( vPos );
+ }
+ }
+ }
+
+ m_flNextRopeCutTime = gpGlobals->curtime + 0.5;
+ }
+#endif
+
+ // True argument because the origin may have stayed the same, but the size is expected to always change
+ g_pClientShadowMgr->AddToDirtyShadowList( this, true );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Recompute my rendering box
+//-----------------------------------------------------------------------------
+void C_Strider::GetRenderBounds( Vector& theMins, Vector& theMaxs )
+{
+ theMins = m_vecRenderMins;
+ theMaxs = m_vecRenderMaxs;
+}
+
+
+//-----------------------------------------------------------------------------
+// Strider muzzle flashes
+//-----------------------------------------------------------------------------
+void MuzzleFlash_Strider( ClientEntityHandle_t hEntity, int attachmentIndex )
+{
+ VPROF_BUDGET( "MuzzleFlash_Strider", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
+
+ // If the client hasn't seen this entity yet, bail.
+ matrix3x4_t matAttachment;
+ if ( !FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) )
+ return;
+
+ CSmartPtr<CLocalSpaceEmitter> pSimple = CLocalSpaceEmitter::Create( "MuzzleFlash_Strider", hEntity, attachmentIndex );
+
+ SimpleParticle *pParticle;
+ Vector forward(1,0,0), offset; //NOTENOTE: All coords are in local space
+
+ float flScale = random->RandomFloat( 3.0f, 4.0f );
+
+ float burstSpeed = random->RandomFloat( 400.0f, 600.0f );
+
+#define FRONT_LENGTH 12
+
+ // Front flash
+ for ( int i = 1; i < FRONT_LENGTH; i++ )
+ {
+ offset = (forward * (i*2.0f*flScale));
+
+ pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( VarArgs( "effects/combinemuzzle%d", random->RandomInt(1,2) ) ), offset );
+
+ if ( pParticle == NULL )
+ return;
+
+ pParticle->m_flLifetime = 0.0f;
+ pParticle->m_flDieTime = 0.1f;
+
+ pParticle->m_vecVelocity = forward * burstSpeed;
+
+ pParticle->m_uchColor[0] = 255;
+ pParticle->m_uchColor[1] = 255;
+ pParticle->m_uchColor[2] = 255;
+
+ pParticle->m_uchStartAlpha = 255.0f;
+ pParticle->m_uchEndAlpha = 0;
+
+ pParticle->m_uchStartSize = ( (random->RandomFloat( 6.0f, 8.0f ) * (FRONT_LENGTH-(i))/(FRONT_LENGTH*0.75f)) * flScale );
+ pParticle->m_uchEndSize = pParticle->m_uchStartSize;
+ pParticle->m_flRoll = random->RandomInt( 0, 360 );
+ pParticle->m_flRollDelta = 0.0f;
+ }
+
+ Vector right(0,1,0), up(0,0,1);
+ Vector dir = right - up;
+
+#define SIDE_LENGTH 8
+
+ burstSpeed = random->RandomFloat( 400.0f, 600.0f );
+
+ // Diagonal flash
+ for ( int i = 1; i < SIDE_LENGTH; i++ )
+ {
+ offset = (dir * (i*flScale));
+
+ pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( VarArgs( "effects/combinemuzzle%d", random->RandomInt(1,2) ) ), offset );
+
+ if ( pParticle == NULL )
+ return;
+
+ pParticle->m_flLifetime = 0.0f;
+ pParticle->m_flDieTime = 0.2f;
+
+ pParticle->m_vecVelocity = dir * burstSpeed * 0.25f;
+
+ pParticle->m_uchColor[0] = 255;
+ pParticle->m_uchColor[1] = 255;
+ pParticle->m_uchColor[2] = 255;
+
+ pParticle->m_uchStartAlpha = 255;
+ pParticle->m_uchEndAlpha = 0;
+
+ pParticle->m_uchStartSize = ( (random->RandomFloat( 2.0f, 4.0f ) * (SIDE_LENGTH-(i))/(SIDE_LENGTH*0.5f)) * flScale );
+ pParticle->m_uchEndSize = pParticle->m_uchStartSize;
+ pParticle->m_flRoll = random->RandomInt( 0, 360 );
+ pParticle->m_flRollDelta = 0.0f;
+ }
+
+ dir = right + up;
+ burstSpeed = random->RandomFloat( 400.0f, 600.0f );
+
+ // Diagonal flash
+ for ( int i = 1; i < SIDE_LENGTH; i++ )
+ {
+ offset = (-dir * (i*flScale));
+
+ pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( VarArgs( "effects/combinemuzzle%d", random->RandomInt(1,2) ) ), offset );
+
+ if ( pParticle == NULL )
+ return;
+
+ pParticle->m_flLifetime = 0.0f;
+ pParticle->m_flDieTime = 0.2f;
+
+ pParticle->m_vecVelocity = dir * -burstSpeed * 0.25f;
+
+ pParticle->m_uchColor[0] = 255;
+ pParticle->m_uchColor[1] = 255;
+ pParticle->m_uchColor[2] = 255;
+
+ pParticle->m_uchStartAlpha = 255;
+ pParticle->m_uchEndAlpha = 0;
+
+ pParticle->m_uchStartSize = ( (random->RandomFloat( 2.0f, 4.0f ) * (SIDE_LENGTH-(i))/(SIDE_LENGTH*0.5f)) * flScale );
+ pParticle->m_uchEndSize = pParticle->m_uchStartSize;
+ pParticle->m_flRoll = random->RandomInt( 0, 360 );
+ pParticle->m_flRollDelta = 0.0f;
+ }
+
+ dir = up;
+ burstSpeed = random->RandomFloat( 400.0f, 600.0f );
+
+ // Top flash
+ for ( int i = 1; i < SIDE_LENGTH; i++ )
+ {
+ offset = (dir * (i*flScale));
+
+ pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( VarArgs( "effects/combinemuzzle%d", random->RandomInt(1,2) ) ), offset );
+
+ if ( pParticle == NULL )
+ return;
+
+ pParticle->m_flLifetime = 0.0f;
+ pParticle->m_flDieTime = 0.2f;
+
+ pParticle->m_vecVelocity = dir * burstSpeed * 0.25f;
+
+ pParticle->m_uchColor[0] = 255;
+ pParticle->m_uchColor[1] = 255;
+ pParticle->m_uchColor[2] = 255;
+
+ pParticle->m_uchStartAlpha = 255;
+ pParticle->m_uchEndAlpha = 0;
+
+ pParticle->m_uchStartSize = ( (random->RandomFloat( 2.0f, 4.0f ) * (SIDE_LENGTH-(i))/(SIDE_LENGTH*0.5f)) * flScale );
+ pParticle->m_uchEndSize = pParticle->m_uchStartSize;
+ pParticle->m_flRoll = random->RandomInt( 0, 360 );
+ pParticle->m_flRollDelta = 0.0f;
+ }
+
+ pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/strider_muzzle" ), vec3_origin );
+
+ if ( pParticle == NULL )
+ return;
+
+ pParticle->m_flLifetime = 0.0f;
+ pParticle->m_flDieTime = random->RandomFloat( 0.3f, 0.4f );
+
+ pParticle->m_vecVelocity.Init();
+
+ pParticle->m_uchColor[0] = 255;
+ pParticle->m_uchColor[1] = 255;
+ pParticle->m_uchColor[2] = 255;
+
+ pParticle->m_uchStartAlpha = 255;
+ pParticle->m_uchEndAlpha = 0;
+
+ pParticle->m_uchStartSize = flScale * random->RandomFloat( 12.0f, 16.0f );
+ pParticle->m_uchEndSize = 0.0f;
+ pParticle->m_flRoll = random->RandomInt( 0, 360 );
+ pParticle->m_flRollDelta = 0.0f;
+
+ Vector origin;
+ MatrixGetColumn( matAttachment, 3, &origin );
+
+ int entityIndex = ClientEntityList().HandleToEntIndex( hEntity );
+ if ( entityIndex >= 0 )
+ {
+ dlight_t *el = effects->CL_AllocElight( LIGHT_INDEX_MUZZLEFLASH + entityIndex );
+
+ el->origin = origin;
+
+ el->color.r = 64;
+ el->color.g = 128;
+ el->color.b = 255;
+ el->color.exponent = 5;
+
+ el->radius = random->RandomInt( 100, 150 );
+ el->decay = el->radius / 0.05f;
+ el->die = gpGlobals->curtime + 0.1f;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &data -
+//-----------------------------------------------------------------------------
+void StriderMuzzleFlashCallback( const CEffectData &data )
+{
+ MuzzleFlash_Strider( data.m_hEntity, data.m_nAttachmentIndex );
+}
+
+DECLARE_CLIENT_EFFECT( "StriderMuzzleFlash", StriderMuzzleFlashCallback );
+
+#define BLOOD_MIN_SPEED 64.0f*2.0f
+#define BLOOD_MAX_SPEED 256.0f*8.0f
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &origin -
+// &normal -
+// scale -
+//-----------------------------------------------------------------------------
+void StriderBlood( const Vector &origin, const Vector &normal, float scale )
+{
+ VPROF_BUDGET( "StriderBlood", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
+
+ //Find area ambient light color and use it to tint smoke
+ Vector worldLight = WorldGetLightForPoint( origin, true );
+ Vector tint;
+ float luminosity;
+ UTIL_GetNormalizedColorTintAndLuminosity( worldLight, &tint, &luminosity );
+
+ // We only take a portion of the tint
+ tint = (tint * 0.25f)+(Vector(0.75f,0.75f,0.75f));
+
+ // Rescale to a character range
+ luminosity = MAX( 200, luminosity*255 );
+
+ CSmartPtr<CSplashParticle> pSimple = CSplashParticle::Create( "splish" );
+ pSimple->SetSortOrigin( origin );
+
+ int i;
+ float flScale = scale / 8.0f;
+
+ PMaterialHandle hMaterial = ParticleMgr()->GetPMaterial( "effects/slime1" );
+
+ float length = 0.2f;
+ Vector vForward, vRight, vUp;
+ Vector offDir;
+
+ TrailParticle *tParticle;
+
+ CSmartPtr<CTrailParticles> sparkEmitter = CTrailParticles::Create( "splash" );
+
+ if ( !sparkEmitter )
+ return;
+
+ sparkEmitter->SetSortOrigin( origin );
+ sparkEmitter->m_ParticleCollision.SetGravity( 600.0f );
+ sparkEmitter->SetFlag( bitsPARTICLE_TRAIL_VELOCITY_DAMPEN );
+ sparkEmitter->SetVelocityDampen( 2.0f );
+
+ //Dump out drops
+ Vector offset;
+ for ( i = 0; i < 64; i++ )
+ {
+ offset = origin;
+ offset[0] += random->RandomFloat( -8.0f, 8.0f ) * flScale;
+ offset[1] += random->RandomFloat( -8.0f, 8.0f ) * flScale;
+ offset[2] += random->RandomFloat( -8.0f, 8.0f ) * flScale;
+
+ tParticle = (TrailParticle *) sparkEmitter->AddParticle( sizeof(TrailParticle), hMaterial, offset );
+
+ if ( tParticle == NULL )
+ break;
+
+ tParticle->m_flLifetime = 0.0f;
+ tParticle->m_flDieTime = 1.0f;
+
+ offDir = normal + RandomVector( -1.0f, 1.0f );
+
+ tParticle->m_vecVelocity = offDir * random->RandomFloat( BLOOD_MIN_SPEED * flScale * 2.0f, BLOOD_MAX_SPEED * flScale * 2.0f );
+ tParticle->m_vecVelocity[2] += random->RandomFloat( 8.0f, 32.0f ) * flScale;
+
+ tParticle->m_flWidth = random->RandomFloat( 20.0f, 26.0f ) * flScale;
+ tParticle->m_flLength = random->RandomFloat( length*0.5f, length ) * flScale;
+
+ int nColor = random->RandomInt( luminosity*0.75f, luminosity );
+ tParticle->m_color.r = nColor * tint.x;
+ tParticle->m_color.g = nColor * tint.y;
+ tParticle->m_color.b = nColor * tint.z;
+ tParticle->m_color.a = 255;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &data -
+//-----------------------------------------------------------------------------
+void StriderBloodCallback( const CEffectData &data )
+{
+ StriderBlood( data.m_vOrigin, data.m_vNormal, data.m_flScale );
+}
+
+DECLARE_CLIENT_EFFECT( "StriderBlood", StriderBloodCallback );
+
diff --git a/mp/src/game/client/hl2/c_te_concussiveexplosion.cpp b/mp/src/game/client/hl2/c_te_concussiveexplosion.cpp
index 9332cc35..530d5d5d 100644
--- a/mp/src/game/client/hl2/c_te_concussiveexplosion.cpp
+++ b/mp/src/game/client/hl2/c_te_concussiveexplosion.cpp
@@ -1,110 +1,110 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//===========================================================================//
-#include "cbase.h"
-#include "c_te_particlesystem.h"
-#include "fx.h"
-#include "ragdollexplosionenumerator.h"
-#include "tier1/KeyValues.h"
-#include "toolframework_client.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//-----------------------------------------------------------------------------
-// Purpose: Concussive explosion entity
-//-----------------------------------------------------------------------------
-class C_TEConcussiveExplosion : public C_TEParticleSystem
-{
-public:
- DECLARE_CLASS( C_TEConcussiveExplosion, C_TEParticleSystem );
- DECLARE_CLIENTCLASS();
-
- virtual void PostDataUpdate( DataUpdateType_t updateType );
-
- void AffectRagdolls( void );
-
- Vector m_vecNormal;
- float m_flScale;
- int m_nRadius;
- int m_nMagnitude;
-};
-
-
-//-----------------------------------------------------------------------------
-// Networking
-//-----------------------------------------------------------------------------
-IMPLEMENT_CLIENTCLASS_EVENT_DT( C_TEConcussiveExplosion, DT_TEConcussiveExplosion, CTEConcussiveExplosion )
- RecvPropVector( RECVINFO(m_vecNormal)),
- RecvPropFloat( RECVINFO(m_flScale)),
- RecvPropInt( RECVINFO(m_nRadius)),
- RecvPropInt( RECVINFO(m_nMagnitude)),
-END_RECV_TABLE()
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_TEConcussiveExplosion::AffectRagdolls( void )
-{
- if ( ( m_nRadius == 0 ) || ( m_nMagnitude == 0 ) )
- return;
-
- CRagdollExplosionEnumerator ragdollEnum( m_vecOrigin, m_nRadius, m_nMagnitude );
- partition->EnumerateElementsInSphere( PARTITION_CLIENT_RESPONSIVE_EDICTS, m_vecOrigin, m_nRadius, false, &ragdollEnum );
-}
-
-
-//-----------------------------------------------------------------------------
-// Recording
-//-----------------------------------------------------------------------------
-static inline void RecordConcussiveExplosion( const Vector& start, const Vector &vecDirection )
-{
- if ( !ToolsEnabled() )
- return;
-
- if ( clienttools->IsInRecordingMode() )
- {
- KeyValues *msg = new KeyValues( "TempEntity" );
-
- msg->SetInt( "te", TE_CONCUSSIVE_EXPLOSION );
- msg->SetString( "name", "TE_ConcussiveExplosion" );
- msg->SetFloat( "time", gpGlobals->curtime );
- msg->SetFloat( "originx", start.x );
- msg->SetFloat( "originy", start.y );
- msg->SetFloat( "originz", start.z );
- msg->SetFloat( "directionx", vecDirection.x );
- msg->SetFloat( "directiony", vecDirection.y );
- msg->SetFloat( "directionz", vecDirection.z );
-
- ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg );
- msg->deleteThis();
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_TEConcussiveExplosion::PostDataUpdate( DataUpdateType_t updateType )
-{
- AffectRagdolls();
-
- FX_ConcussiveExplosion( m_vecOrigin, m_vecNormal );
- RecordConcussiveExplosion( m_vecOrigin, m_vecNormal );
-}
-
-void TE_ConcussiveExplosion( IRecipientFilter& filter, float delay, KeyValues *pKeyValues )
-{
- Vector vecOrigin, vecDirection;
- vecOrigin.x = pKeyValues->GetFloat( "originx" );
- vecOrigin.y = pKeyValues->GetFloat( "originy" );
- vecOrigin.z = pKeyValues->GetFloat( "originz" );
- vecDirection.x = pKeyValues->GetFloat( "directionx" );
- vecDirection.y = pKeyValues->GetFloat( "directiony" );
- vecDirection.z = pKeyValues->GetFloat( "directionz" );
- FX_ConcussiveExplosion( vecOrigin, vecDirection );
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//===========================================================================//
+#include "cbase.h"
+#include "c_te_particlesystem.h"
+#include "fx.h"
+#include "ragdollexplosionenumerator.h"
+#include "tier1/KeyValues.h"
+#include "toolframework_client.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: Concussive explosion entity
+//-----------------------------------------------------------------------------
+class C_TEConcussiveExplosion : public C_TEParticleSystem
+{
+public:
+ DECLARE_CLASS( C_TEConcussiveExplosion, C_TEParticleSystem );
+ DECLARE_CLIENTCLASS();
+
+ virtual void PostDataUpdate( DataUpdateType_t updateType );
+
+ void AffectRagdolls( void );
+
+ Vector m_vecNormal;
+ float m_flScale;
+ int m_nRadius;
+ int m_nMagnitude;
+};
+
+
+//-----------------------------------------------------------------------------
+// Networking
+//-----------------------------------------------------------------------------
+IMPLEMENT_CLIENTCLASS_EVENT_DT( C_TEConcussiveExplosion, DT_TEConcussiveExplosion, CTEConcussiveExplosion )
+ RecvPropVector( RECVINFO(m_vecNormal)),
+ RecvPropFloat( RECVINFO(m_flScale)),
+ RecvPropInt( RECVINFO(m_nRadius)),
+ RecvPropInt( RECVINFO(m_nMagnitude)),
+END_RECV_TABLE()
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_TEConcussiveExplosion::AffectRagdolls( void )
+{
+ if ( ( m_nRadius == 0 ) || ( m_nMagnitude == 0 ) )
+ return;
+
+ CRagdollExplosionEnumerator ragdollEnum( m_vecOrigin, m_nRadius, m_nMagnitude );
+ partition->EnumerateElementsInSphere( PARTITION_CLIENT_RESPONSIVE_EDICTS, m_vecOrigin, m_nRadius, false, &ragdollEnum );
+}
+
+
+//-----------------------------------------------------------------------------
+// Recording
+//-----------------------------------------------------------------------------
+static inline void RecordConcussiveExplosion( const Vector& start, const Vector &vecDirection )
+{
+ if ( !ToolsEnabled() )
+ return;
+
+ if ( clienttools->IsInRecordingMode() )
+ {
+ KeyValues *msg = new KeyValues( "TempEntity" );
+
+ msg->SetInt( "te", TE_CONCUSSIVE_EXPLOSION );
+ msg->SetString( "name", "TE_ConcussiveExplosion" );
+ msg->SetFloat( "time", gpGlobals->curtime );
+ msg->SetFloat( "originx", start.x );
+ msg->SetFloat( "originy", start.y );
+ msg->SetFloat( "originz", start.z );
+ msg->SetFloat( "directionx", vecDirection.x );
+ msg->SetFloat( "directiony", vecDirection.y );
+ msg->SetFloat( "directionz", vecDirection.z );
+
+ ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg );
+ msg->deleteThis();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_TEConcussiveExplosion::PostDataUpdate( DataUpdateType_t updateType )
+{
+ AffectRagdolls();
+
+ FX_ConcussiveExplosion( m_vecOrigin, m_vecNormal );
+ RecordConcussiveExplosion( m_vecOrigin, m_vecNormal );
+}
+
+void TE_ConcussiveExplosion( IRecipientFilter& filter, float delay, KeyValues *pKeyValues )
+{
+ Vector vecOrigin, vecDirection;
+ vecOrigin.x = pKeyValues->GetFloat( "originx" );
+ vecOrigin.y = pKeyValues->GetFloat( "originy" );
+ vecOrigin.z = pKeyValues->GetFloat( "originz" );
+ vecDirection.x = pKeyValues->GetFloat( "directionx" );
+ vecDirection.y = pKeyValues->GetFloat( "directiony" );
+ vecDirection.z = pKeyValues->GetFloat( "directionz" );
+ FX_ConcussiveExplosion( vecOrigin, vecDirection );
} \ No newline at end of file
diff --git a/mp/src/game/client/hl2/c_te_flare.cpp b/mp/src/game/client/hl2/c_te_flare.cpp
index 36c730c7..5e00ea5d 100644
--- a/mp/src/game/client/hl2/c_te_flare.cpp
+++ b/mp/src/game/client/hl2/c_te_flare.cpp
@@ -1,414 +1,414 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Flare effects
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "clienteffectprecachesystem.h"
-#include "particles_simple.h"
-#include "iefx.h"
-#include "dlight.h"
-#include "view.h"
-#include "fx.h"
-#include "clientsideeffects.h"
-#include "c_pixel_visibility.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//Precahce the effects
-CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectFlares )
-CLIENTEFFECT_MATERIAL( "effects/redflare" )
-CLIENTEFFECT_MATERIAL( "effects/yellowflare" )
-CLIENTEFFECT_MATERIAL( "effects/yellowflare_noz" )
-CLIENTEFFECT_REGISTER_END()
-
-class C_Flare : public C_BaseCombatCharacter, CSimpleEmitter
-{
-public:
- DECLARE_CLASS( C_Flare, C_BaseCombatCharacter );
- DECLARE_CLIENTCLASS();
-
- C_Flare();
-
- void OnDataChanged( DataUpdateType_t updateType );
- void Update( float timeDelta );
- void NotifyDestroyParticle( Particle* pParticle );
- void NotifyShouldTransmit( ShouldTransmitState_t state );
- void RestoreResources( void );
-
- float m_flTimeBurnOut;
- float m_flScale;
- bool m_bLight;
- bool m_bSmoke;
- bool m_bPropFlare;
- pixelvis_handle_t m_queryHandle;
-
-
-private:
- C_Flare( const C_Flare & );
- TimedEvent m_teSmokeSpawn;
-
- int m_iAttachment;
-
- SimpleParticle *m_pParticle[2];
-};
-
-IMPLEMENT_CLIENTCLASS_DT( C_Flare, DT_Flare, CFlare )
- RecvPropFloat( RECVINFO( m_flTimeBurnOut ) ),
- RecvPropFloat( RECVINFO( m_flScale ) ),
- RecvPropInt( RECVINFO( m_bLight ) ),
- RecvPropInt( RECVINFO( m_bSmoke ) ),
- RecvPropInt( RECVINFO( m_bPropFlare ) ),
-END_RECV_TABLE()
-
-//-----------------------------------------------------------------------------
-// Constructor
-//-----------------------------------------------------------------------------
-C_Flare::C_Flare() : CSimpleEmitter( "C_Flare" )
-{
- m_pParticle[0] = NULL;
- m_pParticle[1] = NULL;
- m_flTimeBurnOut = 0.0f;
-
- m_bLight = true;
- m_bSmoke = true;
- m_bPropFlare = false;
-
- SetDynamicallyAllocated( false );
- m_queryHandle = 0;
-
- m_iAttachment = -1;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : state -
-//-----------------------------------------------------------------------------
-void C_Flare::NotifyShouldTransmit( ShouldTransmitState_t state )
-{
- if ( state == SHOULDTRANSMIT_END )
- {
- AddEffects( EF_NODRAW );
- }
- else if ( state == SHOULDTRANSMIT_START )
- {
- RemoveEffects( EF_NODRAW );
- }
-
- BaseClass::NotifyShouldTransmit( state );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : bool -
-//-----------------------------------------------------------------------------
-void C_Flare::OnDataChanged( DataUpdateType_t updateType )
-{
- if ( updateType == DATA_UPDATE_CREATED )
- {
- SetSortOrigin( GetAbsOrigin() );
- if ( m_bSmoke )
- {
- m_teSmokeSpawn.Init( 8 );
- }
- }
-
- BaseClass::OnDataChanged( updateType );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_Flare::RestoreResources( void )
-{
- if ( m_pParticle[0] == NULL )
- {
- m_pParticle[0] = (SimpleParticle *) AddParticle( sizeof( SimpleParticle ), GetPMaterial( "effects/redflare" ), GetAbsOrigin() );
-
- if ( m_pParticle[0] != NULL )
- {
- m_pParticle[0]->m_uchColor[0] = m_pParticle[0]->m_uchColor[1] = m_pParticle[0]->m_uchColor[2] = 0;
- m_pParticle[0]->m_flRoll = random->RandomInt( 0, 360 );
- m_pParticle[0]->m_flRollDelta = random->RandomFloat( 1.0f, 4.0f );
- m_pParticle[0]->m_flLifetime = 0.0f;
- m_pParticle[0]->m_flDieTime = 10.0f;
- }
- else
- {
- Assert(0);
- }
- }
-
- if ( m_pParticle[1] == NULL )
- {
- m_pParticle[1] = (SimpleParticle *) AddParticle( sizeof( SimpleParticle ), GetPMaterial( "effects/yellowflare_noz" ), GetAbsOrigin() );
-
- if ( m_pParticle[1] != NULL )
- {
- m_pParticle[1]->m_uchColor[0] = m_pParticle[1]->m_uchColor[1] = m_pParticle[1]->m_uchColor[2] = 0;
- m_pParticle[1]->m_flRoll = random->RandomInt( 0, 360 );
- m_pParticle[1]->m_flRollDelta = random->RandomFloat( 1.0f, 4.0f );
- m_pParticle[1]->m_flLifetime = 0.0f;
- m_pParticle[1]->m_flDieTime = 10.0f;
- }
- else
- {
- Assert(0);
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : pParticle -
-//-----------------------------------------------------------------------------
-void C_Flare::NotifyDestroyParticle( Particle* pParticle )
-{
- if ( pParticle == m_pParticle[0] )
- {
- m_pParticle[0] = NULL;
- }
-
- if ( pParticle == m_pParticle[1] )
- {
- m_pParticle[1] = NULL;
- }
-
- CSimpleEmitter::NotifyDestroyParticle( pParticle );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : timeDelta -
-//-----------------------------------------------------------------------------
-void C_Flare::Update( float timeDelta )
-{
- if ( !IsVisible() )
- return;
-
- CSimpleEmitter::Update( timeDelta );
-
- //Make sure our stored resources are up to date
- RestoreResources();
-
- //Don't do this if the console is down
- if ( timeDelta <= 0.0f )
- return;
-
- //Check for LOS
- pixelvis_queryparams_t params;
- params.Init(GetAbsOrigin());
- params.proxySize = 8.0f; // Inches
-
- float visible = PixelVisibility_FractionVisible( params, &m_queryHandle );
-
- float fColor;
-#ifdef HL2_CLIENT_DLL
- float baseScale = m_flScale;
-#else
- // NOTE!!! This is bigger by a factor of 1.2 to deal with fixing a bug from HL2. See dlight_t.h
- float baseScale = m_flScale * 1.2f;
-#endif
-
- //Account for fading out
- if ( ( m_flTimeBurnOut != -1.0f ) && ( ( m_flTimeBurnOut - gpGlobals->curtime ) <= 10.0f ) )
- {
- baseScale *= ( ( m_flTimeBurnOut - gpGlobals->curtime ) / 10.0f );
- }
-
- bool bVisible = (baseScale < 0.01f || visible == 0.0f) ? false : true;
- //Clamp the scale if vanished
- if ( !bVisible )
- {
- if ( m_pParticle[0] != NULL )
- {
- m_pParticle[0]->m_flDieTime = gpGlobals->curtime;
- m_pParticle[0]->m_uchStartSize = m_pParticle[0]->m_uchEndSize = 0;
- m_pParticle[0]->m_uchColor[0] = 0;
- m_pParticle[0]->m_uchColor[1] = 0;
- m_pParticle[0]->m_uchColor[2] = 0;
- }
-
- if ( m_pParticle[1] != NULL )
- {
- m_pParticle[1]->m_flDieTime = gpGlobals->curtime;
- m_pParticle[1]->m_uchStartSize = m_pParticle[1]->m_uchEndSize = 0;
- m_pParticle[1]->m_uchColor[0] = 0;
- m_pParticle[1]->m_uchColor[1] = 0;
- m_pParticle[1]->m_uchColor[2] = 0;
- }
- }
-
- if ( baseScale < 0.01f )
- return;
- //
- // Dynamic light
- //
-
- if ( m_bLight )
- {
- dlight_t *dl= effects->CL_AllocDlight( index );
-
-
-
- if ( m_bPropFlare == false )
- {
- dl->origin = GetAbsOrigin();
- dl->color.r = 255;
- dl->die = gpGlobals->curtime + 0.1f;
-
- dl->radius = baseScale * random->RandomFloat( 110.0f, 128.0f );
- dl->color.g = dl->color.b = random->RandomInt( 32, 64 );
- }
- else
- {
- if ( m_iAttachment == -1 )
- {
- m_iAttachment = LookupAttachment( "fuse" );
- }
-
- if ( m_iAttachment != -1 )
- {
- Vector effect_origin;
- QAngle effect_angles;
-
- GetAttachment( m_iAttachment, effect_origin, effect_angles );
-
- //Raise the light a little bit away from the flare so it lights it up better.
- dl->origin = effect_origin + Vector( 0, 0, 4 );
- dl->color.r = 255;
- dl->die = gpGlobals->curtime + 0.1f;
-
- dl->radius = baseScale * random->RandomFloat( 245.0f, 256.0f );
- dl->color.g = dl->color.b = random->RandomInt( 95, 128 );
-
- dlight_t *el= effects->CL_AllocElight( index );
-
- el->origin = effect_origin;
- el->color.r = 255;
- el->color.g = dl->color.b = random->RandomInt( 95, 128 );
- el->radius = baseScale * random->RandomFloat( 260.0f, 290.0f );
- el->die = gpGlobals->curtime + 0.1f;
- }
- }
- }
-
- //
- // Smoke
- //
-
- float dt = timeDelta;
-
- if ( m_bSmoke )
- {
- while ( m_teSmokeSpawn.NextEvent( dt ) )
- {
- Vector smokeOrg = GetAbsOrigin();
-
- Vector flareScreenDir = ( smokeOrg - MainViewOrigin() );
- VectorNormalize( flareScreenDir );
-
- smokeOrg = smokeOrg + ( flareScreenDir * 2.0f );
- smokeOrg[2] += baseScale * 4.0f;
-
- SimpleParticle *sParticle = (SimpleParticle *) AddParticle( sizeof( SimpleParticle ), g_Mat_DustPuff[1], smokeOrg );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_flLifetime = 0.0f;
- sParticle->m_flDieTime = 1.0f;
-
- sParticle->m_vecVelocity = Vector( random->RandomFloat( -16.0f, 16.0f ), random->RandomFloat( -16.0f, 16.0f ), random->RandomFloat( 8.0f, 16.0f ) + 32.0f );
-
- if ( m_bPropFlare )
- {
- sParticle->m_uchColor[0] = 255;
- sParticle->m_uchColor[1] = 100;
- sParticle->m_uchColor[2] = 100;
- }
- else
- {
- sParticle->m_uchColor[0] = 255;
- sParticle->m_uchColor[1] = 48;
- sParticle->m_uchColor[2] = 48;
- }
-
- sParticle->m_uchStartAlpha = random->RandomInt( 64, 90 );
- sParticle->m_uchEndAlpha = 0;
- sParticle->m_uchStartSize = random->RandomInt( 2, 4 );
- sParticle->m_uchEndSize = sParticle->m_uchStartSize * 8.0f;
- sParticle->m_flRoll = random->RandomInt( 0, 2*M_PI );
- sParticle->m_flRollDelta = random->RandomFloat( -(M_PI/6.0f), M_PI/6.0f );
- }
- }
-
- if ( !bVisible )
- return;
-
- //
- // Outer glow
- //
-
- Vector offset;
-
- //Cause the base of the effect to shake
- offset.Random( -0.5f * baseScale, 0.5f * baseScale );
- offset += GetAbsOrigin();
-
- if ( m_pParticle[0] != NULL )
- {
- m_pParticle[0]->m_Pos = offset;
- m_pParticle[0]->m_flLifetime = 0.0f;
- m_pParticle[0]->m_flDieTime = 2.0f;
-
- m_pParticle[0]->m_vecVelocity.Init();
-
- fColor = random->RandomInt( 100.0f, 128.0f ) * visible;
-
- m_pParticle[0]->m_uchColor[0] = fColor;
- m_pParticle[0]->m_uchColor[1] = fColor;
- m_pParticle[0]->m_uchColor[2] = fColor;
- m_pParticle[0]->m_uchStartAlpha = fColor;
- m_pParticle[0]->m_uchEndAlpha = fColor;
- m_pParticle[0]->m_uchStartSize = baseScale * (float) random->RandomInt( 32, 48 );
- m_pParticle[0]->m_uchEndSize = m_pParticle[0]->m_uchStartSize;
- m_pParticle[0]->m_flRollDelta = 0.0f;
-
- if ( random->RandomInt( 0, 4 ) == 3 )
- {
- m_pParticle[0]->m_flRoll += random->RandomInt( 2, 8 );
- }
- }
-
- //
- // Inner core
- //
-
- //Cause the base of the effect to shake
- offset.Random( -1.0f * baseScale, 1.0f * baseScale );
- offset += GetAbsOrigin();
-
- if ( m_pParticle[1] != NULL )
- {
- m_pParticle[1]->m_Pos = offset;
- m_pParticle[1]->m_flLifetime = 0.0f;
- m_pParticle[1]->m_flDieTime = 2.0f;
-
- m_pParticle[1]->m_vecVelocity.Init();
-
- fColor = 255 * visible;
-
- m_pParticle[1]->m_uchColor[0] = fColor;
- m_pParticle[1]->m_uchColor[1] = fColor;
- m_pParticle[1]->m_uchColor[2] = fColor;
- m_pParticle[1]->m_uchStartAlpha = fColor;
- m_pParticle[1]->m_uchEndAlpha = fColor;
- m_pParticle[1]->m_uchStartSize = baseScale * (float) random->RandomInt( 2, 4 );
- m_pParticle[1]->m_uchEndSize = m_pParticle[0]->m_uchStartSize;
- m_pParticle[1]->m_flRoll = random->RandomInt( 0, 360 );
- }
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Flare effects
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "clienteffectprecachesystem.h"
+#include "particles_simple.h"
+#include "iefx.h"
+#include "dlight.h"
+#include "view.h"
+#include "fx.h"
+#include "clientsideeffects.h"
+#include "c_pixel_visibility.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//Precahce the effects
+CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectFlares )
+CLIENTEFFECT_MATERIAL( "effects/redflare" )
+CLIENTEFFECT_MATERIAL( "effects/yellowflare" )
+CLIENTEFFECT_MATERIAL( "effects/yellowflare_noz" )
+CLIENTEFFECT_REGISTER_END()
+
+class C_Flare : public C_BaseCombatCharacter, CSimpleEmitter
+{
+public:
+ DECLARE_CLASS( C_Flare, C_BaseCombatCharacter );
+ DECLARE_CLIENTCLASS();
+
+ C_Flare();
+
+ void OnDataChanged( DataUpdateType_t updateType );
+ void Update( float timeDelta );
+ void NotifyDestroyParticle( Particle* pParticle );
+ void NotifyShouldTransmit( ShouldTransmitState_t state );
+ void RestoreResources( void );
+
+ float m_flTimeBurnOut;
+ float m_flScale;
+ bool m_bLight;
+ bool m_bSmoke;
+ bool m_bPropFlare;
+ pixelvis_handle_t m_queryHandle;
+
+
+private:
+ C_Flare( const C_Flare & );
+ TimedEvent m_teSmokeSpawn;
+
+ int m_iAttachment;
+
+ SimpleParticle *m_pParticle[2];
+};
+
+IMPLEMENT_CLIENTCLASS_DT( C_Flare, DT_Flare, CFlare )
+ RecvPropFloat( RECVINFO( m_flTimeBurnOut ) ),
+ RecvPropFloat( RECVINFO( m_flScale ) ),
+ RecvPropInt( RECVINFO( m_bLight ) ),
+ RecvPropInt( RECVINFO( m_bSmoke ) ),
+ RecvPropInt( RECVINFO( m_bPropFlare ) ),
+END_RECV_TABLE()
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+C_Flare::C_Flare() : CSimpleEmitter( "C_Flare" )
+{
+ m_pParticle[0] = NULL;
+ m_pParticle[1] = NULL;
+ m_flTimeBurnOut = 0.0f;
+
+ m_bLight = true;
+ m_bSmoke = true;
+ m_bPropFlare = false;
+
+ SetDynamicallyAllocated( false );
+ m_queryHandle = 0;
+
+ m_iAttachment = -1;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : state -
+//-----------------------------------------------------------------------------
+void C_Flare::NotifyShouldTransmit( ShouldTransmitState_t state )
+{
+ if ( state == SHOULDTRANSMIT_END )
+ {
+ AddEffects( EF_NODRAW );
+ }
+ else if ( state == SHOULDTRANSMIT_START )
+ {
+ RemoveEffects( EF_NODRAW );
+ }
+
+ BaseClass::NotifyShouldTransmit( state );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : bool -
+//-----------------------------------------------------------------------------
+void C_Flare::OnDataChanged( DataUpdateType_t updateType )
+{
+ if ( updateType == DATA_UPDATE_CREATED )
+ {
+ SetSortOrigin( GetAbsOrigin() );
+ if ( m_bSmoke )
+ {
+ m_teSmokeSpawn.Init( 8 );
+ }
+ }
+
+ BaseClass::OnDataChanged( updateType );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_Flare::RestoreResources( void )
+{
+ if ( m_pParticle[0] == NULL )
+ {
+ m_pParticle[0] = (SimpleParticle *) AddParticle( sizeof( SimpleParticle ), GetPMaterial( "effects/redflare" ), GetAbsOrigin() );
+
+ if ( m_pParticle[0] != NULL )
+ {
+ m_pParticle[0]->m_uchColor[0] = m_pParticle[0]->m_uchColor[1] = m_pParticle[0]->m_uchColor[2] = 0;
+ m_pParticle[0]->m_flRoll = random->RandomInt( 0, 360 );
+ m_pParticle[0]->m_flRollDelta = random->RandomFloat( 1.0f, 4.0f );
+ m_pParticle[0]->m_flLifetime = 0.0f;
+ m_pParticle[0]->m_flDieTime = 10.0f;
+ }
+ else
+ {
+ Assert(0);
+ }
+ }
+
+ if ( m_pParticle[1] == NULL )
+ {
+ m_pParticle[1] = (SimpleParticle *) AddParticle( sizeof( SimpleParticle ), GetPMaterial( "effects/yellowflare_noz" ), GetAbsOrigin() );
+
+ if ( m_pParticle[1] != NULL )
+ {
+ m_pParticle[1]->m_uchColor[0] = m_pParticle[1]->m_uchColor[1] = m_pParticle[1]->m_uchColor[2] = 0;
+ m_pParticle[1]->m_flRoll = random->RandomInt( 0, 360 );
+ m_pParticle[1]->m_flRollDelta = random->RandomFloat( 1.0f, 4.0f );
+ m_pParticle[1]->m_flLifetime = 0.0f;
+ m_pParticle[1]->m_flDieTime = 10.0f;
+ }
+ else
+ {
+ Assert(0);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pParticle -
+//-----------------------------------------------------------------------------
+void C_Flare::NotifyDestroyParticle( Particle* pParticle )
+{
+ if ( pParticle == m_pParticle[0] )
+ {
+ m_pParticle[0] = NULL;
+ }
+
+ if ( pParticle == m_pParticle[1] )
+ {
+ m_pParticle[1] = NULL;
+ }
+
+ CSimpleEmitter::NotifyDestroyParticle( pParticle );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : timeDelta -
+//-----------------------------------------------------------------------------
+void C_Flare::Update( float timeDelta )
+{
+ if ( !IsVisible() )
+ return;
+
+ CSimpleEmitter::Update( timeDelta );
+
+ //Make sure our stored resources are up to date
+ RestoreResources();
+
+ //Don't do this if the console is down
+ if ( timeDelta <= 0.0f )
+ return;
+
+ //Check for LOS
+ pixelvis_queryparams_t params;
+ params.Init(GetAbsOrigin());
+ params.proxySize = 8.0f; // Inches
+
+ float visible = PixelVisibility_FractionVisible( params, &m_queryHandle );
+
+ float fColor;
+#ifdef HL2_CLIENT_DLL
+ float baseScale = m_flScale;
+#else
+ // NOTE!!! This is bigger by a factor of 1.2 to deal with fixing a bug from HL2. See dlight_t.h
+ float baseScale = m_flScale * 1.2f;
+#endif
+
+ //Account for fading out
+ if ( ( m_flTimeBurnOut != -1.0f ) && ( ( m_flTimeBurnOut - gpGlobals->curtime ) <= 10.0f ) )
+ {
+ baseScale *= ( ( m_flTimeBurnOut - gpGlobals->curtime ) / 10.0f );
+ }
+
+ bool bVisible = (baseScale < 0.01f || visible == 0.0f) ? false : true;
+ //Clamp the scale if vanished
+ if ( !bVisible )
+ {
+ if ( m_pParticle[0] != NULL )
+ {
+ m_pParticle[0]->m_flDieTime = gpGlobals->curtime;
+ m_pParticle[0]->m_uchStartSize = m_pParticle[0]->m_uchEndSize = 0;
+ m_pParticle[0]->m_uchColor[0] = 0;
+ m_pParticle[0]->m_uchColor[1] = 0;
+ m_pParticle[0]->m_uchColor[2] = 0;
+ }
+
+ if ( m_pParticle[1] != NULL )
+ {
+ m_pParticle[1]->m_flDieTime = gpGlobals->curtime;
+ m_pParticle[1]->m_uchStartSize = m_pParticle[1]->m_uchEndSize = 0;
+ m_pParticle[1]->m_uchColor[0] = 0;
+ m_pParticle[1]->m_uchColor[1] = 0;
+ m_pParticle[1]->m_uchColor[2] = 0;
+ }
+ }
+
+ if ( baseScale < 0.01f )
+ return;
+ //
+ // Dynamic light
+ //
+
+ if ( m_bLight )
+ {
+ dlight_t *dl= effects->CL_AllocDlight( index );
+
+
+
+ if ( m_bPropFlare == false )
+ {
+ dl->origin = GetAbsOrigin();
+ dl->color.r = 255;
+ dl->die = gpGlobals->curtime + 0.1f;
+
+ dl->radius = baseScale * random->RandomFloat( 110.0f, 128.0f );
+ dl->color.g = dl->color.b = random->RandomInt( 32, 64 );
+ }
+ else
+ {
+ if ( m_iAttachment == -1 )
+ {
+ m_iAttachment = LookupAttachment( "fuse" );
+ }
+
+ if ( m_iAttachment != -1 )
+ {
+ Vector effect_origin;
+ QAngle effect_angles;
+
+ GetAttachment( m_iAttachment, effect_origin, effect_angles );
+
+ //Raise the light a little bit away from the flare so it lights it up better.
+ dl->origin = effect_origin + Vector( 0, 0, 4 );
+ dl->color.r = 255;
+ dl->die = gpGlobals->curtime + 0.1f;
+
+ dl->radius = baseScale * random->RandomFloat( 245.0f, 256.0f );
+ dl->color.g = dl->color.b = random->RandomInt( 95, 128 );
+
+ dlight_t *el= effects->CL_AllocElight( index );
+
+ el->origin = effect_origin;
+ el->color.r = 255;
+ el->color.g = dl->color.b = random->RandomInt( 95, 128 );
+ el->radius = baseScale * random->RandomFloat( 260.0f, 290.0f );
+ el->die = gpGlobals->curtime + 0.1f;
+ }
+ }
+ }
+
+ //
+ // Smoke
+ //
+
+ float dt = timeDelta;
+
+ if ( m_bSmoke )
+ {
+ while ( m_teSmokeSpawn.NextEvent( dt ) )
+ {
+ Vector smokeOrg = GetAbsOrigin();
+
+ Vector flareScreenDir = ( smokeOrg - MainViewOrigin() );
+ VectorNormalize( flareScreenDir );
+
+ smokeOrg = smokeOrg + ( flareScreenDir * 2.0f );
+ smokeOrg[2] += baseScale * 4.0f;
+
+ SimpleParticle *sParticle = (SimpleParticle *) AddParticle( sizeof( SimpleParticle ), g_Mat_DustPuff[1], smokeOrg );
+
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_flLifetime = 0.0f;
+ sParticle->m_flDieTime = 1.0f;
+
+ sParticle->m_vecVelocity = Vector( random->RandomFloat( -16.0f, 16.0f ), random->RandomFloat( -16.0f, 16.0f ), random->RandomFloat( 8.0f, 16.0f ) + 32.0f );
+
+ if ( m_bPropFlare )
+ {
+ sParticle->m_uchColor[0] = 255;
+ sParticle->m_uchColor[1] = 100;
+ sParticle->m_uchColor[2] = 100;
+ }
+ else
+ {
+ sParticle->m_uchColor[0] = 255;
+ sParticle->m_uchColor[1] = 48;
+ sParticle->m_uchColor[2] = 48;
+ }
+
+ sParticle->m_uchStartAlpha = random->RandomInt( 64, 90 );
+ sParticle->m_uchEndAlpha = 0;
+ sParticle->m_uchStartSize = random->RandomInt( 2, 4 );
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 8.0f;
+ sParticle->m_flRoll = random->RandomInt( 0, 2*M_PI );
+ sParticle->m_flRollDelta = random->RandomFloat( -(M_PI/6.0f), M_PI/6.0f );
+ }
+ }
+
+ if ( !bVisible )
+ return;
+
+ //
+ // Outer glow
+ //
+
+ Vector offset;
+
+ //Cause the base of the effect to shake
+ offset.Random( -0.5f * baseScale, 0.5f * baseScale );
+ offset += GetAbsOrigin();
+
+ if ( m_pParticle[0] != NULL )
+ {
+ m_pParticle[0]->m_Pos = offset;
+ m_pParticle[0]->m_flLifetime = 0.0f;
+ m_pParticle[0]->m_flDieTime = 2.0f;
+
+ m_pParticle[0]->m_vecVelocity.Init();
+
+ fColor = random->RandomInt( 100.0f, 128.0f ) * visible;
+
+ m_pParticle[0]->m_uchColor[0] = fColor;
+ m_pParticle[0]->m_uchColor[1] = fColor;
+ m_pParticle[0]->m_uchColor[2] = fColor;
+ m_pParticle[0]->m_uchStartAlpha = fColor;
+ m_pParticle[0]->m_uchEndAlpha = fColor;
+ m_pParticle[0]->m_uchStartSize = baseScale * (float) random->RandomInt( 32, 48 );
+ m_pParticle[0]->m_uchEndSize = m_pParticle[0]->m_uchStartSize;
+ m_pParticle[0]->m_flRollDelta = 0.0f;
+
+ if ( random->RandomInt( 0, 4 ) == 3 )
+ {
+ m_pParticle[0]->m_flRoll += random->RandomInt( 2, 8 );
+ }
+ }
+
+ //
+ // Inner core
+ //
+
+ //Cause the base of the effect to shake
+ offset.Random( -1.0f * baseScale, 1.0f * baseScale );
+ offset += GetAbsOrigin();
+
+ if ( m_pParticle[1] != NULL )
+ {
+ m_pParticle[1]->m_Pos = offset;
+ m_pParticle[1]->m_flLifetime = 0.0f;
+ m_pParticle[1]->m_flDieTime = 2.0f;
+
+ m_pParticle[1]->m_vecVelocity.Init();
+
+ fColor = 255 * visible;
+
+ m_pParticle[1]->m_uchColor[0] = fColor;
+ m_pParticle[1]->m_uchColor[1] = fColor;
+ m_pParticle[1]->m_uchColor[2] = fColor;
+ m_pParticle[1]->m_uchStartAlpha = fColor;
+ m_pParticle[1]->m_uchEndAlpha = fColor;
+ m_pParticle[1]->m_uchStartSize = baseScale * (float) random->RandomInt( 2, 4 );
+ m_pParticle[1]->m_uchEndSize = m_pParticle[0]->m_uchStartSize;
+ m_pParticle[1]->m_flRoll = random->RandomInt( 0, 360 );
+ }
+}
diff --git a/mp/src/game/client/hl2/c_thumper_dust.cpp b/mp/src/game/client/hl2/c_thumper_dust.cpp
index d655fd25..ade7b303 100644
--- a/mp/src/game/client/hl2/c_thumper_dust.cpp
+++ b/mp/src/game/client/hl2/c_thumper_dust.cpp
@@ -1,170 +1,170 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "particlemgr.h"
-#include "particle_prototype.h"
-#include "particle_util.h"
-#include "c_te_particlesystem.h"
-#include "fx.h"
-#include "fx_quad.h"
-#include "c_te_effect_dispatch.h"
-#include "view.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-#define THUMPER_DUST_LIFETIME 2.0f
-#define THUMPER_MAX_PARTICLES 24
-
-
-extern IPhysicsSurfaceProps *physprops;
-
-
-class ThumperDustEmitter : public CSimpleEmitter
-{
-public:
-
- ThumperDustEmitter( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
-
- static ThumperDustEmitter *Create( const char *pDebugName )
- {
- return new ThumperDustEmitter( pDebugName );
- }
-
- void UpdateVelocity( SimpleParticle *pParticle, float timeDelta )
- {
- // Float up when lifetime is half gone.
- pParticle->m_vecVelocity[2] -= ( 8.0f * timeDelta );
-
-
- // FIXME: optimize this....
- pParticle->m_vecVelocity *= ExponentialDecay( 0.9, 0.03, timeDelta );
- }
-
- virtual float UpdateRoll( SimpleParticle *pParticle, float timeDelta )
- {
- pParticle->m_flRoll += pParticle->m_flRollDelta * timeDelta;
-
- pParticle->m_flRollDelta += pParticle->m_flRollDelta * ( timeDelta * -4.0f );
-
- //Cap the minimum roll
- if ( fabs( pParticle->m_flRollDelta ) < 0.25f )
- {
- pParticle->m_flRollDelta = ( pParticle->m_flRollDelta > 0.0f ) ? 0.25f : -0.25f;
- }
-
- return pParticle->m_flRoll;
- }
-
- virtual float UpdateAlpha( const SimpleParticle *pParticle )
- {
- return (pParticle->m_uchStartAlpha/255.0f) + ( (float)(pParticle->m_uchEndAlpha/255.0f) - (float)(pParticle->m_uchStartAlpha/255.0f) ) * (pParticle->m_flLifetime / pParticle->m_flDieTime);
- }
-
-private:
- ThumperDustEmitter( const ThumperDustEmitter & );
-};
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : bNewEntity - whether or not to start a new entity
-//-----------------------------------------------------------------------------
-
-void FX_ThumperDust( const CEffectData &data )
-{
- Vector vecDustColor;
- vecDustColor.x = 0.85f;
- vecDustColor.y = 0.75f;
- vecDustColor.z = 0.52f;
-
- CSmartPtr<ThumperDustEmitter> pSimple = ThumperDustEmitter::Create( "thumperdust" );
-
- C_BaseEntity *pEnt = C_BaseEntity::Instance( data.m_hEntity );
- if ( pEnt )
- {
- Vector vWorldMins, vWorldMaxs;
- float scale = pEnt->CollisionProp()->BoundingRadius();
- vWorldMins[0] = data.m_vOrigin[0] - scale;
- vWorldMins[1] = data.m_vOrigin[1] - scale;
- vWorldMins[2] = data.m_vOrigin[2] - scale;
- vWorldMaxs[0] = data.m_vOrigin[0] + scale;
- vWorldMaxs[1] = data.m_vOrigin[1] + scale;
- vWorldMaxs[2] = data.m_vOrigin[2] + scale;
- pSimple->GetBinding().SetBBox( vWorldMins, vWorldMaxs, true );
- }
-
- pSimple->SetSortOrigin( data.m_vOrigin );
- pSimple->SetNearClip( 32, 64 );
-
- SimpleParticle *pParticle = NULL;
-
- Vector offset;
-
- //int numPuffs = IsXbox() ? THUMPER_MAX_PARTICLES/2 : THUMPER_MAX_PARTICLES;
- int numPuffs = THUMPER_MAX_PARTICLES;
-
- float flYaw = 0;
- float flIncr = (2*M_PI) / (float) numPuffs; // Radians
- Vector forward;
- Vector vecColor;
- int i = 0;
-
- float flScale = MIN( data.m_flScale, 255 );
-
- // Setup the color for these particles
- engine->ComputeLighting( data.m_vOrigin, NULL, true, vecColor );
- VectorLerp( vecColor, vecDustColor, 0.5, vecColor );
- vecColor *= 255;
-
- for ( i = 0; i < numPuffs; i++ )
- {
- flYaw += flIncr;
- SinCos( flYaw, &forward.y, &forward.x );
- forward.z = 0.0f;
-
- offset = ( RandomVector( -4.0f, 4.0f ) + data.m_vOrigin ) + ( forward * 128.0f );
-
- pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof(SimpleParticle), g_Mat_DustPuff[random->RandomInt(0,1)], offset );
- if ( pParticle != NULL )
- {
- pParticle->m_flLifetime = 0.0f;
- pParticle->m_flDieTime = 1.5f;
-
- Vector dir = (offset - data.m_vOrigin);
- float length = dir.Length();
- VectorNormalize( dir );
-
- pParticle->m_vecVelocity = dir * ( length * 2.0f );
- pParticle->m_vecVelocity[2] = data.m_flScale / 3;
-
- pParticle->m_uchColor[0] = vecColor[0];
- pParticle->m_uchColor[1] = vecColor[1];
- pParticle->m_uchColor[2] = vecColor[2];
-
- pParticle->m_uchStartAlpha = random->RandomInt( 64, 96 );
- pParticle->m_uchEndAlpha = 0;
-
- pParticle->m_uchStartSize = flScale * 0.25f;
- pParticle->m_uchEndSize = flScale * 0.5f;
-
- pParticle->m_flRoll = random->RandomInt( 0, 360 );
- pParticle->m_flRollDelta = random->RandomFloat( -6.0f, 6.0f );
- }
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : &data -
-//-----------------------------------------------------------------------------
-void ThumperDustCallback( const CEffectData &data )
-{
- FX_ThumperDust( data );
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "particlemgr.h"
+#include "particle_prototype.h"
+#include "particle_util.h"
+#include "c_te_particlesystem.h"
+#include "fx.h"
+#include "fx_quad.h"
+#include "c_te_effect_dispatch.h"
+#include "view.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#define THUMPER_DUST_LIFETIME 2.0f
+#define THUMPER_MAX_PARTICLES 24
+
+
+extern IPhysicsSurfaceProps *physprops;
+
+
+class ThumperDustEmitter : public CSimpleEmitter
+{
+public:
+
+ ThumperDustEmitter( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
+
+ static ThumperDustEmitter *Create( const char *pDebugName )
+ {
+ return new ThumperDustEmitter( pDebugName );
+ }
+
+ void UpdateVelocity( SimpleParticle *pParticle, float timeDelta )
+ {
+ // Float up when lifetime is half gone.
+ pParticle->m_vecVelocity[2] -= ( 8.0f * timeDelta );
+
+
+ // FIXME: optimize this....
+ pParticle->m_vecVelocity *= ExponentialDecay( 0.9, 0.03, timeDelta );
+ }
+
+ virtual float UpdateRoll( SimpleParticle *pParticle, float timeDelta )
+ {
+ pParticle->m_flRoll += pParticle->m_flRollDelta * timeDelta;
+
+ pParticle->m_flRollDelta += pParticle->m_flRollDelta * ( timeDelta * -4.0f );
+
+ //Cap the minimum roll
+ if ( fabs( pParticle->m_flRollDelta ) < 0.25f )
+ {
+ pParticle->m_flRollDelta = ( pParticle->m_flRollDelta > 0.0f ) ? 0.25f : -0.25f;
+ }
+
+ return pParticle->m_flRoll;
+ }
+
+ virtual float UpdateAlpha( const SimpleParticle *pParticle )
+ {
+ return (pParticle->m_uchStartAlpha/255.0f) + ( (float)(pParticle->m_uchEndAlpha/255.0f) - (float)(pParticle->m_uchStartAlpha/255.0f) ) * (pParticle->m_flLifetime / pParticle->m_flDieTime);
+ }
+
+private:
+ ThumperDustEmitter( const ThumperDustEmitter & );
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : bNewEntity - whether or not to start a new entity
+//-----------------------------------------------------------------------------
+
+void FX_ThumperDust( const CEffectData &data )
+{
+ Vector vecDustColor;
+ vecDustColor.x = 0.85f;
+ vecDustColor.y = 0.75f;
+ vecDustColor.z = 0.52f;
+
+ CSmartPtr<ThumperDustEmitter> pSimple = ThumperDustEmitter::Create( "thumperdust" );
+
+ C_BaseEntity *pEnt = C_BaseEntity::Instance( data.m_hEntity );
+ if ( pEnt )
+ {
+ Vector vWorldMins, vWorldMaxs;
+ float scale = pEnt->CollisionProp()->BoundingRadius();
+ vWorldMins[0] = data.m_vOrigin[0] - scale;
+ vWorldMins[1] = data.m_vOrigin[1] - scale;
+ vWorldMins[2] = data.m_vOrigin[2] - scale;
+ vWorldMaxs[0] = data.m_vOrigin[0] + scale;
+ vWorldMaxs[1] = data.m_vOrigin[1] + scale;
+ vWorldMaxs[2] = data.m_vOrigin[2] + scale;
+ pSimple->GetBinding().SetBBox( vWorldMins, vWorldMaxs, true );
+ }
+
+ pSimple->SetSortOrigin( data.m_vOrigin );
+ pSimple->SetNearClip( 32, 64 );
+
+ SimpleParticle *pParticle = NULL;
+
+ Vector offset;
+
+ //int numPuffs = IsXbox() ? THUMPER_MAX_PARTICLES/2 : THUMPER_MAX_PARTICLES;
+ int numPuffs = THUMPER_MAX_PARTICLES;
+
+ float flYaw = 0;
+ float flIncr = (2*M_PI) / (float) numPuffs; // Radians
+ Vector forward;
+ Vector vecColor;
+ int i = 0;
+
+ float flScale = MIN( data.m_flScale, 255 );
+
+ // Setup the color for these particles
+ engine->ComputeLighting( data.m_vOrigin, NULL, true, vecColor );
+ VectorLerp( vecColor, vecDustColor, 0.5, vecColor );
+ vecColor *= 255;
+
+ for ( i = 0; i < numPuffs; i++ )
+ {
+ flYaw += flIncr;
+ SinCos( flYaw, &forward.y, &forward.x );
+ forward.z = 0.0f;
+
+ offset = ( RandomVector( -4.0f, 4.0f ) + data.m_vOrigin ) + ( forward * 128.0f );
+
+ pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof(SimpleParticle), g_Mat_DustPuff[random->RandomInt(0,1)], offset );
+ if ( pParticle != NULL )
+ {
+ pParticle->m_flLifetime = 0.0f;
+ pParticle->m_flDieTime = 1.5f;
+
+ Vector dir = (offset - data.m_vOrigin);
+ float length = dir.Length();
+ VectorNormalize( dir );
+
+ pParticle->m_vecVelocity = dir * ( length * 2.0f );
+ pParticle->m_vecVelocity[2] = data.m_flScale / 3;
+
+ pParticle->m_uchColor[0] = vecColor[0];
+ pParticle->m_uchColor[1] = vecColor[1];
+ pParticle->m_uchColor[2] = vecColor[2];
+
+ pParticle->m_uchStartAlpha = random->RandomInt( 64, 96 );
+ pParticle->m_uchEndAlpha = 0;
+
+ pParticle->m_uchStartSize = flScale * 0.25f;
+ pParticle->m_uchEndSize = flScale * 0.5f;
+
+ pParticle->m_flRoll = random->RandomInt( 0, 360 );
+ pParticle->m_flRollDelta = random->RandomFloat( -6.0f, 6.0f );
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &data -
+//-----------------------------------------------------------------------------
+void ThumperDustCallback( const CEffectData &data )
+{
+ FX_ThumperDust( data );
+}
+
DECLARE_CLIENT_EFFECT( "ThumperDust", ThumperDustCallback ); \ No newline at end of file
diff --git a/mp/src/game/client/hl2/c_vehicle_airboat.cpp b/mp/src/game/client/hl2/c_vehicle_airboat.cpp
index 526985d4..16720370 100644
--- a/mp/src/game/client/hl2/c_vehicle_airboat.cpp
+++ b/mp/src/game/client/hl2/c_vehicle_airboat.cpp
@@ -1,931 +1,931 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Client side implementation of the airboat.
-//
-// - Dampens motion of driver's view to reduce nausea.
-// - Autocenters driver's view after a period of inactivity.
-// - Controls headlights.
-// - Controls curve parameters for pitch/roll blending.
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "c_prop_vehicle.h"
-#include "datacache/imdlcache.h"
-#include "flashlighteffect.h"
-#include "movevars_shared.h"
-#include "ammodef.h"
-#include "SpriteTrail.h"
-#include "beamdraw.h"
-#include "enginesprite.h"
-#include "fx_quad.h"
-#include "fx.h"
-#include "fx_water.h"
-#include "engine/ivdebugoverlay.h"
-#include "view.h"
-#include "clienteffectprecachesystem.h"
-#include "c_basehlplayer.h"
-#include "vgui_controls/Controls.h"
-#include "vgui/ISurface.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-ConVar r_AirboatViewBlendTo( "r_AirboatViewBlendTo", "1", FCVAR_CHEAT );
-ConVar r_AirboatViewBlendToScale( "r_AirboatViewBlendToScale", "0.03", FCVAR_CHEAT );
-ConVar r_AirboatViewBlendToTime( "r_AirboatViewBlendToTime", "1.5", FCVAR_CHEAT );
-
-ConVar cl_draw_airboat_wake( "cl_draw_airboat_wake", "1", FCVAR_CHEAT );
-
-// Curve parameters for pitch/roll blending.
-// NOTE: Must restart (or create a new airboat) after changing these cvars!
-ConVar r_AirboatRollCurveZero( "r_AirboatRollCurveZero", "90.0", FCVAR_CHEAT ); // Roll less than this is clamped to zero.
-ConVar r_AirboatRollCurveLinear( "r_AirboatRollCurveLinear", "120.0", FCVAR_CHEAT ); // Roll greater than this is mapped directly.
- // Spline in between.
-
-ConVar r_AirboatPitchCurveZero( "r_AirboatPitchCurveZero", "25.0", FCVAR_CHEAT ); // Pitch less than this is clamped to zero.
-ConVar r_AirboatPitchCurveLinear( "r_AirboatPitchCurveLinear", "60.0", FCVAR_CHEAT ); // Pitch greater than this is mapped directly.
- // Spline in between.
-
-ConVar airboat_joy_response_move( "airboat_joy_response_move", "1" ); // Quadratic steering response
-
-
-#define AIRBOAT_DELTA_LENGTH_MAX 12.0f // 1 foot
-#define AIRBOAT_FRAMETIME_MIN 1e-6
-
-#define HEADLIGHT_DISTANCE 1000
-
-#define MAX_WAKE_POINTS 16
-#define WAKE_POINT_MASK (MAX_WAKE_POINTS-1)
-
-#define WAKE_LIFETIME 0.5f
-
-//=============================================================================
-//
-// Client-side Airboat Class
-//
-class C_PropAirboat : public C_PropVehicleDriveable
-{
- DECLARE_CLASS( C_PropAirboat, C_PropVehicleDriveable );
-
-public:
-
- DECLARE_CLIENTCLASS();
- DECLARE_INTERPOLATION();
- DECLARE_DATADESC();
-
- C_PropAirboat();
- ~C_PropAirboat();
-
-public:
-
- // C_BaseEntity
- virtual void Simulate();
-
- // IClientVehicle
- virtual void UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd );
- virtual void OnEnteredVehicle( C_BasePlayer *pPlayer );
- virtual int GetPrimaryAmmoType() const;
- virtual int GetPrimaryAmmoClip() const;
- virtual bool PrimaryAmmoUsesClips() const;
- virtual int GetPrimaryAmmoCount() const;
- virtual int GetJoystickResponseCurve() const;
-
- int DrawModel( int flags );
-
- // Draws crosshair in the forward direction of the boat
- void DrawHudElements( );
-
-private:
-
- void DrawPropWake( Vector origin, float speed );
- void DrawPontoonSplash( Vector position, Vector direction, float speed );
- void DrawPontoonWake( Vector startPos, Vector wakeDir, float wakeLength, float speed);
-
- void DampenEyePosition( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles );
- void DampenForwardMotion( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles, float flFrameTime );
- void DampenUpMotion( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles, float flFrameTime );
- void ComputePDControllerCoefficients( float *pCoefficientsOut, float flFrequency, float flDampening, float flDeltaTime );
-
- void UpdateHeadlight( void );
- void UpdateWake( void );
- int DrawWake( void );
- void DrawSegment( const BeamSeg_t &beamSeg, const Vector &vNormal );
-
- TrailPoint_t *GetTrailPoint( int n )
- {
- int nIndex = (n + m_nFirstStep) & WAKE_POINT_MASK;
- return &m_vecSteps[nIndex];
- }
-
-private:
-
- Vector m_vecLastEyePos;
- Vector m_vecLastEyeTarget;
- Vector m_vecEyeSpeed;
- Vector m_vecTargetSpeed;
-
- float m_flViewAngleDeltaTime;
-
- bool m_bHeadlightIsOn;
- int m_nAmmoCount;
- CHeadlightEffect *m_pHeadlight;
-
- int m_nExactWaterLevel;
-
- TrailPoint_t m_vecSteps[MAX_WAKE_POINTS];
- int m_nFirstStep;
- int m_nStepCount;
- float m_flUpdateTime;
-
- TimedEvent m_SplashTime;
- CMeshBuilder m_Mesh;
-
- Vector m_vecPhysVelocity;
-};
-
-IMPLEMENT_CLIENTCLASS_DT( C_PropAirboat, DT_PropAirboat, CPropAirboat )
- RecvPropBool( RECVINFO( m_bHeadlightIsOn ) ),
- RecvPropInt( RECVINFO( m_nAmmoCount ) ),
- RecvPropInt( RECVINFO( m_nExactWaterLevel ) ),
- RecvPropInt( RECVINFO( m_nWaterLevel ) ),
- RecvPropVector( RECVINFO( m_vecPhysVelocity ) ),
-END_RECV_TABLE()
-
-
-BEGIN_DATADESC( C_PropAirboat )
- DEFINE_FIELD( m_vecLastEyePos, FIELD_POSITION_VECTOR ),
- DEFINE_FIELD( m_vecLastEyeTarget, FIELD_POSITION_VECTOR ),
- DEFINE_FIELD( m_vecEyeSpeed, FIELD_VECTOR ),
- DEFINE_FIELD( m_vecTargetSpeed, FIELD_VECTOR ),
- //DEFINE_FIELD( m_flViewAngleDeltaTime, FIELD_FLOAT ),
-END_DATADESC()
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-C_PropAirboat::C_PropAirboat()
-{
- m_vecEyeSpeed.Init();
- m_flViewAngleDeltaTime = 0.0f;
- m_pHeadlight = NULL;
-
- m_ViewSmoothingData.flPitchCurveZero = r_AirboatPitchCurveZero.GetFloat();
- m_ViewSmoothingData.flPitchCurveLinear = r_AirboatPitchCurveLinear.GetFloat();
- m_ViewSmoothingData.flRollCurveZero = r_AirboatRollCurveZero.GetFloat();
- m_ViewSmoothingData.flRollCurveLinear = r_AirboatRollCurveLinear.GetFloat();
-
- m_ViewSmoothingData.rollLockData.flLockInterval = 1.5;
- m_ViewSmoothingData.rollLockData.flUnlockBlendInterval = 1.0;
-
- m_ViewSmoothingData.pitchLockData.flLockInterval = 1.5;
- m_ViewSmoothingData.pitchLockData.flUnlockBlendInterval = 1.0;
-
- m_nFirstStep = 0;
- m_nStepCount = 0;
- m_SplashTime.Init( 60 );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Deconstructor
-//-----------------------------------------------------------------------------
-C_PropAirboat::~C_PropAirboat()
-{
- if (m_pHeadlight)
- {
- delete m_pHeadlight;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Draws the ammo for the airboat
-//-----------------------------------------------------------------------------
-int C_PropAirboat::GetPrimaryAmmoType() const
-{
- if ( m_nAmmoCount < 0 )
- return -1;
-
- int nAmmoType = GetAmmoDef()->Index( "AirboatGun" );
- return nAmmoType;
-}
-
-int C_PropAirboat::GetPrimaryAmmoCount() const
-{
- return m_nAmmoCount;
-}
-
-bool C_PropAirboat::PrimaryAmmoUsesClips() const
-{
- return false;
-}
-
-int C_PropAirboat::GetPrimaryAmmoClip() const
-{
- return -1;
-}
-
-//-----------------------------------------------------------------------------
-// The airboat prefers a more peppy response curve for joystick control.
-//-----------------------------------------------------------------------------
-int C_PropAirboat::GetJoystickResponseCurve() const
-{
- return airboat_joy_response_move.GetInt();
-}
-
-//-----------------------------------------------------------------------------
-// Draws crosshair in the forward direction of the boat
-//-----------------------------------------------------------------------------
-void C_PropAirboat::DrawHudElements( )
-{
- BaseClass::DrawHudElements();
-
- MDLCACHE_CRITICAL_SECTION();
-
- CHudTexture *pIcon = gHUD.GetIcon( IsX360() ? "crosshair_default" : "plushair" );
- if ( pIcon != NULL )
- {
- float x, y;
- Vector screen;
-
- int vx, vy, vw, vh;
- vgui::surface()->GetFullscreenViewport( vx, vy, vw, vh );
- float screenWidth = vw;
- float screenHeight = vh;
-
- x = screenWidth/2;
- y = screenHeight/2;
-
- int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
- Vector vehicleEyeOrigin;
- QAngle vehicleEyeAngles;
- GetAttachment( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
-
- // Only worry about yaw.
- vehicleEyeAngles.x = vehicleEyeAngles.z = 0.0f;
-
- Vector vecForward;
- AngleVectors( vehicleEyeAngles, &vecForward );
- VectorMA( vehicleEyeOrigin, 100.0f, vecForward, vehicleEyeOrigin );
-
- ScreenTransform( vehicleEyeOrigin, screen );
- x += 0.5 * screen[0] * screenWidth + 0.5;
- y -= 0.5 * screen[1] * screenHeight + 0.5;
-
- x -= pIcon->Width() / 2;
- y -= pIcon->Height() / 2;
-
- pIcon->DrawSelf( x, y, gHUD.m_clrNormal );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Blend view angles.
-//-----------------------------------------------------------------------------
-void C_PropAirboat::UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd )
-{
- if ( r_AirboatViewBlendTo.GetInt() )
- {
- //
- // Autocenter the view after a period of no mouse movement while throttling.
- //
- bool bResetViewAngleTime = false;
-
- if ( ( pCmd->mousedx != 0 || pCmd->mousedy != 0 ) || ( fabsf( m_flThrottle ) < 0.01f ) )
- {
- if ( IsX360() )
- {
- // Only reset this if there isn't an autoaim target!
- C_BaseHLPlayer *pLocalHLPlayer = (C_BaseHLPlayer *)pLocalPlayer;
- if ( pLocalHLPlayer )
- {
- // Get the autoaim target.
- CBaseEntity *pTarget = pLocalHLPlayer->m_HL2Local.m_hAutoAimTarget.Get();
-
- if( !pTarget )
- {
- bResetViewAngleTime = true;
- }
- }
- }
- else
- {
- bResetViewAngleTime = true;
- }
- }
-
- if( bResetViewAngleTime )
- {
- m_flViewAngleDeltaTime = 0.0f;
- }
- else
- {
- m_flViewAngleDeltaTime += gpGlobals->frametime;
- }
-
- if ( m_flViewAngleDeltaTime > r_AirboatViewBlendToTime.GetFloat() )
- {
- // Blend the view angles.
- int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
- Vector vehicleEyeOrigin;
- QAngle vehicleEyeAngles;
- GetAttachmentLocal( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
-
- QAngle outAngles;
- InterpolateAngles( pCmd->viewangles, vehicleEyeAngles, outAngles, r_AirboatViewBlendToScale.GetFloat() );
- pCmd->viewangles = outAngles;
- }
- }
-
- BaseClass::UpdateViewAngles( pLocalPlayer, pCmd );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_PropAirboat::DampenEyePosition( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles )
-{
- // Get the frametime. (Check to see if enough time has passed to warrent dampening).
- float flFrameTime = gpGlobals->frametime;
- if ( flFrameTime < AIRBOAT_FRAMETIME_MIN )
- {
- vecVehicleEyePos = m_vecLastEyePos;
- DampenUpMotion( vecVehicleEyePos, vecVehicleEyeAngles, 0.0f );
- return;
- }
-
- // Keep static the sideways motion.
-
- // Dampen forward/backward motion.
- DampenForwardMotion( vecVehicleEyePos, vecVehicleEyeAngles, flFrameTime );
-
- // Blend up/down motion.
- DampenUpMotion( vecVehicleEyePos, vecVehicleEyeAngles, flFrameTime );
-}
-
-
-//-----------------------------------------------------------------------------
-// Use the controller as follows:
-// speed += ( pCoefficientsOut[0] * ( targetPos - currentPos ) + pCoefficientsOut[1] * ( targetSpeed - currentSpeed ) ) * flDeltaTime;
-//-----------------------------------------------------------------------------
-void C_PropAirboat::ComputePDControllerCoefficients( float *pCoefficientsOut,
- float flFrequency, float flDampening,
- float flDeltaTime )
-{
- float flKs = 9.0f * flFrequency * flFrequency;
- float flKd = 4.5f * flFrequency * flDampening;
-
- float flScale = 1.0f / ( 1.0f + flKd * flDeltaTime + flKs * flDeltaTime * flDeltaTime );
-
- pCoefficientsOut[0] = flKs * flScale;
- pCoefficientsOut[1] = ( flKd + flKs * flDeltaTime ) * flScale;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_PropAirboat::DampenForwardMotion( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles, float flFrameTime )
-{
- // vecVehicleEyePos = real eye position this frame
-
- // m_vecLastEyePos = eye position last frame
- // m_vecEyeSpeed = eye speed last frame
- // vecPredEyePos = predicted eye position this frame (assuming no acceleration - it will get that from the pd controller).
- // vecPredEyeSpeed = predicted eye speed
- Vector vecPredEyePos = m_vecLastEyePos + m_vecEyeSpeed * flFrameTime;
- Vector vecPredEyeSpeed = m_vecEyeSpeed;
-
- // m_vecLastEyeTarget = real eye position last frame (used for speed calculation).
- // Calculate the approximate speed based on the current vehicle eye position and the eye position last frame.
- Vector vecVehicleEyeSpeed = ( vecVehicleEyePos - m_vecLastEyeTarget ) / flFrameTime;
- m_vecLastEyeTarget = vecVehicleEyePos;
- if (vecVehicleEyeSpeed.Length() == 0.0)
- {
- return;
- }
-
- // Calculate the delta between the predicted eye position and speed and the current eye position and speed.
- Vector vecDeltaSpeed = vecVehicleEyeSpeed - vecPredEyeSpeed;
- Vector vecDeltaPos = vecVehicleEyePos - vecPredEyePos;
-
- // Forward vector.
- Vector vecForward;
- AngleVectors( vecVehicleEyeAngles, &vecForward );
-
- float flDeltaLength = vecDeltaPos.Length();
- if ( flDeltaLength > AIRBOAT_DELTA_LENGTH_MAX )
- {
- // Clamp.
- float flDelta = flDeltaLength - AIRBOAT_DELTA_LENGTH_MAX;
- if ( flDelta > 40.0f )
- {
- // This part is a bit of a hack to get rid of large deltas (at level load, etc.).
- m_vecLastEyePos = vecVehicleEyePos;
- m_vecEyeSpeed = vecVehicleEyeSpeed;
- }
- else
- {
- // Position clamp.
- float flRatio = AIRBOAT_DELTA_LENGTH_MAX / flDeltaLength;
- vecDeltaPos *= flRatio;
- Vector vecForwardOffset = vecForward * ( vecForward.Dot( vecDeltaPos ) );
- vecVehicleEyePos -= vecForwardOffset;
- m_vecLastEyePos = vecVehicleEyePos;
-
- // Speed clamp.
- vecDeltaSpeed *= flRatio;
- float flCoefficients[2];
- ComputePDControllerCoefficients( flCoefficients, r_AirboatViewDampenFreq.GetFloat(), r_AirboatViewDampenDamp.GetFloat(), flFrameTime );
- m_vecEyeSpeed += ( ( flCoefficients[0] * vecDeltaPos + flCoefficients[1] * vecDeltaSpeed ) * flFrameTime );
- }
- }
- else
- {
- // Generate an updated (dampening) speed for use in next frames position prediction.
- float flCoefficients[2];
- ComputePDControllerCoefficients( flCoefficients, r_AirboatViewDampenFreq.GetFloat(), r_AirboatViewDampenDamp.GetFloat(), flFrameTime );
- m_vecEyeSpeed += ( ( flCoefficients[0] * vecDeltaPos + flCoefficients[1] * vecDeltaSpeed ) * flFrameTime );
-
- // Save off data for next frame.
- m_vecLastEyePos = vecPredEyePos;
-
- // Move eye forward/backward.
- Vector vecForwardOffset = vecForward * ( vecForward.Dot( vecDeltaPos ) );
- vecVehicleEyePos -= vecForwardOffset;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_PropAirboat::DampenUpMotion( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles, float flFrameTime )
-{
- // Get up vector.
- Vector vecUp;
- AngleVectors( vecVehicleEyeAngles, NULL, NULL, &vecUp );
- vecUp.z = clamp( vecUp.z, 0.0f, vecUp.z );
- vecVehicleEyePos.z += r_AirboatViewZHeight.GetFloat() * vecUp.z;
-
- // NOTE: Should probably use some damped equation here.
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_PropAirboat::OnEnteredVehicle( C_BasePlayer *pPlayer )
-{
- int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
- Vector vehicleEyeOrigin;
- QAngle vehicleEyeAngles;
- GetAttachment( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
-
- m_vecLastEyeTarget = vehicleEyeOrigin;
- m_vecLastEyePos = vehicleEyeOrigin;
- m_vecEyeSpeed = vec3_origin;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_PropAirboat::Simulate()
-{
- UpdateHeadlight();
- UpdateWake();
-
- BaseClass::Simulate();
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Creates, destroys, and updates the headlight effect as needed.
-//-----------------------------------------------------------------------------
-void C_PropAirboat::UpdateHeadlight()
-{
- if (m_bHeadlightIsOn)
- {
- if (!m_pHeadlight)
- {
- // Turned on the headlight; create it.
- m_pHeadlight = new CHeadlightEffect();
-
- if (!m_pHeadlight)
- return;
-
- m_pHeadlight->TurnOn();
- }
-
- // The headlight is emitted from an attachment point so that it can move
- // as we turn the handlebars.
- int nHeadlightIndex = LookupAttachment( "vehicle_headlight" );
-
- Vector vecLightPos;
- QAngle angLightDir;
- GetAttachment(nHeadlightIndex, vecLightPos, angLightDir);
-
- Vector vecLightDir, vecLightRight, vecLightUp;
- AngleVectors( angLightDir, &vecLightDir, &vecLightRight, &vecLightUp );
-
- // Update the light with the new position and direction.
- m_pHeadlight->UpdateLight( vecLightPos, vecLightDir, vecLightRight, vecLightUp, HEADLIGHT_DISTANCE );
- }
- else if (m_pHeadlight)
- {
- // Turned off the headlight; delete it.
- delete m_pHeadlight;
- m_pHeadlight = NULL;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_PropAirboat::UpdateWake( void )
-{
- if ( gpGlobals->frametime <= 0.0f )
- return;
-
- // Can't update too quickly
- if ( m_flUpdateTime > gpGlobals->curtime )
- return;
-
- Vector screenPos = GetRenderOrigin();
- screenPos.z = m_nExactWaterLevel;
-
- TrailPoint_t *pLast = m_nStepCount ? GetTrailPoint( m_nStepCount-1 ) : NULL;
- if ( ( pLast == NULL ) || ( pLast->m_vecScreenPos.DistToSqr( screenPos ) > 4.0f ) )
- {
- // If we're over our limit, steal the last point and put it up front
- if ( m_nStepCount >= MAX_WAKE_POINTS )
- {
- --m_nStepCount;
- ++m_nFirstStep;
- }
-
- // Save off its screen position, not its world position
- TrailPoint_t *pNewPoint = GetTrailPoint( m_nStepCount );
- pNewPoint->m_vecScreenPos = screenPos + Vector( 0, 0, 2 );
- pNewPoint->m_flDieTime = gpGlobals->curtime + WAKE_LIFETIME;
- pNewPoint->m_flWidthVariance = random->RandomFloat( -16, 16 );
-
- if ( pLast )
- {
- pNewPoint->m_flTexCoord = pLast->m_flTexCoord + pLast->m_vecScreenPos.DistTo( screenPos );
- pNewPoint->m_flTexCoord = fmod( pNewPoint->m_flTexCoord, 1 );
- }
- else
- {
- pNewPoint->m_flTexCoord = 0.0f;
- }
-
- ++m_nStepCount;
- }
-
- // Don't update again for a bit
- m_flUpdateTime = gpGlobals->curtime + ( 0.5f / (float) MAX_WAKE_POINTS );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : &beamSeg -
-//-----------------------------------------------------------------------------
-void C_PropAirboat::DrawSegment( const BeamSeg_t &beamSeg, const Vector &vNormal )
-{
- // Build the endpoints.
- Vector vPoint1, vPoint2;
- VectorMA( beamSeg.m_vPos, beamSeg.m_flWidth*0.5f, vNormal, vPoint1 );
- VectorMA( beamSeg.m_vPos, -beamSeg.m_flWidth*0.5f, vNormal, vPoint2 );
-
- // Specify the points.
- m_Mesh.Position3fv( vPoint1.Base() );
- m_Mesh.Color4f( VectorExpand( beamSeg.m_vColor ), beamSeg.m_flAlpha );
- m_Mesh.TexCoord2f( 0, 0, beamSeg.m_flTexCoord );
- m_Mesh.TexCoord2f( 1, 0, beamSeg.m_flTexCoord );
- m_Mesh.AdvanceVertex();
-
- m_Mesh.Position3fv( vPoint2.Base() );
- m_Mesh.Color4f( VectorExpand( beamSeg.m_vColor ), beamSeg.m_flAlpha );
- m_Mesh.TexCoord2f( 0, 1, beamSeg.m_flTexCoord );
- m_Mesh.TexCoord2f( 1, 1, beamSeg.m_flTexCoord );
- m_Mesh.AdvanceVertex();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : position -
-//-----------------------------------------------------------------------------
-void C_PropAirboat::DrawPontoonSplash( Vector origin, Vector direction, float speed )
-{
- Vector offset;
-
- CSmartPtr<CSplashParticle> pSimple = CSplashParticle::Create( "splish" );
- pSimple->SetSortOrigin( origin );
-
- SimpleParticle *pParticle;
-
- Vector color = Vector( 0.8f, 0.8f, 0.75f );
- float colorRamp;
-
- float flScale = RemapVal( speed, 64, 256, 0.75f, 1.0f );
-
- PMaterialHandle hMaterial;
-
- float tempDelta = gpGlobals->frametime;
-
- while( m_SplashTime.NextEvent( tempDelta ) )
- {
- if ( random->RandomInt( 0, 1 ) )
- {
- hMaterial = ParticleMgr()->GetPMaterial( "effects/splash1" );
- }
- else
- {
- hMaterial = ParticleMgr()->GetPMaterial( "effects/splash2" );
- }
-
- offset = RandomVector( -8.0f * flScale, 8.0f * flScale );
- offset[2] = 0.0f;
- offset += origin;
-
- pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), hMaterial, offset );
-
- if ( pParticle == NULL )
- continue;
-
- pParticle->m_flLifetime = 0.0f;
- pParticle->m_flDieTime = 0.25f;
-
- pParticle->m_vecVelocity.Random( -0.4f, 0.4f );
- pParticle->m_vecVelocity += (direction*5.0f+Vector(0,0,1));
-
- VectorNormalize( pParticle->m_vecVelocity );
-
- pParticle->m_vecVelocity *= speed + random->RandomFloat( -128.0f, 128.0f );
-
- colorRamp = random->RandomFloat( 0.75f, 1.25f );
-
- pParticle->m_uchColor[0] = MIN( 1.0f, color[0] * colorRamp ) * 255.0f;
- pParticle->m_uchColor[1] = MIN( 1.0f, color[1] * colorRamp ) * 255.0f;
- pParticle->m_uchColor[2] = MIN( 1.0f, color[2] * colorRamp ) * 255.0f;
-
- pParticle->m_uchStartSize = random->RandomFloat( 8, 16 ) * flScale;
- pParticle->m_uchEndSize = pParticle->m_uchStartSize * 2;
-
- pParticle->m_uchStartAlpha = 255;
- pParticle->m_uchEndAlpha = 0;
-
- pParticle->m_flRoll = random->RandomInt( 0, 360 );
- pParticle->m_flRollDelta = random->RandomFloat( -4.0f, 4.0f );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : Vector startPos -
-// wakeDir -
-// wakeLength -
-//-----------------------------------------------------------------------------
-void C_PropAirboat::DrawPontoonWake( Vector startPos, Vector wakeDir, float wakeLength, float speed )
-{
-#define WAKE_STEPS 6
-
- Vector wakeStep = wakeDir * ( wakeLength / (float) WAKE_STEPS );
- Vector origin;
- float scale;
-
- IMaterial *pMaterial = materials->FindMaterial( "effects/splashwake1", NULL, false );
- CMatRenderContextPtr pRenderContext( materials );
- IMesh* pMesh = pRenderContext->GetDynamicMesh( 0, 0, 0, pMaterial );
-
- CMeshBuilder meshBuilder;
- meshBuilder.Begin( pMesh, MATERIAL_QUADS, WAKE_STEPS );
-
- for ( int i = 0; i < WAKE_STEPS; i++ )
- {
- origin = startPos + ( wakeStep * i );
- origin[0] += random->RandomFloat( -4.0f, 4.0f );
- origin[1] += random->RandomFloat( -4.0f, 4.0f );
- origin[2] = m_nExactWaterLevel + 2.0f;
-
- float scaleRange = RemapVal( i, 0, WAKE_STEPS-1, 32, 64 );
- scale = scaleRange + ( 8.0f * sin( gpGlobals->curtime * 5 * i ) );
-
- float alpha = RemapValClamped( speed, 128, 600, 0.05f, 0.25f );
- float color[4] = { 1.0f, 1.0f, 1.0f, alpha };
-
- // Needs to be time based so it'll freeze when the game is frozen
- float yaw = random->RandomFloat( 0, 360 );
-
- Vector rRight = ( Vector(1,0,0) * cos( DEG2RAD( yaw ) ) ) - ( Vector(0,1,0) * sin( DEG2RAD( yaw ) ) );
- Vector rUp = ( Vector(1,0,0) * cos( DEG2RAD( yaw+90.0f ) ) ) - ( Vector(0,1,0) * sin( DEG2RAD( yaw+90.0f ) ) );
-
- Vector point;
- meshBuilder.Color4fv (color);
- meshBuilder.TexCoord2f (0, 0, 1);
- VectorMA (origin, -scale, rRight, point);
- VectorMA (point, -scale, rUp, point);
- meshBuilder.Position3fv (point.Base());
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color4fv (color);
- meshBuilder.TexCoord2f (0, 0, 0);
- VectorMA (origin, scale, rRight, point);
- VectorMA (point, -scale, rUp, point);
- meshBuilder.Position3fv (point.Base());
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color4fv (color);
- meshBuilder.TexCoord2f (0, 1, 0);
- VectorMA (origin, scale, rRight, point);
- VectorMA (point, scale, rUp, point);
- meshBuilder.Position3fv (point.Base());
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color4fv (color);
- meshBuilder.TexCoord2f (0, 1, 1);
- VectorMA (origin, -scale, rRight, point);
- VectorMA (point, scale, rUp, point);
- meshBuilder.Position3fv (point.Base());
- meshBuilder.AdvanceVertex();
- }
-
- meshBuilder.End();
- pMesh->Draw();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : int
-//-----------------------------------------------------------------------------
-int C_PropAirboat::DrawWake( void )
-{
- if ( cl_draw_airboat_wake.GetBool() == false )
- return 0;
-
- // Make sure we're in water...
- if ( GetWaterLevel() == 0 )
- return 0;
-
- //FIXME: For now, we don't draw slime this way
- if ( GetWaterLevel() == 2 )
- return 0;
-
- bool bDriven = ( GetPassenger( VEHICLE_ROLE_DRIVER ) != NULL );
-
- Vector vehicleDir = m_vecPhysVelocity;
- float vehicleSpeed = VectorNormalize( vehicleDir );
-
- Vector vecPontoonFrontLeft;
- Vector vecPontoonFrontRight;
- Vector vecPontoonRearLeft;
- Vector vecPontoonRearRight;
- Vector vecSplashPoint;
-
- QAngle fooAngles;
-
- //FIXME: This lookup should be cached off
- // Get all attachments
- GetAttachment( LookupAttachment( "raytrace_fl" ), vecPontoonFrontLeft, fooAngles );
- GetAttachment( LookupAttachment( "raytrace_fr" ), vecPontoonFrontRight, fooAngles );
- GetAttachment( LookupAttachment( "raytrace_rl" ), vecPontoonRearLeft, fooAngles );
- GetAttachment( LookupAttachment( "raytrace_rr" ), vecPontoonRearRight, fooAngles );
- GetAttachment( LookupAttachment( "splash_pt" ), vecSplashPoint, fooAngles );
-
- // Find the direction of the pontoons
- Vector vecLeftWakeDir = ( vecPontoonRearLeft - vecPontoonFrontLeft );
- Vector vecRightWakeDir = ( vecPontoonRearRight - vecPontoonFrontRight );
-
- // Find the pontoon's size
- float flWakeLeftLength = VectorNormalize( vecLeftWakeDir );
- float flWakeRightLength = VectorNormalize( vecRightWakeDir );
-
- vecPontoonFrontLeft.z = m_nExactWaterLevel;
- vecPontoonFrontRight.z = m_nExactWaterLevel;
-
- if ( bDriven && vehicleSpeed > 128.0f )
- {
- DrawPontoonWake( vecPontoonFrontLeft, vecLeftWakeDir, flWakeLeftLength, vehicleSpeed );
- DrawPontoonWake( vecPontoonFrontRight, vecRightWakeDir, flWakeRightLength, vehicleSpeed );
-
- Vector vecSplashDir;
- Vector vForward;
- GetVectors( &vForward, NULL, NULL );
-
- if ( m_vecPhysVelocity.x < -64.0f )
- {
- vecSplashDir = vecLeftWakeDir - vForward;
- VectorNormalize( vecSplashDir );
-
- // Don't do this if we're going backwards
- if ( m_vecPhysVelocity.y > 0.0f )
- {
- DrawPontoonSplash( vecPontoonFrontLeft + ( vecLeftWakeDir * 1.0f ), vecSplashDir, m_vecPhysVelocity.y );
- }
- }
- else if ( m_vecPhysVelocity.x > 64.0f )
- {
- vecSplashDir = vecRightWakeDir + vForward;
- VectorNormalize( vecSplashDir );
-
- // Don't do this if we're going backwards
- if ( m_vecPhysVelocity.y > 0.0f )
- {
- DrawPontoonSplash( vecPontoonFrontRight + ( vecRightWakeDir * 1.0f ), vecSplashDir, m_vecPhysVelocity.y );
- }
- }
- }
-
- // Must have at least one point
- if ( m_nStepCount <= 1 )
- return 1;
-
- IMaterial *pMaterial = materials->FindMaterial( "effects/splashwake4", 0);
-
- //Bind the material
- CMatRenderContextPtr pRenderContext( materials );
- IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, pMaterial );
-
- m_Mesh.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, (m_nStepCount-1) * 2 );
-
- TrailPoint_t *pLast = GetTrailPoint( m_nStepCount - 1 );
-
- TrailPoint_t currentPoint;
- currentPoint.m_flDieTime = gpGlobals->curtime + 0.5f;
- currentPoint.m_vecScreenPos = GetAbsOrigin();
- currentPoint.m_vecScreenPos[2] = m_nExactWaterLevel + 16;
- currentPoint.m_flTexCoord = pLast->m_flTexCoord + currentPoint.m_vecScreenPos.DistTo(pLast->m_vecScreenPos);
- currentPoint.m_flTexCoord = fmod( currentPoint.m_flTexCoord, 1 );
- currentPoint.m_flWidthVariance = 0.0f;
-
- TrailPoint_t *pPrevPoint = NULL;
-
- Vector segDir, normal;
-
- for ( int i = 0; i <= m_nStepCount; ++i )
- {
- // This makes it so that we're always drawing to the current location
- TrailPoint_t *pPoint = (i != m_nStepCount) ? GetTrailPoint(i) : &currentPoint;
-
- float flLifePerc = RemapValClamped( ( pPoint->m_flDieTime - gpGlobals->curtime ), 0, WAKE_LIFETIME, 0.0f, 1.0f );
-
- BeamSeg_t curSeg;
- curSeg.m_vColor.x = curSeg.m_vColor.y = curSeg.m_vColor.z = 1.0f;
-
- float flAlphaFade = flLifePerc;
- float alpha = RemapValClamped( fabs( m_vecPhysVelocity.y ), 128, 600, 0.0f, 1.0f );
-
- curSeg.m_flAlpha = 0.25f;
- curSeg.m_flAlpha *= flAlphaFade * alpha;
-
- curSeg.m_vPos = pPoint->m_vecScreenPos;
-
- float widthBase = SimpleSplineRemapVal( fabs( m_vecPhysVelocity.y ), 128, 600, 32, 48 );
-
- curSeg.m_flWidth = Lerp( flLifePerc, widthBase*6, widthBase );
- curSeg.m_flWidth += pPoint->m_flWidthVariance;
-
- if ( curSeg.m_flWidth < 0.0f )
- {
- curSeg.m_flWidth = 0.0f;
- }
-
- curSeg.m_flTexCoord = pPoint->m_flTexCoord;
-
- if ( pPrevPoint != NULL )
- {
- segDir = ( pPrevPoint->m_vecScreenPos - pPoint->m_vecScreenPos );
- VectorNormalize( segDir );
-
- normal = CrossProduct( segDir, Vector( 0, 0, -1 ) );
-
- DrawSegment( curSeg, normal );
- }
-
- pPrevPoint = pPoint;
- }
-
- m_Mesh.End();
- pMesh->Draw();
-
- return 1;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : flags -
-// Output : int
-//-----------------------------------------------------------------------------
-int C_PropAirboat::DrawModel( int flags )
-{
- if ( BaseClass::DrawModel( flags ) == false )
- return 0;
-
- if ( !m_bReadyToDraw )
- return 0;
-
- return DrawWake();
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Client side implementation of the airboat.
+//
+// - Dampens motion of driver's view to reduce nausea.
+// - Autocenters driver's view after a period of inactivity.
+// - Controls headlights.
+// - Controls curve parameters for pitch/roll blending.
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "c_prop_vehicle.h"
+#include "datacache/imdlcache.h"
+#include "flashlighteffect.h"
+#include "movevars_shared.h"
+#include "ammodef.h"
+#include "SpriteTrail.h"
+#include "beamdraw.h"
+#include "enginesprite.h"
+#include "fx_quad.h"
+#include "fx.h"
+#include "fx_water.h"
+#include "engine/ivdebugoverlay.h"
+#include "view.h"
+#include "clienteffectprecachesystem.h"
+#include "c_basehlplayer.h"
+#include "vgui_controls/Controls.h"
+#include "vgui/ISurface.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+ConVar r_AirboatViewBlendTo( "r_AirboatViewBlendTo", "1", FCVAR_CHEAT );
+ConVar r_AirboatViewBlendToScale( "r_AirboatViewBlendToScale", "0.03", FCVAR_CHEAT );
+ConVar r_AirboatViewBlendToTime( "r_AirboatViewBlendToTime", "1.5", FCVAR_CHEAT );
+
+ConVar cl_draw_airboat_wake( "cl_draw_airboat_wake", "1", FCVAR_CHEAT );
+
+// Curve parameters for pitch/roll blending.
+// NOTE: Must restart (or create a new airboat) after changing these cvars!
+ConVar r_AirboatRollCurveZero( "r_AirboatRollCurveZero", "90.0", FCVAR_CHEAT ); // Roll less than this is clamped to zero.
+ConVar r_AirboatRollCurveLinear( "r_AirboatRollCurveLinear", "120.0", FCVAR_CHEAT ); // Roll greater than this is mapped directly.
+ // Spline in between.
+
+ConVar r_AirboatPitchCurveZero( "r_AirboatPitchCurveZero", "25.0", FCVAR_CHEAT ); // Pitch less than this is clamped to zero.
+ConVar r_AirboatPitchCurveLinear( "r_AirboatPitchCurveLinear", "60.0", FCVAR_CHEAT ); // Pitch greater than this is mapped directly.
+ // Spline in between.
+
+ConVar airboat_joy_response_move( "airboat_joy_response_move", "1" ); // Quadratic steering response
+
+
+#define AIRBOAT_DELTA_LENGTH_MAX 12.0f // 1 foot
+#define AIRBOAT_FRAMETIME_MIN 1e-6
+
+#define HEADLIGHT_DISTANCE 1000
+
+#define MAX_WAKE_POINTS 16
+#define WAKE_POINT_MASK (MAX_WAKE_POINTS-1)
+
+#define WAKE_LIFETIME 0.5f
+
+//=============================================================================
+//
+// Client-side Airboat Class
+//
+class C_PropAirboat : public C_PropVehicleDriveable
+{
+ DECLARE_CLASS( C_PropAirboat, C_PropVehicleDriveable );
+
+public:
+
+ DECLARE_CLIENTCLASS();
+ DECLARE_INTERPOLATION();
+ DECLARE_DATADESC();
+
+ C_PropAirboat();
+ ~C_PropAirboat();
+
+public:
+
+ // C_BaseEntity
+ virtual void Simulate();
+
+ // IClientVehicle
+ virtual void UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd );
+ virtual void OnEnteredVehicle( C_BasePlayer *pPlayer );
+ virtual int GetPrimaryAmmoType() const;
+ virtual int GetPrimaryAmmoClip() const;
+ virtual bool PrimaryAmmoUsesClips() const;
+ virtual int GetPrimaryAmmoCount() const;
+ virtual int GetJoystickResponseCurve() const;
+
+ int DrawModel( int flags );
+
+ // Draws crosshair in the forward direction of the boat
+ void DrawHudElements( );
+
+private:
+
+ void DrawPropWake( Vector origin, float speed );
+ void DrawPontoonSplash( Vector position, Vector direction, float speed );
+ void DrawPontoonWake( Vector startPos, Vector wakeDir, float wakeLength, float speed);
+
+ void DampenEyePosition( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles );
+ void DampenForwardMotion( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles, float flFrameTime );
+ void DampenUpMotion( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles, float flFrameTime );
+ void ComputePDControllerCoefficients( float *pCoefficientsOut, float flFrequency, float flDampening, float flDeltaTime );
+
+ void UpdateHeadlight( void );
+ void UpdateWake( void );
+ int DrawWake( void );
+ void DrawSegment( const BeamSeg_t &beamSeg, const Vector &vNormal );
+
+ TrailPoint_t *GetTrailPoint( int n )
+ {
+ int nIndex = (n + m_nFirstStep) & WAKE_POINT_MASK;
+ return &m_vecSteps[nIndex];
+ }
+
+private:
+
+ Vector m_vecLastEyePos;
+ Vector m_vecLastEyeTarget;
+ Vector m_vecEyeSpeed;
+ Vector m_vecTargetSpeed;
+
+ float m_flViewAngleDeltaTime;
+
+ bool m_bHeadlightIsOn;
+ int m_nAmmoCount;
+ CHeadlightEffect *m_pHeadlight;
+
+ int m_nExactWaterLevel;
+
+ TrailPoint_t m_vecSteps[MAX_WAKE_POINTS];
+ int m_nFirstStep;
+ int m_nStepCount;
+ float m_flUpdateTime;
+
+ TimedEvent m_SplashTime;
+ CMeshBuilder m_Mesh;
+
+ Vector m_vecPhysVelocity;
+};
+
+IMPLEMENT_CLIENTCLASS_DT( C_PropAirboat, DT_PropAirboat, CPropAirboat )
+ RecvPropBool( RECVINFO( m_bHeadlightIsOn ) ),
+ RecvPropInt( RECVINFO( m_nAmmoCount ) ),
+ RecvPropInt( RECVINFO( m_nExactWaterLevel ) ),
+ RecvPropInt( RECVINFO( m_nWaterLevel ) ),
+ RecvPropVector( RECVINFO( m_vecPhysVelocity ) ),
+END_RECV_TABLE()
+
+
+BEGIN_DATADESC( C_PropAirboat )
+ DEFINE_FIELD( m_vecLastEyePos, FIELD_POSITION_VECTOR ),
+ DEFINE_FIELD( m_vecLastEyeTarget, FIELD_POSITION_VECTOR ),
+ DEFINE_FIELD( m_vecEyeSpeed, FIELD_VECTOR ),
+ DEFINE_FIELD( m_vecTargetSpeed, FIELD_VECTOR ),
+ //DEFINE_FIELD( m_flViewAngleDeltaTime, FIELD_FLOAT ),
+END_DATADESC()
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+C_PropAirboat::C_PropAirboat()
+{
+ m_vecEyeSpeed.Init();
+ m_flViewAngleDeltaTime = 0.0f;
+ m_pHeadlight = NULL;
+
+ m_ViewSmoothingData.flPitchCurveZero = r_AirboatPitchCurveZero.GetFloat();
+ m_ViewSmoothingData.flPitchCurveLinear = r_AirboatPitchCurveLinear.GetFloat();
+ m_ViewSmoothingData.flRollCurveZero = r_AirboatRollCurveZero.GetFloat();
+ m_ViewSmoothingData.flRollCurveLinear = r_AirboatRollCurveLinear.GetFloat();
+
+ m_ViewSmoothingData.rollLockData.flLockInterval = 1.5;
+ m_ViewSmoothingData.rollLockData.flUnlockBlendInterval = 1.0;
+
+ m_ViewSmoothingData.pitchLockData.flLockInterval = 1.5;
+ m_ViewSmoothingData.pitchLockData.flUnlockBlendInterval = 1.0;
+
+ m_nFirstStep = 0;
+ m_nStepCount = 0;
+ m_SplashTime.Init( 60 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Deconstructor
+//-----------------------------------------------------------------------------
+C_PropAirboat::~C_PropAirboat()
+{
+ if (m_pHeadlight)
+ {
+ delete m_pHeadlight;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Draws the ammo for the airboat
+//-----------------------------------------------------------------------------
+int C_PropAirboat::GetPrimaryAmmoType() const
+{
+ if ( m_nAmmoCount < 0 )
+ return -1;
+
+ int nAmmoType = GetAmmoDef()->Index( "AirboatGun" );
+ return nAmmoType;
+}
+
+int C_PropAirboat::GetPrimaryAmmoCount() const
+{
+ return m_nAmmoCount;
+}
+
+bool C_PropAirboat::PrimaryAmmoUsesClips() const
+{
+ return false;
+}
+
+int C_PropAirboat::GetPrimaryAmmoClip() const
+{
+ return -1;
+}
+
+//-----------------------------------------------------------------------------
+// The airboat prefers a more peppy response curve for joystick control.
+//-----------------------------------------------------------------------------
+int C_PropAirboat::GetJoystickResponseCurve() const
+{
+ return airboat_joy_response_move.GetInt();
+}
+
+//-----------------------------------------------------------------------------
+// Draws crosshair in the forward direction of the boat
+//-----------------------------------------------------------------------------
+void C_PropAirboat::DrawHudElements( )
+{
+ BaseClass::DrawHudElements();
+
+ MDLCACHE_CRITICAL_SECTION();
+
+ CHudTexture *pIcon = gHUD.GetIcon( IsX360() ? "crosshair_default" : "plushair" );
+ if ( pIcon != NULL )
+ {
+ float x, y;
+ Vector screen;
+
+ int vx, vy, vw, vh;
+ vgui::surface()->GetFullscreenViewport( vx, vy, vw, vh );
+ float screenWidth = vw;
+ float screenHeight = vh;
+
+ x = screenWidth/2;
+ y = screenHeight/2;
+
+ int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
+ Vector vehicleEyeOrigin;
+ QAngle vehicleEyeAngles;
+ GetAttachment( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
+
+ // Only worry about yaw.
+ vehicleEyeAngles.x = vehicleEyeAngles.z = 0.0f;
+
+ Vector vecForward;
+ AngleVectors( vehicleEyeAngles, &vecForward );
+ VectorMA( vehicleEyeOrigin, 100.0f, vecForward, vehicleEyeOrigin );
+
+ ScreenTransform( vehicleEyeOrigin, screen );
+ x += 0.5 * screen[0] * screenWidth + 0.5;
+ y -= 0.5 * screen[1] * screenHeight + 0.5;
+
+ x -= pIcon->Width() / 2;
+ y -= pIcon->Height() / 2;
+
+ pIcon->DrawSelf( x, y, gHUD.m_clrNormal );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Blend view angles.
+//-----------------------------------------------------------------------------
+void C_PropAirboat::UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd )
+{
+ if ( r_AirboatViewBlendTo.GetInt() )
+ {
+ //
+ // Autocenter the view after a period of no mouse movement while throttling.
+ //
+ bool bResetViewAngleTime = false;
+
+ if ( ( pCmd->mousedx != 0 || pCmd->mousedy != 0 ) || ( fabsf( m_flThrottle ) < 0.01f ) )
+ {
+ if ( IsX360() )
+ {
+ // Only reset this if there isn't an autoaim target!
+ C_BaseHLPlayer *pLocalHLPlayer = (C_BaseHLPlayer *)pLocalPlayer;
+ if ( pLocalHLPlayer )
+ {
+ // Get the autoaim target.
+ CBaseEntity *pTarget = pLocalHLPlayer->m_HL2Local.m_hAutoAimTarget.Get();
+
+ if( !pTarget )
+ {
+ bResetViewAngleTime = true;
+ }
+ }
+ }
+ else
+ {
+ bResetViewAngleTime = true;
+ }
+ }
+
+ if( bResetViewAngleTime )
+ {
+ m_flViewAngleDeltaTime = 0.0f;
+ }
+ else
+ {
+ m_flViewAngleDeltaTime += gpGlobals->frametime;
+ }
+
+ if ( m_flViewAngleDeltaTime > r_AirboatViewBlendToTime.GetFloat() )
+ {
+ // Blend the view angles.
+ int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
+ Vector vehicleEyeOrigin;
+ QAngle vehicleEyeAngles;
+ GetAttachmentLocal( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
+
+ QAngle outAngles;
+ InterpolateAngles( pCmd->viewangles, vehicleEyeAngles, outAngles, r_AirboatViewBlendToScale.GetFloat() );
+ pCmd->viewangles = outAngles;
+ }
+ }
+
+ BaseClass::UpdateViewAngles( pLocalPlayer, pCmd );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_PropAirboat::DampenEyePosition( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles )
+{
+ // Get the frametime. (Check to see if enough time has passed to warrent dampening).
+ float flFrameTime = gpGlobals->frametime;
+ if ( flFrameTime < AIRBOAT_FRAMETIME_MIN )
+ {
+ vecVehicleEyePos = m_vecLastEyePos;
+ DampenUpMotion( vecVehicleEyePos, vecVehicleEyeAngles, 0.0f );
+ return;
+ }
+
+ // Keep static the sideways motion.
+
+ // Dampen forward/backward motion.
+ DampenForwardMotion( vecVehicleEyePos, vecVehicleEyeAngles, flFrameTime );
+
+ // Blend up/down motion.
+ DampenUpMotion( vecVehicleEyePos, vecVehicleEyeAngles, flFrameTime );
+}
+
+
+//-----------------------------------------------------------------------------
+// Use the controller as follows:
+// speed += ( pCoefficientsOut[0] * ( targetPos - currentPos ) + pCoefficientsOut[1] * ( targetSpeed - currentSpeed ) ) * flDeltaTime;
+//-----------------------------------------------------------------------------
+void C_PropAirboat::ComputePDControllerCoefficients( float *pCoefficientsOut,
+ float flFrequency, float flDampening,
+ float flDeltaTime )
+{
+ float flKs = 9.0f * flFrequency * flFrequency;
+ float flKd = 4.5f * flFrequency * flDampening;
+
+ float flScale = 1.0f / ( 1.0f + flKd * flDeltaTime + flKs * flDeltaTime * flDeltaTime );
+
+ pCoefficientsOut[0] = flKs * flScale;
+ pCoefficientsOut[1] = ( flKd + flKs * flDeltaTime ) * flScale;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_PropAirboat::DampenForwardMotion( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles, float flFrameTime )
+{
+ // vecVehicleEyePos = real eye position this frame
+
+ // m_vecLastEyePos = eye position last frame
+ // m_vecEyeSpeed = eye speed last frame
+ // vecPredEyePos = predicted eye position this frame (assuming no acceleration - it will get that from the pd controller).
+ // vecPredEyeSpeed = predicted eye speed
+ Vector vecPredEyePos = m_vecLastEyePos + m_vecEyeSpeed * flFrameTime;
+ Vector vecPredEyeSpeed = m_vecEyeSpeed;
+
+ // m_vecLastEyeTarget = real eye position last frame (used for speed calculation).
+ // Calculate the approximate speed based on the current vehicle eye position and the eye position last frame.
+ Vector vecVehicleEyeSpeed = ( vecVehicleEyePos - m_vecLastEyeTarget ) / flFrameTime;
+ m_vecLastEyeTarget = vecVehicleEyePos;
+ if (vecVehicleEyeSpeed.Length() == 0.0)
+ {
+ return;
+ }
+
+ // Calculate the delta between the predicted eye position and speed and the current eye position and speed.
+ Vector vecDeltaSpeed = vecVehicleEyeSpeed - vecPredEyeSpeed;
+ Vector vecDeltaPos = vecVehicleEyePos - vecPredEyePos;
+
+ // Forward vector.
+ Vector vecForward;
+ AngleVectors( vecVehicleEyeAngles, &vecForward );
+
+ float flDeltaLength = vecDeltaPos.Length();
+ if ( flDeltaLength > AIRBOAT_DELTA_LENGTH_MAX )
+ {
+ // Clamp.
+ float flDelta = flDeltaLength - AIRBOAT_DELTA_LENGTH_MAX;
+ if ( flDelta > 40.0f )
+ {
+ // This part is a bit of a hack to get rid of large deltas (at level load, etc.).
+ m_vecLastEyePos = vecVehicleEyePos;
+ m_vecEyeSpeed = vecVehicleEyeSpeed;
+ }
+ else
+ {
+ // Position clamp.
+ float flRatio = AIRBOAT_DELTA_LENGTH_MAX / flDeltaLength;
+ vecDeltaPos *= flRatio;
+ Vector vecForwardOffset = vecForward * ( vecForward.Dot( vecDeltaPos ) );
+ vecVehicleEyePos -= vecForwardOffset;
+ m_vecLastEyePos = vecVehicleEyePos;
+
+ // Speed clamp.
+ vecDeltaSpeed *= flRatio;
+ float flCoefficients[2];
+ ComputePDControllerCoefficients( flCoefficients, r_AirboatViewDampenFreq.GetFloat(), r_AirboatViewDampenDamp.GetFloat(), flFrameTime );
+ m_vecEyeSpeed += ( ( flCoefficients[0] * vecDeltaPos + flCoefficients[1] * vecDeltaSpeed ) * flFrameTime );
+ }
+ }
+ else
+ {
+ // Generate an updated (dampening) speed for use in next frames position prediction.
+ float flCoefficients[2];
+ ComputePDControllerCoefficients( flCoefficients, r_AirboatViewDampenFreq.GetFloat(), r_AirboatViewDampenDamp.GetFloat(), flFrameTime );
+ m_vecEyeSpeed += ( ( flCoefficients[0] * vecDeltaPos + flCoefficients[1] * vecDeltaSpeed ) * flFrameTime );
+
+ // Save off data for next frame.
+ m_vecLastEyePos = vecPredEyePos;
+
+ // Move eye forward/backward.
+ Vector vecForwardOffset = vecForward * ( vecForward.Dot( vecDeltaPos ) );
+ vecVehicleEyePos -= vecForwardOffset;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_PropAirboat::DampenUpMotion( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles, float flFrameTime )
+{
+ // Get up vector.
+ Vector vecUp;
+ AngleVectors( vecVehicleEyeAngles, NULL, NULL, &vecUp );
+ vecUp.z = clamp( vecUp.z, 0.0f, vecUp.z );
+ vecVehicleEyePos.z += r_AirboatViewZHeight.GetFloat() * vecUp.z;
+
+ // NOTE: Should probably use some damped equation here.
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_PropAirboat::OnEnteredVehicle( C_BasePlayer *pPlayer )
+{
+ int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
+ Vector vehicleEyeOrigin;
+ QAngle vehicleEyeAngles;
+ GetAttachment( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
+
+ m_vecLastEyeTarget = vehicleEyeOrigin;
+ m_vecLastEyePos = vehicleEyeOrigin;
+ m_vecEyeSpeed = vec3_origin;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_PropAirboat::Simulate()
+{
+ UpdateHeadlight();
+ UpdateWake();
+
+ BaseClass::Simulate();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Creates, destroys, and updates the headlight effect as needed.
+//-----------------------------------------------------------------------------
+void C_PropAirboat::UpdateHeadlight()
+{
+ if (m_bHeadlightIsOn)
+ {
+ if (!m_pHeadlight)
+ {
+ // Turned on the headlight; create it.
+ m_pHeadlight = new CHeadlightEffect();
+
+ if (!m_pHeadlight)
+ return;
+
+ m_pHeadlight->TurnOn();
+ }
+
+ // The headlight is emitted from an attachment point so that it can move
+ // as we turn the handlebars.
+ int nHeadlightIndex = LookupAttachment( "vehicle_headlight" );
+
+ Vector vecLightPos;
+ QAngle angLightDir;
+ GetAttachment(nHeadlightIndex, vecLightPos, angLightDir);
+
+ Vector vecLightDir, vecLightRight, vecLightUp;
+ AngleVectors( angLightDir, &vecLightDir, &vecLightRight, &vecLightUp );
+
+ // Update the light with the new position and direction.
+ m_pHeadlight->UpdateLight( vecLightPos, vecLightDir, vecLightRight, vecLightUp, HEADLIGHT_DISTANCE );
+ }
+ else if (m_pHeadlight)
+ {
+ // Turned off the headlight; delete it.
+ delete m_pHeadlight;
+ m_pHeadlight = NULL;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_PropAirboat::UpdateWake( void )
+{
+ if ( gpGlobals->frametime <= 0.0f )
+ return;
+
+ // Can't update too quickly
+ if ( m_flUpdateTime > gpGlobals->curtime )
+ return;
+
+ Vector screenPos = GetRenderOrigin();
+ screenPos.z = m_nExactWaterLevel;
+
+ TrailPoint_t *pLast = m_nStepCount ? GetTrailPoint( m_nStepCount-1 ) : NULL;
+ if ( ( pLast == NULL ) || ( pLast->m_vecScreenPos.DistToSqr( screenPos ) > 4.0f ) )
+ {
+ // If we're over our limit, steal the last point and put it up front
+ if ( m_nStepCount >= MAX_WAKE_POINTS )
+ {
+ --m_nStepCount;
+ ++m_nFirstStep;
+ }
+
+ // Save off its screen position, not its world position
+ TrailPoint_t *pNewPoint = GetTrailPoint( m_nStepCount );
+ pNewPoint->m_vecScreenPos = screenPos + Vector( 0, 0, 2 );
+ pNewPoint->m_flDieTime = gpGlobals->curtime + WAKE_LIFETIME;
+ pNewPoint->m_flWidthVariance = random->RandomFloat( -16, 16 );
+
+ if ( pLast )
+ {
+ pNewPoint->m_flTexCoord = pLast->m_flTexCoord + pLast->m_vecScreenPos.DistTo( screenPos );
+ pNewPoint->m_flTexCoord = fmod( pNewPoint->m_flTexCoord, 1 );
+ }
+ else
+ {
+ pNewPoint->m_flTexCoord = 0.0f;
+ }
+
+ ++m_nStepCount;
+ }
+
+ // Don't update again for a bit
+ m_flUpdateTime = gpGlobals->curtime + ( 0.5f / (float) MAX_WAKE_POINTS );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &beamSeg -
+//-----------------------------------------------------------------------------
+void C_PropAirboat::DrawSegment( const BeamSeg_t &beamSeg, const Vector &vNormal )
+{
+ // Build the endpoints.
+ Vector vPoint1, vPoint2;
+ VectorMA( beamSeg.m_vPos, beamSeg.m_flWidth*0.5f, vNormal, vPoint1 );
+ VectorMA( beamSeg.m_vPos, -beamSeg.m_flWidth*0.5f, vNormal, vPoint2 );
+
+ // Specify the points.
+ m_Mesh.Position3fv( vPoint1.Base() );
+ m_Mesh.Color4f( VectorExpand( beamSeg.m_vColor ), beamSeg.m_flAlpha );
+ m_Mesh.TexCoord2f( 0, 0, beamSeg.m_flTexCoord );
+ m_Mesh.TexCoord2f( 1, 0, beamSeg.m_flTexCoord );
+ m_Mesh.AdvanceVertex();
+
+ m_Mesh.Position3fv( vPoint2.Base() );
+ m_Mesh.Color4f( VectorExpand( beamSeg.m_vColor ), beamSeg.m_flAlpha );
+ m_Mesh.TexCoord2f( 0, 1, beamSeg.m_flTexCoord );
+ m_Mesh.TexCoord2f( 1, 1, beamSeg.m_flTexCoord );
+ m_Mesh.AdvanceVertex();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : position -
+//-----------------------------------------------------------------------------
+void C_PropAirboat::DrawPontoonSplash( Vector origin, Vector direction, float speed )
+{
+ Vector offset;
+
+ CSmartPtr<CSplashParticle> pSimple = CSplashParticle::Create( "splish" );
+ pSimple->SetSortOrigin( origin );
+
+ SimpleParticle *pParticle;
+
+ Vector color = Vector( 0.8f, 0.8f, 0.75f );
+ float colorRamp;
+
+ float flScale = RemapVal( speed, 64, 256, 0.75f, 1.0f );
+
+ PMaterialHandle hMaterial;
+
+ float tempDelta = gpGlobals->frametime;
+
+ while( m_SplashTime.NextEvent( tempDelta ) )
+ {
+ if ( random->RandomInt( 0, 1 ) )
+ {
+ hMaterial = ParticleMgr()->GetPMaterial( "effects/splash1" );
+ }
+ else
+ {
+ hMaterial = ParticleMgr()->GetPMaterial( "effects/splash2" );
+ }
+
+ offset = RandomVector( -8.0f * flScale, 8.0f * flScale );
+ offset[2] = 0.0f;
+ offset += origin;
+
+ pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), hMaterial, offset );
+
+ if ( pParticle == NULL )
+ continue;
+
+ pParticle->m_flLifetime = 0.0f;
+ pParticle->m_flDieTime = 0.25f;
+
+ pParticle->m_vecVelocity.Random( -0.4f, 0.4f );
+ pParticle->m_vecVelocity += (direction*5.0f+Vector(0,0,1));
+
+ VectorNormalize( pParticle->m_vecVelocity );
+
+ pParticle->m_vecVelocity *= speed + random->RandomFloat( -128.0f, 128.0f );
+
+ colorRamp = random->RandomFloat( 0.75f, 1.25f );
+
+ pParticle->m_uchColor[0] = MIN( 1.0f, color[0] * colorRamp ) * 255.0f;
+ pParticle->m_uchColor[1] = MIN( 1.0f, color[1] * colorRamp ) * 255.0f;
+ pParticle->m_uchColor[2] = MIN( 1.0f, color[2] * colorRamp ) * 255.0f;
+
+ pParticle->m_uchStartSize = random->RandomFloat( 8, 16 ) * flScale;
+ pParticle->m_uchEndSize = pParticle->m_uchStartSize * 2;
+
+ pParticle->m_uchStartAlpha = 255;
+ pParticle->m_uchEndAlpha = 0;
+
+ pParticle->m_flRoll = random->RandomInt( 0, 360 );
+ pParticle->m_flRollDelta = random->RandomFloat( -4.0f, 4.0f );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : Vector startPos -
+// wakeDir -
+// wakeLength -
+//-----------------------------------------------------------------------------
+void C_PropAirboat::DrawPontoonWake( Vector startPos, Vector wakeDir, float wakeLength, float speed )
+{
+#define WAKE_STEPS 6
+
+ Vector wakeStep = wakeDir * ( wakeLength / (float) WAKE_STEPS );
+ Vector origin;
+ float scale;
+
+ IMaterial *pMaterial = materials->FindMaterial( "effects/splashwake1", NULL, false );
+ CMatRenderContextPtr pRenderContext( materials );
+ IMesh* pMesh = pRenderContext->GetDynamicMesh( 0, 0, 0, pMaterial );
+
+ CMeshBuilder meshBuilder;
+ meshBuilder.Begin( pMesh, MATERIAL_QUADS, WAKE_STEPS );
+
+ for ( int i = 0; i < WAKE_STEPS; i++ )
+ {
+ origin = startPos + ( wakeStep * i );
+ origin[0] += random->RandomFloat( -4.0f, 4.0f );
+ origin[1] += random->RandomFloat( -4.0f, 4.0f );
+ origin[2] = m_nExactWaterLevel + 2.0f;
+
+ float scaleRange = RemapVal( i, 0, WAKE_STEPS-1, 32, 64 );
+ scale = scaleRange + ( 8.0f * sin( gpGlobals->curtime * 5 * i ) );
+
+ float alpha = RemapValClamped( speed, 128, 600, 0.05f, 0.25f );
+ float color[4] = { 1.0f, 1.0f, 1.0f, alpha };
+
+ // Needs to be time based so it'll freeze when the game is frozen
+ float yaw = random->RandomFloat( 0, 360 );
+
+ Vector rRight = ( Vector(1,0,0) * cos( DEG2RAD( yaw ) ) ) - ( Vector(0,1,0) * sin( DEG2RAD( yaw ) ) );
+ Vector rUp = ( Vector(1,0,0) * cos( DEG2RAD( yaw+90.0f ) ) ) - ( Vector(0,1,0) * sin( DEG2RAD( yaw+90.0f ) ) );
+
+ Vector point;
+ meshBuilder.Color4fv (color);
+ meshBuilder.TexCoord2f (0, 0, 1);
+ VectorMA (origin, -scale, rRight, point);
+ VectorMA (point, -scale, rUp, point);
+ meshBuilder.Position3fv (point.Base());
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4fv (color);
+ meshBuilder.TexCoord2f (0, 0, 0);
+ VectorMA (origin, scale, rRight, point);
+ VectorMA (point, -scale, rUp, point);
+ meshBuilder.Position3fv (point.Base());
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4fv (color);
+ meshBuilder.TexCoord2f (0, 1, 0);
+ VectorMA (origin, scale, rRight, point);
+ VectorMA (point, scale, rUp, point);
+ meshBuilder.Position3fv (point.Base());
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4fv (color);
+ meshBuilder.TexCoord2f (0, 1, 1);
+ VectorMA (origin, -scale, rRight, point);
+ VectorMA (point, scale, rUp, point);
+ meshBuilder.Position3fv (point.Base());
+ meshBuilder.AdvanceVertex();
+ }
+
+ meshBuilder.End();
+ pMesh->Draw();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : int
+//-----------------------------------------------------------------------------
+int C_PropAirboat::DrawWake( void )
+{
+ if ( cl_draw_airboat_wake.GetBool() == false )
+ return 0;
+
+ // Make sure we're in water...
+ if ( GetWaterLevel() == 0 )
+ return 0;
+
+ //FIXME: For now, we don't draw slime this way
+ if ( GetWaterLevel() == 2 )
+ return 0;
+
+ bool bDriven = ( GetPassenger( VEHICLE_ROLE_DRIVER ) != NULL );
+
+ Vector vehicleDir = m_vecPhysVelocity;
+ float vehicleSpeed = VectorNormalize( vehicleDir );
+
+ Vector vecPontoonFrontLeft;
+ Vector vecPontoonFrontRight;
+ Vector vecPontoonRearLeft;
+ Vector vecPontoonRearRight;
+ Vector vecSplashPoint;
+
+ QAngle fooAngles;
+
+ //FIXME: This lookup should be cached off
+ // Get all attachments
+ GetAttachment( LookupAttachment( "raytrace_fl" ), vecPontoonFrontLeft, fooAngles );
+ GetAttachment( LookupAttachment( "raytrace_fr" ), vecPontoonFrontRight, fooAngles );
+ GetAttachment( LookupAttachment( "raytrace_rl" ), vecPontoonRearLeft, fooAngles );
+ GetAttachment( LookupAttachment( "raytrace_rr" ), vecPontoonRearRight, fooAngles );
+ GetAttachment( LookupAttachment( "splash_pt" ), vecSplashPoint, fooAngles );
+
+ // Find the direction of the pontoons
+ Vector vecLeftWakeDir = ( vecPontoonRearLeft - vecPontoonFrontLeft );
+ Vector vecRightWakeDir = ( vecPontoonRearRight - vecPontoonFrontRight );
+
+ // Find the pontoon's size
+ float flWakeLeftLength = VectorNormalize( vecLeftWakeDir );
+ float flWakeRightLength = VectorNormalize( vecRightWakeDir );
+
+ vecPontoonFrontLeft.z = m_nExactWaterLevel;
+ vecPontoonFrontRight.z = m_nExactWaterLevel;
+
+ if ( bDriven && vehicleSpeed > 128.0f )
+ {
+ DrawPontoonWake( vecPontoonFrontLeft, vecLeftWakeDir, flWakeLeftLength, vehicleSpeed );
+ DrawPontoonWake( vecPontoonFrontRight, vecRightWakeDir, flWakeRightLength, vehicleSpeed );
+
+ Vector vecSplashDir;
+ Vector vForward;
+ GetVectors( &vForward, NULL, NULL );
+
+ if ( m_vecPhysVelocity.x < -64.0f )
+ {
+ vecSplashDir = vecLeftWakeDir - vForward;
+ VectorNormalize( vecSplashDir );
+
+ // Don't do this if we're going backwards
+ if ( m_vecPhysVelocity.y > 0.0f )
+ {
+ DrawPontoonSplash( vecPontoonFrontLeft + ( vecLeftWakeDir * 1.0f ), vecSplashDir, m_vecPhysVelocity.y );
+ }
+ }
+ else if ( m_vecPhysVelocity.x > 64.0f )
+ {
+ vecSplashDir = vecRightWakeDir + vForward;
+ VectorNormalize( vecSplashDir );
+
+ // Don't do this if we're going backwards
+ if ( m_vecPhysVelocity.y > 0.0f )
+ {
+ DrawPontoonSplash( vecPontoonFrontRight + ( vecRightWakeDir * 1.0f ), vecSplashDir, m_vecPhysVelocity.y );
+ }
+ }
+ }
+
+ // Must have at least one point
+ if ( m_nStepCount <= 1 )
+ return 1;
+
+ IMaterial *pMaterial = materials->FindMaterial( "effects/splashwake4", 0);
+
+ //Bind the material
+ CMatRenderContextPtr pRenderContext( materials );
+ IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, pMaterial );
+
+ m_Mesh.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, (m_nStepCount-1) * 2 );
+
+ TrailPoint_t *pLast = GetTrailPoint( m_nStepCount - 1 );
+
+ TrailPoint_t currentPoint;
+ currentPoint.m_flDieTime = gpGlobals->curtime + 0.5f;
+ currentPoint.m_vecScreenPos = GetAbsOrigin();
+ currentPoint.m_vecScreenPos[2] = m_nExactWaterLevel + 16;
+ currentPoint.m_flTexCoord = pLast->m_flTexCoord + currentPoint.m_vecScreenPos.DistTo(pLast->m_vecScreenPos);
+ currentPoint.m_flTexCoord = fmod( currentPoint.m_flTexCoord, 1 );
+ currentPoint.m_flWidthVariance = 0.0f;
+
+ TrailPoint_t *pPrevPoint = NULL;
+
+ Vector segDir, normal;
+
+ for ( int i = 0; i <= m_nStepCount; ++i )
+ {
+ // This makes it so that we're always drawing to the current location
+ TrailPoint_t *pPoint = (i != m_nStepCount) ? GetTrailPoint(i) : &currentPoint;
+
+ float flLifePerc = RemapValClamped( ( pPoint->m_flDieTime - gpGlobals->curtime ), 0, WAKE_LIFETIME, 0.0f, 1.0f );
+
+ BeamSeg_t curSeg;
+ curSeg.m_vColor.x = curSeg.m_vColor.y = curSeg.m_vColor.z = 1.0f;
+
+ float flAlphaFade = flLifePerc;
+ float alpha = RemapValClamped( fabs( m_vecPhysVelocity.y ), 128, 600, 0.0f, 1.0f );
+
+ curSeg.m_flAlpha = 0.25f;
+ curSeg.m_flAlpha *= flAlphaFade * alpha;
+
+ curSeg.m_vPos = pPoint->m_vecScreenPos;
+
+ float widthBase = SimpleSplineRemapVal( fabs( m_vecPhysVelocity.y ), 128, 600, 32, 48 );
+
+ curSeg.m_flWidth = Lerp( flLifePerc, widthBase*6, widthBase );
+ curSeg.m_flWidth += pPoint->m_flWidthVariance;
+
+ if ( curSeg.m_flWidth < 0.0f )
+ {
+ curSeg.m_flWidth = 0.0f;
+ }
+
+ curSeg.m_flTexCoord = pPoint->m_flTexCoord;
+
+ if ( pPrevPoint != NULL )
+ {
+ segDir = ( pPrevPoint->m_vecScreenPos - pPoint->m_vecScreenPos );
+ VectorNormalize( segDir );
+
+ normal = CrossProduct( segDir, Vector( 0, 0, -1 ) );
+
+ DrawSegment( curSeg, normal );
+ }
+
+ pPrevPoint = pPoint;
+ }
+
+ m_Mesh.End();
+ pMesh->Draw();
+
+ return 1;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : flags -
+// Output : int
+//-----------------------------------------------------------------------------
+int C_PropAirboat::DrawModel( int flags )
+{
+ if ( BaseClass::DrawModel( flags ) == false )
+ return 0;
+
+ if ( !m_bReadyToDraw )
+ return 0;
+
+ return DrawWake();
+}
diff --git a/mp/src/game/client/hl2/c_vehicle_cannon.cpp b/mp/src/game/client/hl2/c_vehicle_cannon.cpp
index 703bc271..74e49ce6 100644
--- a/mp/src/game/client/hl2/c_vehicle_cannon.cpp
+++ b/mp/src/game/client/hl2/c_vehicle_cannon.cpp
@@ -1,187 +1,187 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "hud.h"
-#include <vgui_controls/Controls.h>
-#include <Color.h>
-#include "c_vehicle_crane.h"
-#include "view.h"
-#include "vehicle_viewblend_shared.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-int ScreenTransform( const Vector& point, Vector& screen );
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-class C_PropCannon : public C_BaseAnimating, public IClientVehicle
-{
-
- DECLARE_CLASS( C_PropCannon, C_BaseAnimating );
-
-public:
-
- DECLARE_CLIENTCLASS();
- DECLARE_DATADESC();
-
- C_PropCannon();
-
- void PreDataUpdate( DataUpdateType_t updateType );
-
-public:
-
- // IClientVehicle overrides.
- virtual void GetVehicleViewPosition( int nRole, Vector *pOrigin, QAngle *pAngles, float *pFOV = NULL );
- virtual void GetVehicleFOV( float &flFOV ) { flFOV = 0.0f; }
- virtual void DrawHudElements();
- virtual bool IsPassengerUsingStandardWeapons( int nRole = VEHICLE_ROLE_DRIVER ) { return false; }
- virtual void UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd ) {}
- virtual C_BaseCombatCharacter *GetPassenger( int nRole );
- virtual int GetPassengerRole( C_BaseCombatCharacter *pPassenger );
- virtual void GetVehicleClipPlanes( float &flZNear, float &flZFar ) const;
- virtual int GetPrimaryAmmoType() const { return -1; }
- virtual int GetPrimaryAmmoCount() const { return -1; }
- virtual int GetPrimaryAmmoClip() const { return -1; }
- virtual bool PrimaryAmmoUsesClips() const { return false; }
- virtual int GetJoystickResponseCurve() const { return 0; }
-
-public:
-
- // C_BaseEntity overrides.
- virtual IClientVehicle* GetClientVehicle() { return this; }
- virtual C_BaseEntity *GetVehicleEnt() { return this; }
- virtual void SetupMove( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move ) {}
- virtual void ProcessMovement( C_BasePlayer *pPlayer, CMoveData *pMoveData ) {}
- virtual void FinishMove( C_BasePlayer *player, CUserCmd *ucmd, CMoveData *move ) {}
- virtual bool IsPredicted() const { return false; }
- virtual void ItemPostFrame( C_BasePlayer *pPlayer ) {}
- virtual bool IsSelfAnimating() { return false; };
- virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
-
-private:
-
- CHandle<C_BasePlayer> m_hPlayer;
- CHandle<C_BasePlayer> m_hPrevPlayer;
-
- bool m_bEnterAnimOn;
- bool m_bExitAnimOn;
- Vector m_vecEyeExitEndpoint;
-
- Vector m_vecOldShadowDir;
-
- ViewSmoothingData_t m_ViewSmoothingData;
-};
-
-
-IMPLEMENT_CLIENTCLASS_DT(C_PropCannon, DT_PropCannon, CPropCannon)
- RecvPropEHandle( RECVINFO(m_hPlayer) ),
- RecvPropBool( RECVINFO( m_bEnterAnimOn ) ),
- RecvPropBool( RECVINFO( m_bExitAnimOn ) ),
- RecvPropVector( RECVINFO( m_vecEyeExitEndpoint ) ),
-END_RECV_TABLE()
-
-
-BEGIN_DATADESC( C_PropCannon )
- DEFINE_EMBEDDED( m_ViewSmoothingData ),
-END_DATADESC()
-
-
-#define ROLL_CURVE_ZERO 5 // roll less than this is clamped to zero
-#define ROLL_CURVE_LINEAR 45 // roll greater than this is copied out
-
-#define PITCH_CURVE_ZERO 10 // pitch less than this is clamped to zero
-#define PITCH_CURVE_LINEAR 45 // pitch greater than this is copied out
- // spline in between
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-C_PropCannon::C_PropCannon( void )
-{
- memset( &m_ViewSmoothingData, 0, sizeof( m_ViewSmoothingData ) );
- m_ViewSmoothingData.pVehicle = this;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : updateType -
-//-----------------------------------------------------------------------------
-void C_PropCannon::PreDataUpdate( DataUpdateType_t updateType )
-{
- BaseClass::PreDataUpdate( updateType );
-
- m_hPrevPlayer = m_hPlayer;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-C_BaseCombatCharacter *C_PropCannon::GetPassenger( int nRole )
-{
- if ( nRole == VEHICLE_ROLE_DRIVER )
- return m_hPlayer.Get();
-
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Returns the role of the passenger
-//-----------------------------------------------------------------------------
-int C_PropCannon::GetPassengerRole( C_BaseCombatCharacter *pPassenger )
-{
- if ( m_hPlayer.Get() == pPassenger )
- return VEHICLE_ROLE_DRIVER;
-
- return VEHICLE_ROLE_NONE;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Modify the player view/camera while in a vehicle
-//-----------------------------------------------------------------------------
-void C_PropCannon::GetVehicleViewPosition( int nRole, Vector *pAbsOrigin, QAngle *pAbsAngles, float *pFOV /*=NULL*/ )
-{
- SharedVehicleViewSmoothing( m_hPlayer,
- pAbsOrigin, pAbsAngles,
- m_bEnterAnimOn, m_bExitAnimOn,
- m_vecEyeExitEndpoint,
- &m_ViewSmoothingData,
- pFOV );
-}
-
-
-//-----------------------------------------------------------------------------
-// Futzes with the clip planes
-//-----------------------------------------------------------------------------
-void C_PropCannon::GetVehicleClipPlanes( float &flZNear, float &flZFar ) const
-{
- // FIXME: Need something a better long-term, this fixes the buggy.
- flZNear = 6;
-}
-
-
-//-----------------------------------------------------------------------------
-// Renders hud elements
-//-----------------------------------------------------------------------------
-void C_PropCannon::DrawHudElements( )
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : theMins -
-// theMaxs -
-//-----------------------------------------------------------------------------
-void C_PropCannon::GetRenderBounds( Vector &theMins, Vector &theMaxs )
-{
- // This is kind of hacky:( Add 660.0 to the y coordinate of the bounding box to
- // allow for the full extension of the crane arm.
- BaseClass::GetRenderBounds( theMins, theMaxs );
- theMaxs.y += 660.0f;
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "hud.h"
+#include <vgui_controls/Controls.h>
+#include <Color.h>
+#include "c_vehicle_crane.h"
+#include "view.h"
+#include "vehicle_viewblend_shared.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+int ScreenTransform( const Vector& point, Vector& screen );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class C_PropCannon : public C_BaseAnimating, public IClientVehicle
+{
+
+ DECLARE_CLASS( C_PropCannon, C_BaseAnimating );
+
+public:
+
+ DECLARE_CLIENTCLASS();
+ DECLARE_DATADESC();
+
+ C_PropCannon();
+
+ void PreDataUpdate( DataUpdateType_t updateType );
+
+public:
+
+ // IClientVehicle overrides.
+ virtual void GetVehicleViewPosition( int nRole, Vector *pOrigin, QAngle *pAngles, float *pFOV = NULL );
+ virtual void GetVehicleFOV( float &flFOV ) { flFOV = 0.0f; }
+ virtual void DrawHudElements();
+ virtual bool IsPassengerUsingStandardWeapons( int nRole = VEHICLE_ROLE_DRIVER ) { return false; }
+ virtual void UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd ) {}
+ virtual C_BaseCombatCharacter *GetPassenger( int nRole );
+ virtual int GetPassengerRole( C_BaseCombatCharacter *pPassenger );
+ virtual void GetVehicleClipPlanes( float &flZNear, float &flZFar ) const;
+ virtual int GetPrimaryAmmoType() const { return -1; }
+ virtual int GetPrimaryAmmoCount() const { return -1; }
+ virtual int GetPrimaryAmmoClip() const { return -1; }
+ virtual bool PrimaryAmmoUsesClips() const { return false; }
+ virtual int GetJoystickResponseCurve() const { return 0; }
+
+public:
+
+ // C_BaseEntity overrides.
+ virtual IClientVehicle* GetClientVehicle() { return this; }
+ virtual C_BaseEntity *GetVehicleEnt() { return this; }
+ virtual void SetupMove( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move ) {}
+ virtual void ProcessMovement( C_BasePlayer *pPlayer, CMoveData *pMoveData ) {}
+ virtual void FinishMove( C_BasePlayer *player, CUserCmd *ucmd, CMoveData *move ) {}
+ virtual bool IsPredicted() const { return false; }
+ virtual void ItemPostFrame( C_BasePlayer *pPlayer ) {}
+ virtual bool IsSelfAnimating() { return false; };
+ virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
+
+private:
+
+ CHandle<C_BasePlayer> m_hPlayer;
+ CHandle<C_BasePlayer> m_hPrevPlayer;
+
+ bool m_bEnterAnimOn;
+ bool m_bExitAnimOn;
+ Vector m_vecEyeExitEndpoint;
+
+ Vector m_vecOldShadowDir;
+
+ ViewSmoothingData_t m_ViewSmoothingData;
+};
+
+
+IMPLEMENT_CLIENTCLASS_DT(C_PropCannon, DT_PropCannon, CPropCannon)
+ RecvPropEHandle( RECVINFO(m_hPlayer) ),
+ RecvPropBool( RECVINFO( m_bEnterAnimOn ) ),
+ RecvPropBool( RECVINFO( m_bExitAnimOn ) ),
+ RecvPropVector( RECVINFO( m_vecEyeExitEndpoint ) ),
+END_RECV_TABLE()
+
+
+BEGIN_DATADESC( C_PropCannon )
+ DEFINE_EMBEDDED( m_ViewSmoothingData ),
+END_DATADESC()
+
+
+#define ROLL_CURVE_ZERO 5 // roll less than this is clamped to zero
+#define ROLL_CURVE_LINEAR 45 // roll greater than this is copied out
+
+#define PITCH_CURVE_ZERO 10 // pitch less than this is clamped to zero
+#define PITCH_CURVE_LINEAR 45 // pitch greater than this is copied out
+ // spline in between
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_PropCannon::C_PropCannon( void )
+{
+ memset( &m_ViewSmoothingData, 0, sizeof( m_ViewSmoothingData ) );
+ m_ViewSmoothingData.pVehicle = this;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : updateType -
+//-----------------------------------------------------------------------------
+void C_PropCannon::PreDataUpdate( DataUpdateType_t updateType )
+{
+ BaseClass::PreDataUpdate( updateType );
+
+ m_hPrevPlayer = m_hPlayer;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_BaseCombatCharacter *C_PropCannon::GetPassenger( int nRole )
+{
+ if ( nRole == VEHICLE_ROLE_DRIVER )
+ return m_hPlayer.Get();
+
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Returns the role of the passenger
+//-----------------------------------------------------------------------------
+int C_PropCannon::GetPassengerRole( C_BaseCombatCharacter *pPassenger )
+{
+ if ( m_hPlayer.Get() == pPassenger )
+ return VEHICLE_ROLE_DRIVER;
+
+ return VEHICLE_ROLE_NONE;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Modify the player view/camera while in a vehicle
+//-----------------------------------------------------------------------------
+void C_PropCannon::GetVehicleViewPosition( int nRole, Vector *pAbsOrigin, QAngle *pAbsAngles, float *pFOV /*=NULL*/ )
+{
+ SharedVehicleViewSmoothing( m_hPlayer,
+ pAbsOrigin, pAbsAngles,
+ m_bEnterAnimOn, m_bExitAnimOn,
+ m_vecEyeExitEndpoint,
+ &m_ViewSmoothingData,
+ pFOV );
+}
+
+
+//-----------------------------------------------------------------------------
+// Futzes with the clip planes
+//-----------------------------------------------------------------------------
+void C_PropCannon::GetVehicleClipPlanes( float &flZNear, float &flZFar ) const
+{
+ // FIXME: Need something a better long-term, this fixes the buggy.
+ flZNear = 6;
+}
+
+
+//-----------------------------------------------------------------------------
+// Renders hud elements
+//-----------------------------------------------------------------------------
+void C_PropCannon::DrawHudElements( )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : theMins -
+// theMaxs -
+//-----------------------------------------------------------------------------
+void C_PropCannon::GetRenderBounds( Vector &theMins, Vector &theMaxs )
+{
+ // This is kind of hacky:( Add 660.0 to the y coordinate of the bounding box to
+ // allow for the full extension of the crane arm.
+ BaseClass::GetRenderBounds( theMins, theMaxs );
+ theMaxs.y += 660.0f;
+}
+
diff --git a/mp/src/game/client/hl2/c_vehicle_crane.cpp b/mp/src/game/client/hl2/c_vehicle_crane.cpp
index acb34916..933bef81 100644
--- a/mp/src/game/client/hl2/c_vehicle_crane.cpp
+++ b/mp/src/game/client/hl2/c_vehicle_crane.cpp
@@ -1,151 +1,151 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "hud.h"
-#include <vgui_controls/Controls.h>
-#include <Color.h>
-#include "c_vehicle_crane.h"
-#include "view.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-int ScreenTransform( const Vector& point, Vector& screen );
-
-IMPLEMENT_CLIENTCLASS_DT(C_PropCrane, DT_PropCrane, CPropCrane)
- RecvPropEHandle( RECVINFO(m_hPlayer) ),
- RecvPropBool( RECVINFO(m_bMagnetOn) ),
- RecvPropBool( RECVINFO( m_bEnterAnimOn ) ),
- RecvPropBool( RECVINFO( m_bExitAnimOn ) ),
- RecvPropVector( RECVINFO( m_vecEyeExitEndpoint ) ),
-END_RECV_TABLE()
-
-
-BEGIN_DATADESC( C_PropCrane )
- DEFINE_EMBEDDED( m_ViewSmoothingData ),
-END_DATADESC()
-
-
-#define ROLL_CURVE_ZERO 5 // roll less than this is clamped to zero
-#define ROLL_CURVE_LINEAR 45 // roll greater than this is copied out
-
-#define PITCH_CURVE_ZERO 10 // pitch less than this is clamped to zero
-#define PITCH_CURVE_LINEAR 45 // pitch greater than this is copied out
- // spline in between
-
-#define CRANE_FOV 75
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-C_PropCrane::C_PropCrane( void )
-{
- memset( &m_ViewSmoothingData, 0, sizeof( m_ViewSmoothingData ) );
- m_ViewSmoothingData.pVehicle = this;
- m_ViewSmoothingData.flFOV = CRANE_FOV;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : updateType -
-//-----------------------------------------------------------------------------
-void C_PropCrane::PreDataUpdate( DataUpdateType_t updateType )
-{
- BaseClass::PreDataUpdate( updateType );
-
- m_hPrevPlayer = m_hPlayer;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_PropCrane::PostDataUpdate( DataUpdateType_t updateType )
-{
- BaseClass::PostDataUpdate( updateType );
-
- // Store off the old shadow direction
- if ( m_hPlayer && !m_hPrevPlayer )
- {
- m_vecOldShadowDir = g_pClientShadowMgr->GetShadowDirection();
- //Vector vecDown = m_vecOldShadowDir - Vector(0,0,0.5);
- //VectorNormalize( vecDown );
- Vector vecDown = Vector(0,0,-1);
- g_pClientShadowMgr->SetShadowDirection( vecDown );
- }
- else if ( !m_hPlayer && m_hPrevPlayer )
- {
- g_pClientShadowMgr->SetShadowDirection( m_vecOldShadowDir );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-C_BaseCombatCharacter *C_PropCrane::GetPassenger( int nRole )
-{
- if ( nRole == VEHICLE_ROLE_DRIVER )
- return m_hPlayer.Get();
-
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Returns the role of the passenger
-//-----------------------------------------------------------------------------
-int C_PropCrane::GetPassengerRole( C_BaseCombatCharacter *pPassenger )
-{
- if ( m_hPlayer.Get() == pPassenger )
- return VEHICLE_ROLE_DRIVER;
-
- return VEHICLE_ROLE_NONE;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Modify the player view/camera while in a vehicle
-//-----------------------------------------------------------------------------
-void C_PropCrane::GetVehicleViewPosition( int nRole, Vector *pAbsOrigin, QAngle *pAbsAngles, float *pFOV /*=NULL*/ )
-{
- SharedVehicleViewSmoothing( m_hPlayer,
- pAbsOrigin, pAbsAngles,
- m_bEnterAnimOn, m_bExitAnimOn,
- m_vecEyeExitEndpoint,
- &m_ViewSmoothingData,
- pFOV );
-}
-
-
-//-----------------------------------------------------------------------------
-// Futzes with the clip planes
-//-----------------------------------------------------------------------------
-void C_PropCrane::GetVehicleClipPlanes( float &flZNear, float &flZFar ) const
-{
- // FIXME: Need something a better long-term, this fixes the buggy.
- flZNear = 6;
-}
-
-
-//-----------------------------------------------------------------------------
-// Renders hud elements
-//-----------------------------------------------------------------------------
-void C_PropCrane::DrawHudElements( )
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : theMins -
-// theMaxs -
-//-----------------------------------------------------------------------------
-void C_PropCrane::GetRenderBounds( Vector &theMins, Vector &theMaxs )
-{
- // This is kind of hacky:( Add 660.0 to the y coordinate of the bounding box to
- // allow for the full extension of the crane arm.
- BaseClass::GetRenderBounds( theMins, theMaxs );
- theMaxs.y += 660.0f;
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "hud.h"
+#include <vgui_controls/Controls.h>
+#include <Color.h>
+#include "c_vehicle_crane.h"
+#include "view.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+int ScreenTransform( const Vector& point, Vector& screen );
+
+IMPLEMENT_CLIENTCLASS_DT(C_PropCrane, DT_PropCrane, CPropCrane)
+ RecvPropEHandle( RECVINFO(m_hPlayer) ),
+ RecvPropBool( RECVINFO(m_bMagnetOn) ),
+ RecvPropBool( RECVINFO( m_bEnterAnimOn ) ),
+ RecvPropBool( RECVINFO( m_bExitAnimOn ) ),
+ RecvPropVector( RECVINFO( m_vecEyeExitEndpoint ) ),
+END_RECV_TABLE()
+
+
+BEGIN_DATADESC( C_PropCrane )
+ DEFINE_EMBEDDED( m_ViewSmoothingData ),
+END_DATADESC()
+
+
+#define ROLL_CURVE_ZERO 5 // roll less than this is clamped to zero
+#define ROLL_CURVE_LINEAR 45 // roll greater than this is copied out
+
+#define PITCH_CURVE_ZERO 10 // pitch less than this is clamped to zero
+#define PITCH_CURVE_LINEAR 45 // pitch greater than this is copied out
+ // spline in between
+
+#define CRANE_FOV 75
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_PropCrane::C_PropCrane( void )
+{
+ memset( &m_ViewSmoothingData, 0, sizeof( m_ViewSmoothingData ) );
+ m_ViewSmoothingData.pVehicle = this;
+ m_ViewSmoothingData.flFOV = CRANE_FOV;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : updateType -
+//-----------------------------------------------------------------------------
+void C_PropCrane::PreDataUpdate( DataUpdateType_t updateType )
+{
+ BaseClass::PreDataUpdate( updateType );
+
+ m_hPrevPlayer = m_hPlayer;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_PropCrane::PostDataUpdate( DataUpdateType_t updateType )
+{
+ BaseClass::PostDataUpdate( updateType );
+
+ // Store off the old shadow direction
+ if ( m_hPlayer && !m_hPrevPlayer )
+ {
+ m_vecOldShadowDir = g_pClientShadowMgr->GetShadowDirection();
+ //Vector vecDown = m_vecOldShadowDir - Vector(0,0,0.5);
+ //VectorNormalize( vecDown );
+ Vector vecDown = Vector(0,0,-1);
+ g_pClientShadowMgr->SetShadowDirection( vecDown );
+ }
+ else if ( !m_hPlayer && m_hPrevPlayer )
+ {
+ g_pClientShadowMgr->SetShadowDirection( m_vecOldShadowDir );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_BaseCombatCharacter *C_PropCrane::GetPassenger( int nRole )
+{
+ if ( nRole == VEHICLE_ROLE_DRIVER )
+ return m_hPlayer.Get();
+
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Returns the role of the passenger
+//-----------------------------------------------------------------------------
+int C_PropCrane::GetPassengerRole( C_BaseCombatCharacter *pPassenger )
+{
+ if ( m_hPlayer.Get() == pPassenger )
+ return VEHICLE_ROLE_DRIVER;
+
+ return VEHICLE_ROLE_NONE;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Modify the player view/camera while in a vehicle
+//-----------------------------------------------------------------------------
+void C_PropCrane::GetVehicleViewPosition( int nRole, Vector *pAbsOrigin, QAngle *pAbsAngles, float *pFOV /*=NULL*/ )
+{
+ SharedVehicleViewSmoothing( m_hPlayer,
+ pAbsOrigin, pAbsAngles,
+ m_bEnterAnimOn, m_bExitAnimOn,
+ m_vecEyeExitEndpoint,
+ &m_ViewSmoothingData,
+ pFOV );
+}
+
+
+//-----------------------------------------------------------------------------
+// Futzes with the clip planes
+//-----------------------------------------------------------------------------
+void C_PropCrane::GetVehicleClipPlanes( float &flZNear, float &flZFar ) const
+{
+ // FIXME: Need something a better long-term, this fixes the buggy.
+ flZNear = 6;
+}
+
+
+//-----------------------------------------------------------------------------
+// Renders hud elements
+//-----------------------------------------------------------------------------
+void C_PropCrane::DrawHudElements( )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : theMins -
+// theMaxs -
+//-----------------------------------------------------------------------------
+void C_PropCrane::GetRenderBounds( Vector &theMins, Vector &theMaxs )
+{
+ // This is kind of hacky:( Add 660.0 to the y coordinate of the bounding box to
+ // allow for the full extension of the crane arm.
+ BaseClass::GetRenderBounds( theMins, theMaxs );
+ theMaxs.y += 660.0f;
+}
+
diff --git a/mp/src/game/client/hl2/c_vehicle_crane.h b/mp/src/game/client/hl2/c_vehicle_crane.h
index 43ece069..81ca6d1e 100644
--- a/mp/src/game/client/hl2/c_vehicle_crane.h
+++ b/mp/src/game/client/hl2/c_vehicle_crane.h
@@ -1,80 +1,80 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "iclientvehicle.h"
-#include "vehicle_viewblend_shared.h"
-
-#ifndef C_VEHICLE_CRANE_H
-#define C_VEHICLE_CRANE_H
-#pragma once
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-class C_PropCrane : public C_BaseAnimating, public IClientVehicle
-{
-
- DECLARE_CLASS( C_PropCrane, C_BaseAnimating );
-
-public:
-
- DECLARE_CLIENTCLASS();
- DECLARE_DATADESC();
-
- C_PropCrane();
-
- void PreDataUpdate( DataUpdateType_t updateType );
- void PostDataUpdate( DataUpdateType_t updateType );
-
- bool IsMagnetOn( void ) { return m_bMagnetOn; }
-
-public:
-
- // IClientVehicle overrides.
- virtual void GetVehicleViewPosition( int nRole, Vector *pOrigin, QAngle *pAngles, float *pFOV =NULL );
- virtual void GetVehicleFOV( float &flFOV ) { flFOV = 0.0f; }
- virtual void DrawHudElements();
- virtual bool IsPassengerUsingStandardWeapons( int nRole = VEHICLE_ROLE_DRIVER ) { return false; }
- virtual void UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd ) {}
- virtual C_BaseCombatCharacter* GetPassenger( int nRole );
- virtual int GetPassengerRole( C_BaseCombatCharacter *pPassenger );
- virtual void GetVehicleClipPlanes( float &flZNear, float &flZFar ) const;
- virtual int GetPrimaryAmmoType() const { return -1; }
- virtual int GetPrimaryAmmoCount() const { return -1; }
- virtual int GetPrimaryAmmoClip() const { return -1; }
- virtual bool PrimaryAmmoUsesClips() const { return false; }
- virtual int GetJoystickResponseCurve() const { return 0; }
-
-public:
-
- // C_BaseEntity overrides.
- virtual IClientVehicle* GetClientVehicle() { return this; }
- virtual C_BaseEntity *GetVehicleEnt() { return this; }
- virtual void SetupMove( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move ) {}
- virtual void ProcessMovement( C_BasePlayer *pPlayer, CMoveData *pMoveData ) {}
- virtual void FinishMove( C_BasePlayer *player, CUserCmd *ucmd, CMoveData *move ) {}
- virtual bool IsPredicted() const { return false; }
- virtual void ItemPostFrame( C_BasePlayer *pPlayer ) {}
- virtual bool IsSelfAnimating() { return false; };
- virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
-
-private:
-
- CHandle<C_BasePlayer> m_hPlayer;
- CHandle<C_BasePlayer> m_hPrevPlayer;
-
- bool m_bEnterAnimOn;
- bool m_bExitAnimOn;
- Vector m_vecEyeExitEndpoint;
-
- bool m_bMagnetOn;
-
- Vector m_vecOldShadowDir;
-
- ViewSmoothingData_t m_ViewSmoothingData;
-};
-
-#endif // C_VEHICLE_CRANE_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "iclientvehicle.h"
+#include "vehicle_viewblend_shared.h"
+
+#ifndef C_VEHICLE_CRANE_H
+#define C_VEHICLE_CRANE_H
+#pragma once
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class C_PropCrane : public C_BaseAnimating, public IClientVehicle
+{
+
+ DECLARE_CLASS( C_PropCrane, C_BaseAnimating );
+
+public:
+
+ DECLARE_CLIENTCLASS();
+ DECLARE_DATADESC();
+
+ C_PropCrane();
+
+ void PreDataUpdate( DataUpdateType_t updateType );
+ void PostDataUpdate( DataUpdateType_t updateType );
+
+ bool IsMagnetOn( void ) { return m_bMagnetOn; }
+
+public:
+
+ // IClientVehicle overrides.
+ virtual void GetVehicleViewPosition( int nRole, Vector *pOrigin, QAngle *pAngles, float *pFOV =NULL );
+ virtual void GetVehicleFOV( float &flFOV ) { flFOV = 0.0f; }
+ virtual void DrawHudElements();
+ virtual bool IsPassengerUsingStandardWeapons( int nRole = VEHICLE_ROLE_DRIVER ) { return false; }
+ virtual void UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd ) {}
+ virtual C_BaseCombatCharacter* GetPassenger( int nRole );
+ virtual int GetPassengerRole( C_BaseCombatCharacter *pPassenger );
+ virtual void GetVehicleClipPlanes( float &flZNear, float &flZFar ) const;
+ virtual int GetPrimaryAmmoType() const { return -1; }
+ virtual int GetPrimaryAmmoCount() const { return -1; }
+ virtual int GetPrimaryAmmoClip() const { return -1; }
+ virtual bool PrimaryAmmoUsesClips() const { return false; }
+ virtual int GetJoystickResponseCurve() const { return 0; }
+
+public:
+
+ // C_BaseEntity overrides.
+ virtual IClientVehicle* GetClientVehicle() { return this; }
+ virtual C_BaseEntity *GetVehicleEnt() { return this; }
+ virtual void SetupMove( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move ) {}
+ virtual void ProcessMovement( C_BasePlayer *pPlayer, CMoveData *pMoveData ) {}
+ virtual void FinishMove( C_BasePlayer *player, CUserCmd *ucmd, CMoveData *move ) {}
+ virtual bool IsPredicted() const { return false; }
+ virtual void ItemPostFrame( C_BasePlayer *pPlayer ) {}
+ virtual bool IsSelfAnimating() { return false; };
+ virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
+
+private:
+
+ CHandle<C_BasePlayer> m_hPlayer;
+ CHandle<C_BasePlayer> m_hPrevPlayer;
+
+ bool m_bEnterAnimOn;
+ bool m_bExitAnimOn;
+ Vector m_vecEyeExitEndpoint;
+
+ bool m_bMagnetOn;
+
+ Vector m_vecOldShadowDir;
+
+ ViewSmoothingData_t m_ViewSmoothingData;
+};
+
+#endif // C_VEHICLE_CRANE_H
diff --git a/mp/src/game/client/hl2/c_vehicle_prisoner_pod.cpp b/mp/src/game/client/hl2/c_vehicle_prisoner_pod.cpp
index 2a1c70ac..1b78bdda 100644
--- a/mp/src/game/client/hl2/c_vehicle_prisoner_pod.cpp
+++ b/mp/src/game/client/hl2/c_vehicle_prisoner_pod.cpp
@@ -1,237 +1,237 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "hud.h"
-#include "c_physicsprop.h"
-#include "iclientvehicle.h"
-#include <vgui_controls/Controls.h>
-#include <Color.h>
-#include "vehicle_viewblend_shared.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-extern float RemapAngleRange( float startInterval, float endInterval, float value );
-
-
-#define ROLL_CURVE_ZERO 5 // roll less than this is clamped to zero
-#define ROLL_CURVE_LINEAR 45 // roll greater than this is copied out
-
-#define PITCH_CURVE_ZERO 10 // pitch less than this is clamped to zero
-#define PITCH_CURVE_LINEAR 45 // pitch greater than this is copied out
- // spline in between
-
-#define POD_VIEW_FOV 90
-#define POD_VIEW_YAW_MIN -60
-#define POD_VIEW_YAW_MAX 60
-#define POD_VIEW_PITCH_MIN -90
-#define POD_VIEW_PITCH_MAX 38 // Don't let players look down and see that the pod is empty
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-class C_PropVehiclePrisonerPod : public C_PhysicsProp, public IClientVehicle
-{
- DECLARE_CLASS( C_PropVehiclePrisonerPod, C_PhysicsProp );
-
-public:
-
- DECLARE_CLIENTCLASS();
- DECLARE_DATADESC();
-
- C_PropVehiclePrisonerPod();
-
- void PreDataUpdate( DataUpdateType_t updateType );
- void PostDataUpdate( DataUpdateType_t updateType );
-
-public:
-
- // IClientVehicle overrides.
- virtual void GetVehicleViewPosition( int nRole, Vector *pOrigin, QAngle *pAngles, float *pFOV = NULL );
- virtual void GetVehicleFOV( float &flFOV )
- {
- flFOV = m_flFOV;
- }
- virtual void DrawHudElements();
- virtual bool IsPassengerUsingStandardWeapons( int nRole = VEHICLE_ROLE_DRIVER ) { return false; }
- virtual void UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd );
- virtual C_BaseCombatCharacter* GetPassenger( int nRole );
- virtual int GetPassengerRole( C_BaseCombatCharacter *pEnt );
- virtual void GetVehicleClipPlanes( float &flZNear, float &flZFar ) const;
- virtual int GetPrimaryAmmoType() const { return -1; }
- virtual int GetPrimaryAmmoCount() const { return -1; }
- virtual int GetPrimaryAmmoClip() const { return -1; }
- virtual bool PrimaryAmmoUsesClips() const { return false; }
- virtual int GetJoystickResponseCurve() const { return 0; }
-
-public:
-
- // C_BaseEntity overrides.
- virtual IClientVehicle* GetClientVehicle() { return this; }
- virtual C_BaseEntity *GetVehicleEnt() { return this; }
- virtual void SetupMove( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move ) {}
- virtual void ProcessMovement( C_BasePlayer *pPlayer, CMoveData *pMoveData ) {}
- virtual void FinishMove( C_BasePlayer *player, CUserCmd *ucmd, CMoveData *move ) {}
- virtual bool IsPredicted() const { return false; }
- virtual void ItemPostFrame( C_BasePlayer *pPlayer ) {}
- virtual bool IsSelfAnimating() { return false; };
-
-private:
-
- CHandle<C_BasePlayer> m_hPlayer;
- CHandle<C_BasePlayer> m_hPrevPlayer;
-
- bool m_bEnterAnimOn;
- bool m_bExitAnimOn;
- Vector m_vecEyeExitEndpoint;
- float m_flFOV; // The current FOV (changes during entry/exit anims).
-
- ViewSmoothingData_t m_ViewSmoothingData;
-};
-
-
-IMPLEMENT_CLIENTCLASS_DT(C_PropVehiclePrisonerPod, DT_PropVehiclePrisonerPod, CPropVehiclePrisonerPod)
- RecvPropEHandle( RECVINFO(m_hPlayer) ),
- RecvPropBool( RECVINFO( m_bEnterAnimOn ) ),
- RecvPropBool( RECVINFO( m_bExitAnimOn ) ),
- RecvPropVector( RECVINFO( m_vecEyeExitEndpoint ) ),
-END_RECV_TABLE()
-
-
-BEGIN_DATADESC( C_PropVehiclePrisonerPod )
- DEFINE_EMBEDDED( m_ViewSmoothingData ),
-END_DATADESC()
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-C_PropVehiclePrisonerPod::C_PropVehiclePrisonerPod( void )
-{
- memset( &m_ViewSmoothingData, 0, sizeof( m_ViewSmoothingData ) );
-
- m_ViewSmoothingData.pVehicle = this;
- m_ViewSmoothingData.bClampEyeAngles = true;
- m_ViewSmoothingData.flPitchCurveZero = PITCH_CURVE_ZERO;
- m_ViewSmoothingData.flPitchCurveLinear = PITCH_CURVE_LINEAR;
- m_ViewSmoothingData.flRollCurveZero = ROLL_CURVE_ZERO;
- m_ViewSmoothingData.flRollCurveLinear = ROLL_CURVE_LINEAR;
- m_ViewSmoothingData.flFOV = POD_VIEW_FOV;
-
- m_flFOV = 0;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : updateType -
-//-----------------------------------------------------------------------------
-void C_PropVehiclePrisonerPod::PreDataUpdate( DataUpdateType_t updateType )
-{
- BaseClass::PreDataUpdate( updateType );
-
- m_hPrevPlayer = m_hPlayer;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_PropVehiclePrisonerPod::PostDataUpdate( DataUpdateType_t updateType )
-{
- BaseClass::PostDataUpdate( updateType );
-
- if ( !m_hPlayer && m_hPrevPlayer )
- {
- // They have just exited the vehicle.
- // Sometimes we never reach the end of our exit anim, such as if the
- // animation doesn't have fadeout 0 specified in the QC, so we fail to
- // catch it in VehicleViewSmoothing. Catch it here instead.
- m_ViewSmoothingData.bWasRunningAnim = false;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-C_BaseCombatCharacter *C_PropVehiclePrisonerPod::GetPassenger( int nRole )
-{
- if ( nRole == VEHICLE_ROLE_DRIVER )
- return m_hPlayer.Get();
-
- return NULL;
-}
-
-
-//-----------------------------------------------------------------------------
-// Returns the role of the passenger
-//-----------------------------------------------------------------------------
-int C_PropVehiclePrisonerPod::GetPassengerRole( C_BaseCombatCharacter *pPassenger )
-{
- if ( m_hPlayer.Get() == pPassenger )
- return VEHICLE_ROLE_DRIVER;
-
- return VEHICLE_ROLE_NONE;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Modify the player view/camera while in a vehicle
-//-----------------------------------------------------------------------------
-void C_PropVehiclePrisonerPod::GetVehicleViewPosition( int nRole, Vector *pAbsOrigin, QAngle *pAbsAngles, float *pFOV /*=NULL*/ )
-{
- SharedVehicleViewSmoothing( m_hPlayer,
- pAbsOrigin, pAbsAngles,
- m_bEnterAnimOn, m_bExitAnimOn,
- m_vecEyeExitEndpoint,
- &m_ViewSmoothingData,
- pFOV );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : pLocalPlayer -
-// pCmd -
-//-----------------------------------------------------------------------------
-void C_PropVehiclePrisonerPod::UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd )
-{
- int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
- Vector vehicleEyeOrigin;
- QAngle vehicleEyeAngles;
- GetAttachmentLocal( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
-
- // Limit the yaw.
- float flAngleDiff = AngleDiff( pCmd->viewangles.y, vehicleEyeAngles.y );
- flAngleDiff = clamp( flAngleDiff, POD_VIEW_YAW_MIN, POD_VIEW_YAW_MAX );
- pCmd->viewangles.y = vehicleEyeAngles.y + flAngleDiff;
-
- // Limit the pitch -- don't let them look down into the empty pod!
- flAngleDiff = AngleDiff( pCmd->viewangles.x, vehicleEyeAngles.x );
- flAngleDiff = clamp( flAngleDiff, POD_VIEW_PITCH_MIN, POD_VIEW_PITCH_MAX );
- pCmd->viewangles.x = vehicleEyeAngles.x + flAngleDiff;
-}
-
-
-//-----------------------------------------------------------------------------
-// Futzes with the clip planes
-//-----------------------------------------------------------------------------
-void C_PropVehiclePrisonerPod::GetVehicleClipPlanes( float &flZNear, float &flZFar ) const
-{
- // Pod doesn't need to adjust the clip planes.
- //flZNear = 6;
-}
-
-
-//-----------------------------------------------------------------------------
-// Renders hud elements
-//-----------------------------------------------------------------------------
-void C_PropVehiclePrisonerPod::DrawHudElements( )
-{
-}
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "hud.h"
+#include "c_physicsprop.h"
+#include "iclientvehicle.h"
+#include <vgui_controls/Controls.h>
+#include <Color.h>
+#include "vehicle_viewblend_shared.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+extern float RemapAngleRange( float startInterval, float endInterval, float value );
+
+
+#define ROLL_CURVE_ZERO 5 // roll less than this is clamped to zero
+#define ROLL_CURVE_LINEAR 45 // roll greater than this is copied out
+
+#define PITCH_CURVE_ZERO 10 // pitch less than this is clamped to zero
+#define PITCH_CURVE_LINEAR 45 // pitch greater than this is copied out
+ // spline in between
+
+#define POD_VIEW_FOV 90
+#define POD_VIEW_YAW_MIN -60
+#define POD_VIEW_YAW_MAX 60
+#define POD_VIEW_PITCH_MIN -90
+#define POD_VIEW_PITCH_MAX 38 // Don't let players look down and see that the pod is empty
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class C_PropVehiclePrisonerPod : public C_PhysicsProp, public IClientVehicle
+{
+ DECLARE_CLASS( C_PropVehiclePrisonerPod, C_PhysicsProp );
+
+public:
+
+ DECLARE_CLIENTCLASS();
+ DECLARE_DATADESC();
+
+ C_PropVehiclePrisonerPod();
+
+ void PreDataUpdate( DataUpdateType_t updateType );
+ void PostDataUpdate( DataUpdateType_t updateType );
+
+public:
+
+ // IClientVehicle overrides.
+ virtual void GetVehicleViewPosition( int nRole, Vector *pOrigin, QAngle *pAngles, float *pFOV = NULL );
+ virtual void GetVehicleFOV( float &flFOV )
+ {
+ flFOV = m_flFOV;
+ }
+ virtual void DrawHudElements();
+ virtual bool IsPassengerUsingStandardWeapons( int nRole = VEHICLE_ROLE_DRIVER ) { return false; }
+ virtual void UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd );
+ virtual C_BaseCombatCharacter* GetPassenger( int nRole );
+ virtual int GetPassengerRole( C_BaseCombatCharacter *pEnt );
+ virtual void GetVehicleClipPlanes( float &flZNear, float &flZFar ) const;
+ virtual int GetPrimaryAmmoType() const { return -1; }
+ virtual int GetPrimaryAmmoCount() const { return -1; }
+ virtual int GetPrimaryAmmoClip() const { return -1; }
+ virtual bool PrimaryAmmoUsesClips() const { return false; }
+ virtual int GetJoystickResponseCurve() const { return 0; }
+
+public:
+
+ // C_BaseEntity overrides.
+ virtual IClientVehicle* GetClientVehicle() { return this; }
+ virtual C_BaseEntity *GetVehicleEnt() { return this; }
+ virtual void SetupMove( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move ) {}
+ virtual void ProcessMovement( C_BasePlayer *pPlayer, CMoveData *pMoveData ) {}
+ virtual void FinishMove( C_BasePlayer *player, CUserCmd *ucmd, CMoveData *move ) {}
+ virtual bool IsPredicted() const { return false; }
+ virtual void ItemPostFrame( C_BasePlayer *pPlayer ) {}
+ virtual bool IsSelfAnimating() { return false; };
+
+private:
+
+ CHandle<C_BasePlayer> m_hPlayer;
+ CHandle<C_BasePlayer> m_hPrevPlayer;
+
+ bool m_bEnterAnimOn;
+ bool m_bExitAnimOn;
+ Vector m_vecEyeExitEndpoint;
+ float m_flFOV; // The current FOV (changes during entry/exit anims).
+
+ ViewSmoothingData_t m_ViewSmoothingData;
+};
+
+
+IMPLEMENT_CLIENTCLASS_DT(C_PropVehiclePrisonerPod, DT_PropVehiclePrisonerPod, CPropVehiclePrisonerPod)
+ RecvPropEHandle( RECVINFO(m_hPlayer) ),
+ RecvPropBool( RECVINFO( m_bEnterAnimOn ) ),
+ RecvPropBool( RECVINFO( m_bExitAnimOn ) ),
+ RecvPropVector( RECVINFO( m_vecEyeExitEndpoint ) ),
+END_RECV_TABLE()
+
+
+BEGIN_DATADESC( C_PropVehiclePrisonerPod )
+ DEFINE_EMBEDDED( m_ViewSmoothingData ),
+END_DATADESC()
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_PropVehiclePrisonerPod::C_PropVehiclePrisonerPod( void )
+{
+ memset( &m_ViewSmoothingData, 0, sizeof( m_ViewSmoothingData ) );
+
+ m_ViewSmoothingData.pVehicle = this;
+ m_ViewSmoothingData.bClampEyeAngles = true;
+ m_ViewSmoothingData.flPitchCurveZero = PITCH_CURVE_ZERO;
+ m_ViewSmoothingData.flPitchCurveLinear = PITCH_CURVE_LINEAR;
+ m_ViewSmoothingData.flRollCurveZero = ROLL_CURVE_ZERO;
+ m_ViewSmoothingData.flRollCurveLinear = ROLL_CURVE_LINEAR;
+ m_ViewSmoothingData.flFOV = POD_VIEW_FOV;
+
+ m_flFOV = 0;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : updateType -
+//-----------------------------------------------------------------------------
+void C_PropVehiclePrisonerPod::PreDataUpdate( DataUpdateType_t updateType )
+{
+ BaseClass::PreDataUpdate( updateType );
+
+ m_hPrevPlayer = m_hPlayer;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_PropVehiclePrisonerPod::PostDataUpdate( DataUpdateType_t updateType )
+{
+ BaseClass::PostDataUpdate( updateType );
+
+ if ( !m_hPlayer && m_hPrevPlayer )
+ {
+ // They have just exited the vehicle.
+ // Sometimes we never reach the end of our exit anim, such as if the
+ // animation doesn't have fadeout 0 specified in the QC, so we fail to
+ // catch it in VehicleViewSmoothing. Catch it here instead.
+ m_ViewSmoothingData.bWasRunningAnim = false;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_BaseCombatCharacter *C_PropVehiclePrisonerPod::GetPassenger( int nRole )
+{
+ if ( nRole == VEHICLE_ROLE_DRIVER )
+ return m_hPlayer.Get();
+
+ return NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// Returns the role of the passenger
+//-----------------------------------------------------------------------------
+int C_PropVehiclePrisonerPod::GetPassengerRole( C_BaseCombatCharacter *pPassenger )
+{
+ if ( m_hPlayer.Get() == pPassenger )
+ return VEHICLE_ROLE_DRIVER;
+
+ return VEHICLE_ROLE_NONE;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Modify the player view/camera while in a vehicle
+//-----------------------------------------------------------------------------
+void C_PropVehiclePrisonerPod::GetVehicleViewPosition( int nRole, Vector *pAbsOrigin, QAngle *pAbsAngles, float *pFOV /*=NULL*/ )
+{
+ SharedVehicleViewSmoothing( m_hPlayer,
+ pAbsOrigin, pAbsAngles,
+ m_bEnterAnimOn, m_bExitAnimOn,
+ m_vecEyeExitEndpoint,
+ &m_ViewSmoothingData,
+ pFOV );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pLocalPlayer -
+// pCmd -
+//-----------------------------------------------------------------------------
+void C_PropVehiclePrisonerPod::UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd )
+{
+ int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
+ Vector vehicleEyeOrigin;
+ QAngle vehicleEyeAngles;
+ GetAttachmentLocal( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
+
+ // Limit the yaw.
+ float flAngleDiff = AngleDiff( pCmd->viewangles.y, vehicleEyeAngles.y );
+ flAngleDiff = clamp( flAngleDiff, POD_VIEW_YAW_MIN, POD_VIEW_YAW_MAX );
+ pCmd->viewangles.y = vehicleEyeAngles.y + flAngleDiff;
+
+ // Limit the pitch -- don't let them look down into the empty pod!
+ flAngleDiff = AngleDiff( pCmd->viewangles.x, vehicleEyeAngles.x );
+ flAngleDiff = clamp( flAngleDiff, POD_VIEW_PITCH_MIN, POD_VIEW_PITCH_MAX );
+ pCmd->viewangles.x = vehicleEyeAngles.x + flAngleDiff;
+}
+
+
+//-----------------------------------------------------------------------------
+// Futzes with the clip planes
+//-----------------------------------------------------------------------------
+void C_PropVehiclePrisonerPod::GetVehicleClipPlanes( float &flZNear, float &flZFar ) const
+{
+ // Pod doesn't need to adjust the clip planes.
+ //flZNear = 6;
+}
+
+
+//-----------------------------------------------------------------------------
+// Renders hud elements
+//-----------------------------------------------------------------------------
+void C_PropVehiclePrisonerPod::DrawHudElements( )
+{
+}
+
+
diff --git a/mp/src/game/client/hl2/c_waterbullet.cpp b/mp/src/game/client/hl2/c_waterbullet.cpp
index 2b05ebee..b4491ca1 100644
--- a/mp/src/game/client/hl2/c_waterbullet.cpp
+++ b/mp/src/game/client/hl2/c_waterbullet.cpp
@@ -1,121 +1,121 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "particles_simple.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-class C_WaterBullet : public C_BaseAnimating
-{
-public:
-
- DECLARE_CLIENTCLASS();
- DECLARE_CLASS( C_WaterBullet, C_BaseAnimating );
-
- C_WaterBullet( void ) {};
- ~C_WaterBullet( void ) {};
-
- void OnDataChanged( DataUpdateType_t updateType )
- {
- BaseClass::OnDataChanged( updateType );
-
- if ( updateType == DATA_UPDATE_CREATED )
- {
- m_pEmitter = CSimpleEmitter::Create( "FX_Bubble" );
- m_pEmitter->SetSortOrigin( GetAbsOrigin() );
-
- m_vecLastOrigin = GetAbsOrigin();
- }
- }
-
-#define BUBBLES_PER_INCH 0.2
-
- void AddEntity( void )
- {
- Vector direction = GetAbsOrigin() - m_vecLastOrigin;
- float flDist = VectorNormalize( direction );
-
- int numBubbles = (int) ( flDist * BUBBLES_PER_INCH );
-
- if ( numBubbles < 1 )
- numBubbles = 1;
-
- // Make bubbles
- SimpleParticle *sParticle;
-
- Vector offset;
-
- for ( int i = 0; i < numBubbles; i++ )
- {
- offset = m_vecLastOrigin + ( direction * ( flDist / numBubbles ) * i ) + RandomVector( -2.5f, 2.5f );
-
- sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_pEmitter->GetPMaterial( "effects/bubble" ), offset );
-
- if ( sParticle )
- {
- sParticle->m_flLifetime = 0.0f;
- sParticle->m_flDieTime = random->RandomFloat( 0.75f, 1.25f );
-
- sParticle->m_flRoll = 0;
- sParticle->m_flRollDelta = 0;
-
- unsigned char color = random->RandomInt( 128, 255 );
-
- sParticle->m_uchColor[0] = color;
- sParticle->m_uchColor[1] = color;
- sParticle->m_uchColor[2] = color;
- sParticle->m_uchStartAlpha = 255;
- sParticle->m_uchEndAlpha = 0;
- sParticle->m_uchStartSize = random->RandomInt( 1, 2 );
- sParticle->m_uchEndSize = sParticle->m_uchStartSize;
-
- sParticle->m_vecVelocity = ( direction * 64.0f ) + Vector( 0, 0, 32 );
- }
-
- sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_pEmitter->GetPMaterial( "effects/splash2" ), offset );
-
- if ( sParticle )
- {
- sParticle->m_flLifetime = 0.0f;
- sParticle->m_flDieTime = 0.2f;
-
- sParticle->m_flRoll = random->RandomInt( 0, 360 );
- sParticle->m_flRollDelta = random->RandomInt( -4, 4 );;
-
- unsigned char color = random->RandomInt( 200, 255 );
-
- sParticle->m_uchColor[0] = color;
- sParticle->m_uchColor[1] = color;
- sParticle->m_uchColor[2] = color;
- sParticle->m_uchStartAlpha = 128;
- sParticle->m_uchEndAlpha = 0;
- sParticle->m_uchStartSize = 2;
- sParticle->m_uchEndSize = sParticle->m_uchStartSize * 4;
-
- sParticle->m_vecVelocity = ( direction * 64.0f ) + Vector( 0, 0, 32 );
- }
- }
-
- // Save our last position
- m_vecLastOrigin = GetAbsOrigin();
-
- BaseClass::AddEntity();
- }
-
- bool ShouldDraw( void ) { return true; }
-
-private:
- C_WaterBullet( const C_WaterBullet & );
-
- CSmartPtr<CSimpleEmitter> m_pEmitter;
-
- Vector m_vecLastOrigin;
-};
-
-IMPLEMENT_CLIENTCLASS_DT( C_WaterBullet, DT_WaterBullet, CWaterBullet )
-END_RECV_TABLE()
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "particles_simple.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+class C_WaterBullet : public C_BaseAnimating
+{
+public:
+
+ DECLARE_CLIENTCLASS();
+ DECLARE_CLASS( C_WaterBullet, C_BaseAnimating );
+
+ C_WaterBullet( void ) {};
+ ~C_WaterBullet( void ) {};
+
+ void OnDataChanged( DataUpdateType_t updateType )
+ {
+ BaseClass::OnDataChanged( updateType );
+
+ if ( updateType == DATA_UPDATE_CREATED )
+ {
+ m_pEmitter = CSimpleEmitter::Create( "FX_Bubble" );
+ m_pEmitter->SetSortOrigin( GetAbsOrigin() );
+
+ m_vecLastOrigin = GetAbsOrigin();
+ }
+ }
+
+#define BUBBLES_PER_INCH 0.2
+
+ void AddEntity( void )
+ {
+ Vector direction = GetAbsOrigin() - m_vecLastOrigin;
+ float flDist = VectorNormalize( direction );
+
+ int numBubbles = (int) ( flDist * BUBBLES_PER_INCH );
+
+ if ( numBubbles < 1 )
+ numBubbles = 1;
+
+ // Make bubbles
+ SimpleParticle *sParticle;
+
+ Vector offset;
+
+ for ( int i = 0; i < numBubbles; i++ )
+ {
+ offset = m_vecLastOrigin + ( direction * ( flDist / numBubbles ) * i ) + RandomVector( -2.5f, 2.5f );
+
+ sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_pEmitter->GetPMaterial( "effects/bubble" ), offset );
+
+ if ( sParticle )
+ {
+ sParticle->m_flLifetime = 0.0f;
+ sParticle->m_flDieTime = random->RandomFloat( 0.75f, 1.25f );
+
+ sParticle->m_flRoll = 0;
+ sParticle->m_flRollDelta = 0;
+
+ unsigned char color = random->RandomInt( 128, 255 );
+
+ sParticle->m_uchColor[0] = color;
+ sParticle->m_uchColor[1] = color;
+ sParticle->m_uchColor[2] = color;
+ sParticle->m_uchStartAlpha = 255;
+ sParticle->m_uchEndAlpha = 0;
+ sParticle->m_uchStartSize = random->RandomInt( 1, 2 );
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize;
+
+ sParticle->m_vecVelocity = ( direction * 64.0f ) + Vector( 0, 0, 32 );
+ }
+
+ sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_pEmitter->GetPMaterial( "effects/splash2" ), offset );
+
+ if ( sParticle )
+ {
+ sParticle->m_flLifetime = 0.0f;
+ sParticle->m_flDieTime = 0.2f;
+
+ sParticle->m_flRoll = random->RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = random->RandomInt( -4, 4 );;
+
+ unsigned char color = random->RandomInt( 200, 255 );
+
+ sParticle->m_uchColor[0] = color;
+ sParticle->m_uchColor[1] = color;
+ sParticle->m_uchColor[2] = color;
+ sParticle->m_uchStartAlpha = 128;
+ sParticle->m_uchEndAlpha = 0;
+ sParticle->m_uchStartSize = 2;
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 4;
+
+ sParticle->m_vecVelocity = ( direction * 64.0f ) + Vector( 0, 0, 32 );
+ }
+ }
+
+ // Save our last position
+ m_vecLastOrigin = GetAbsOrigin();
+
+ BaseClass::AddEntity();
+ }
+
+ bool ShouldDraw( void ) { return true; }
+
+private:
+ C_WaterBullet( const C_WaterBullet & );
+
+ CSmartPtr<CSimpleEmitter> m_pEmitter;
+
+ Vector m_vecLastOrigin;
+};
+
+IMPLEMENT_CLIENTCLASS_DT( C_WaterBullet, DT_WaterBullet, CWaterBullet )
+END_RECV_TABLE()
diff --git a/mp/src/game/client/hl2/c_weapon__stubs_hl2.cpp b/mp/src/game/client/hl2/c_weapon__stubs_hl2.cpp
index 08a24341..68693bfc 100644
--- a/mp/src/game/client/hl2/c_weapon__stubs_hl2.cpp
+++ b/mp/src/game/client/hl2/c_weapon__stubs_hl2.cpp
@@ -1,47 +1,47 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "c_weapon__stubs.h"
-#include "basehlcombatweapon_shared.h"
-#include "c_basehlcombatweapon.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-STUB_WEAPON_CLASS( cycler_weapon, WeaponCycler, C_BaseCombatWeapon );
-
-STUB_WEAPON_CLASS( weapon_binoculars, WeaponBinoculars, C_BaseHLCombatWeapon );
-STUB_WEAPON_CLASS( weapon_bugbait, WeaponBugBait, C_BaseHLCombatWeapon );
-STUB_WEAPON_CLASS( weapon_flaregun, Flaregun, C_BaseHLCombatWeapon );
-STUB_WEAPON_CLASS( weapon_annabelle, WeaponAnnabelle, C_BaseHLCombatWeapon );
-STUB_WEAPON_CLASS( weapon_gauss, WeaponGaussGun, C_BaseHLCombatWeapon );
-STUB_WEAPON_CLASS( weapon_cubemap, WeaponCubemap, C_BaseCombatWeapon );
-STUB_WEAPON_CLASS( weapon_alyxgun, WeaponAlyxGun, C_HLSelectFireMachineGun );
-STUB_WEAPON_CLASS( weapon_citizenpackage, WeaponCitizenPackage, C_BaseHLCombatWeapon );
-STUB_WEAPON_CLASS( weapon_citizensuitcase, WeaponCitizenSuitcase, C_WeaponCitizenPackage );
-
-#ifndef HL2MP
-STUB_WEAPON_CLASS( weapon_ar2, WeaponAR2, C_HLMachineGun );
-STUB_WEAPON_CLASS( weapon_frag, WeaponFrag, C_BaseHLCombatWeapon );
-STUB_WEAPON_CLASS( weapon_rpg, WeaponRPG, C_BaseHLCombatWeapon );
-STUB_WEAPON_CLASS( weapon_pistol, WeaponPistol, C_BaseHLCombatWeapon );
-STUB_WEAPON_CLASS( weapon_shotgun, WeaponShotgun, C_BaseHLCombatWeapon );
-STUB_WEAPON_CLASS( weapon_smg1, WeaponSMG1, C_HLSelectFireMachineGun );
-STUB_WEAPON_CLASS( weapon_357, Weapon357, C_BaseHLCombatWeapon );
-STUB_WEAPON_CLASS( weapon_crossbow, WeaponCrossbow, C_BaseHLCombatWeapon );
-STUB_WEAPON_CLASS( weapon_slam, Weapon_SLAM, C_BaseHLCombatWeapon );
-STUB_WEAPON_CLASS( weapon_crowbar, WeaponCrowbar, C_BaseHLBludgeonWeapon );
-#ifdef HL2_EPISODIC
-STUB_WEAPON_CLASS( weapon_hopwire, WeaponHopwire, C_BaseHLCombatWeapon );
-//STUB_WEAPON_CLASS( weapon_proto1, WeaponProto1, C_BaseHLCombatWeapon );
-#endif
-#ifdef HL2_LOSTCOAST
-STUB_WEAPON_CLASS( weapon_oldmanharpoon, WeaponOldManHarpoon, C_WeaponCitizenPackage );
-#endif
-#endif
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "c_weapon__stubs.h"
+#include "basehlcombatweapon_shared.h"
+#include "c_basehlcombatweapon.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+STUB_WEAPON_CLASS( cycler_weapon, WeaponCycler, C_BaseCombatWeapon );
+
+STUB_WEAPON_CLASS( weapon_binoculars, WeaponBinoculars, C_BaseHLCombatWeapon );
+STUB_WEAPON_CLASS( weapon_bugbait, WeaponBugBait, C_BaseHLCombatWeapon );
+STUB_WEAPON_CLASS( weapon_flaregun, Flaregun, C_BaseHLCombatWeapon );
+STUB_WEAPON_CLASS( weapon_annabelle, WeaponAnnabelle, C_BaseHLCombatWeapon );
+STUB_WEAPON_CLASS( weapon_gauss, WeaponGaussGun, C_BaseHLCombatWeapon );
+STUB_WEAPON_CLASS( weapon_cubemap, WeaponCubemap, C_BaseCombatWeapon );
+STUB_WEAPON_CLASS( weapon_alyxgun, WeaponAlyxGun, C_HLSelectFireMachineGun );
+STUB_WEAPON_CLASS( weapon_citizenpackage, WeaponCitizenPackage, C_BaseHLCombatWeapon );
+STUB_WEAPON_CLASS( weapon_citizensuitcase, WeaponCitizenSuitcase, C_WeaponCitizenPackage );
+
+#ifndef HL2MP
+STUB_WEAPON_CLASS( weapon_ar2, WeaponAR2, C_HLMachineGun );
+STUB_WEAPON_CLASS( weapon_frag, WeaponFrag, C_BaseHLCombatWeapon );
+STUB_WEAPON_CLASS( weapon_rpg, WeaponRPG, C_BaseHLCombatWeapon );
+STUB_WEAPON_CLASS( weapon_pistol, WeaponPistol, C_BaseHLCombatWeapon );
+STUB_WEAPON_CLASS( weapon_shotgun, WeaponShotgun, C_BaseHLCombatWeapon );
+STUB_WEAPON_CLASS( weapon_smg1, WeaponSMG1, C_HLSelectFireMachineGun );
+STUB_WEAPON_CLASS( weapon_357, Weapon357, C_BaseHLCombatWeapon );
+STUB_WEAPON_CLASS( weapon_crossbow, WeaponCrossbow, C_BaseHLCombatWeapon );
+STUB_WEAPON_CLASS( weapon_slam, Weapon_SLAM, C_BaseHLCombatWeapon );
+STUB_WEAPON_CLASS( weapon_crowbar, WeaponCrowbar, C_BaseHLBludgeonWeapon );
+#ifdef HL2_EPISODIC
+STUB_WEAPON_CLASS( weapon_hopwire, WeaponHopwire, C_BaseHLCombatWeapon );
+//STUB_WEAPON_CLASS( weapon_proto1, WeaponProto1, C_BaseHLCombatWeapon );
+#endif
+#ifdef HL2_LOSTCOAST
+STUB_WEAPON_CLASS( weapon_oldmanharpoon, WeaponOldManHarpoon, C_WeaponCitizenPackage );
+#endif
+#endif
+
+
diff --git a/mp/src/game/client/hl2/c_weapon_crossbow.cpp b/mp/src/game/client/hl2/c_weapon_crossbow.cpp
index ca2eedd6..a4860412 100644
--- a/mp/src/game/client/hl2/c_weapon_crossbow.cpp
+++ b/mp/src/game/client/hl2/c_weapon_crossbow.cpp
@@ -1,159 +1,159 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "model_types.h"
-#include "clienteffectprecachesystem.h"
-#include "fx.h"
-#include "c_te_effect_dispatch.h"
-#include "beamdraw.h"
-
-CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectCrossbow )
-CLIENTEFFECT_MATERIAL( "effects/muzzleflash1" )
-CLIENTEFFECT_REGISTER_END()
-
-//
-// Crossbow bolt
-//
-
-class C_CrossbowBolt : public C_BaseCombatCharacter
-{
- DECLARE_CLASS( C_CrossbowBolt, C_BaseCombatCharacter );
- DECLARE_CLIENTCLASS();
-public:
-
- C_CrossbowBolt( void );
-
- virtual RenderGroup_t GetRenderGroup( void )
- {
- // We want to draw translucent bits as well as our main model
- return RENDER_GROUP_TWOPASS;
- }
-
- virtual void ClientThink( void );
-
- virtual void OnDataChanged( DataUpdateType_t updateType );
- virtual int DrawModel( int flags );
-
-private:
-
- C_CrossbowBolt( const C_CrossbowBolt & ); // not defined, not accessible
-
- Vector m_vecLastOrigin;
- bool m_bUpdated;
-};
-
-IMPLEMENT_CLIENTCLASS_DT( C_CrossbowBolt, DT_CrossbowBolt, CCrossbowBolt )
-END_RECV_TABLE()
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-C_CrossbowBolt::C_CrossbowBolt( void )
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : updateType -
-//-----------------------------------------------------------------------------
-void C_CrossbowBolt::OnDataChanged( DataUpdateType_t updateType )
-{
- BaseClass::OnDataChanged( updateType );
-
- if ( updateType == DATA_UPDATE_CREATED )
- {
- m_bUpdated = false;
- m_vecLastOrigin = GetAbsOrigin();
- SetNextClientThink( CLIENT_THINK_ALWAYS );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : flags -
-// Output : int
-//-----------------------------------------------------------------------------
-int C_CrossbowBolt::DrawModel( int flags )
-{
- // See if we're drawing the motion blur
- if ( flags & STUDIO_TRANSPARENCY )
- {
- float color[3];
- IMaterial *pBlurMaterial = materials->FindMaterial( "effects/muzzleflash1", NULL, false );
-
- Vector vecDir = GetAbsOrigin() - m_vecLastOrigin;
- float speed = VectorNormalize( vecDir );
-
- speed = clamp( speed, 0, 32 );
-
- if ( speed > 0 )
- {
- float stepSize = MIN( ( speed * 0.5f ), 4.0f );
-
- Vector spawnPos = GetAbsOrigin() + ( vecDir * 24.0f );
- Vector spawnStep = -vecDir * stepSize;
-
- CMatRenderContextPtr pRenderContext( materials );
- pRenderContext->Bind( pBlurMaterial );
-
- float alpha;
-
- // Draw the motion blurred trail
- for ( int i = 0; i < 20; i++ )
- {
- spawnPos += spawnStep;
-
- alpha = RemapValClamped( i, 5, 11, 0.25f, 0.05f );
-
- color[0] = color[1] = color[2] = alpha;
-
- DrawHalo( pBlurMaterial, spawnPos, 3.0f, color );
- }
- }
-
- if ( gpGlobals->frametime > 0.0f && !m_bUpdated)
- {
- m_bUpdated = true;
- m_vecLastOrigin = GetAbsOrigin();
- }
-
- return 1;
- }
-
- // Draw the normal portion
- return BaseClass::DrawModel( flags );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_CrossbowBolt::ClientThink( void )
-{
- m_bUpdated = false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : &data -
-//-----------------------------------------------------------------------------
-void CrosshairLoadCallback( const CEffectData &data )
-{
- IClientRenderable *pRenderable = data.GetRenderable( );
- if ( !pRenderable )
- return;
-
- Vector position;
- QAngle angles;
-
- // If we found the attachment, emit sparks there
- if ( pRenderable->GetAttachment( data.m_nAttachmentIndex, position, angles ) )
- {
- FX_ElectricSpark( position, 1.0f, 1.0f, NULL );
- }
-}
-
-DECLARE_CLIENT_EFFECT( "CrossbowLoad", CrosshairLoadCallback );
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "model_types.h"
+#include "clienteffectprecachesystem.h"
+#include "fx.h"
+#include "c_te_effect_dispatch.h"
+#include "beamdraw.h"
+
+CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectCrossbow )
+CLIENTEFFECT_MATERIAL( "effects/muzzleflash1" )
+CLIENTEFFECT_REGISTER_END()
+
+//
+// Crossbow bolt
+//
+
+class C_CrossbowBolt : public C_BaseCombatCharacter
+{
+ DECLARE_CLASS( C_CrossbowBolt, C_BaseCombatCharacter );
+ DECLARE_CLIENTCLASS();
+public:
+
+ C_CrossbowBolt( void );
+
+ virtual RenderGroup_t GetRenderGroup( void )
+ {
+ // We want to draw translucent bits as well as our main model
+ return RENDER_GROUP_TWOPASS;
+ }
+
+ virtual void ClientThink( void );
+
+ virtual void OnDataChanged( DataUpdateType_t updateType );
+ virtual int DrawModel( int flags );
+
+private:
+
+ C_CrossbowBolt( const C_CrossbowBolt & ); // not defined, not accessible
+
+ Vector m_vecLastOrigin;
+ bool m_bUpdated;
+};
+
+IMPLEMENT_CLIENTCLASS_DT( C_CrossbowBolt, DT_CrossbowBolt, CCrossbowBolt )
+END_RECV_TABLE()
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_CrossbowBolt::C_CrossbowBolt( void )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : updateType -
+//-----------------------------------------------------------------------------
+void C_CrossbowBolt::OnDataChanged( DataUpdateType_t updateType )
+{
+ BaseClass::OnDataChanged( updateType );
+
+ if ( updateType == DATA_UPDATE_CREATED )
+ {
+ m_bUpdated = false;
+ m_vecLastOrigin = GetAbsOrigin();
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : flags -
+// Output : int
+//-----------------------------------------------------------------------------
+int C_CrossbowBolt::DrawModel( int flags )
+{
+ // See if we're drawing the motion blur
+ if ( flags & STUDIO_TRANSPARENCY )
+ {
+ float color[3];
+ IMaterial *pBlurMaterial = materials->FindMaterial( "effects/muzzleflash1", NULL, false );
+
+ Vector vecDir = GetAbsOrigin() - m_vecLastOrigin;
+ float speed = VectorNormalize( vecDir );
+
+ speed = clamp( speed, 0, 32 );
+
+ if ( speed > 0 )
+ {
+ float stepSize = MIN( ( speed * 0.5f ), 4.0f );
+
+ Vector spawnPos = GetAbsOrigin() + ( vecDir * 24.0f );
+ Vector spawnStep = -vecDir * stepSize;
+
+ CMatRenderContextPtr pRenderContext( materials );
+ pRenderContext->Bind( pBlurMaterial );
+
+ float alpha;
+
+ // Draw the motion blurred trail
+ for ( int i = 0; i < 20; i++ )
+ {
+ spawnPos += spawnStep;
+
+ alpha = RemapValClamped( i, 5, 11, 0.25f, 0.05f );
+
+ color[0] = color[1] = color[2] = alpha;
+
+ DrawHalo( pBlurMaterial, spawnPos, 3.0f, color );
+ }
+ }
+
+ if ( gpGlobals->frametime > 0.0f && !m_bUpdated)
+ {
+ m_bUpdated = true;
+ m_vecLastOrigin = GetAbsOrigin();
+ }
+
+ return 1;
+ }
+
+ // Draw the normal portion
+ return BaseClass::DrawModel( flags );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_CrossbowBolt::ClientThink( void )
+{
+ m_bUpdated = false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &data -
+//-----------------------------------------------------------------------------
+void CrosshairLoadCallback( const CEffectData &data )
+{
+ IClientRenderable *pRenderable = data.GetRenderable( );
+ if ( !pRenderable )
+ return;
+
+ Vector position;
+ QAngle angles;
+
+ // If we found the attachment, emit sparks there
+ if ( pRenderable->GetAttachment( data.m_nAttachmentIndex, position, angles ) )
+ {
+ FX_ElectricSpark( position, 1.0f, 1.0f, NULL );
+ }
+}
+
+DECLARE_CLIENT_EFFECT( "CrossbowLoad", CrosshairLoadCallback );
diff --git a/mp/src/game/client/hl2/c_weapon_gravitygun.cpp b/mp/src/game/client/hl2/c_weapon_gravitygun.cpp
index fbfab05a..a3285842 100644
--- a/mp/src/game/client/hl2/c_weapon_gravitygun.cpp
+++ b/mp/src/game/client/hl2/c_weapon_gravitygun.cpp
@@ -1,166 +1,166 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//===========================================================================//
-
-#include "cbase.h"
-#include "hud.h"
-#include "in_buttons.h"
-#include "beamdraw.h"
-#include "c_weapon__stubs.h"
-#include "clienteffectprecachesystem.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectGravityGun )
-CLIENTEFFECT_MATERIAL( "sprites/physbeam" )
-CLIENTEFFECT_REGISTER_END()
-
-class C_BeamQuadratic : public CDefaultClientRenderable
-{
-public:
- C_BeamQuadratic();
- void Update( C_BaseEntity *pOwner );
-
- // IClientRenderable
- virtual const Vector& GetRenderOrigin( void ) { return m_worldPosition; }
- virtual const QAngle& GetRenderAngles( void ) { return vec3_angle; }
- virtual bool ShouldDraw( void ) { return true; }
- virtual bool IsTransparent( void ) { return true; }
- virtual bool ShouldReceiveProjectedTextures( int flags ) { return false; }
- virtual int DrawModel( int flags );
-
- // Returns the bounds relative to the origin (render bounds)
- virtual void GetRenderBounds( Vector& mins, Vector& maxs )
- {
- // bogus. But it should draw if you can see the end point
- mins.Init(-32,-32,-32);
- maxs.Init(32,32,32);
- }
-
- C_BaseEntity *m_pOwner;
- Vector m_targetPosition;
- Vector m_worldPosition;
- int m_active;
- int m_glueTouching;
- int m_viewModelIndex;
-};
-
-
-class C_WeaponGravityGun : public C_BaseCombatWeapon
-{
- DECLARE_CLASS( C_WeaponGravityGun, C_BaseCombatWeapon );
-public:
- C_WeaponGravityGun() {}
-
- DECLARE_CLIENTCLASS();
- DECLARE_PREDICTABLE();
-
- int KeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding )
- {
- if ( gHUD.m_iKeyBits & IN_ATTACK )
- {
- switch ( keynum )
- {
- case MOUSE_WHEEL_UP:
- gHUD.m_iKeyBits |= IN_WEAPON1;
- return 0;
-
- case MOUSE_WHEEL_DOWN:
- gHUD.m_iKeyBits |= IN_WEAPON2;
- return 0;
- }
- }
-
- // Allow engine to process
- return BaseClass::KeyInput( down, keynum, pszCurrentBinding );
- }
-
- void OnDataChanged( DataUpdateType_t updateType )
- {
- BaseClass::OnDataChanged( updateType );
- m_beam.Update( this );
- }
-
-private:
- C_WeaponGravityGun( const C_WeaponGravityGun & );
-
- C_BeamQuadratic m_beam;
-};
-
-STUB_WEAPON_CLASS_IMPLEMENT( weapon_physgun, C_WeaponGravityGun );
-
-IMPLEMENT_CLIENTCLASS_DT( C_WeaponGravityGun, DT_WeaponGravityGun, CWeaponGravityGun )
- RecvPropVector( RECVINFO_NAME(m_beam.m_targetPosition,m_targetPosition) ),
- RecvPropVector( RECVINFO_NAME(m_beam.m_worldPosition, m_worldPosition) ),
- RecvPropInt( RECVINFO_NAME(m_beam.m_active, m_active) ),
- RecvPropInt( RECVINFO_NAME(m_beam.m_glueTouching, m_glueTouching) ),
- RecvPropInt( RECVINFO_NAME(m_beam.m_viewModelIndex, m_viewModelIndex) ),
-END_RECV_TABLE()
-
-
-C_BeamQuadratic::C_BeamQuadratic()
-{
- m_pOwner = NULL;
-}
-
-void C_BeamQuadratic::Update( C_BaseEntity *pOwner )
-{
- m_pOwner = pOwner;
- if ( m_active )
- {
- if ( m_hRenderHandle == INVALID_CLIENT_RENDER_HANDLE )
- {
- ClientLeafSystem()->AddRenderable( this, RENDER_GROUP_TRANSLUCENT_ENTITY );
- }
- else
- {
- ClientLeafSystem()->RenderableChanged( m_hRenderHandle );
- }
- }
- else if ( !m_active && m_hRenderHandle != INVALID_CLIENT_RENDER_HANDLE )
- {
- ClientLeafSystem()->RemoveRenderable( m_hRenderHandle );
- }
-}
-
-
-int C_BeamQuadratic::DrawModel( int )
-{
- Vector points[3];
- QAngle tmpAngle;
-
- if ( !m_active )
- return 0;
-
- C_BaseEntity *pEnt = cl_entitylist->GetEnt( m_viewModelIndex );
- if ( !pEnt )
- return 0;
- pEnt->GetAttachment( 1, points[0], tmpAngle );
-
- points[1] = 0.5 * (m_targetPosition + points[0]);
-
- // a little noise 11t & 13t should be somewhat non-periodic looking
- //points[1].z += 4*sin( gpGlobals->curtime*11 ) + 5*cos( gpGlobals->curtime*13 );
- points[2] = m_worldPosition;
-
- IMaterial *pMat = materials->FindMaterial( "sprites/physbeam", TEXTURE_GROUP_CLIENT_EFFECTS );
- Vector color;
- if ( m_glueTouching )
- {
- color.Init(1,0,0);
- }
- else
- {
- color.Init(1,1,1);
- }
-
- float scrollOffset = gpGlobals->curtime - (int)gpGlobals->curtime;
- materials->Bind( pMat );
- DrawBeamQuadratic( points[0], points[1], points[2], 13, color, scrollOffset );
- return 1;
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//===========================================================================//
+
+#include "cbase.h"
+#include "hud.h"
+#include "in_buttons.h"
+#include "beamdraw.h"
+#include "c_weapon__stubs.h"
+#include "clienteffectprecachesystem.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectGravityGun )
+CLIENTEFFECT_MATERIAL( "sprites/physbeam" )
+CLIENTEFFECT_REGISTER_END()
+
+class C_BeamQuadratic : public CDefaultClientRenderable
+{
+public:
+ C_BeamQuadratic();
+ void Update( C_BaseEntity *pOwner );
+
+ // IClientRenderable
+ virtual const Vector& GetRenderOrigin( void ) { return m_worldPosition; }
+ virtual const QAngle& GetRenderAngles( void ) { return vec3_angle; }
+ virtual bool ShouldDraw( void ) { return true; }
+ virtual bool IsTransparent( void ) { return true; }
+ virtual bool ShouldReceiveProjectedTextures( int flags ) { return false; }
+ virtual int DrawModel( int flags );
+
+ // Returns the bounds relative to the origin (render bounds)
+ virtual void GetRenderBounds( Vector& mins, Vector& maxs )
+ {
+ // bogus. But it should draw if you can see the end point
+ mins.Init(-32,-32,-32);
+ maxs.Init(32,32,32);
+ }
+
+ C_BaseEntity *m_pOwner;
+ Vector m_targetPosition;
+ Vector m_worldPosition;
+ int m_active;
+ int m_glueTouching;
+ int m_viewModelIndex;
+};
+
+
+class C_WeaponGravityGun : public C_BaseCombatWeapon
+{
+ DECLARE_CLASS( C_WeaponGravityGun, C_BaseCombatWeapon );
+public:
+ C_WeaponGravityGun() {}
+
+ DECLARE_CLIENTCLASS();
+ DECLARE_PREDICTABLE();
+
+ int KeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding )
+ {
+ if ( gHUD.m_iKeyBits & IN_ATTACK )
+ {
+ switch ( keynum )
+ {
+ case MOUSE_WHEEL_UP:
+ gHUD.m_iKeyBits |= IN_WEAPON1;
+ return 0;
+
+ case MOUSE_WHEEL_DOWN:
+ gHUD.m_iKeyBits |= IN_WEAPON2;
+ return 0;
+ }
+ }
+
+ // Allow engine to process
+ return BaseClass::KeyInput( down, keynum, pszCurrentBinding );
+ }
+
+ void OnDataChanged( DataUpdateType_t updateType )
+ {
+ BaseClass::OnDataChanged( updateType );
+ m_beam.Update( this );
+ }
+
+private:
+ C_WeaponGravityGun( const C_WeaponGravityGun & );
+
+ C_BeamQuadratic m_beam;
+};
+
+STUB_WEAPON_CLASS_IMPLEMENT( weapon_physgun, C_WeaponGravityGun );
+
+IMPLEMENT_CLIENTCLASS_DT( C_WeaponGravityGun, DT_WeaponGravityGun, CWeaponGravityGun )
+ RecvPropVector( RECVINFO_NAME(m_beam.m_targetPosition,m_targetPosition) ),
+ RecvPropVector( RECVINFO_NAME(m_beam.m_worldPosition, m_worldPosition) ),
+ RecvPropInt( RECVINFO_NAME(m_beam.m_active, m_active) ),
+ RecvPropInt( RECVINFO_NAME(m_beam.m_glueTouching, m_glueTouching) ),
+ RecvPropInt( RECVINFO_NAME(m_beam.m_viewModelIndex, m_viewModelIndex) ),
+END_RECV_TABLE()
+
+
+C_BeamQuadratic::C_BeamQuadratic()
+{
+ m_pOwner = NULL;
+}
+
+void C_BeamQuadratic::Update( C_BaseEntity *pOwner )
+{
+ m_pOwner = pOwner;
+ if ( m_active )
+ {
+ if ( m_hRenderHandle == INVALID_CLIENT_RENDER_HANDLE )
+ {
+ ClientLeafSystem()->AddRenderable( this, RENDER_GROUP_TRANSLUCENT_ENTITY );
+ }
+ else
+ {
+ ClientLeafSystem()->RenderableChanged( m_hRenderHandle );
+ }
+ }
+ else if ( !m_active && m_hRenderHandle != INVALID_CLIENT_RENDER_HANDLE )
+ {
+ ClientLeafSystem()->RemoveRenderable( m_hRenderHandle );
+ }
+}
+
+
+int C_BeamQuadratic::DrawModel( int )
+{
+ Vector points[3];
+ QAngle tmpAngle;
+
+ if ( !m_active )
+ return 0;
+
+ C_BaseEntity *pEnt = cl_entitylist->GetEnt( m_viewModelIndex );
+ if ( !pEnt )
+ return 0;
+ pEnt->GetAttachment( 1, points[0], tmpAngle );
+
+ points[1] = 0.5 * (m_targetPosition + points[0]);
+
+ // a little noise 11t & 13t should be somewhat non-periodic looking
+ //points[1].z += 4*sin( gpGlobals->curtime*11 ) + 5*cos( gpGlobals->curtime*13 );
+ points[2] = m_worldPosition;
+
+ IMaterial *pMat = materials->FindMaterial( "sprites/physbeam", TEXTURE_GROUP_CLIENT_EFFECTS );
+ Vector color;
+ if ( m_glueTouching )
+ {
+ color.Init(1,0,0);
+ }
+ else
+ {
+ color.Init(1,1,1);
+ }
+
+ float scrollOffset = gpGlobals->curtime - (int)gpGlobals->curtime;
+ materials->Bind( pMat );
+ DrawBeamQuadratic( points[0], points[1], points[2], 13, color, scrollOffset );
+ return 1;
+}
+
diff --git a/mp/src/game/client/hl2/c_weapon_physcannon.cpp b/mp/src/game/client/hl2/c_weapon_physcannon.cpp
index 0953292c..5dff9a28 100644
--- a/mp/src/game/client/hl2/c_weapon_physcannon.cpp
+++ b/mp/src/game/client/hl2/c_weapon_physcannon.cpp
@@ -1,442 +1,442 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "c_weapon__stubs.h"
-#include "c_basehlcombatweapon.h"
-#include "fx.h"
-#include "particles_localspace.h"
-#include "view.h"
-#include "particles_attractor.h"
-
-class C_WeaponPhysCannon: public C_BaseHLCombatWeapon
-{
- DECLARE_CLASS( C_WeaponPhysCannon, C_BaseHLCombatWeapon );
-public:
- C_WeaponPhysCannon( void );
-
- DECLARE_CLIENTCLASS();
- DECLARE_PREDICTABLE();
-
- virtual void OnDataChanged( DataUpdateType_t updateType );
- virtual int DrawModel( int flags );
- virtual void ClientThink( void );
-
- virtual bool ShouldUseLargeViewModelVROverride() OVERRIDE { return true; }
-
-private:
-
- bool SetupEmitter( void );
-
- bool m_bIsCurrentlyUpgrading;
- float m_flTimeForceView;
- float m_flTimeIgnoreForceView;
- bool m_bWasUpgraded;
-
- CSmartPtr<CLocalSpaceEmitter> m_pLocalEmitter;
- CSmartPtr<CSimpleEmitter> m_pEmitter;
- CSmartPtr<CParticleAttractor> m_pAttractor;
-};
-
-STUB_WEAPON_CLASS_IMPLEMENT( weapon_physcannon, C_WeaponPhysCannon );
-
-IMPLEMENT_CLIENTCLASS_DT( C_WeaponPhysCannon, DT_WeaponPhysCannon, CWeaponPhysCannon )
- RecvPropBool( RECVINFO( m_bIsCurrentlyUpgrading ) ),
- RecvPropFloat( RECVINFO( m_flTimeForceView) ),
-END_RECV_TABLE()
-
-//-----------------------------------------------------------------------------
-// Constructor
-//-----------------------------------------------------------------------------
-C_WeaponPhysCannon::C_WeaponPhysCannon( void )
-{
- m_bWasUpgraded = false;
- m_flTimeIgnoreForceView = -1;
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void C_WeaponPhysCannon::OnDataChanged( DataUpdateType_t updateType )
-{
- BaseClass::OnDataChanged( updateType );
- SetNextClientThink( CLIENT_THINK_ALWAYS );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool C_WeaponPhysCannon::SetupEmitter( void )
-{
- if ( !m_pLocalEmitter.IsValid() )
- {
- m_pLocalEmitter = CLocalSpaceEmitter::Create( "physpowerup", GetRefEHandle(), LookupAttachment( "core" ) );
-
- if ( m_pLocalEmitter.IsValid() == false )
- return false;
- }
-
- if ( !m_pAttractor.IsValid() )
- {
- m_pAttractor = CParticleAttractor::Create( vec3_origin, "physpowerup_att" );
-
- if ( m_pAttractor.IsValid() == false )
- return false;
- }
-
- if ( !m_pEmitter.IsValid() )
- {
- m_pEmitter = CSimpleEmitter::Create( "physpowerup_glow" );
-
- if ( m_pEmitter.IsValid() == false )
- return false;
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Sorts the components of a vector
-//-----------------------------------------------------------------------------
-static inline void SortAbsVectorComponents( const Vector& src, int* pVecIdx )
-{
- Vector absVec( fabs(src[0]), fabs(src[1]), fabs(src[2]) );
-
- int maxIdx = (absVec[0] > absVec[1]) ? 0 : 1;
- if (absVec[2] > absVec[maxIdx])
- {
- maxIdx = 2;
- }
-
- // always choose something right-handed....
- switch( maxIdx )
- {
- case 0:
- pVecIdx[0] = 1;
- pVecIdx[1] = 2;
- pVecIdx[2] = 0;
- break;
- case 1:
- pVecIdx[0] = 2;
- pVecIdx[1] = 0;
- pVecIdx[2] = 1;
- break;
- case 2:
- pVecIdx[0] = 0;
- pVecIdx[1] = 1;
- pVecIdx[2] = 2;
- break;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Compute the bounding box's center, size, and basis
-//-----------------------------------------------------------------------------
-void ComputeRenderInfo( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld,
- Vector *pVecAbsOrigin, Vector *pXVec, Vector *pYVec )
-{
- // Compute the center of the hitbox in worldspace
- Vector vecHitboxCenter;
- VectorAdd( pHitBox->bbmin, pHitBox->bbmax, vecHitboxCenter );
- vecHitboxCenter *= 0.5f;
- VectorTransform( vecHitboxCenter, hitboxToWorld, *pVecAbsOrigin );
-
- // Get the object's basis
- Vector vec[3];
- MatrixGetColumn( hitboxToWorld, 0, vec[0] );
- MatrixGetColumn( hitboxToWorld, 1, vec[1] );
- MatrixGetColumn( hitboxToWorld, 2, vec[2] );
-// vec[1] *= -1.0f;
-
- Vector vecViewDir;
- VectorSubtract( CurrentViewOrigin(), *pVecAbsOrigin, vecViewDir );
- VectorNormalize( vecViewDir );
-
- // Project the shadow casting direction into the space of the hitbox
- Vector localViewDir;
- localViewDir[0] = DotProduct( vec[0], vecViewDir );
- localViewDir[1] = DotProduct( vec[1], vecViewDir );
- localViewDir[2] = DotProduct( vec[2], vecViewDir );
-
- // Figure out which vector has the largest component perpendicular
- // to the view direction...
- // Sort by how perpendicular it is
- int vecIdx[3];
- SortAbsVectorComponents( localViewDir, vecIdx );
-
- // Here's our hitbox basis vectors; namely the ones that are
- // most perpendicular to the view direction
- *pXVec = vec[vecIdx[0]];
- *pYVec = vec[vecIdx[1]];
-
- // Project them into a plane perpendicular to the view direction
- *pXVec -= vecViewDir * DotProduct( vecViewDir, *pXVec );
- *pYVec -= vecViewDir * DotProduct( vecViewDir, *pYVec );
- VectorNormalize( *pXVec );
- VectorNormalize( *pYVec );
-
- // Compute the hitbox size
- Vector boxSize;
- VectorSubtract( pHitBox->bbmax, pHitBox->bbmin, boxSize );
-
- // We project the two longest sides into the vectors perpendicular
- // to the projection direction, then add in the projection of the perp direction
- Vector2D size( boxSize[vecIdx[0]], boxSize[vecIdx[1]] );
- size.x *= fabs( DotProduct( vec[vecIdx[0]], *pXVec ) );
- size.y *= fabs( DotProduct( vec[vecIdx[1]], *pYVec ) );
-
- // Add the third component into x and y
- size.x += boxSize[vecIdx[2]] * fabs( DotProduct( vec[vecIdx[2]], *pXVec ) );
- size.y += boxSize[vecIdx[2]] * fabs( DotProduct( vec[vecIdx[2]], *pYVec ) );
-
- // Bloat a bit, since the shadow wants to extend outside the model a bit
- size *= 2.0f;
-
- // Clamp the minimum size
- Vector2DMax( size, Vector2D(10.0f, 10.0f), size );
-
- // Factor the size into the xvec + yvec
- (*pXVec) *= size.x * 0.5f;
- (*pYVec) *= size.y * 0.5f;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : flags -
-// Output : int
-//-----------------------------------------------------------------------------
-int C_WeaponPhysCannon::DrawModel( int flags )
-{
- // If we're not ugrading, don't do anything special
- if ( m_bIsCurrentlyUpgrading == false && m_bWasUpgraded == false )
- return BaseClass::DrawModel( flags );
-
- if ( gpGlobals->frametime == 0 )
- return BaseClass::DrawModel( flags );
-
- if ( !m_bReadyToDraw )
- return 0;
-
- m_bWasUpgraded = true;
-
- // Create the particle emitter if it's not already
- if ( SetupEmitter() )
- {
- // Add the power-up particles
-
- // See if we should draw
- if ( m_bReadyToDraw == false )
- return 0;
-
- C_BaseAnimating *pAnimating = GetBaseAnimating();
- if (!pAnimating)
- return 0;
-
- matrix3x4_t *hitboxbones[MAXSTUDIOBONES];
- if ( !pAnimating->HitboxToWorldTransforms( hitboxbones ) )
- return 0;
-
- studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() );
- if (!pStudioHdr)
- return false;
-
- mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() );
- if ( !set )
- return false;
-
- int i;
-
- float fadePerc = 1.0f;
-
- if ( m_bIsCurrentlyUpgrading )
- {
- Vector vecSkew = vec3_origin;
-
- // Skew the particles in front or in back of their targets
- vecSkew = CurrentViewForward() * 4.0f;
-
- float spriteScale = 1.0f;
- spriteScale = clamp( spriteScale, 0.75f, 1.0f );
-
- SimpleParticle *sParticle;
-
- for ( i = 0; i < set->numhitboxes; ++i )
- {
- Vector vecAbsOrigin, xvec, yvec;
- mstudiobbox_t *pBox = set->pHitbox(i);
- ComputeRenderInfo( pBox, *hitboxbones[pBox->bone], &vecAbsOrigin, &xvec, &yvec );
-
- Vector offset;
- Vector xDir, yDir;
-
- xDir = xvec;
- float xScale = VectorNormalize( xDir ) * 0.75f;
-
- yDir = yvec;
- float yScale = VectorNormalize( yDir ) * 0.75f;
-
- int numParticles = clamp( 4.0f * fadePerc, 1, 3 );
-
- for ( int j = 0; j < numParticles; j++ )
- {
- offset = xDir * Helper_RandomFloat( -xScale*0.5f, xScale*0.5f ) + yDir * Helper_RandomFloat( -yScale*0.5f, yScale*0.5f );
- offset += vecSkew;
-
- sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_pEmitter->GetPMaterial( "effects/combinemuzzle1" ), vecAbsOrigin + offset );
-
- if ( sParticle == NULL )
- return 1;
-
- sParticle->m_vecVelocity = vec3_origin;
- sParticle->m_uchStartSize = 16.0f * spriteScale;
- sParticle->m_flDieTime = 0.2f;
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
- sParticle->m_flRollDelta = Helper_RandomFloat( -2.0f, 2.0f );
-
- float alpha = 40;
-
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = 0;
- sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2;
- }
- }
- }
- }
-
- int attachment = LookupAttachment( "core" );
- Vector coreOrigin;
- QAngle coreAngles;
-
- GetAttachment( attachment, coreOrigin, coreAngles );
-
- SimpleParticle *sParticle;
-
- // Do the core effects
- for ( int i = 0; i < 4; i++ )
- {
- sParticle = (SimpleParticle *) m_pLocalEmitter->AddParticle( sizeof(SimpleParticle), m_pLocalEmitter->GetPMaterial( "effects/strider_muzzle" ), vec3_origin );
-
- if ( sParticle == NULL )
- return 1;
-
- sParticle->m_vecVelocity = vec3_origin;
- sParticle->m_flDieTime = 0.1f;
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
- sParticle->m_flRollDelta = 0.0f;
-
- float alpha = 255;
-
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = 0;
-
- if ( i < 2 )
- {
- sParticle->m_uchStartSize = random->RandomFloat( 1, 2 ) * (i+1);
- sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
- }
- else
- {
- if ( random->RandomInt( 0, 20 ) == 0 )
- {
- sParticle->m_uchStartSize = random->RandomFloat( 1, 2 ) * (i+1);
- sParticle->m_uchEndSize = sParticle->m_uchStartSize * 4.0f;
- sParticle->m_flDieTime = 0.25f;
- }
- else
- {
- sParticle->m_uchStartSize = random->RandomFloat( 1, 2 ) * (i+1);
- sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
- }
- }
- }
-
- if ( m_bWasUpgraded && m_bIsCurrentlyUpgrading )
- {
- // Update our attractor point
- m_pAttractor->SetAttractorOrigin( coreOrigin );
-
- Vector offset;
-
- for ( int i = 0; i < 4; i++ )
- {
- offset = coreOrigin + RandomVector( -32.0f, 32.0f );
-
- sParticle = (SimpleParticle *) m_pAttractor->AddParticle( sizeof(SimpleParticle), m_pAttractor->GetPMaterial( "effects/strider_muzzle" ), offset );
-
- if ( sParticle == NULL )
- return 1;
-
- sParticle->m_vecVelocity = Vector(0,0,8);
- sParticle->m_flDieTime = 0.5f;
- sParticle->m_flLifetime = 0.0f;
-
- sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
- sParticle->m_flRollDelta = 0.0f;
-
- float alpha = 255;
-
- sParticle->m_uchColor[0] = alpha;
- sParticle->m_uchColor[1] = alpha;
- sParticle->m_uchColor[2] = alpha;
- sParticle->m_uchStartAlpha = alpha;
- sParticle->m_uchEndAlpha = 0;
-
- sParticle->m_uchStartSize = random->RandomFloat( 1, 2 );
- sParticle->m_uchEndSize = 0;
- }
- }
-
- return BaseClass::DrawModel( flags );
-}
-
-//---------------------------------------------------------
-// On 360, raise up the player's view if the server has
-// asked us to.
-//---------------------------------------------------------
-#define PHYSCANNON_RAISE_VIEW_GOAL 0.0f
-void C_WeaponPhysCannon::ClientThink( void )
-{
- if( m_flTimeIgnoreForceView > gpGlobals->curtime )
- return;
-
- float flTime = (m_flTimeForceView - gpGlobals->curtime);
-
- if( flTime < 0.0f )
- return;
-
- float flDT = 1.0f - flTime;
- if( flDT > 0.0f )
- {
- QAngle viewangles;
- engine->GetViewAngles( viewangles );
-
- if( viewangles.x > PHYSCANNON_RAISE_VIEW_GOAL + 1.0f )
- {
- float flDelta = PHYSCANNON_RAISE_VIEW_GOAL - viewangles.x;
- viewangles.x += (flDelta * flDT);
- engine->SetViewAngles(viewangles);
- }
- else
- {
- // We've reached our goal. Ignore the forced view angles for now.
- m_flTimeIgnoreForceView = m_flTimeForceView + 0.1f;
- }
- }
-
- return BaseClass::ClientThink();
-}
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "c_weapon__stubs.h"
+#include "c_basehlcombatweapon.h"
+#include "fx.h"
+#include "particles_localspace.h"
+#include "view.h"
+#include "particles_attractor.h"
+
+class C_WeaponPhysCannon: public C_BaseHLCombatWeapon
+{
+ DECLARE_CLASS( C_WeaponPhysCannon, C_BaseHLCombatWeapon );
+public:
+ C_WeaponPhysCannon( void );
+
+ DECLARE_CLIENTCLASS();
+ DECLARE_PREDICTABLE();
+
+ virtual void OnDataChanged( DataUpdateType_t updateType );
+ virtual int DrawModel( int flags );
+ virtual void ClientThink( void );
+
+ virtual bool ShouldUseLargeViewModelVROverride() OVERRIDE { return true; }
+
+private:
+
+ bool SetupEmitter( void );
+
+ bool m_bIsCurrentlyUpgrading;
+ float m_flTimeForceView;
+ float m_flTimeIgnoreForceView;
+ bool m_bWasUpgraded;
+
+ CSmartPtr<CLocalSpaceEmitter> m_pLocalEmitter;
+ CSmartPtr<CSimpleEmitter> m_pEmitter;
+ CSmartPtr<CParticleAttractor> m_pAttractor;
+};
+
+STUB_WEAPON_CLASS_IMPLEMENT( weapon_physcannon, C_WeaponPhysCannon );
+
+IMPLEMENT_CLIENTCLASS_DT( C_WeaponPhysCannon, DT_WeaponPhysCannon, CWeaponPhysCannon )
+ RecvPropBool( RECVINFO( m_bIsCurrentlyUpgrading ) ),
+ RecvPropFloat( RECVINFO( m_flTimeForceView) ),
+END_RECV_TABLE()
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+C_WeaponPhysCannon::C_WeaponPhysCannon( void )
+{
+ m_bWasUpgraded = false;
+ m_flTimeIgnoreForceView = -1;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void C_WeaponPhysCannon::OnDataChanged( DataUpdateType_t updateType )
+{
+ BaseClass::OnDataChanged( updateType );
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool C_WeaponPhysCannon::SetupEmitter( void )
+{
+ if ( !m_pLocalEmitter.IsValid() )
+ {
+ m_pLocalEmitter = CLocalSpaceEmitter::Create( "physpowerup", GetRefEHandle(), LookupAttachment( "core" ) );
+
+ if ( m_pLocalEmitter.IsValid() == false )
+ return false;
+ }
+
+ if ( !m_pAttractor.IsValid() )
+ {
+ m_pAttractor = CParticleAttractor::Create( vec3_origin, "physpowerup_att" );
+
+ if ( m_pAttractor.IsValid() == false )
+ return false;
+ }
+
+ if ( !m_pEmitter.IsValid() )
+ {
+ m_pEmitter = CSimpleEmitter::Create( "physpowerup_glow" );
+
+ if ( m_pEmitter.IsValid() == false )
+ return false;
+ }
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Sorts the components of a vector
+//-----------------------------------------------------------------------------
+static inline void SortAbsVectorComponents( const Vector& src, int* pVecIdx )
+{
+ Vector absVec( fabs(src[0]), fabs(src[1]), fabs(src[2]) );
+
+ int maxIdx = (absVec[0] > absVec[1]) ? 0 : 1;
+ if (absVec[2] > absVec[maxIdx])
+ {
+ maxIdx = 2;
+ }
+
+ // always choose something right-handed....
+ switch( maxIdx )
+ {
+ case 0:
+ pVecIdx[0] = 1;
+ pVecIdx[1] = 2;
+ pVecIdx[2] = 0;
+ break;
+ case 1:
+ pVecIdx[0] = 2;
+ pVecIdx[1] = 0;
+ pVecIdx[2] = 1;
+ break;
+ case 2:
+ pVecIdx[0] = 0;
+ pVecIdx[1] = 1;
+ pVecIdx[2] = 2;
+ break;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Compute the bounding box's center, size, and basis
+//-----------------------------------------------------------------------------
+void ComputeRenderInfo( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld,
+ Vector *pVecAbsOrigin, Vector *pXVec, Vector *pYVec )
+{
+ // Compute the center of the hitbox in worldspace
+ Vector vecHitboxCenter;
+ VectorAdd( pHitBox->bbmin, pHitBox->bbmax, vecHitboxCenter );
+ vecHitboxCenter *= 0.5f;
+ VectorTransform( vecHitboxCenter, hitboxToWorld, *pVecAbsOrigin );
+
+ // Get the object's basis
+ Vector vec[3];
+ MatrixGetColumn( hitboxToWorld, 0, vec[0] );
+ MatrixGetColumn( hitboxToWorld, 1, vec[1] );
+ MatrixGetColumn( hitboxToWorld, 2, vec[2] );
+// vec[1] *= -1.0f;
+
+ Vector vecViewDir;
+ VectorSubtract( CurrentViewOrigin(), *pVecAbsOrigin, vecViewDir );
+ VectorNormalize( vecViewDir );
+
+ // Project the shadow casting direction into the space of the hitbox
+ Vector localViewDir;
+ localViewDir[0] = DotProduct( vec[0], vecViewDir );
+ localViewDir[1] = DotProduct( vec[1], vecViewDir );
+ localViewDir[2] = DotProduct( vec[2], vecViewDir );
+
+ // Figure out which vector has the largest component perpendicular
+ // to the view direction...
+ // Sort by how perpendicular it is
+ int vecIdx[3];
+ SortAbsVectorComponents( localViewDir, vecIdx );
+
+ // Here's our hitbox basis vectors; namely the ones that are
+ // most perpendicular to the view direction
+ *pXVec = vec[vecIdx[0]];
+ *pYVec = vec[vecIdx[1]];
+
+ // Project them into a plane perpendicular to the view direction
+ *pXVec -= vecViewDir * DotProduct( vecViewDir, *pXVec );
+ *pYVec -= vecViewDir * DotProduct( vecViewDir, *pYVec );
+ VectorNormalize( *pXVec );
+ VectorNormalize( *pYVec );
+
+ // Compute the hitbox size
+ Vector boxSize;
+ VectorSubtract( pHitBox->bbmax, pHitBox->bbmin, boxSize );
+
+ // We project the two longest sides into the vectors perpendicular
+ // to the projection direction, then add in the projection of the perp direction
+ Vector2D size( boxSize[vecIdx[0]], boxSize[vecIdx[1]] );
+ size.x *= fabs( DotProduct( vec[vecIdx[0]], *pXVec ) );
+ size.y *= fabs( DotProduct( vec[vecIdx[1]], *pYVec ) );
+
+ // Add the third component into x and y
+ size.x += boxSize[vecIdx[2]] * fabs( DotProduct( vec[vecIdx[2]], *pXVec ) );
+ size.y += boxSize[vecIdx[2]] * fabs( DotProduct( vec[vecIdx[2]], *pYVec ) );
+
+ // Bloat a bit, since the shadow wants to extend outside the model a bit
+ size *= 2.0f;
+
+ // Clamp the minimum size
+ Vector2DMax( size, Vector2D(10.0f, 10.0f), size );
+
+ // Factor the size into the xvec + yvec
+ (*pXVec) *= size.x * 0.5f;
+ (*pYVec) *= size.y * 0.5f;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : flags -
+// Output : int
+//-----------------------------------------------------------------------------
+int C_WeaponPhysCannon::DrawModel( int flags )
+{
+ // If we're not ugrading, don't do anything special
+ if ( m_bIsCurrentlyUpgrading == false && m_bWasUpgraded == false )
+ return BaseClass::DrawModel( flags );
+
+ if ( gpGlobals->frametime == 0 )
+ return BaseClass::DrawModel( flags );
+
+ if ( !m_bReadyToDraw )
+ return 0;
+
+ m_bWasUpgraded = true;
+
+ // Create the particle emitter if it's not already
+ if ( SetupEmitter() )
+ {
+ // Add the power-up particles
+
+ // See if we should draw
+ if ( m_bReadyToDraw == false )
+ return 0;
+
+ C_BaseAnimating *pAnimating = GetBaseAnimating();
+ if (!pAnimating)
+ return 0;
+
+ matrix3x4_t *hitboxbones[MAXSTUDIOBONES];
+ if ( !pAnimating->HitboxToWorldTransforms( hitboxbones ) )
+ return 0;
+
+ studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() );
+ if (!pStudioHdr)
+ return false;
+
+ mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() );
+ if ( !set )
+ return false;
+
+ int i;
+
+ float fadePerc = 1.0f;
+
+ if ( m_bIsCurrentlyUpgrading )
+ {
+ Vector vecSkew = vec3_origin;
+
+ // Skew the particles in front or in back of their targets
+ vecSkew = CurrentViewForward() * 4.0f;
+
+ float spriteScale = 1.0f;
+ spriteScale = clamp( spriteScale, 0.75f, 1.0f );
+
+ SimpleParticle *sParticle;
+
+ for ( i = 0; i < set->numhitboxes; ++i )
+ {
+ Vector vecAbsOrigin, xvec, yvec;
+ mstudiobbox_t *pBox = set->pHitbox(i);
+ ComputeRenderInfo( pBox, *hitboxbones[pBox->bone], &vecAbsOrigin, &xvec, &yvec );
+
+ Vector offset;
+ Vector xDir, yDir;
+
+ xDir = xvec;
+ float xScale = VectorNormalize( xDir ) * 0.75f;
+
+ yDir = yvec;
+ float yScale = VectorNormalize( yDir ) * 0.75f;
+
+ int numParticles = clamp( 4.0f * fadePerc, 1, 3 );
+
+ for ( int j = 0; j < numParticles; j++ )
+ {
+ offset = xDir * Helper_RandomFloat( -xScale*0.5f, xScale*0.5f ) + yDir * Helper_RandomFloat( -yScale*0.5f, yScale*0.5f );
+ offset += vecSkew;
+
+ sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_pEmitter->GetPMaterial( "effects/combinemuzzle1" ), vecAbsOrigin + offset );
+
+ if ( sParticle == NULL )
+ return 1;
+
+ sParticle->m_vecVelocity = vec3_origin;
+ sParticle->m_uchStartSize = 16.0f * spriteScale;
+ sParticle->m_flDieTime = 0.2f;
+ sParticle->m_flLifetime = 0.0f;
+
+ sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = Helper_RandomFloat( -2.0f, 2.0f );
+
+ float alpha = 40;
+
+ sParticle->m_uchColor[0] = alpha;
+ sParticle->m_uchColor[1] = alpha;
+ sParticle->m_uchColor[2] = alpha;
+ sParticle->m_uchStartAlpha = alpha;
+ sParticle->m_uchEndAlpha = 0;
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2;
+ }
+ }
+ }
+ }
+
+ int attachment = LookupAttachment( "core" );
+ Vector coreOrigin;
+ QAngle coreAngles;
+
+ GetAttachment( attachment, coreOrigin, coreAngles );
+
+ SimpleParticle *sParticle;
+
+ // Do the core effects
+ for ( int i = 0; i < 4; i++ )
+ {
+ sParticle = (SimpleParticle *) m_pLocalEmitter->AddParticle( sizeof(SimpleParticle), m_pLocalEmitter->GetPMaterial( "effects/strider_muzzle" ), vec3_origin );
+
+ if ( sParticle == NULL )
+ return 1;
+
+ sParticle->m_vecVelocity = vec3_origin;
+ sParticle->m_flDieTime = 0.1f;
+ sParticle->m_flLifetime = 0.0f;
+
+ sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = 0.0f;
+
+ float alpha = 255;
+
+ sParticle->m_uchColor[0] = alpha;
+ sParticle->m_uchColor[1] = alpha;
+ sParticle->m_uchColor[2] = alpha;
+ sParticle->m_uchStartAlpha = alpha;
+ sParticle->m_uchEndAlpha = 0;
+
+ if ( i < 2 )
+ {
+ sParticle->m_uchStartSize = random->RandomFloat( 1, 2 ) * (i+1);
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
+ }
+ else
+ {
+ if ( random->RandomInt( 0, 20 ) == 0 )
+ {
+ sParticle->m_uchStartSize = random->RandomFloat( 1, 2 ) * (i+1);
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 4.0f;
+ sParticle->m_flDieTime = 0.25f;
+ }
+ else
+ {
+ sParticle->m_uchStartSize = random->RandomFloat( 1, 2 ) * (i+1);
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
+ }
+ }
+ }
+
+ if ( m_bWasUpgraded && m_bIsCurrentlyUpgrading )
+ {
+ // Update our attractor point
+ m_pAttractor->SetAttractorOrigin( coreOrigin );
+
+ Vector offset;
+
+ for ( int i = 0; i < 4; i++ )
+ {
+ offset = coreOrigin + RandomVector( -32.0f, 32.0f );
+
+ sParticle = (SimpleParticle *) m_pAttractor->AddParticle( sizeof(SimpleParticle), m_pAttractor->GetPMaterial( "effects/strider_muzzle" ), offset );
+
+ if ( sParticle == NULL )
+ return 1;
+
+ sParticle->m_vecVelocity = Vector(0,0,8);
+ sParticle->m_flDieTime = 0.5f;
+ sParticle->m_flLifetime = 0.0f;
+
+ sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = 0.0f;
+
+ float alpha = 255;
+
+ sParticle->m_uchColor[0] = alpha;
+ sParticle->m_uchColor[1] = alpha;
+ sParticle->m_uchColor[2] = alpha;
+ sParticle->m_uchStartAlpha = alpha;
+ sParticle->m_uchEndAlpha = 0;
+
+ sParticle->m_uchStartSize = random->RandomFloat( 1, 2 );
+ sParticle->m_uchEndSize = 0;
+ }
+ }
+
+ return BaseClass::DrawModel( flags );
+}
+
+//---------------------------------------------------------
+// On 360, raise up the player's view if the server has
+// asked us to.
+//---------------------------------------------------------
+#define PHYSCANNON_RAISE_VIEW_GOAL 0.0f
+void C_WeaponPhysCannon::ClientThink( void )
+{
+ if( m_flTimeIgnoreForceView > gpGlobals->curtime )
+ return;
+
+ float flTime = (m_flTimeForceView - gpGlobals->curtime);
+
+ if( flTime < 0.0f )
+ return;
+
+ float flDT = 1.0f - flTime;
+ if( flDT > 0.0f )
+ {
+ QAngle viewangles;
+ engine->GetViewAngles( viewangles );
+
+ if( viewangles.x > PHYSCANNON_RAISE_VIEW_GOAL + 1.0f )
+ {
+ float flDelta = PHYSCANNON_RAISE_VIEW_GOAL - viewangles.x;
+ viewangles.x += (flDelta * flDT);
+ engine->SetViewAngles(viewangles);
+ }
+ else
+ {
+ // We've reached our goal. Ignore the forced view angles for now.
+ m_flTimeIgnoreForceView = m_flTimeForceView + 0.1f;
+ }
+ }
+
+ return BaseClass::ClientThink();
+}
+
+
diff --git a/mp/src/game/client/hl2/c_weapon_stunstick.cpp b/mp/src/game/client/hl2/c_weapon_stunstick.cpp
index ef4061cf..28359c33 100644
--- a/mp/src/game/client/hl2/c_weapon_stunstick.cpp
+++ b/mp/src/game/client/hl2/c_weapon_stunstick.cpp
@@ -1,187 +1,187 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-#include "cbase.h"
-#include "c_basehlcombatweapon.h"
-#include "iviewrender_beams.h"
-#include "beam_shared.h"
-#include "c_weapon__stubs.h"
-#include "materialsystem/imaterial.h"
-#include "clienteffectprecachesystem.h"
-#include "beamdraw.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectStunstick )
-CLIENTEFFECT_MATERIAL( "effects/stunstick" )
-CLIENTEFFECT_REGISTER_END()
-
-class C_WeaponStunStick : public C_BaseHLBludgeonWeapon
-{
- DECLARE_CLASS( C_WeaponStunStick, C_BaseHLBludgeonWeapon );
-public:
- DECLARE_CLIENTCLASS();
- DECLARE_PREDICTABLE();
-
- int DrawModel( int flags )
- {
- //FIXME: This sucks, but I can't easily create temp ents...
-
- if ( m_bActive )
- {
- Vector vecOrigin;
- QAngle vecAngles;
- float color[3];
-
- color[0] = color[1] = color[2] = random->RandomFloat( 0.1f, 0.2f );
-
- GetAttachment( 1, vecOrigin, vecAngles );
-
- Vector vForward;
- AngleVectors( vecAngles, &vForward );
-
- Vector vEnd = vecOrigin - vForward * 1.0f;
-
- IMaterial *pMaterial = materials->FindMaterial( "effects/stunstick", NULL, false );
-
- CMatRenderContextPtr pRenderContext( materials );
- pRenderContext->Bind( pMaterial );
- DrawHalo( pMaterial, vEnd, random->RandomFloat( 4.0f, 6.0f ), color );
-
- color[0] = color[1] = color[2] = random->RandomFloat( 0.9f, 1.0f );
-
- DrawHalo( pMaterial, vEnd, random->RandomFloat( 2.0f, 3.0f ), color );
- }
-
- return BaseClass::DrawModel( flags );
- }
-
- // Do part of our effect
- void ClientThink( void )
- {
- // Update our effects
- if ( m_bActive &&
- gpGlobals->frametime != 0.0f &&
- ( random->RandomInt( 0, 5 ) == 0 ) )
- {
- Vector vecOrigin;
- QAngle vecAngles;
-
- GetAttachment( 1, vecOrigin, vecAngles );
-
- Vector vForward;
- AngleVectors( vecAngles, &vForward );
-
- Vector vEnd = vecOrigin - vForward * 1.0f;
-
- // Inner beams
- BeamInfo_t beamInfo;
-
- beamInfo.m_vecStart = vEnd;
- Vector offset = RandomVector( -6, 2 );
-
- offset += Vector(2,2,2);
- beamInfo.m_vecEnd = vecOrigin + offset;
-
- beamInfo.m_pStartEnt= cl_entitylist->GetEnt( BEAMENT_ENTITY( entindex() ) );
- beamInfo.m_pEndEnt = cl_entitylist->GetEnt( BEAMENT_ENTITY( entindex() ) );
- beamInfo.m_nStartAttachment = 1;
- beamInfo.m_nEndAttachment = 2;
-
- beamInfo.m_nType = TE_BEAMTESLA;
- beamInfo.m_pszModelName = "sprites/physbeam.vmt";
- beamInfo.m_flHaloScale = 0.0f;
- beamInfo.m_flLife = 0.01f;
- beamInfo.m_flWidth = random->RandomFloat( 0.5f, 2.0f );
- beamInfo.m_flEndWidth = 0;
- beamInfo.m_flFadeLength = 0.0f;
- beamInfo.m_flAmplitude = random->RandomFloat( 1, 2 );
- beamInfo.m_flBrightness = 255.0;
- beamInfo.m_flSpeed = 0.0;
- beamInfo.m_nStartFrame = 0.0;
- beamInfo.m_flFrameRate = 1.0f;
- beamInfo.m_flRed = 255.0f;;
- beamInfo.m_flGreen = 255.0f;
- beamInfo.m_flBlue = 255.0f;
- beamInfo.m_nSegments = 8;
- beamInfo.m_bRenderable = true;
- beamInfo.m_nFlags = (FBEAM_ONLYNOISEONCE|FBEAM_SHADEOUT);
-
- beams->CreateBeamPoints( beamInfo );
- }
- }
-
- void OnDataChanged( DataUpdateType_t updateType )
- {
- BaseClass::OnDataChanged( updateType );
- if ( updateType == DATA_UPDATE_CREATED )
- {
- SetNextClientThink( CLIENT_THINK_ALWAYS );
- }
- }
-
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- void StartStunEffect( void )
- {
- //TODO: Play startup sound
- }
-
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- void StopStunEffect( void )
- {
- //TODO: Play shutdown sound
- }
-
- //-----------------------------------------------------------------------------
- // Purpose:
- // Output : RenderGroup_t
- //-----------------------------------------------------------------------------
- RenderGroup_t GetRenderGroup( void )
- {
- return RENDER_GROUP_TRANSLUCENT_ENTITY;
- }
-
-private:
- CNetworkVar( bool, m_bActive );
-};
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pData -
-// *pStruct -
-// *pOut -
-//-----------------------------------------------------------------------------
-void RecvProxy_StunActive( const CRecvProxyData *pData, void *pStruct, void *pOut )
-{
- bool state = *((bool *)&pData->m_Value.m_Int);
-
- C_WeaponStunStick *pWeapon = (C_WeaponStunStick *) pStruct;
-
- if ( state )
- {
- // Turn on the effect
- pWeapon->StartStunEffect();
- }
- else
- {
- // Turn off the effect
- pWeapon->StopStunEffect();
- }
-
- *(bool *)pOut = state;
-}
-
-STUB_WEAPON_CLASS_IMPLEMENT( weapon_stunstick, C_WeaponStunStick );
-
-IMPLEMENT_CLIENTCLASS_DT( C_WeaponStunStick, DT_WeaponStunStick, CWeaponStunStick )
- RecvPropInt( RECVINFO(m_bActive), 0, RecvProxy_StunActive ),
-END_RECV_TABLE()
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+#include "cbase.h"
+#include "c_basehlcombatweapon.h"
+#include "iviewrender_beams.h"
+#include "beam_shared.h"
+#include "c_weapon__stubs.h"
+#include "materialsystem/imaterial.h"
+#include "clienteffectprecachesystem.h"
+#include "beamdraw.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectStunstick )
+CLIENTEFFECT_MATERIAL( "effects/stunstick" )
+CLIENTEFFECT_REGISTER_END()
+
+class C_WeaponStunStick : public C_BaseHLBludgeonWeapon
+{
+ DECLARE_CLASS( C_WeaponStunStick, C_BaseHLBludgeonWeapon );
+public:
+ DECLARE_CLIENTCLASS();
+ DECLARE_PREDICTABLE();
+
+ int DrawModel( int flags )
+ {
+ //FIXME: This sucks, but I can't easily create temp ents...
+
+ if ( m_bActive )
+ {
+ Vector vecOrigin;
+ QAngle vecAngles;
+ float color[3];
+
+ color[0] = color[1] = color[2] = random->RandomFloat( 0.1f, 0.2f );
+
+ GetAttachment( 1, vecOrigin, vecAngles );
+
+ Vector vForward;
+ AngleVectors( vecAngles, &vForward );
+
+ Vector vEnd = vecOrigin - vForward * 1.0f;
+
+ IMaterial *pMaterial = materials->FindMaterial( "effects/stunstick", NULL, false );
+
+ CMatRenderContextPtr pRenderContext( materials );
+ pRenderContext->Bind( pMaterial );
+ DrawHalo( pMaterial, vEnd, random->RandomFloat( 4.0f, 6.0f ), color );
+
+ color[0] = color[1] = color[2] = random->RandomFloat( 0.9f, 1.0f );
+
+ DrawHalo( pMaterial, vEnd, random->RandomFloat( 2.0f, 3.0f ), color );
+ }
+
+ return BaseClass::DrawModel( flags );
+ }
+
+ // Do part of our effect
+ void ClientThink( void )
+ {
+ // Update our effects
+ if ( m_bActive &&
+ gpGlobals->frametime != 0.0f &&
+ ( random->RandomInt( 0, 5 ) == 0 ) )
+ {
+ Vector vecOrigin;
+ QAngle vecAngles;
+
+ GetAttachment( 1, vecOrigin, vecAngles );
+
+ Vector vForward;
+ AngleVectors( vecAngles, &vForward );
+
+ Vector vEnd = vecOrigin - vForward * 1.0f;
+
+ // Inner beams
+ BeamInfo_t beamInfo;
+
+ beamInfo.m_vecStart = vEnd;
+ Vector offset = RandomVector( -6, 2 );
+
+ offset += Vector(2,2,2);
+ beamInfo.m_vecEnd = vecOrigin + offset;
+
+ beamInfo.m_pStartEnt= cl_entitylist->GetEnt( BEAMENT_ENTITY( entindex() ) );
+ beamInfo.m_pEndEnt = cl_entitylist->GetEnt( BEAMENT_ENTITY( entindex() ) );
+ beamInfo.m_nStartAttachment = 1;
+ beamInfo.m_nEndAttachment = 2;
+
+ beamInfo.m_nType = TE_BEAMTESLA;
+ beamInfo.m_pszModelName = "sprites/physbeam.vmt";
+ beamInfo.m_flHaloScale = 0.0f;
+ beamInfo.m_flLife = 0.01f;
+ beamInfo.m_flWidth = random->RandomFloat( 0.5f, 2.0f );
+ beamInfo.m_flEndWidth = 0;
+ beamInfo.m_flFadeLength = 0.0f;
+ beamInfo.m_flAmplitude = random->RandomFloat( 1, 2 );
+ beamInfo.m_flBrightness = 255.0;
+ beamInfo.m_flSpeed = 0.0;
+ beamInfo.m_nStartFrame = 0.0;
+ beamInfo.m_flFrameRate = 1.0f;
+ beamInfo.m_flRed = 255.0f;;
+ beamInfo.m_flGreen = 255.0f;
+ beamInfo.m_flBlue = 255.0f;
+ beamInfo.m_nSegments = 8;
+ beamInfo.m_bRenderable = true;
+ beamInfo.m_nFlags = (FBEAM_ONLYNOISEONCE|FBEAM_SHADEOUT);
+
+ beams->CreateBeamPoints( beamInfo );
+ }
+ }
+
+ void OnDataChanged( DataUpdateType_t updateType )
+ {
+ BaseClass::OnDataChanged( updateType );
+ if ( updateType == DATA_UPDATE_CREATED )
+ {
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+ }
+ }
+
+ //-----------------------------------------------------------------------------
+ // Purpose:
+ //-----------------------------------------------------------------------------
+ void StartStunEffect( void )
+ {
+ //TODO: Play startup sound
+ }
+
+ //-----------------------------------------------------------------------------
+ // Purpose:
+ //-----------------------------------------------------------------------------
+ void StopStunEffect( void )
+ {
+ //TODO: Play shutdown sound
+ }
+
+ //-----------------------------------------------------------------------------
+ // Purpose:
+ // Output : RenderGroup_t
+ //-----------------------------------------------------------------------------
+ RenderGroup_t GetRenderGroup( void )
+ {
+ return RENDER_GROUP_TRANSLUCENT_ENTITY;
+ }
+
+private:
+ CNetworkVar( bool, m_bActive );
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pData -
+// *pStruct -
+// *pOut -
+//-----------------------------------------------------------------------------
+void RecvProxy_StunActive( const CRecvProxyData *pData, void *pStruct, void *pOut )
+{
+ bool state = *((bool *)&pData->m_Value.m_Int);
+
+ C_WeaponStunStick *pWeapon = (C_WeaponStunStick *) pStruct;
+
+ if ( state )
+ {
+ // Turn on the effect
+ pWeapon->StartStunEffect();
+ }
+ else
+ {
+ // Turn off the effect
+ pWeapon->StopStunEffect();
+ }
+
+ *(bool *)pOut = state;
+}
+
+STUB_WEAPON_CLASS_IMPLEMENT( weapon_stunstick, C_WeaponStunStick );
+
+IMPLEMENT_CLIENTCLASS_DT( C_WeaponStunStick, DT_WeaponStunStick, CWeaponStunStick )
+ RecvPropInt( RECVINFO(m_bActive), 0, RecvProxy_StunActive ),
+END_RECV_TABLE()
+
diff --git a/mp/src/game/client/hl2/clientmode_hlnormal.cpp b/mp/src/game/client/hl2/clientmode_hlnormal.cpp
index e9eddacf..dc1415af 100644
--- a/mp/src/game/client/hl2/clientmode_hlnormal.cpp
+++ b/mp/src/game/client/hl2/clientmode_hlnormal.cpp
@@ -1,99 +1,99 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Draws the normal TF2 or HL2 HUD.
-//
-//=============================================================================
-#include "cbase.h"
-#include "clientmode_hlnormal.h"
-#include "vgui_int.h"
-#include "hud.h"
-#include <vgui/IInput.h>
-#include <vgui/IPanel.h>
-#include <vgui/ISurface.h>
-#include <vgui_controls/AnimationController.h>
-#include "iinput.h"
-#include "ienginevgui.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-extern bool g_bRollingCredits;
-
-ConVar fov_desired( "fov_desired", "75", FCVAR_ARCHIVE | FCVAR_USERINFO, "Sets the base field-of-view.", true, 75.0, true, 90.0 );
-
-//-----------------------------------------------------------------------------
-// Globals
-//-----------------------------------------------------------------------------
-vgui::HScheme g_hVGuiCombineScheme = 0;
-
-
-// Instance the singleton and expose the interface to it.
-IClientMode *GetClientModeNormal()
-{
- static ClientModeHLNormal g_ClientModeNormal;
- return &g_ClientModeNormal;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: this is the viewport that contains all the hud elements
-//-----------------------------------------------------------------------------
-class CHudViewport : public CBaseViewport
-{
-private:
- DECLARE_CLASS_SIMPLE( CHudViewport, CBaseViewport );
-
-protected:
- virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
- {
- BaseClass::ApplySchemeSettings( pScheme );
-
- gHUD.InitColors( pScheme );
-
- SetPaintBackgroundEnabled( false );
- }
-
- virtual void CreateDefaultPanels( void ) { /* don't create any panels yet*/ };
-};
-
-
-//-----------------------------------------------------------------------------
-// ClientModeHLNormal implementation
-//-----------------------------------------------------------------------------
-ClientModeHLNormal::ClientModeHLNormal()
-{
- m_pViewport = new CHudViewport();
- m_pViewport->Start( gameuifuncs, gameeventmanager );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-ClientModeHLNormal::~ClientModeHLNormal()
-{
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void ClientModeHLNormal::Init()
-{
- BaseClass::Init();
-
- // Load up the combine control panel scheme
- g_hVGuiCombineScheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), IsXbox() ? "resource/ClientScheme.res" : "resource/CombinePanelScheme.res", "CombineScheme" );
- if (!g_hVGuiCombineScheme)
- {
- Warning( "Couldn't load combine panel scheme!\n" );
- }
-}
-
-bool ClientModeHLNormal::ShouldDrawCrosshair( void )
-{
- return ( g_bRollingCredits == false );
-}
-
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Draws the normal TF2 or HL2 HUD.
+//
+//=============================================================================
+#include "cbase.h"
+#include "clientmode_hlnormal.h"
+#include "vgui_int.h"
+#include "hud.h"
+#include <vgui/IInput.h>
+#include <vgui/IPanel.h>
+#include <vgui/ISurface.h>
+#include <vgui_controls/AnimationController.h>
+#include "iinput.h"
+#include "ienginevgui.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+extern bool g_bRollingCredits;
+
+ConVar fov_desired( "fov_desired", "75", FCVAR_ARCHIVE | FCVAR_USERINFO, "Sets the base field-of-view.", true, 75.0, true, 90.0 );
+
+//-----------------------------------------------------------------------------
+// Globals
+//-----------------------------------------------------------------------------
+vgui::HScheme g_hVGuiCombineScheme = 0;
+
+
+// Instance the singleton and expose the interface to it.
+IClientMode *GetClientModeNormal()
+{
+ static ClientModeHLNormal g_ClientModeNormal;
+ return &g_ClientModeNormal;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: this is the viewport that contains all the hud elements
+//-----------------------------------------------------------------------------
+class CHudViewport : public CBaseViewport
+{
+private:
+ DECLARE_CLASS_SIMPLE( CHudViewport, CBaseViewport );
+
+protected:
+ virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
+ {
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ gHUD.InitColors( pScheme );
+
+ SetPaintBackgroundEnabled( false );
+ }
+
+ virtual void CreateDefaultPanels( void ) { /* don't create any panels yet*/ };
+};
+
+
+//-----------------------------------------------------------------------------
+// ClientModeHLNormal implementation
+//-----------------------------------------------------------------------------
+ClientModeHLNormal::ClientModeHLNormal()
+{
+ m_pViewport = new CHudViewport();
+ m_pViewport->Start( gameuifuncs, gameeventmanager );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+ClientModeHLNormal::~ClientModeHLNormal()
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void ClientModeHLNormal::Init()
+{
+ BaseClass::Init();
+
+ // Load up the combine control panel scheme
+ g_hVGuiCombineScheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), IsXbox() ? "resource/ClientScheme.res" : "resource/CombinePanelScheme.res", "CombineScheme" );
+ if (!g_hVGuiCombineScheme)
+ {
+ Warning( "Couldn't load combine panel scheme!\n" );
+ }
+}
+
+bool ClientModeHLNormal::ShouldDrawCrosshair( void )
+{
+ return ( g_bRollingCredits == false );
+}
+
+
+
diff --git a/mp/src/game/client/hl2/clientmode_hlnormal.h b/mp/src/game/client/hl2/clientmode_hlnormal.h
index bd7d128a..623da433 100644
--- a/mp/src/game/client/hl2/clientmode_hlnormal.h
+++ b/mp/src/game/client/hl2/clientmode_hlnormal.h
@@ -1,45 +1,45 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $Workfile: $
-// $Date: $
-// $NoKeywords: $
-//=============================================================================//
-#if !defined( CLIENTMODE_HLNORMAL_H )
-#define CLIENTMODE_HLNORMAL_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "clientmode_shared.h"
-#include <vgui_controls/EditablePanel.h>
-#include <vgui/Cursor.h>
-
-class CHudViewport;
-
-namespace vgui
-{
- typedef unsigned long HScheme;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-class ClientModeHLNormal : public ClientModeShared
-{
-public:
- DECLARE_CLASS( ClientModeHLNormal, ClientModeShared );
-
- ClientModeHLNormal();
- ~ClientModeHLNormal();
-
- virtual void Init();
- virtual bool ShouldDrawCrosshair( void );
-};
-
-extern IClientMode *GetClientModeNormal();
-extern vgui::HScheme g_hVGuiCombineScheme;
-
-#endif // CLIENTMODE_HLNORMAL_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $Workfile: $
+// $Date: $
+// $NoKeywords: $
+//=============================================================================//
+#if !defined( CLIENTMODE_HLNORMAL_H )
+#define CLIENTMODE_HLNORMAL_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "clientmode_shared.h"
+#include <vgui_controls/EditablePanel.h>
+#include <vgui/Cursor.h>
+
+class CHudViewport;
+
+namespace vgui
+{
+ typedef unsigned long HScheme;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class ClientModeHLNormal : public ClientModeShared
+{
+public:
+ DECLARE_CLASS( ClientModeHLNormal, ClientModeShared );
+
+ ClientModeHLNormal();
+ ~ClientModeHLNormal();
+
+ virtual void Init();
+ virtual bool ShouldDrawCrosshair( void );
+};
+
+extern IClientMode *GetClientModeNormal();
+extern vgui::HScheme g_hVGuiCombineScheme;
+
+#endif // CLIENTMODE_HLNORMAL_H
diff --git a/mp/src/game/client/hl2/fx_antlion.cpp b/mp/src/game/client/hl2/fx_antlion.cpp
index 3933bc37..eafca9b0 100644
--- a/mp/src/game/client/hl2/fx_antlion.cpp
+++ b/mp/src/game/client/hl2/fx_antlion.cpp
@@ -1,334 +1,334 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "fx.h"
-#include "c_gib.h"
-#include "c_te_effect_dispatch.h"
-#include "iefx.h"
-#include "decals.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-PMaterialHandle g_Material_Blood[2] = { NULL, NULL };
-
-#ifdef _XBOX
-
-// XBox only uses a few gibs
-#define NUM_ANTLION_GIBS 3
-const char *pszAntlionGibs[NUM_ANTLION_GIBS] = {
- "models/gibs/antlion_gib_large_2.mdl", // Head
- "models/gibs/antlion_gib_medium_1.mdl", // Pincher
- "models/gibs/antlion_gib_medium_2.mdl", // Leg
-};
-
-#else
-
-// Use all the gibs
-#define NUM_ANTLION_GIBS_UNIQUE 3
-const char *pszAntlionGibs_Unique[NUM_ANTLION_GIBS_UNIQUE] = {
- "models/gibs/antlion_gib_large_1.mdl",
- "models/gibs/antlion_gib_large_2.mdl",
- "models/gibs/antlion_gib_large_3.mdl"
-};
-
-#define NUM_ANTLION_GIBS_MEDIUM 3
-const char *pszAntlionGibs_Medium[NUM_ANTLION_GIBS_MEDIUM] = {
- "models/gibs/antlion_gib_medium_1.mdl",
- "models/gibs/antlion_gib_medium_2.mdl",
- "models/gibs/antlion_gib_medium_3.mdl"
-};
-
-// XBox doesn't use the smaller gibs, so don't cache them
-#define NUM_ANTLION_GIBS_SMALL 3
-const char *pszAntlionGibs_Small[NUM_ANTLION_GIBS_SMALL] = {
- "models/gibs/antlion_gib_small_1.mdl",
- "models/gibs/antlion_gib_small_2.mdl",
- "models/gibs/antlion_gib_small_3.mdl"
-};
-#endif
-
-ConVar g_antlion_maxgibs( "g_antlion_maxgibs", "16", FCVAR_ARCHIVE );
-
-void CAntlionGibManager::LevelInitPreEntity( void )
-{
- m_LRU.Purge();
-}
-
-CAntlionGibManager s_AntlionGibManager( "CAntlionGibManager" );
-
-void CAntlionGibManager::AddGib( C_BaseEntity *pEntity )
-{
- m_LRU.AddToTail( pEntity );
-}
-
-void CAntlionGibManager::RemoveGib( C_BaseEntity *pEntity )
-{
- m_LRU.FindAndRemove( pEntity );
-}
-
-
-//-----------------------------------------------------------------------------
-// Methods of IGameSystem
-//-----------------------------------------------------------------------------
-void CAntlionGibManager::Update( float frametime )
-{
- if ( m_LRU.Count() < g_antlion_maxgibs.GetInt() )
- return;
-
- int i = 0;
- i = m_LRU.Head();
-
- if ( m_LRU[ i ].Get() )
- {
- m_LRU[ i ].Get()->SetNextClientThink( gpGlobals->curtime );
- }
-
- m_LRU.Remove(i);
-}
-
-// Antlion gib - marks surfaces when it bounces
-
-class C_AntlionGib : public C_Gib
-{
- typedef C_Gib BaseClass;
-public:
-
- static C_AntlionGib *CreateClientsideGib( const char *pszModelName, Vector vecOrigin, Vector vecForceDir, AngularImpulse vecAngularImp, float m_flLifetime = DEFAULT_GIB_LIFETIME )
- {
- C_AntlionGib *pGib = new C_AntlionGib;
-
- if ( pGib == NULL )
- return NULL;
-
- if ( pGib->InitializeGib( pszModelName, vecOrigin, vecForceDir, vecAngularImp, m_flLifetime ) == false )
- return NULL;
-
- s_AntlionGibManager.AddGib( pGib );
-
- return pGib;
- }
-
- // Decal the surface
- virtual void HitSurface( C_BaseEntity *pOther )
- {
- //JDW: Removed for the time being
-
- /*
- int index = decalsystem->GetDecalIndexForName( "YellowBlood" );
-
- if (index >= 0 )
- {
- effects->DecalShoot( index, pOther->entindex(), pOther->GetModel(), pOther->GetAbsOrigin(), pOther->GetAbsAngles(), GetAbsOrigin(), 0, 0 );
- }
- */
- }
-};
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : &origin -
-//-----------------------------------------------------------------------------
-void FX_AntlionGib( const Vector &origin, const Vector &direction, float scale )
-{
- Vector offset;
-
-#ifdef _XBOX
-
- // Throw less gibs for XBox
- for ( int i = 0; i < NUM_ANTLION_GIBS; i++ )
- {
- offset = RandomVector( -32, 32 ) + origin;
- C_AntlionGib::CreateClientsideGib( pszAntlionGibs[i], offset, ( direction + RandomVector( -0.8f, 0.8f ) ) * ( 250 * scale ), RandomAngularImpulse( -32, 32 ), 1.0f );
- }
-
-#else
-
- int numGibs = random->RandomInt( 1, NUM_ANTLION_GIBS_UNIQUE );
-
- // Spawn all the unique gibs
- for ( int i = 0; i < numGibs; i++ )
- {
- offset = RandomVector( -16, 16 ) + origin;
-
- C_AntlionGib::CreateClientsideGib( pszAntlionGibs_Unique[i], offset, ( direction + RandomVector( -0.8f, 0.8f ) ) * ( 150 * scale ), RandomAngularImpulse( -32, 32 ), 2.0f);
- }
-
- numGibs = random->RandomInt( 1, NUM_ANTLION_GIBS_MEDIUM );
-
- // Spawn all the medium gibs
- for ( int i = 0; i < numGibs; i++ )
- {
- offset = RandomVector( -16, 16 ) + origin;
-
- C_AntlionGib::CreateClientsideGib( pszAntlionGibs_Medium[i], offset, ( direction + RandomVector( -0.8f, 0.8f ) ) * ( 250 * scale ), RandomAngularImpulse( -200, 200 ), 1.0f );
- }
-
- numGibs = random->RandomInt( 1, NUM_ANTLION_GIBS_SMALL );
-
- // Spawn all the small gibs
- for ( int i = 0; i < NUM_ANTLION_GIBS_SMALL; i++ )
- {
- offset = RandomVector( -16, 16 ) + origin;
-
- C_AntlionGib::CreateClientsideGib( pszAntlionGibs_Small[i], offset, ( direction + RandomVector( -0.8f, 0.8f ) ) * ( 400 * scale ), RandomAngularImpulse( -300, 300 ), 0.5f );
- }
-
-#endif
-
-#ifdef _XBOX
-
- //
- // Throw some blood
- //
-
- CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "FX_AntlionGib" );
- pSimple->SetSortOrigin( origin );
- pSimple->GetBinding().SetBBox( origin - Vector(64,64,64), origin + Vector(64,64,64) );
-
- // Cache this if we're not already
- if ( g_Material_Blood[0] == NULL )
- {
- g_Material_Blood[0] = g_Mat_BloodPuff[0];
- }
-
- if ( g_Material_Blood[1] == NULL )
- {
- g_Material_Blood[1] = g_Mat_BloodPuff[1];
- }
-
- Vector vDir;
- vDir.Random( -1.0f, 1.0f );
-
- // Gore bits
- for ( int i = 0; i < 4; i++ )
- {
- SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Material_Blood[0], origin + RandomVector(-16,16));
- if ( sParticle == NULL )
- return;
-
- sParticle->m_flLifetime = 0.0f;
- sParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f );
-
- float speed = random->RandomFloat( 16.0f, 64.0f );
-
- sParticle->m_vecVelocity.Init();
-
- sParticle->m_uchColor[0] = 255;
- sParticle->m_uchColor[1] = 200;
- sParticle->m_uchColor[2] = 32;
- sParticle->m_uchStartAlpha = 255;
- sParticle->m_uchEndAlpha = 0;
- sParticle->m_uchStartSize = random->RandomInt( 4, 16 );
- sParticle->m_uchEndSize = sParticle->m_uchStartSize * 4;
- sParticle->m_flRoll = random->RandomInt( 0, 360 );
- sParticle->m_flRollDelta = 0.0f;
- }
-
- // Middle core
- SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Material_Blood[1], origin );
- if ( sParticle == NULL )
- return;
-
- sParticle->m_flLifetime = 0.0f;
- sParticle->m_flDieTime = random->RandomFloat( 0.5f, 0.75f );
-
- float speed = random->RandomFloat( 16.0f, 64.0f );
-
- sParticle->m_vecVelocity = vDir * -speed;
- sParticle->m_vecVelocity[2] += 16.0f;
-
- sParticle->m_uchColor[0] = 255;
- sParticle->m_uchColor[1] = 200;
- sParticle->m_uchColor[2] = 32;
- sParticle->m_uchStartAlpha = random->RandomInt( 64, 128 );
- sParticle->m_uchEndAlpha = 0;
- sParticle->m_uchStartSize = random->RandomInt( 16, 32 );
- sParticle->m_uchEndSize = sParticle->m_uchStartSize * 3;
- sParticle->m_flRoll = random->RandomInt( 0, 360 );
- sParticle->m_flRollDelta = random->RandomFloat( -0.2f, 0.2f );
-
-#else
-
- //
- // Non-XBox blood
- //
-
- CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "FX_AntlionGib" );
- pSimple->SetSortOrigin( origin );
-
- Vector vDir;
-
- vDir.Random( -1.0f, 1.0f );
-
- for ( int i = 0; i < 4; i++ )
- {
- SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_BloodPuff[0], origin );
-
- if ( sParticle == NULL )
- return;
-
- sParticle->m_flLifetime = 0.0f;
- sParticle->m_flDieTime = random->RandomFloat( 0.5f, 0.75f );
-
- float speed = random->RandomFloat( 16.0f, 64.0f );
-
- sParticle->m_vecVelocity = vDir * -speed;
- sParticle->m_vecVelocity[2] += 16.0f;
-
- sParticle->m_uchColor[0] = 255;
- sParticle->m_uchColor[1] = 200;
- sParticle->m_uchColor[2] = 32;
- sParticle->m_uchStartAlpha = 255;
- sParticle->m_uchEndAlpha = 0;
- sParticle->m_uchStartSize = random->RandomInt( 16, 32 );
- sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2;
- sParticle->m_flRoll = random->RandomInt( 0, 360 );
- sParticle->m_flRollDelta = random->RandomFloat( -1.0f, 1.0f );
- }
-
- for ( int i = 0; i < 4; i++ )
- {
- SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_BloodPuff[1], origin );
-
- if ( sParticle == NULL )
- {
- return;
- }
-
- sParticle->m_flLifetime = 0.0f;
- sParticle->m_flDieTime = random->RandomFloat( 0.5f, 0.75f );
-
- float speed = random->RandomFloat( 16.0f, 64.0f );
-
- sParticle->m_vecVelocity = vDir * -speed;
- sParticle->m_vecVelocity[2] += 16.0f;
-
- sParticle->m_uchColor[0] = 255;
- sParticle->m_uchColor[1] = 200;
- sParticle->m_uchColor[2] = 32;
- sParticle->m_uchStartAlpha = random->RandomInt( 64, 128 );
- sParticle->m_uchEndAlpha = 0;
- sParticle->m_uchStartSize = random->RandomInt( 16, 32 );
- sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2;
- sParticle->m_flRoll = random->RandomInt( 0, 360 );
- sParticle->m_flRollDelta = random->RandomFloat( -1.0f, 1.0f );
- }
-
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : &data -
-//-----------------------------------------------------------------------------
-void AntlionGibCallback( const CEffectData &data )
-{
- FX_AntlionGib( data.m_vOrigin, data.m_vNormal, data.m_flScale );
-}
-
-DECLARE_CLIENT_EFFECT( "AntlionGib", AntlionGibCallback );
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "fx.h"
+#include "c_gib.h"
+#include "c_te_effect_dispatch.h"
+#include "iefx.h"
+#include "decals.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+PMaterialHandle g_Material_Blood[2] = { NULL, NULL };
+
+#ifdef _XBOX
+
+// XBox only uses a few gibs
+#define NUM_ANTLION_GIBS 3
+const char *pszAntlionGibs[NUM_ANTLION_GIBS] = {
+ "models/gibs/antlion_gib_large_2.mdl", // Head
+ "models/gibs/antlion_gib_medium_1.mdl", // Pincher
+ "models/gibs/antlion_gib_medium_2.mdl", // Leg
+};
+
+#else
+
+// Use all the gibs
+#define NUM_ANTLION_GIBS_UNIQUE 3
+const char *pszAntlionGibs_Unique[NUM_ANTLION_GIBS_UNIQUE] = {
+ "models/gibs/antlion_gib_large_1.mdl",
+ "models/gibs/antlion_gib_large_2.mdl",
+ "models/gibs/antlion_gib_large_3.mdl"
+};
+
+#define NUM_ANTLION_GIBS_MEDIUM 3
+const char *pszAntlionGibs_Medium[NUM_ANTLION_GIBS_MEDIUM] = {
+ "models/gibs/antlion_gib_medium_1.mdl",
+ "models/gibs/antlion_gib_medium_2.mdl",
+ "models/gibs/antlion_gib_medium_3.mdl"
+};
+
+// XBox doesn't use the smaller gibs, so don't cache them
+#define NUM_ANTLION_GIBS_SMALL 3
+const char *pszAntlionGibs_Small[NUM_ANTLION_GIBS_SMALL] = {
+ "models/gibs/antlion_gib_small_1.mdl",
+ "models/gibs/antlion_gib_small_2.mdl",
+ "models/gibs/antlion_gib_small_3.mdl"
+};
+#endif
+
+ConVar g_antlion_maxgibs( "g_antlion_maxgibs", "16", FCVAR_ARCHIVE );
+
+void CAntlionGibManager::LevelInitPreEntity( void )
+{
+ m_LRU.Purge();
+}
+
+CAntlionGibManager s_AntlionGibManager( "CAntlionGibManager" );
+
+void CAntlionGibManager::AddGib( C_BaseEntity *pEntity )
+{
+ m_LRU.AddToTail( pEntity );
+}
+
+void CAntlionGibManager::RemoveGib( C_BaseEntity *pEntity )
+{
+ m_LRU.FindAndRemove( pEntity );
+}
+
+
+//-----------------------------------------------------------------------------
+// Methods of IGameSystem
+//-----------------------------------------------------------------------------
+void CAntlionGibManager::Update( float frametime )
+{
+ if ( m_LRU.Count() < g_antlion_maxgibs.GetInt() )
+ return;
+
+ int i = 0;
+ i = m_LRU.Head();
+
+ if ( m_LRU[ i ].Get() )
+ {
+ m_LRU[ i ].Get()->SetNextClientThink( gpGlobals->curtime );
+ }
+
+ m_LRU.Remove(i);
+}
+
+// Antlion gib - marks surfaces when it bounces
+
+class C_AntlionGib : public C_Gib
+{
+ typedef C_Gib BaseClass;
+public:
+
+ static C_AntlionGib *CreateClientsideGib( const char *pszModelName, Vector vecOrigin, Vector vecForceDir, AngularImpulse vecAngularImp, float m_flLifetime = DEFAULT_GIB_LIFETIME )
+ {
+ C_AntlionGib *pGib = new C_AntlionGib;
+
+ if ( pGib == NULL )
+ return NULL;
+
+ if ( pGib->InitializeGib( pszModelName, vecOrigin, vecForceDir, vecAngularImp, m_flLifetime ) == false )
+ return NULL;
+
+ s_AntlionGibManager.AddGib( pGib );
+
+ return pGib;
+ }
+
+ // Decal the surface
+ virtual void HitSurface( C_BaseEntity *pOther )
+ {
+ //JDW: Removed for the time being
+
+ /*
+ int index = decalsystem->GetDecalIndexForName( "YellowBlood" );
+
+ if (index >= 0 )
+ {
+ effects->DecalShoot( index, pOther->entindex(), pOther->GetModel(), pOther->GetAbsOrigin(), pOther->GetAbsAngles(), GetAbsOrigin(), 0, 0 );
+ }
+ */
+ }
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &origin -
+//-----------------------------------------------------------------------------
+void FX_AntlionGib( const Vector &origin, const Vector &direction, float scale )
+{
+ Vector offset;
+
+#ifdef _XBOX
+
+ // Throw less gibs for XBox
+ for ( int i = 0; i < NUM_ANTLION_GIBS; i++ )
+ {
+ offset = RandomVector( -32, 32 ) + origin;
+ C_AntlionGib::CreateClientsideGib( pszAntlionGibs[i], offset, ( direction + RandomVector( -0.8f, 0.8f ) ) * ( 250 * scale ), RandomAngularImpulse( -32, 32 ), 1.0f );
+ }
+
+#else
+
+ int numGibs = random->RandomInt( 1, NUM_ANTLION_GIBS_UNIQUE );
+
+ // Spawn all the unique gibs
+ for ( int i = 0; i < numGibs; i++ )
+ {
+ offset = RandomVector( -16, 16 ) + origin;
+
+ C_AntlionGib::CreateClientsideGib( pszAntlionGibs_Unique[i], offset, ( direction + RandomVector( -0.8f, 0.8f ) ) * ( 150 * scale ), RandomAngularImpulse( -32, 32 ), 2.0f);
+ }
+
+ numGibs = random->RandomInt( 1, NUM_ANTLION_GIBS_MEDIUM );
+
+ // Spawn all the medium gibs
+ for ( int i = 0; i < numGibs; i++ )
+ {
+ offset = RandomVector( -16, 16 ) + origin;
+
+ C_AntlionGib::CreateClientsideGib( pszAntlionGibs_Medium[i], offset, ( direction + RandomVector( -0.8f, 0.8f ) ) * ( 250 * scale ), RandomAngularImpulse( -200, 200 ), 1.0f );
+ }
+
+ numGibs = random->RandomInt( 1, NUM_ANTLION_GIBS_SMALL );
+
+ // Spawn all the small gibs
+ for ( int i = 0; i < NUM_ANTLION_GIBS_SMALL; i++ )
+ {
+ offset = RandomVector( -16, 16 ) + origin;
+
+ C_AntlionGib::CreateClientsideGib( pszAntlionGibs_Small[i], offset, ( direction + RandomVector( -0.8f, 0.8f ) ) * ( 400 * scale ), RandomAngularImpulse( -300, 300 ), 0.5f );
+ }
+
+#endif
+
+#ifdef _XBOX
+
+ //
+ // Throw some blood
+ //
+
+ CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "FX_AntlionGib" );
+ pSimple->SetSortOrigin( origin );
+ pSimple->GetBinding().SetBBox( origin - Vector(64,64,64), origin + Vector(64,64,64) );
+
+ // Cache this if we're not already
+ if ( g_Material_Blood[0] == NULL )
+ {
+ g_Material_Blood[0] = g_Mat_BloodPuff[0];
+ }
+
+ if ( g_Material_Blood[1] == NULL )
+ {
+ g_Material_Blood[1] = g_Mat_BloodPuff[1];
+ }
+
+ Vector vDir;
+ vDir.Random( -1.0f, 1.0f );
+
+ // Gore bits
+ for ( int i = 0; i < 4; i++ )
+ {
+ SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Material_Blood[0], origin + RandomVector(-16,16));
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_flLifetime = 0.0f;
+ sParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f );
+
+ float speed = random->RandomFloat( 16.0f, 64.0f );
+
+ sParticle->m_vecVelocity.Init();
+
+ sParticle->m_uchColor[0] = 255;
+ sParticle->m_uchColor[1] = 200;
+ sParticle->m_uchColor[2] = 32;
+ sParticle->m_uchStartAlpha = 255;
+ sParticle->m_uchEndAlpha = 0;
+ sParticle->m_uchStartSize = random->RandomInt( 4, 16 );
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 4;
+ sParticle->m_flRoll = random->RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = 0.0f;
+ }
+
+ // Middle core
+ SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Material_Blood[1], origin );
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_flLifetime = 0.0f;
+ sParticle->m_flDieTime = random->RandomFloat( 0.5f, 0.75f );
+
+ float speed = random->RandomFloat( 16.0f, 64.0f );
+
+ sParticle->m_vecVelocity = vDir * -speed;
+ sParticle->m_vecVelocity[2] += 16.0f;
+
+ sParticle->m_uchColor[0] = 255;
+ sParticle->m_uchColor[1] = 200;
+ sParticle->m_uchColor[2] = 32;
+ sParticle->m_uchStartAlpha = random->RandomInt( 64, 128 );
+ sParticle->m_uchEndAlpha = 0;
+ sParticle->m_uchStartSize = random->RandomInt( 16, 32 );
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 3;
+ sParticle->m_flRoll = random->RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = random->RandomFloat( -0.2f, 0.2f );
+
+#else
+
+ //
+ // Non-XBox blood
+ //
+
+ CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "FX_AntlionGib" );
+ pSimple->SetSortOrigin( origin );
+
+ Vector vDir;
+
+ vDir.Random( -1.0f, 1.0f );
+
+ for ( int i = 0; i < 4; i++ )
+ {
+ SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_BloodPuff[0], origin );
+
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_flLifetime = 0.0f;
+ sParticle->m_flDieTime = random->RandomFloat( 0.5f, 0.75f );
+
+ float speed = random->RandomFloat( 16.0f, 64.0f );
+
+ sParticle->m_vecVelocity = vDir * -speed;
+ sParticle->m_vecVelocity[2] += 16.0f;
+
+ sParticle->m_uchColor[0] = 255;
+ sParticle->m_uchColor[1] = 200;
+ sParticle->m_uchColor[2] = 32;
+ sParticle->m_uchStartAlpha = 255;
+ sParticle->m_uchEndAlpha = 0;
+ sParticle->m_uchStartSize = random->RandomInt( 16, 32 );
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2;
+ sParticle->m_flRoll = random->RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = random->RandomFloat( -1.0f, 1.0f );
+ }
+
+ for ( int i = 0; i < 4; i++ )
+ {
+ SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_BloodPuff[1], origin );
+
+ if ( sParticle == NULL )
+ {
+ return;
+ }
+
+ sParticle->m_flLifetime = 0.0f;
+ sParticle->m_flDieTime = random->RandomFloat( 0.5f, 0.75f );
+
+ float speed = random->RandomFloat( 16.0f, 64.0f );
+
+ sParticle->m_vecVelocity = vDir * -speed;
+ sParticle->m_vecVelocity[2] += 16.0f;
+
+ sParticle->m_uchColor[0] = 255;
+ sParticle->m_uchColor[1] = 200;
+ sParticle->m_uchColor[2] = 32;
+ sParticle->m_uchStartAlpha = random->RandomInt( 64, 128 );
+ sParticle->m_uchEndAlpha = 0;
+ sParticle->m_uchStartSize = random->RandomInt( 16, 32 );
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2;
+ sParticle->m_flRoll = random->RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = random->RandomFloat( -1.0f, 1.0f );
+ }
+
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &data -
+//-----------------------------------------------------------------------------
+void AntlionGibCallback( const CEffectData &data )
+{
+ FX_AntlionGib( data.m_vOrigin, data.m_vNormal, data.m_flScale );
+}
+
+DECLARE_CLIENT_EFFECT( "AntlionGib", AntlionGibCallback );
diff --git a/mp/src/game/client/hl2/fx_bugbait.cpp b/mp/src/game/client/hl2/fx_bugbait.cpp
index b807d423..6d12a1c0 100644
--- a/mp/src/game/client/hl2/fx_bugbait.cpp
+++ b/mp/src/game/client/hl2/fx_bugbait.cpp
@@ -1,63 +1,63 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "particlemgr.h"
-#include "particle_prototype.h"
-#include "particle_util.h"
-#include "particles_simple.h"
-#include "c_baseentity.h"
-#include "baseparticleentity.h"
-#include "engine/ivdebugoverlay.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//==================================================
-// SporeSmokeEffect
-//==================================================
-
-class SporeSmokeEffect : public CSimpleEmitter
-{
-public:
- SporeSmokeEffect( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
-
- static SporeSmokeEffect* Create( const char *pDebugName );
-
- virtual void UpdateVelocity( SimpleParticle *pParticle, float timeDelta );
- virtual float UpdateAlpha( const SimpleParticle *pParticle );
-
-private:
- SporeSmokeEffect( const SporeSmokeEffect & );
-};
-
-
-SporeSmokeEffect* SporeSmokeEffect::Create( const char *pDebugName )
-{
- return new SporeSmokeEffect( pDebugName );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pParticle -
-// timeDelta -
-// Output : float
-//-----------------------------------------------------------------------------
-float SporeSmokeEffect::UpdateAlpha( const SimpleParticle *pParticle )
-{
- //return ( ((float)pParticle->m_uchStartAlpha/255.0f) * sin( M_PI * (pParticle->m_flLifetime / pParticle->m_flDieTime) ) );
- return (pParticle->m_uchStartAlpha/255.0f) + ( (float)(pParticle->m_uchEndAlpha/255.0f) - (float)(pParticle->m_uchStartAlpha/255.0f) ) * (pParticle->m_flLifetime / pParticle->m_flDieTime);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pParticle -
-// timeDelta -
-//-----------------------------------------------------------------------------
-void SporeSmokeEffect::UpdateVelocity( SimpleParticle *pParticle, float timeDelta )
-{
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "particlemgr.h"
+#include "particle_prototype.h"
+#include "particle_util.h"
+#include "particles_simple.h"
+#include "c_baseentity.h"
+#include "baseparticleentity.h"
+#include "engine/ivdebugoverlay.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//==================================================
+// SporeSmokeEffect
+//==================================================
+
+class SporeSmokeEffect : public CSimpleEmitter
+{
+public:
+ SporeSmokeEffect( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
+
+ static SporeSmokeEffect* Create( const char *pDebugName );
+
+ virtual void UpdateVelocity( SimpleParticle *pParticle, float timeDelta );
+ virtual float UpdateAlpha( const SimpleParticle *pParticle );
+
+private:
+ SporeSmokeEffect( const SporeSmokeEffect & );
+};
+
+
+SporeSmokeEffect* SporeSmokeEffect::Create( const char *pDebugName )
+{
+ return new SporeSmokeEffect( pDebugName );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pParticle -
+// timeDelta -
+// Output : float
+//-----------------------------------------------------------------------------
+float SporeSmokeEffect::UpdateAlpha( const SimpleParticle *pParticle )
+{
+ //return ( ((float)pParticle->m_uchStartAlpha/255.0f) * sin( M_PI * (pParticle->m_flLifetime / pParticle->m_flDieTime) ) );
+ return (pParticle->m_uchStartAlpha/255.0f) + ( (float)(pParticle->m_uchEndAlpha/255.0f) - (float)(pParticle->m_uchStartAlpha/255.0f) ) * (pParticle->m_flLifetime / pParticle->m_flDieTime);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pParticle -
+// timeDelta -
+//-----------------------------------------------------------------------------
+void SporeSmokeEffect::UpdateVelocity( SimpleParticle *pParticle, float timeDelta )
+{
+}
+
diff --git a/mp/src/game/client/hl2/fx_hl2_impacts.cpp b/mp/src/game/client/hl2/fx_hl2_impacts.cpp
index 1d79cc36..ac75b85a 100644
--- a/mp/src/game/client/hl2/fx_hl2_impacts.cpp
+++ b/mp/src/game/client/hl2/fx_hl2_impacts.cpp
@@ -1,275 +1,275 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Game-specific impact effect hooks
-//
-//=============================================================================//
-#include "cbase.h"
-#include "fx_impact.h"
-#include "fx.h"
-#include "decals.h"
-#include "fx_quad.h"
-#include "fx_sparks.h"
-
-#include "tier0/vprof.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//-----------------------------------------------------------------------------
-// Purpose: Handle jeep impacts
-//-----------------------------------------------------------------------------
-void ImpactJeepCallback( 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 )
- {
- // This happens for impacts that occur on an object that's then destroyed.
- // Clear out the fraction so it uses the server's data
- tr.fraction = 1.0;
- PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
- 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, 2 );
- }
-
- PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
-}
-
-DECLARE_CLIENT_EFFECT( "ImpactJeep", ImpactJeepCallback );
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Handle gauss impacts
-//-----------------------------------------------------------------------------
-void ImpactGaussCallback( 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 )
- {
- // This happens for impacts that occur on an object that's then destroyed.
- // Clear out the fraction so it uses the server's data
- tr.fraction = 1.0;
- PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
- 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, 2 );
- }
-
- PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
-}
-
-DECLARE_CLIENT_EFFECT( "ImpactGauss", ImpactGaussCallback );
-
-//-----------------------------------------------------------------------------
-// Purpose: Handle weapon impacts
-//-----------------------------------------------------------------------------
-void ImpactCallback( const CEffectData &data )
-{
- VPROF_BUDGET( "ImpactCallback", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
-
- 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 )
- {
- // This happens for impacts that occur on an object that's then destroyed.
- // Clear out the fraction so it uses the server's data
- tr.fraction = 1.0;
- PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
- 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 );
- }
-
- PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
-}
-
-DECLARE_CLIENT_EFFECT( "Impact", ImpactCallback );
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : &origin -
-// &normal -
-// scale -
-//-----------------------------------------------------------------------------
-void FX_AirboatGunImpact( const Vector &origin, const Vector &normal, float scale )
-{
-#ifdef _XBOX
-
- Vector offset = origin + ( normal * 1.0f );
-
- CSmartPtr<CTrailParticles> sparkEmitter = CTrailParticles::Create( "FX_MetalSpark 1" );
-
- if ( sparkEmitter == NULL )
- return;
-
- //Setup our information
- sparkEmitter->SetSortOrigin( offset );
- sparkEmitter->SetFlag( bitsPARTICLE_TRAIL_VELOCITY_DAMPEN );
- sparkEmitter->SetVelocityDampen( 8.0f );
- sparkEmitter->SetGravity( 800.0f );
- sparkEmitter->SetCollisionDamped( 0.25f );
- sparkEmitter->GetBinding().SetBBox( offset - Vector( 32, 32, 32 ), offset + Vector( 32, 32, 32 ) );
-
- int numSparks = random->RandomInt( 4, 8 );
-
- TrailParticle *pParticle;
- PMaterialHandle hMaterial = sparkEmitter->GetPMaterial( "effects/spark" );
- Vector dir;
-
- float length = 0.1f;
-
- //Dump out sparks
- for ( int i = 0; i < numSparks; i++ )
- {
- pParticle = (TrailParticle *) sparkEmitter->AddParticle( sizeof(TrailParticle), hMaterial, offset );
-
- if ( pParticle == NULL )
- return;
-
- pParticle->m_flLifetime = 0.0f;
- pParticle->m_flDieTime = random->RandomFloat( 0.05f, 0.1f );
-
- float spreadOfs = random->RandomFloat( 0.0f, 2.0f );
-
- dir[0] = normal[0] + random->RandomFloat( -(0.5f*spreadOfs), (0.5f*spreadOfs) );
- dir[1] = normal[1] + random->RandomFloat( -(0.5f*spreadOfs), (0.5f*spreadOfs) );
- dir[2] = normal[2] + random->RandomFloat( -(0.5f*spreadOfs), (0.5f*spreadOfs) );
-
- VectorNormalize( dir );
-
- pParticle->m_flWidth = random->RandomFloat( 1.0f, 4.0f );
- pParticle->m_flLength = random->RandomFloat( length*0.25f, length );
-
- pParticle->m_vecVelocity = dir * random->RandomFloat( (128.0f*(2.0f-spreadOfs)), (512.0f*(2.0f-spreadOfs)) );
-
- Color32Init( pParticle->m_color, 255, 255, 255, 255 );
- }
-
-#else
-
- // Normal metal spark
- FX_MetalSpark( origin, normal, normal, (int) scale );
-
-#endif // _XBOX
-
- // Add a quad to highlite the hit point
- FX_AddQuad( origin,
- normal,
- random->RandomFloat( 16, 32 ),
- random->RandomFloat( 32, 48 ),
- 0.75f,
- 1.0f,
- 0.0f,
- 0.4f,
- random->RandomInt( 0, 360 ),
- 0,
- Vector( 1.0f, 1.0f, 1.0f ),
- 0.05f,
- "effects/combinemuzzle2_nocull",
- (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Handle weapon impacts from the airboat gun shooting (cheaper versions)
-//-----------------------------------------------------------------------------
-void ImpactAirboatGunCallback( const CEffectData &data )
-{
- VPROF_BUDGET( "ImpactAirboatGunCallback", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
-
- 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 )
- {
- // This happens for impacts that occur on an object that's then destroyed.
- // Clear out the fraction so it uses the server's data
- tr.fraction = 1.0;
- PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
- return;
- }
-
-#if !defined( _XBOX )
- // If we hit, perform our custom effects and play the sound. Don't create decals
- if ( Impact( vecOrigin, vecStart, iMaterial, iDamageType, iHitbox, pEntity, tr, IMPACT_NODECAL | IMPACT_REPORT_RAGDOLL_IMPACTS ) )
- {
- FX_AirboatGunImpact( vecOrigin, tr.plane.normal, 2 );
- }
-#else
- FX_AirboatGunImpact( vecOrigin, tr.plane.normal, 1 );
-#endif
-}
-
-DECLARE_CLIENT_EFFECT( "AirboatGunImpact", ImpactAirboatGunCallback );
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Handle weapon impacts from the helicopter shooting (cheaper versions)
-//-----------------------------------------------------------------------------
-void ImpactHelicopterCallback( const CEffectData &data )
-{
- VPROF_BUDGET( "ImpactHelicopterCallback", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
-
- 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 )
- {
- // This happens for impacts that occur on an object that's then destroyed.
- // Clear out the fraction so it uses the server's data
- tr.fraction = 1.0;
- PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
- return;
- }
-
- // If we hit, perform our custom effects and play the sound. Don't create decals
- if ( Impact( vecOrigin, vecStart, iMaterial, iDamageType, iHitbox, pEntity, tr, IMPACT_NODECAL | IMPACT_REPORT_RAGDOLL_IMPACTS ) )
- {
- FX_AirboatGunImpact( vecOrigin, tr.plane.normal, IsXbox() ? 1 : 2 );
-
- // Only do metal + computer custom effects
- if ( (iMaterial == CHAR_TEX_METAL) || (iMaterial == CHAR_TEX_COMPUTER) )
- {
- PerformCustomEffects( vecOrigin, tr, vecShotDir, iMaterial, 1.0, FLAGS_CUSTIOM_EFFECTS_NOFLECKS );
- }
- }
-
- PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
-}
-
-DECLARE_CLIENT_EFFECT( "HelicopterImpact", ImpactHelicopterCallback );
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Game-specific impact effect hooks
+//
+//=============================================================================//
+#include "cbase.h"
+#include "fx_impact.h"
+#include "fx.h"
+#include "decals.h"
+#include "fx_quad.h"
+#include "fx_sparks.h"
+
+#include "tier0/vprof.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: Handle jeep impacts
+//-----------------------------------------------------------------------------
+void ImpactJeepCallback( 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 )
+ {
+ // This happens for impacts that occur on an object that's then destroyed.
+ // Clear out the fraction so it uses the server's data
+ tr.fraction = 1.0;
+ PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
+ 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, 2 );
+ }
+
+ PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
+}
+
+DECLARE_CLIENT_EFFECT( "ImpactJeep", ImpactJeepCallback );
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handle gauss impacts
+//-----------------------------------------------------------------------------
+void ImpactGaussCallback( 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 )
+ {
+ // This happens for impacts that occur on an object that's then destroyed.
+ // Clear out the fraction so it uses the server's data
+ tr.fraction = 1.0;
+ PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
+ 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, 2 );
+ }
+
+ PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
+}
+
+DECLARE_CLIENT_EFFECT( "ImpactGauss", ImpactGaussCallback );
+
+//-----------------------------------------------------------------------------
+// Purpose: Handle weapon impacts
+//-----------------------------------------------------------------------------
+void ImpactCallback( const CEffectData &data )
+{
+ VPROF_BUDGET( "ImpactCallback", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
+
+ 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 )
+ {
+ // This happens for impacts that occur on an object that's then destroyed.
+ // Clear out the fraction so it uses the server's data
+ tr.fraction = 1.0;
+ PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
+ 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 );
+ }
+
+ PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
+}
+
+DECLARE_CLIENT_EFFECT( "Impact", ImpactCallback );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &origin -
+// &normal -
+// scale -
+//-----------------------------------------------------------------------------
+void FX_AirboatGunImpact( const Vector &origin, const Vector &normal, float scale )
+{
+#ifdef _XBOX
+
+ Vector offset = origin + ( normal * 1.0f );
+
+ CSmartPtr<CTrailParticles> sparkEmitter = CTrailParticles::Create( "FX_MetalSpark 1" );
+
+ if ( sparkEmitter == NULL )
+ return;
+
+ //Setup our information
+ sparkEmitter->SetSortOrigin( offset );
+ sparkEmitter->SetFlag( bitsPARTICLE_TRAIL_VELOCITY_DAMPEN );
+ sparkEmitter->SetVelocityDampen( 8.0f );
+ sparkEmitter->SetGravity( 800.0f );
+ sparkEmitter->SetCollisionDamped( 0.25f );
+ sparkEmitter->GetBinding().SetBBox( offset - Vector( 32, 32, 32 ), offset + Vector( 32, 32, 32 ) );
+
+ int numSparks = random->RandomInt( 4, 8 );
+
+ TrailParticle *pParticle;
+ PMaterialHandle hMaterial = sparkEmitter->GetPMaterial( "effects/spark" );
+ Vector dir;
+
+ float length = 0.1f;
+
+ //Dump out sparks
+ for ( int i = 0; i < numSparks; i++ )
+ {
+ pParticle = (TrailParticle *) sparkEmitter->AddParticle( sizeof(TrailParticle), hMaterial, offset );
+
+ if ( pParticle == NULL )
+ return;
+
+ pParticle->m_flLifetime = 0.0f;
+ pParticle->m_flDieTime = random->RandomFloat( 0.05f, 0.1f );
+
+ float spreadOfs = random->RandomFloat( 0.0f, 2.0f );
+
+ dir[0] = normal[0] + random->RandomFloat( -(0.5f*spreadOfs), (0.5f*spreadOfs) );
+ dir[1] = normal[1] + random->RandomFloat( -(0.5f*spreadOfs), (0.5f*spreadOfs) );
+ dir[2] = normal[2] + random->RandomFloat( -(0.5f*spreadOfs), (0.5f*spreadOfs) );
+
+ VectorNormalize( dir );
+
+ pParticle->m_flWidth = random->RandomFloat( 1.0f, 4.0f );
+ pParticle->m_flLength = random->RandomFloat( length*0.25f, length );
+
+ pParticle->m_vecVelocity = dir * random->RandomFloat( (128.0f*(2.0f-spreadOfs)), (512.0f*(2.0f-spreadOfs)) );
+
+ Color32Init( pParticle->m_color, 255, 255, 255, 255 );
+ }
+
+#else
+
+ // Normal metal spark
+ FX_MetalSpark( origin, normal, normal, (int) scale );
+
+#endif // _XBOX
+
+ // Add a quad to highlite the hit point
+ FX_AddQuad( origin,
+ normal,
+ random->RandomFloat( 16, 32 ),
+ random->RandomFloat( 32, 48 ),
+ 0.75f,
+ 1.0f,
+ 0.0f,
+ 0.4f,
+ random->RandomInt( 0, 360 ),
+ 0,
+ Vector( 1.0f, 1.0f, 1.0f ),
+ 0.05f,
+ "effects/combinemuzzle2_nocull",
+ (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Handle weapon impacts from the airboat gun shooting (cheaper versions)
+//-----------------------------------------------------------------------------
+void ImpactAirboatGunCallback( const CEffectData &data )
+{
+ VPROF_BUDGET( "ImpactAirboatGunCallback", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
+
+ 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 )
+ {
+ // This happens for impacts that occur on an object that's then destroyed.
+ // Clear out the fraction so it uses the server's data
+ tr.fraction = 1.0;
+ PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
+ return;
+ }
+
+#if !defined( _XBOX )
+ // If we hit, perform our custom effects and play the sound. Don't create decals
+ if ( Impact( vecOrigin, vecStart, iMaterial, iDamageType, iHitbox, pEntity, tr, IMPACT_NODECAL | IMPACT_REPORT_RAGDOLL_IMPACTS ) )
+ {
+ FX_AirboatGunImpact( vecOrigin, tr.plane.normal, 2 );
+ }
+#else
+ FX_AirboatGunImpact( vecOrigin, tr.plane.normal, 1 );
+#endif
+}
+
+DECLARE_CLIENT_EFFECT( "AirboatGunImpact", ImpactAirboatGunCallback );
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handle weapon impacts from the helicopter shooting (cheaper versions)
+//-----------------------------------------------------------------------------
+void ImpactHelicopterCallback( const CEffectData &data )
+{
+ VPROF_BUDGET( "ImpactHelicopterCallback", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
+
+ 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 )
+ {
+ // This happens for impacts that occur on an object that's then destroyed.
+ // Clear out the fraction so it uses the server's data
+ tr.fraction = 1.0;
+ PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
+ return;
+ }
+
+ // If we hit, perform our custom effects and play the sound. Don't create decals
+ if ( Impact( vecOrigin, vecStart, iMaterial, iDamageType, iHitbox, pEntity, tr, IMPACT_NODECAL | IMPACT_REPORT_RAGDOLL_IMPACTS ) )
+ {
+ FX_AirboatGunImpact( vecOrigin, tr.plane.normal, IsXbox() ? 1 : 2 );
+
+ // Only do metal + computer custom effects
+ if ( (iMaterial == CHAR_TEX_METAL) || (iMaterial == CHAR_TEX_COMPUTER) )
+ {
+ PerformCustomEffects( vecOrigin, tr, vecShotDir, iMaterial, 1.0, FLAGS_CUSTIOM_EFFECTS_NOFLECKS );
+ }
+ }
+
+ PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
+}
+
+DECLARE_CLIENT_EFFECT( "HelicopterImpact", ImpactHelicopterCallback );
+
diff --git a/mp/src/game/client/hl2/fx_hl2_tracers.cpp b/mp/src/game/client/hl2/fx_hl2_tracers.cpp
index 5fc16522..c252937a 100644
--- a/mp/src/game/client/hl2/fx_hl2_tracers.cpp
+++ b/mp/src/game/client/hl2/fx_hl2_tracers.cpp
@@ -1,695 +1,695 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Game-specific impact effect hooks
-//
-//=============================================================================//
-#include "cbase.h"
-#include "fx.h"
-#include "c_te_effect_dispatch.h"
-#include "tier0/vprof.h"
-#include "fx_line.h"
-#include "fx_quad.h"
-#include "view.h"
-#include "particles_localspace.h"
-#include "dlight.h"
-#include "iefx.h"
-#include "clienteffectprecachesystem.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-extern Vector GetTracerOrigin( const CEffectData &data );
-extern void FX_TracerSound( const Vector &start, const Vector &end, int iTracerType );
-
-extern ConVar muzzleflash_light;
-
-
-CLIENTEFFECT_REGISTER_BEGIN( PrecacheTracers )
-CLIENTEFFECT_MATERIAL( "effects/gunshiptracer" )
-CLIENTEFFECT_MATERIAL( "effects/combinemuzzle1" )
-CLIENTEFFECT_MATERIAL( "effects/combinemuzzle2_nocull" )
-CLIENTEFFECT_REGISTER_END()
-
-//-----------------------------------------------------------------------------
-// Purpose: Gunship's Tracer
-//-----------------------------------------------------------------------------
-void GunshipTracerCallback( const CEffectData &data )
-{
- float flVelocity = data.m_flScale;
- bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
- FX_GunshipTracer( (Vector&)data.m_vStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
-}
-
-DECLARE_CLIENT_EFFECT( "GunshipTracer", GunshipTracerCallback );
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Strider's Tracer
-//-----------------------------------------------------------------------------
-void StriderTracerCallback( const CEffectData &data )
-{
- float flVelocity = data.m_flScale;
- bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
- FX_StriderTracer( (Vector&)data.m_vStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
-}
-
-DECLARE_CLIENT_EFFECT( "StriderTracer", StriderTracerCallback );
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Hunter's Tracer
-//-----------------------------------------------------------------------------
-void HunterTracerCallback( const CEffectData &data )
-{
- float flVelocity = data.m_flScale;
- bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
- FX_HunterTracer( (Vector&)data.m_vStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
-}
-
-DECLARE_CLIENT_EFFECT( "HunterTracer", HunterTracerCallback );
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Gauss Gun's Tracer
-//-----------------------------------------------------------------------------
-void GaussTracerCallback( const CEffectData &data )
-{
- float flVelocity = data.m_flScale;
- bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
- FX_GaussTracer( (Vector&)data.m_vStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
-}
-
-DECLARE_CLIENT_EFFECT( "GaussTracer", GaussTracerCallback );
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Airboat gun tracers
-//-----------------------------------------------------------------------------
-void AirboatGunHeavyTracerCallback( const CEffectData &data )
-{
- // Grab the data
- Vector vecStart = GetTracerOrigin( data );
- float flVelocity = data.m_flScale;
-
- // Use default velocity if none specified
- if ( !flVelocity )
- {
- flVelocity = 8000;
- }
-
- //Get out shot direction and length
- Vector vecShotDir;
- VectorSubtract( data.m_vOrigin, vecStart, vecShotDir );
- float flTotalDist = VectorNormalize( vecShotDir );
-
- // Don't make small tracers
- if ( flTotalDist <= 64 )
- return;
-
- float flLength = random->RandomFloat( 300.0f, 400.0f );
- float flLife = ( flTotalDist + flLength ) / flVelocity; //NOTENOTE: We want the tail to finish its run as well
-
- // Add it
- FX_AddDiscreetLine( vecStart, vecShotDir, flVelocity, flLength, flTotalDist, 5.0f, flLife, "effects/gunshiptracer" );
-}
-
-DECLARE_CLIENT_EFFECT( "AirboatGunHeavyTracer", AirboatGunHeavyTracerCallback );
-
-//-----------------------------------------------------------------------------
-// Purpose: Airboat gun tracers
-//-----------------------------------------------------------------------------
-void AirboatGunTracerCallback( const CEffectData &data )
-{
- // Grab the data
- Vector vecStart = GetTracerOrigin( data );
- float flVelocity = data.m_flScale;
-
- // Use default velocity if none specified
- if ( !flVelocity )
- {
- flVelocity = 10000;
- }
-
- //Get out shot direction and length
- Vector vecShotDir;
- VectorSubtract( data.m_vOrigin, vecStart, vecShotDir );
- float flTotalDist = VectorNormalize( vecShotDir );
-
- // Don't make small tracers
- if ( flTotalDist <= 64 )
- return;
-
- float flLength = random->RandomFloat( 256.0f, 384.0f );
- float flLife = ( flTotalDist + flLength ) / flVelocity; //NOTENOTE: We want the tail to finish its run as well
-
- // Add it
- FX_AddDiscreetLine( vecStart, vecShotDir, flVelocity, flLength, flTotalDist, 2.0f, flLife, "effects/gunshiptracer" );
-}
-
-DECLARE_CLIENT_EFFECT( "AirboatGunTracer", AirboatGunTracerCallback );
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Airboat gun tracers
-//-----------------------------------------------------------------------------
-void HelicopterTracerCallback( const CEffectData &data )
-{
- // Grab the data
- Vector vecStart = GetTracerOrigin( data );
- float flVelocity = data.m_flScale;
-
- // Use default velocity if none specified
- if ( !flVelocity )
- {
- flVelocity = 8000;
- }
-
- //Get out shot direction and length
- Vector vecShotDir;
- VectorSubtract( data.m_vOrigin, vecStart, vecShotDir );
- float flTotalDist = VectorNormalize( vecShotDir );
-
- // Don't make small tracers
- if ( flTotalDist <= 256 )
- return;
-
- float flLength = random->RandomFloat( 256.0f, 384.0f );
- float flLife = ( flTotalDist + flLength ) / flVelocity; //NOTENOTE: We want the tail to finish its run as well
-
- // Add it
- FX_AddDiscreetLine( vecStart, vecShotDir, flVelocity, flLength, flTotalDist, 5.0f, flLife, "effects/gunshiptracer" );
-
- if (data.m_fFlags & TRACER_FLAG_WHIZ)
- {
- FX_TracerSound( vecStart, data.m_vOrigin, TRACER_TYPE_GUNSHIP );
- }
-}
-
-DECLARE_CLIENT_EFFECT( "HelicopterTracer", HelicopterTracerCallback );
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : start -
-// end -
-//-----------------------------------------------------------------------------
-void FX_PlayerAR2Tracer( const Vector &start, const Vector &end )
-{
- VPROF_BUDGET( "FX_PlayerAR2Tracer", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
-
- Vector shotDir, dStart, dEnd;
- float length;
-
- //Find the direction of the tracer
- VectorSubtract( end, start, shotDir );
- length = VectorNormalize( shotDir );
-
- //We don't want to draw them if they're too close to us
- if ( length < 128 )
- return;
-
- //Randomly place the tracer along this line, with a random length
- VectorMA( start, random->RandomFloat( 0.0f, 8.0f ), shotDir, dStart );
- VectorMA( dStart, MIN( length, random->RandomFloat( 256.0f, 1024.0f ) ), shotDir, dEnd );
-
- //Create the line
- CFXStaticLine *tracerLine = new CFXStaticLine( "Tracer", dStart, dEnd, random->RandomFloat( 6.0f, 12.0f ), 0.01f, "effects/gunshiptracer", 0 );
- assert( tracerLine );
-
- //Throw it into the list
- clienteffects->AddEffect( tracerLine );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : start -
-// end -
-// velocity -
-// makeWhiz -
-//-----------------------------------------------------------------------------
-void FX_AR2Tracer( Vector& start, Vector& end, int velocity, bool makeWhiz )
-{
- VPROF_BUDGET( "FX_AR2Tracer", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
-
- //Don't make small tracers
- float dist;
- Vector dir;
-
- VectorSubtract( end, start, dir );
- dist = VectorNormalize( dir );
-
- // Don't make short tracers.
- if ( dist < 128 )
- return;
-
- float length = random->RandomFloat( 128.0f, 256.0f );
- float life = ( dist + length ) / velocity; //NOTENOTE: We want the tail to finish its run as well
-
- //Add it
- FX_AddDiscreetLine( start, dir, velocity, length, dist, random->RandomFloat( 0.5f, 1.5f ), life, "effects/gunshiptracer" );
-
- if( makeWhiz )
- {
- FX_TracerSound( start, end, TRACER_TYPE_GUNSHIP );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void AR2TracerCallback( const CEffectData &data )
-{
- C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
-
- if ( player == NULL )
- return;
-
- // Grab the data
- Vector vecStart = GetTracerOrigin( data );
- float flVelocity = data.m_flScale;
- bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
- int iEntIndex = data.entindex();
-
- if ( iEntIndex && iEntIndex == player->index )
- {
- Vector foo = data.m_vStart;
- QAngle vangles;
- Vector vforward, vright, vup;
-
- engine->GetViewAngles( vangles );
- AngleVectors( vangles, &vforward, &vright, &vup );
-
- VectorMA( data.m_vStart, 4, vright, foo );
- foo[2] -= 0.5f;
-
- FX_PlayerAR2Tracer( foo, (Vector&)data.m_vOrigin );
- return;
- }
-
- // Use default velocity if none specified
- if ( !flVelocity )
- {
- flVelocity = 8000;
- }
-
- // Do tracer effect
- FX_AR2Tracer( (Vector&)vecStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
-}
-
-DECLARE_CLIENT_EFFECT( "AR2Tracer", AR2TracerCallback );
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : &data -
-//-----------------------------------------------------------------------------
-void AR2ExplosionCallback( const CEffectData &data )
-{
- float lifetime = random->RandomFloat( 0.4f, 0.75f );
-
- // Ground splash
- FX_AddQuad( data.m_vOrigin,
- data.m_vNormal,
- data.m_flRadius,
- data.m_flRadius * 4.0f,
- 0.85f,
- 1.0f,
- 0.0f,
- 0.25f,
- random->RandomInt( 0, 360 ),
- random->RandomFloat( -4, 4 ),
- Vector( 1.0f, 1.0f, 1.0f ),
- lifetime,
- "effects/combinemuzzle1",
- (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
-
- Vector vRight, vUp;
- VectorVectors( data.m_vNormal, vRight, vUp );
-
- Vector start, end;
-
- float radius = data.m_flRadius * 0.15f;
-
- // Base vertical shaft
- FXLineData_t lineData;
-
- start = data.m_vOrigin;
- end = start + ( data.m_vNormal * random->RandomFloat( radius*2.0f, radius*4.0f ) );
-
- lineData.m_flDieTime = lifetime;
-
- lineData.m_flStartAlpha= 1.0f;
- lineData.m_flEndAlpha = 0.0f;
-
- lineData.m_flStartScale = radius*4;
- lineData.m_flEndScale = radius*5;
-
- lineData.m_pMaterial = materials->FindMaterial( "effects/ar2ground2", 0, 0 );
-
- lineData.m_vecStart = start;
- lineData.m_vecStartVelocity = vec3_origin;
-
- lineData.m_vecEnd = end;
- lineData.m_vecEndVelocity = data.m_vNormal * random->RandomFloat( 200, 350 );
-
- FX_AddLine( lineData );
-
- // Inner filler shaft
- start = data.m_vOrigin;
- end = start + ( data.m_vNormal * random->RandomFloat( 16, radius*0.25f ) );
-
- lineData.m_flDieTime = lifetime - 0.1f;
-
- lineData.m_flStartAlpha= 1.0f;
- lineData.m_flEndAlpha = 0.0f;
-
- lineData.m_flStartScale = radius*2;
- lineData.m_flEndScale = radius*4;
-
- lineData.m_pMaterial = materials->FindMaterial( "effects/ar2ground2", 0, 0 );
-
- lineData.m_vecStart = start;
- lineData.m_vecStartVelocity = vec3_origin;
-
- lineData.m_vecEnd = end;
- lineData.m_vecEndVelocity = data.m_vNormal * random->RandomFloat( 64, 128 );
-
- FX_AddLine( lineData );
-}
-
-DECLARE_CLIENT_EFFECT( "AR2Explosion", AR2ExplosionCallback );
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : &data -
-//-----------------------------------------------------------------------------
-void AR2ImpactCallback( const CEffectData &data )
-{
- FX_AddQuad( data.m_vOrigin,
- data.m_vNormal,
- random->RandomFloat( 24, 32 ),
- 0,
- 0.75f,
- 1.0f,
- 0.0f,
- 0.4f,
- random->RandomInt( 0, 360 ),
- 0,
- Vector( 1.0f, 1.0f, 1.0f ),
- 0.25f,
- "effects/combinemuzzle2_nocull",
- (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
-}
-
-DECLARE_CLIENT_EFFECT( "AR2Impact", AR2ImpactCallback );
-
-//-----------------------------------------------------------------------------
-// Creates a muzzleflash elight
-//-----------------------------------------------------------------------------
-void CreateMuzzleflashELight( const Vector &origin, int exponent, int nMinRadius, int nMaxRadius, ClientEntityHandle_t hEntity )
-{
- if ( muzzleflash_light.GetInt() )
- {
- int entityIndex = ClientEntityList().HandleToEntIndex( hEntity );
- if ( entityIndex >= 0 )
- {
- dlight_t *el = effects->CL_AllocElight( LIGHT_INDEX_MUZZLEFLASH + entityIndex );
-
- el->origin = origin;
-
- el->color.r = 255;
- el->color.g = 192;
- el->color.b = 64;
- el->color.exponent = exponent;
-
- el->radius = random->RandomInt( nMinRadius, nMaxRadius );
- el->decay = el->radius / 0.05f;
- el->die = gpGlobals->curtime + 0.1f;
- }
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Airboat muzzle flashes
-//-----------------------------------------------------------------------------
-void MuzzleFlash_Airboat( ClientEntityHandle_t hEntity, int attachmentIndex )
-{
- VPROF_BUDGET( "MuzzleFlash_Airboat", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
-
- CSmartPtr<CLocalSpaceEmitter> pSimple = CLocalSpaceEmitter::Create( "MuzzleFlash", hEntity, attachmentIndex );
-
- SimpleParticle *pParticle;
- Vector forward(1,0,0), offset; //NOTENOTE: All coords are in local space
-
- float flScale = random->RandomFloat( 0.75f, IsXbox() ? 2.0f : 2.5f );
-
- PMaterialHandle pMuzzle[2];
- pMuzzle[0] = pSimple->GetPMaterial( "effects/combinemuzzle1" );
- pMuzzle[1] = pSimple->GetPMaterial( "effects/combinemuzzle2" );
-
- // Flash
- for ( int i = 1; i < 7; i++ )
- {
- offset = (forward * (i*6.0f*flScale));
-
- pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pMuzzle[random->RandomInt(0,1)], offset );
-
- if ( pParticle == NULL )
- return;
-
- pParticle->m_flLifetime = 0.0f;
- pParticle->m_flDieTime = IsXbox() ? 0.0001f : 0.01f;
-
- pParticle->m_vecVelocity.Init();
-
- pParticle->m_uchColor[0] = 255;
- pParticle->m_uchColor[1] = 255;
- pParticle->m_uchColor[2] = 255;
-
- pParticle->m_uchStartAlpha = 255;
- pParticle->m_uchEndAlpha = 128;
-
- pParticle->m_uchStartSize = ( (random->RandomFloat( 6.0f, 8.0f ) * (9-(i))/7) * flScale );
- pParticle->m_uchEndSize = pParticle->m_uchStartSize;
- pParticle->m_flRoll = random->RandomInt( 0, 360 );
- pParticle->m_flRollDelta = 0.0f;
- }
-
- // Tack on the smoke
- pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "sprites/ar2_muzzle1" ), vec3_origin );
-
- if ( pParticle == NULL )
- return;
-
- pParticle->m_flLifetime = 0.0f;
- pParticle->m_flDieTime = 0.05f;
-
- pParticle->m_vecVelocity.Init();
-
- pParticle->m_uchColor[0] = 255;
- pParticle->m_uchColor[1] = 255;
- pParticle->m_uchColor[2] = 255;
-
- pParticle->m_uchStartAlpha = 255;
- pParticle->m_uchEndAlpha = 128;
-
- pParticle->m_uchStartSize = random->RandomFloat( 16.0f, 24.0f );
- pParticle->m_uchEndSize = pParticle->m_uchStartSize;
-
- float spokePos = random->RandomInt( 0, 5 );
-
- pParticle->m_flRoll = (360.0/6.0f)*spokePos;
- pParticle->m_flRollDelta = 0.0f;
-
-#ifndef _XBOX
- // Grab the origin out of the transform for the attachment
- if ( muzzleflash_light.GetInt() )
- {
- // If the client hasn't seen this entity yet, bail.
- matrix3x4_t matAttachment;
- if ( FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) )
- {
- Vector origin;
- MatrixGetColumn( matAttachment, 3, &origin );
- CreateMuzzleflashELight( origin, 5, 64, 128, hEntity );
- }
- }
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void AirboatMuzzleFlashCallback( const CEffectData &data )
-{
- MuzzleFlash_Airboat( data.m_hEntity, data.m_nAttachmentIndex );
-}
-
-DECLARE_CLIENT_EFFECT( "AirboatMuzzleFlash", AirboatMuzzleFlashCallback );
-
-
-//-----------------------------------------------------------------------------
-// Chopper muzzle flashes
-//-----------------------------------------------------------------------------
-void MuzzleFlash_Chopper( ClientEntityHandle_t hEntity, int attachmentIndex )
-{
- VPROF_BUDGET( "MuzzleFlash_Chopper", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
-
- matrix3x4_t matAttachment;
- // If the client hasn't seen this entity yet, bail.
- if ( !FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) )
- return;
-
- CSmartPtr<CLocalSpaceEmitter> pSimple = CLocalSpaceEmitter::Create( "MuzzleFlash", hEntity, attachmentIndex );
-
- SimpleParticle *pParticle;
- Vector forward(1,0,0), offset; //NOTENOTE: All coords are in local space
-
- float flScale = random->RandomFloat( 2.5f, 4.5f );
-
- // Flash
- for ( int i = 1; i < 7; i++ )
- {
- offset = (forward * (i*2.0f*flScale));
-
- pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( VarArgs( "effects/combinemuzzle%d", random->RandomInt(1,2) ) ), offset );
-
- if ( pParticle == NULL )
- return;
-
- pParticle->m_flLifetime = 0.0f;
- pParticle->m_flDieTime = random->RandomFloat( 0.05f, 0.1f );
-
- pParticle->m_vecVelocity.Init();
-
- pParticle->m_uchColor[0] = 255;
- pParticle->m_uchColor[1] = 255;
- pParticle->m_uchColor[2] = 255;
-
- pParticle->m_uchStartAlpha = 255;
- pParticle->m_uchEndAlpha = 128;
-
- pParticle->m_uchStartSize = ( (random->RandomFloat( 6.0f, 8.0f ) * (10-(i))/7) * flScale );
- pParticle->m_uchEndSize = pParticle->m_uchStartSize;
- pParticle->m_flRoll = random->RandomInt( 0, 360 );
- pParticle->m_flRollDelta = 0.0f;
- }
-
- // Grab the origin out of the transform for the attachment
- Vector origin;
- MatrixGetColumn( matAttachment, 3, &origin );
- CreateMuzzleflashELight( origin, 6, 128, 256, hEntity );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void ChopperMuzzleFlashCallback( const CEffectData &data )
-{
- MuzzleFlash_Chopper( data.m_hEntity, data.m_nAttachmentIndex );
-}
-
-DECLARE_CLIENT_EFFECT( "ChopperMuzzleFlash", ChopperMuzzleFlashCallback );
-
-
-//-----------------------------------------------------------------------------
-// Gunship muzzle flashes
-//-----------------------------------------------------------------------------
-void MuzzleFlash_Gunship( ClientEntityHandle_t hEntity, int attachmentIndex )
-{
- VPROF_BUDGET( "MuzzleFlash_Gunship", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
-
- // If the client hasn't seen this entity yet, bail.
- matrix3x4_t matAttachment;
- if ( !FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) )
- return;
-
- CSmartPtr<CLocalSpaceEmitter> pSimple = CLocalSpaceEmitter::Create( "MuzzleFlash", hEntity, attachmentIndex );
-
- SimpleParticle *pParticle;
- Vector forward(1,0,0), offset; //NOTENOTE: All coords are in local space
-
- float flScale = random->RandomFloat( 2.5f, 4.5f );
-
- // Flash
- offset = (forward * (2.0f*flScale));
-
- pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/gunshipmuzzle" ), offset );
- if ( pParticle == NULL )
- return;
-
- pParticle->m_flLifetime = 0.0f;
- pParticle->m_flDieTime = random->RandomFloat( 0.05f, 0.1f );
-
- pParticle->m_vecVelocity.Init();
-
- pParticle->m_uchColor[0] = 255;
- pParticle->m_uchColor[1] = 255;
- pParticle->m_uchColor[2] = 255;
-
- pParticle->m_uchStartAlpha = 255;
- pParticle->m_uchEndAlpha = 128;
-
- pParticle->m_uchStartSize = ( (random->RandomFloat( 6.0f, 8.0f ) * 10.0/7.0) * flScale );
- pParticle->m_uchEndSize = pParticle->m_uchStartSize;
- pParticle->m_flRoll = random->RandomInt( 0, 360 );
- pParticle->m_flRollDelta = 0.0f;
-
- // Grab the origin out of the transform for the attachment
- Vector origin;
- MatrixGetColumn( matAttachment, 3, &origin );
- CreateMuzzleflashELight( origin, 6, 128, 256, hEntity );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void GunshipMuzzleFlashCallback( const CEffectData &data )
-{
- MuzzleFlash_Gunship( data.m_hEntity, data.m_nAttachmentIndex );
-}
-
-DECLARE_CLIENT_EFFECT( "GunshipMuzzleFlash", GunshipMuzzleFlashCallback );
-
-
-//-----------------------------------------------------------------------------
-// Hunter muzzle flashes
-//-----------------------------------------------------------------------------
-void MuzzleFlash_Hunter( ClientEntityHandle_t hEntity, int attachmentIndex )
-{
- VPROF_BUDGET( "MuzzleFlash_Hunter", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
-
- // If the client hasn't seen this entity yet, bail.
- matrix3x4_t matAttachment;
- if ( !FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) )
- return;
-
- // Grab the origin out of the transform for the attachment
- Vector origin;
- MatrixGetColumn( matAttachment, 3, &origin );
-
- dlight_t *el = effects->CL_AllocElight( LIGHT_INDEX_MUZZLEFLASH );
- el->origin = origin;// + Vector( 12.0f, 0, 0 );
-
- el->color.r = 50;
- el->color.g = 222;
- el->color.b = 213;
- el->color.exponent = 5;
-
- el->radius = random->RandomInt( 120, 200 );
- el->decay = el->radius / 0.05f;
- el->die = gpGlobals->curtime + 0.05f;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void HunterMuzzleFlashCallback( const CEffectData &data )
-{
- MuzzleFlash_Hunter( data.m_hEntity, data.m_nAttachmentIndex );
-}
-
-DECLARE_CLIENT_EFFECT( "HunterMuzzleFlash", HunterMuzzleFlashCallback );
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Game-specific impact effect hooks
+//
+//=============================================================================//
+#include "cbase.h"
+#include "fx.h"
+#include "c_te_effect_dispatch.h"
+#include "tier0/vprof.h"
+#include "fx_line.h"
+#include "fx_quad.h"
+#include "view.h"
+#include "particles_localspace.h"
+#include "dlight.h"
+#include "iefx.h"
+#include "clienteffectprecachesystem.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+extern Vector GetTracerOrigin( const CEffectData &data );
+extern void FX_TracerSound( const Vector &start, const Vector &end, int iTracerType );
+
+extern ConVar muzzleflash_light;
+
+
+CLIENTEFFECT_REGISTER_BEGIN( PrecacheTracers )
+CLIENTEFFECT_MATERIAL( "effects/gunshiptracer" )
+CLIENTEFFECT_MATERIAL( "effects/combinemuzzle1" )
+CLIENTEFFECT_MATERIAL( "effects/combinemuzzle2_nocull" )
+CLIENTEFFECT_REGISTER_END()
+
+//-----------------------------------------------------------------------------
+// Purpose: Gunship's Tracer
+//-----------------------------------------------------------------------------
+void GunshipTracerCallback( const CEffectData &data )
+{
+ float flVelocity = data.m_flScale;
+ bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
+ FX_GunshipTracer( (Vector&)data.m_vStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
+}
+
+DECLARE_CLIENT_EFFECT( "GunshipTracer", GunshipTracerCallback );
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Strider's Tracer
+//-----------------------------------------------------------------------------
+void StriderTracerCallback( const CEffectData &data )
+{
+ float flVelocity = data.m_flScale;
+ bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
+ FX_StriderTracer( (Vector&)data.m_vStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
+}
+
+DECLARE_CLIENT_EFFECT( "StriderTracer", StriderTracerCallback );
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Hunter's Tracer
+//-----------------------------------------------------------------------------
+void HunterTracerCallback( const CEffectData &data )
+{
+ float flVelocity = data.m_flScale;
+ bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
+ FX_HunterTracer( (Vector&)data.m_vStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
+}
+
+DECLARE_CLIENT_EFFECT( "HunterTracer", HunterTracerCallback );
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Gauss Gun's Tracer
+//-----------------------------------------------------------------------------
+void GaussTracerCallback( const CEffectData &data )
+{
+ float flVelocity = data.m_flScale;
+ bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
+ FX_GaussTracer( (Vector&)data.m_vStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
+}
+
+DECLARE_CLIENT_EFFECT( "GaussTracer", GaussTracerCallback );
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Airboat gun tracers
+//-----------------------------------------------------------------------------
+void AirboatGunHeavyTracerCallback( const CEffectData &data )
+{
+ // Grab the data
+ Vector vecStart = GetTracerOrigin( data );
+ float flVelocity = data.m_flScale;
+
+ // Use default velocity if none specified
+ if ( !flVelocity )
+ {
+ flVelocity = 8000;
+ }
+
+ //Get out shot direction and length
+ Vector vecShotDir;
+ VectorSubtract( data.m_vOrigin, vecStart, vecShotDir );
+ float flTotalDist = VectorNormalize( vecShotDir );
+
+ // Don't make small tracers
+ if ( flTotalDist <= 64 )
+ return;
+
+ float flLength = random->RandomFloat( 300.0f, 400.0f );
+ float flLife = ( flTotalDist + flLength ) / flVelocity; //NOTENOTE: We want the tail to finish its run as well
+
+ // Add it
+ FX_AddDiscreetLine( vecStart, vecShotDir, flVelocity, flLength, flTotalDist, 5.0f, flLife, "effects/gunshiptracer" );
+}
+
+DECLARE_CLIENT_EFFECT( "AirboatGunHeavyTracer", AirboatGunHeavyTracerCallback );
+
+//-----------------------------------------------------------------------------
+// Purpose: Airboat gun tracers
+//-----------------------------------------------------------------------------
+void AirboatGunTracerCallback( const CEffectData &data )
+{
+ // Grab the data
+ Vector vecStart = GetTracerOrigin( data );
+ float flVelocity = data.m_flScale;
+
+ // Use default velocity if none specified
+ if ( !flVelocity )
+ {
+ flVelocity = 10000;
+ }
+
+ //Get out shot direction and length
+ Vector vecShotDir;
+ VectorSubtract( data.m_vOrigin, vecStart, vecShotDir );
+ float flTotalDist = VectorNormalize( vecShotDir );
+
+ // Don't make small tracers
+ if ( flTotalDist <= 64 )
+ return;
+
+ float flLength = random->RandomFloat( 256.0f, 384.0f );
+ float flLife = ( flTotalDist + flLength ) / flVelocity; //NOTENOTE: We want the tail to finish its run as well
+
+ // Add it
+ FX_AddDiscreetLine( vecStart, vecShotDir, flVelocity, flLength, flTotalDist, 2.0f, flLife, "effects/gunshiptracer" );
+}
+
+DECLARE_CLIENT_EFFECT( "AirboatGunTracer", AirboatGunTracerCallback );
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Airboat gun tracers
+//-----------------------------------------------------------------------------
+void HelicopterTracerCallback( const CEffectData &data )
+{
+ // Grab the data
+ Vector vecStart = GetTracerOrigin( data );
+ float flVelocity = data.m_flScale;
+
+ // Use default velocity if none specified
+ if ( !flVelocity )
+ {
+ flVelocity = 8000;
+ }
+
+ //Get out shot direction and length
+ Vector vecShotDir;
+ VectorSubtract( data.m_vOrigin, vecStart, vecShotDir );
+ float flTotalDist = VectorNormalize( vecShotDir );
+
+ // Don't make small tracers
+ if ( flTotalDist <= 256 )
+ return;
+
+ float flLength = random->RandomFloat( 256.0f, 384.0f );
+ float flLife = ( flTotalDist + flLength ) / flVelocity; //NOTENOTE: We want the tail to finish its run as well
+
+ // Add it
+ FX_AddDiscreetLine( vecStart, vecShotDir, flVelocity, flLength, flTotalDist, 5.0f, flLife, "effects/gunshiptracer" );
+
+ if (data.m_fFlags & TRACER_FLAG_WHIZ)
+ {
+ FX_TracerSound( vecStart, data.m_vOrigin, TRACER_TYPE_GUNSHIP );
+ }
+}
+
+DECLARE_CLIENT_EFFECT( "HelicopterTracer", HelicopterTracerCallback );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : start -
+// end -
+//-----------------------------------------------------------------------------
+void FX_PlayerAR2Tracer( const Vector &start, const Vector &end )
+{
+ VPROF_BUDGET( "FX_PlayerAR2Tracer", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
+
+ Vector shotDir, dStart, dEnd;
+ float length;
+
+ //Find the direction of the tracer
+ VectorSubtract( end, start, shotDir );
+ length = VectorNormalize( shotDir );
+
+ //We don't want to draw them if they're too close to us
+ if ( length < 128 )
+ return;
+
+ //Randomly place the tracer along this line, with a random length
+ VectorMA( start, random->RandomFloat( 0.0f, 8.0f ), shotDir, dStart );
+ VectorMA( dStart, MIN( length, random->RandomFloat( 256.0f, 1024.0f ) ), shotDir, dEnd );
+
+ //Create the line
+ CFXStaticLine *tracerLine = new CFXStaticLine( "Tracer", dStart, dEnd, random->RandomFloat( 6.0f, 12.0f ), 0.01f, "effects/gunshiptracer", 0 );
+ assert( tracerLine );
+
+ //Throw it into the list
+ clienteffects->AddEffect( tracerLine );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : start -
+// end -
+// velocity -
+// makeWhiz -
+//-----------------------------------------------------------------------------
+void FX_AR2Tracer( Vector& start, Vector& end, int velocity, bool makeWhiz )
+{
+ VPROF_BUDGET( "FX_AR2Tracer", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
+
+ //Don't make small tracers
+ float dist;
+ Vector dir;
+
+ VectorSubtract( end, start, dir );
+ dist = VectorNormalize( dir );
+
+ // Don't make short tracers.
+ if ( dist < 128 )
+ return;
+
+ float length = random->RandomFloat( 128.0f, 256.0f );
+ float life = ( dist + length ) / velocity; //NOTENOTE: We want the tail to finish its run as well
+
+ //Add it
+ FX_AddDiscreetLine( start, dir, velocity, length, dist, random->RandomFloat( 0.5f, 1.5f ), life, "effects/gunshiptracer" );
+
+ if( makeWhiz )
+ {
+ FX_TracerSound( start, end, TRACER_TYPE_GUNSHIP );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void AR2TracerCallback( const CEffectData &data )
+{
+ C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
+
+ if ( player == NULL )
+ return;
+
+ // Grab the data
+ Vector vecStart = GetTracerOrigin( data );
+ float flVelocity = data.m_flScale;
+ bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
+ int iEntIndex = data.entindex();
+
+ if ( iEntIndex && iEntIndex == player->index )
+ {
+ Vector foo = data.m_vStart;
+ QAngle vangles;
+ Vector vforward, vright, vup;
+
+ engine->GetViewAngles( vangles );
+ AngleVectors( vangles, &vforward, &vright, &vup );
+
+ VectorMA( data.m_vStart, 4, vright, foo );
+ foo[2] -= 0.5f;
+
+ FX_PlayerAR2Tracer( foo, (Vector&)data.m_vOrigin );
+ return;
+ }
+
+ // Use default velocity if none specified
+ if ( !flVelocity )
+ {
+ flVelocity = 8000;
+ }
+
+ // Do tracer effect
+ FX_AR2Tracer( (Vector&)vecStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
+}
+
+DECLARE_CLIENT_EFFECT( "AR2Tracer", AR2TracerCallback );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &data -
+//-----------------------------------------------------------------------------
+void AR2ExplosionCallback( const CEffectData &data )
+{
+ float lifetime = random->RandomFloat( 0.4f, 0.75f );
+
+ // Ground splash
+ FX_AddQuad( data.m_vOrigin,
+ data.m_vNormal,
+ data.m_flRadius,
+ data.m_flRadius * 4.0f,
+ 0.85f,
+ 1.0f,
+ 0.0f,
+ 0.25f,
+ random->RandomInt( 0, 360 ),
+ random->RandomFloat( -4, 4 ),
+ Vector( 1.0f, 1.0f, 1.0f ),
+ lifetime,
+ "effects/combinemuzzle1",
+ (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
+
+ Vector vRight, vUp;
+ VectorVectors( data.m_vNormal, vRight, vUp );
+
+ Vector start, end;
+
+ float radius = data.m_flRadius * 0.15f;
+
+ // Base vertical shaft
+ FXLineData_t lineData;
+
+ start = data.m_vOrigin;
+ end = start + ( data.m_vNormal * random->RandomFloat( radius*2.0f, radius*4.0f ) );
+
+ lineData.m_flDieTime = lifetime;
+
+ lineData.m_flStartAlpha= 1.0f;
+ lineData.m_flEndAlpha = 0.0f;
+
+ lineData.m_flStartScale = radius*4;
+ lineData.m_flEndScale = radius*5;
+
+ lineData.m_pMaterial = materials->FindMaterial( "effects/ar2ground2", 0, 0 );
+
+ lineData.m_vecStart = start;
+ lineData.m_vecStartVelocity = vec3_origin;
+
+ lineData.m_vecEnd = end;
+ lineData.m_vecEndVelocity = data.m_vNormal * random->RandomFloat( 200, 350 );
+
+ FX_AddLine( lineData );
+
+ // Inner filler shaft
+ start = data.m_vOrigin;
+ end = start + ( data.m_vNormal * random->RandomFloat( 16, radius*0.25f ) );
+
+ lineData.m_flDieTime = lifetime - 0.1f;
+
+ lineData.m_flStartAlpha= 1.0f;
+ lineData.m_flEndAlpha = 0.0f;
+
+ lineData.m_flStartScale = radius*2;
+ lineData.m_flEndScale = radius*4;
+
+ lineData.m_pMaterial = materials->FindMaterial( "effects/ar2ground2", 0, 0 );
+
+ lineData.m_vecStart = start;
+ lineData.m_vecStartVelocity = vec3_origin;
+
+ lineData.m_vecEnd = end;
+ lineData.m_vecEndVelocity = data.m_vNormal * random->RandomFloat( 64, 128 );
+
+ FX_AddLine( lineData );
+}
+
+DECLARE_CLIENT_EFFECT( "AR2Explosion", AR2ExplosionCallback );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &data -
+//-----------------------------------------------------------------------------
+void AR2ImpactCallback( const CEffectData &data )
+{
+ FX_AddQuad( data.m_vOrigin,
+ data.m_vNormal,
+ random->RandomFloat( 24, 32 ),
+ 0,
+ 0.75f,
+ 1.0f,
+ 0.0f,
+ 0.4f,
+ random->RandomInt( 0, 360 ),
+ 0,
+ Vector( 1.0f, 1.0f, 1.0f ),
+ 0.25f,
+ "effects/combinemuzzle2_nocull",
+ (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
+}
+
+DECLARE_CLIENT_EFFECT( "AR2Impact", AR2ImpactCallback );
+
+//-----------------------------------------------------------------------------
+// Creates a muzzleflash elight
+//-----------------------------------------------------------------------------
+void CreateMuzzleflashELight( const Vector &origin, int exponent, int nMinRadius, int nMaxRadius, ClientEntityHandle_t hEntity )
+{
+ if ( muzzleflash_light.GetInt() )
+ {
+ int entityIndex = ClientEntityList().HandleToEntIndex( hEntity );
+ if ( entityIndex >= 0 )
+ {
+ dlight_t *el = effects->CL_AllocElight( LIGHT_INDEX_MUZZLEFLASH + entityIndex );
+
+ el->origin = origin;
+
+ el->color.r = 255;
+ el->color.g = 192;
+ el->color.b = 64;
+ el->color.exponent = exponent;
+
+ el->radius = random->RandomInt( nMinRadius, nMaxRadius );
+ el->decay = el->radius / 0.05f;
+ el->die = gpGlobals->curtime + 0.1f;
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Airboat muzzle flashes
+//-----------------------------------------------------------------------------
+void MuzzleFlash_Airboat( ClientEntityHandle_t hEntity, int attachmentIndex )
+{
+ VPROF_BUDGET( "MuzzleFlash_Airboat", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
+
+ CSmartPtr<CLocalSpaceEmitter> pSimple = CLocalSpaceEmitter::Create( "MuzzleFlash", hEntity, attachmentIndex );
+
+ SimpleParticle *pParticle;
+ Vector forward(1,0,0), offset; //NOTENOTE: All coords are in local space
+
+ float flScale = random->RandomFloat( 0.75f, IsXbox() ? 2.0f : 2.5f );
+
+ PMaterialHandle pMuzzle[2];
+ pMuzzle[0] = pSimple->GetPMaterial( "effects/combinemuzzle1" );
+ pMuzzle[1] = pSimple->GetPMaterial( "effects/combinemuzzle2" );
+
+ // Flash
+ for ( int i = 1; i < 7; i++ )
+ {
+ offset = (forward * (i*6.0f*flScale));
+
+ pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pMuzzle[random->RandomInt(0,1)], offset );
+
+ if ( pParticle == NULL )
+ return;
+
+ pParticle->m_flLifetime = 0.0f;
+ pParticle->m_flDieTime = IsXbox() ? 0.0001f : 0.01f;
+
+ pParticle->m_vecVelocity.Init();
+
+ pParticle->m_uchColor[0] = 255;
+ pParticle->m_uchColor[1] = 255;
+ pParticle->m_uchColor[2] = 255;
+
+ pParticle->m_uchStartAlpha = 255;
+ pParticle->m_uchEndAlpha = 128;
+
+ pParticle->m_uchStartSize = ( (random->RandomFloat( 6.0f, 8.0f ) * (9-(i))/7) * flScale );
+ pParticle->m_uchEndSize = pParticle->m_uchStartSize;
+ pParticle->m_flRoll = random->RandomInt( 0, 360 );
+ pParticle->m_flRollDelta = 0.0f;
+ }
+
+ // Tack on the smoke
+ pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "sprites/ar2_muzzle1" ), vec3_origin );
+
+ if ( pParticle == NULL )
+ return;
+
+ pParticle->m_flLifetime = 0.0f;
+ pParticle->m_flDieTime = 0.05f;
+
+ pParticle->m_vecVelocity.Init();
+
+ pParticle->m_uchColor[0] = 255;
+ pParticle->m_uchColor[1] = 255;
+ pParticle->m_uchColor[2] = 255;
+
+ pParticle->m_uchStartAlpha = 255;
+ pParticle->m_uchEndAlpha = 128;
+
+ pParticle->m_uchStartSize = random->RandomFloat( 16.0f, 24.0f );
+ pParticle->m_uchEndSize = pParticle->m_uchStartSize;
+
+ float spokePos = random->RandomInt( 0, 5 );
+
+ pParticle->m_flRoll = (360.0/6.0f)*spokePos;
+ pParticle->m_flRollDelta = 0.0f;
+
+#ifndef _XBOX
+ // Grab the origin out of the transform for the attachment
+ if ( muzzleflash_light.GetInt() )
+ {
+ // If the client hasn't seen this entity yet, bail.
+ matrix3x4_t matAttachment;
+ if ( FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) )
+ {
+ Vector origin;
+ MatrixGetColumn( matAttachment, 3, &origin );
+ CreateMuzzleflashELight( origin, 5, 64, 128, hEntity );
+ }
+ }
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void AirboatMuzzleFlashCallback( const CEffectData &data )
+{
+ MuzzleFlash_Airboat( data.m_hEntity, data.m_nAttachmentIndex );
+}
+
+DECLARE_CLIENT_EFFECT( "AirboatMuzzleFlash", AirboatMuzzleFlashCallback );
+
+
+//-----------------------------------------------------------------------------
+// Chopper muzzle flashes
+//-----------------------------------------------------------------------------
+void MuzzleFlash_Chopper( ClientEntityHandle_t hEntity, int attachmentIndex )
+{
+ VPROF_BUDGET( "MuzzleFlash_Chopper", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
+
+ matrix3x4_t matAttachment;
+ // If the client hasn't seen this entity yet, bail.
+ if ( !FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) )
+ return;
+
+ CSmartPtr<CLocalSpaceEmitter> pSimple = CLocalSpaceEmitter::Create( "MuzzleFlash", hEntity, attachmentIndex );
+
+ SimpleParticle *pParticle;
+ Vector forward(1,0,0), offset; //NOTENOTE: All coords are in local space
+
+ float flScale = random->RandomFloat( 2.5f, 4.5f );
+
+ // Flash
+ for ( int i = 1; i < 7; i++ )
+ {
+ offset = (forward * (i*2.0f*flScale));
+
+ pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( VarArgs( "effects/combinemuzzle%d", random->RandomInt(1,2) ) ), offset );
+
+ if ( pParticle == NULL )
+ return;
+
+ pParticle->m_flLifetime = 0.0f;
+ pParticle->m_flDieTime = random->RandomFloat( 0.05f, 0.1f );
+
+ pParticle->m_vecVelocity.Init();
+
+ pParticle->m_uchColor[0] = 255;
+ pParticle->m_uchColor[1] = 255;
+ pParticle->m_uchColor[2] = 255;
+
+ pParticle->m_uchStartAlpha = 255;
+ pParticle->m_uchEndAlpha = 128;
+
+ pParticle->m_uchStartSize = ( (random->RandomFloat( 6.0f, 8.0f ) * (10-(i))/7) * flScale );
+ pParticle->m_uchEndSize = pParticle->m_uchStartSize;
+ pParticle->m_flRoll = random->RandomInt( 0, 360 );
+ pParticle->m_flRollDelta = 0.0f;
+ }
+
+ // Grab the origin out of the transform for the attachment
+ Vector origin;
+ MatrixGetColumn( matAttachment, 3, &origin );
+ CreateMuzzleflashELight( origin, 6, 128, 256, hEntity );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void ChopperMuzzleFlashCallback( const CEffectData &data )
+{
+ MuzzleFlash_Chopper( data.m_hEntity, data.m_nAttachmentIndex );
+}
+
+DECLARE_CLIENT_EFFECT( "ChopperMuzzleFlash", ChopperMuzzleFlashCallback );
+
+
+//-----------------------------------------------------------------------------
+// Gunship muzzle flashes
+//-----------------------------------------------------------------------------
+void MuzzleFlash_Gunship( ClientEntityHandle_t hEntity, int attachmentIndex )
+{
+ VPROF_BUDGET( "MuzzleFlash_Gunship", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
+
+ // If the client hasn't seen this entity yet, bail.
+ matrix3x4_t matAttachment;
+ if ( !FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) )
+ return;
+
+ CSmartPtr<CLocalSpaceEmitter> pSimple = CLocalSpaceEmitter::Create( "MuzzleFlash", hEntity, attachmentIndex );
+
+ SimpleParticle *pParticle;
+ Vector forward(1,0,0), offset; //NOTENOTE: All coords are in local space
+
+ float flScale = random->RandomFloat( 2.5f, 4.5f );
+
+ // Flash
+ offset = (forward * (2.0f*flScale));
+
+ pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/gunshipmuzzle" ), offset );
+ if ( pParticle == NULL )
+ return;
+
+ pParticle->m_flLifetime = 0.0f;
+ pParticle->m_flDieTime = random->RandomFloat( 0.05f, 0.1f );
+
+ pParticle->m_vecVelocity.Init();
+
+ pParticle->m_uchColor[0] = 255;
+ pParticle->m_uchColor[1] = 255;
+ pParticle->m_uchColor[2] = 255;
+
+ pParticle->m_uchStartAlpha = 255;
+ pParticle->m_uchEndAlpha = 128;
+
+ pParticle->m_uchStartSize = ( (random->RandomFloat( 6.0f, 8.0f ) * 10.0/7.0) * flScale );
+ pParticle->m_uchEndSize = pParticle->m_uchStartSize;
+ pParticle->m_flRoll = random->RandomInt( 0, 360 );
+ pParticle->m_flRollDelta = 0.0f;
+
+ // Grab the origin out of the transform for the attachment
+ Vector origin;
+ MatrixGetColumn( matAttachment, 3, &origin );
+ CreateMuzzleflashELight( origin, 6, 128, 256, hEntity );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void GunshipMuzzleFlashCallback( const CEffectData &data )
+{
+ MuzzleFlash_Gunship( data.m_hEntity, data.m_nAttachmentIndex );
+}
+
+DECLARE_CLIENT_EFFECT( "GunshipMuzzleFlash", GunshipMuzzleFlashCallback );
+
+
+//-----------------------------------------------------------------------------
+// Hunter muzzle flashes
+//-----------------------------------------------------------------------------
+void MuzzleFlash_Hunter( ClientEntityHandle_t hEntity, int attachmentIndex )
+{
+ VPROF_BUDGET( "MuzzleFlash_Hunter", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
+
+ // If the client hasn't seen this entity yet, bail.
+ matrix3x4_t matAttachment;
+ if ( !FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) )
+ return;
+
+ // Grab the origin out of the transform for the attachment
+ Vector origin;
+ MatrixGetColumn( matAttachment, 3, &origin );
+
+ dlight_t *el = effects->CL_AllocElight( LIGHT_INDEX_MUZZLEFLASH );
+ el->origin = origin;// + Vector( 12.0f, 0, 0 );
+
+ el->color.r = 50;
+ el->color.g = 222;
+ el->color.b = 213;
+ el->color.exponent = 5;
+
+ el->radius = random->RandomInt( 120, 200 );
+ el->decay = el->radius / 0.05f;
+ el->die = gpGlobals->curtime + 0.05f;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void HunterMuzzleFlashCallback( const CEffectData &data )
+{
+ MuzzleFlash_Hunter( data.m_hEntity, data.m_nAttachmentIndex );
+}
+
+DECLARE_CLIENT_EFFECT( "HunterMuzzleFlash", HunterMuzzleFlashCallback );
diff --git a/mp/src/game/client/hl2/hl2_clientmode.cpp b/mp/src/game/client/hl2/hl2_clientmode.cpp
index 425c226a..26650ce2 100644
--- a/mp/src/game/client/hl2/hl2_clientmode.cpp
+++ b/mp/src/game/client/hl2/hl2_clientmode.cpp
@@ -1,77 +1,77 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-#include "cbase.h"
-#include "ivmodemanager.h"
-#include "clientmode_hlnormal.h"
-#include "panelmetaclassmgr.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-// default FOV for HL2
-ConVar default_fov( "default_fov", "75", FCVAR_CHEAT );
-
-// The current client mode. Always ClientModeNormal in HL.
-IClientMode *g_pClientMode = NULL;
-
-#define SCREEN_FILE "scripts/vgui_screens.txt"
-
-class CHLModeManager : public IVModeManager
-{
-public:
- CHLModeManager( void );
- virtual ~CHLModeManager( void );
-
- virtual void Init( void );
- virtual void SwitchMode( bool commander, bool force );
- virtual void OverrideView( CViewSetup *pSetup );
- virtual void CreateMove( float flInputSampleTime, CUserCmd *cmd );
- virtual void LevelInit( const char *newmap );
- virtual void LevelShutdown( void );
-};
-
-CHLModeManager::CHLModeManager( void )
-{
-}
-
-CHLModeManager::~CHLModeManager( void )
-{
-}
-
-void CHLModeManager::Init( void )
-{
- g_pClientMode = GetClientModeNormal();
- PanelMetaClassMgr()->LoadMetaClassDefinitionFile( SCREEN_FILE );
-}
-
-void CHLModeManager::SwitchMode( bool commander, bool force )
-{
-}
-
-void CHLModeManager::OverrideView( CViewSetup *pSetup )
-{
-}
-
-void CHLModeManager::CreateMove( float flInputSampleTime, CUserCmd *cmd )
-{
-}
-
-void CHLModeManager::LevelInit( const char *newmap )
-{
- g_pClientMode->LevelInit( newmap );
-}
-
-void CHLModeManager::LevelShutdown( void )
-{
- g_pClientMode->LevelShutdown();
-}
-
-
-static CHLModeManager g_HLModeManager;
-IVModeManager *modemanager = &g_HLModeManager;
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#include "cbase.h"
+#include "ivmodemanager.h"
+#include "clientmode_hlnormal.h"
+#include "panelmetaclassmgr.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+// default FOV for HL2
+ConVar default_fov( "default_fov", "75", FCVAR_CHEAT );
+
+// The current client mode. Always ClientModeNormal in HL.
+IClientMode *g_pClientMode = NULL;
+
+#define SCREEN_FILE "scripts/vgui_screens.txt"
+
+class CHLModeManager : public IVModeManager
+{
+public:
+ CHLModeManager( void );
+ virtual ~CHLModeManager( void );
+
+ virtual void Init( void );
+ virtual void SwitchMode( bool commander, bool force );
+ virtual void OverrideView( CViewSetup *pSetup );
+ virtual void CreateMove( float flInputSampleTime, CUserCmd *cmd );
+ virtual void LevelInit( const char *newmap );
+ virtual void LevelShutdown( void );
+};
+
+CHLModeManager::CHLModeManager( void )
+{
+}
+
+CHLModeManager::~CHLModeManager( void )
+{
+}
+
+void CHLModeManager::Init( void )
+{
+ g_pClientMode = GetClientModeNormal();
+ PanelMetaClassMgr()->LoadMetaClassDefinitionFile( SCREEN_FILE );
+}
+
+void CHLModeManager::SwitchMode( bool commander, bool force )
+{
+}
+
+void CHLModeManager::OverrideView( CViewSetup *pSetup )
+{
+}
+
+void CHLModeManager::CreateMove( float flInputSampleTime, CUserCmd *cmd )
+{
+}
+
+void CHLModeManager::LevelInit( const char *newmap )
+{
+ g_pClientMode->LevelInit( newmap );
+}
+
+void CHLModeManager::LevelShutdown( void )
+{
+ g_pClientMode->LevelShutdown();
+}
+
+
+static CHLModeManager g_HLModeManager;
+IVModeManager *modemanager = &g_HLModeManager;
+
diff --git a/mp/src/game/client/hl2/hl_in_main.cpp b/mp/src/game/client/hl2/hl_in_main.cpp
index 578950f0..7cdf4e07 100644
--- a/mp/src/game/client/hl2/hl_in_main.cpp
+++ b/mp/src/game/client/hl2/hl_in_main.cpp
@@ -1,25 +1,25 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: HL2 specific input handling
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "kbutton.h"
-#include "input.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//-----------------------------------------------------------------------------
-// Purpose: HL Input interface
-//-----------------------------------------------------------------------------
-class CHLInput : public CInput
-{
-public:
-};
-
-static CHLInput g_Input;
-
-// Expose this interface
-IInput *input = ( IInput * )&g_Input;
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: HL2 specific input handling
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "kbutton.h"
+#include "input.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: HL Input interface
+//-----------------------------------------------------------------------------
+class CHLInput : public CInput
+{
+public:
+};
+
+static CHLInput g_Input;
+
+// Expose this interface
+IInput *input = ( IInput * )&g_Input;
diff --git a/mp/src/game/client/hl2/hl_prediction.cpp b/mp/src/game/client/hl2/hl_prediction.cpp
index c12ce094..090598f0 100644
--- a/mp/src/game/client/hl2/hl_prediction.cpp
+++ b/mp/src/game/client/hl2/hl_prediction.cpp
@@ -1,24 +1,24 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "prediction.h"
-#include "hl_movedata.h"
-#include "c_basehlplayer.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-static CHLMoveData g_HLMoveData;
-CMoveData *g_pMoveData = &g_HLMoveData;
-
-// Expose interface to engine
-static CPrediction g_Prediction;
-
-EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CPrediction, IPrediction, VCLIENT_PREDICTION_INTERFACE_VERSION, g_Prediction );
-
-CPrediction *prediction = &g_Prediction;
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "prediction.h"
+#include "hl_movedata.h"
+#include "c_basehlplayer.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+static CHLMoveData g_HLMoveData;
+CMoveData *g_pMoveData = &g_HLMoveData;
+
+// Expose interface to engine
+static CPrediction g_Prediction;
+
+EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CPrediction, IPrediction, VCLIENT_PREDICTION_INTERFACE_VERSION, g_Prediction );
+
+CPrediction *prediction = &g_Prediction;
+
diff --git a/mp/src/game/client/hl2/hud_ammo.cpp b/mp/src/game/client/hl2/hud_ammo.cpp
index f6641d5b..9e9e9139 100644
--- a/mp/src/game/client/hl2/hud_ammo.cpp
+++ b/mp/src/game/client/hl2/hud_ammo.cpp
@@ -1,502 +1,502 @@
-//========= 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 <vgui/ISurface.h>
-#include "ihudlcd.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-using namespace vgui;
-
-//-----------------------------------------------------------------------------
-// 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);
- virtual void Paint( void );
-
-protected:
- virtual void OnThink();
-
- void UpdateAmmoDisplays();
- void UpdatePlayerAmmo( C_BasePlayer *player );
- void UpdateVehicleAmmo( C_BasePlayer *player, IClientVehicle *pVehicle );
-
-private:
- CHandle< C_BaseCombatWeapon > m_hCurrentActiveWeapon;
- CHandle< C_BaseEntity > m_hCurrentVehicle;
- int m_iAmmo;
- int m_iAmmo2;
- CHudTexture *m_iconPrimaryAmmo;
-};
-
-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;
-
- m_iconPrimaryAmmo = NULL;
-
- 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 our icons for the ammo types
- m_iconPrimaryAmmo = gWR.GetAmmoIconFromWeapon( wpn->GetPrimaryAmmoType() );
-
- // 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();
- IClientVehicle *pVehicle = player ? player->GetVehicle() : NULL;
-
- if ( !pVehicle )
- {
- UpdatePlayerAmmo( player );
- }
- else
- {
- UpdateVehicleAmmo( player, pVehicle );
- }
-}
-
-//-----------------------------------------------------------------------------
-// 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: We add an icon into the
-//-----------------------------------------------------------------------------
-void CHudAmmo::Paint( void )
-{
- BaseClass::Paint();
-
-#ifndef HL2MP
- if ( m_hCurrentVehicle == NULL && m_iconPrimaryAmmo )
- {
- int nLabelHeight;
- int nLabelWidth;
- surface()->GetTextSize( m_hTextFont, m_LabelText, nLabelWidth, nLabelHeight );
-
- // Figure out where we're going to put this
- int x = text_xpos + ( nLabelWidth - m_iconPrimaryAmmo->Width() ) / 2;
- int y = text_ypos - ( nLabelHeight + ( m_iconPrimaryAmmo->Height() / 2 ) );
-
- m_iconPrimaryAmmo->DrawSelf( x, y, GetFgColor() );
- }
-#endif // HL2MP
-}
-
-//-----------------------------------------------------------------------------
-// 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 )
- {
-#ifndef HL2MP
- wchar_t *tempString = g_pVGuiLocalize->Find("#Valve_Hud_AMMO_ALT");
- if (tempString)
- {
- SetLabelText(tempString);
- }
- else
- {
- SetLabelText(L"ALT");
- }
-#endif // HL2MP
- }
-
- 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();
- }
-
- virtual void Paint( void )
- {
- BaseClass::Paint();
-
-#ifndef HL2MP
- if ( m_iconSecondaryAmmo )
- {
- int nLabelHeight;
- int nLabelWidth;
- surface()->GetTextSize( m_hTextFont, m_LabelText, nLabelWidth, nLabelHeight );
-
- // Figure out where we're going to put this
- int x = text_xpos + ( nLabelWidth - m_iconSecondaryAmmo->Width() ) / 2;
- int y = text_ypos - ( nLabelHeight + ( m_iconSecondaryAmmo->Height() / 2 ) );
-
- m_iconSecondaryAmmo->DrawSelf( x, y, GetFgColor() );
- }
-#endif // HL2MP
- }
-
-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;
-
- // Get the icon we should be displaying
- m_iconSecondaryAmmo = gWR.GetAmmoIconFromWeapon( m_hCurrentActiveWeapon->GetSecondaryAmmoType() );
- }
- }
-
-private:
- CHandle< C_BaseCombatWeapon > m_hCurrentActiveWeapon;
- CHudTexture *m_iconSecondaryAmmo;
- int m_iAmmo;
-};
-
-DECLARE_HUDELEMENT( CHudSecondaryAmmo );
-
+//========= 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 <vgui/ISurface.h>
+#include "ihudlcd.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+using namespace vgui;
+
+//-----------------------------------------------------------------------------
+// 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);
+ virtual void Paint( void );
+
+protected:
+ virtual void OnThink();
+
+ void UpdateAmmoDisplays();
+ void UpdatePlayerAmmo( C_BasePlayer *player );
+ void UpdateVehicleAmmo( C_BasePlayer *player, IClientVehicle *pVehicle );
+
+private:
+ CHandle< C_BaseCombatWeapon > m_hCurrentActiveWeapon;
+ CHandle< C_BaseEntity > m_hCurrentVehicle;
+ int m_iAmmo;
+ int m_iAmmo2;
+ CHudTexture *m_iconPrimaryAmmo;
+};
+
+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;
+
+ m_iconPrimaryAmmo = NULL;
+
+ 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 our icons for the ammo types
+ m_iconPrimaryAmmo = gWR.GetAmmoIconFromWeapon( wpn->GetPrimaryAmmoType() );
+
+ // 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();
+ IClientVehicle *pVehicle = player ? player->GetVehicle() : NULL;
+
+ if ( !pVehicle )
+ {
+ UpdatePlayerAmmo( player );
+ }
+ else
+ {
+ UpdateVehicleAmmo( player, pVehicle );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// 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: We add an icon into the
+//-----------------------------------------------------------------------------
+void CHudAmmo::Paint( void )
+{
+ BaseClass::Paint();
+
+#ifndef HL2MP
+ if ( m_hCurrentVehicle == NULL && m_iconPrimaryAmmo )
+ {
+ int nLabelHeight;
+ int nLabelWidth;
+ surface()->GetTextSize( m_hTextFont, m_LabelText, nLabelWidth, nLabelHeight );
+
+ // Figure out where we're going to put this
+ int x = text_xpos + ( nLabelWidth - m_iconPrimaryAmmo->Width() ) / 2;
+ int y = text_ypos - ( nLabelHeight + ( m_iconPrimaryAmmo->Height() / 2 ) );
+
+ m_iconPrimaryAmmo->DrawSelf( x, y, GetFgColor() );
+ }
+#endif // HL2MP
+}
+
+//-----------------------------------------------------------------------------
+// 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 )
+ {
+#ifndef HL2MP
+ wchar_t *tempString = g_pVGuiLocalize->Find("#Valve_Hud_AMMO_ALT");
+ if (tempString)
+ {
+ SetLabelText(tempString);
+ }
+ else
+ {
+ SetLabelText(L"ALT");
+ }
+#endif // HL2MP
+ }
+
+ 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();
+ }
+
+ virtual void Paint( void )
+ {
+ BaseClass::Paint();
+
+#ifndef HL2MP
+ if ( m_iconSecondaryAmmo )
+ {
+ int nLabelHeight;
+ int nLabelWidth;
+ surface()->GetTextSize( m_hTextFont, m_LabelText, nLabelWidth, nLabelHeight );
+
+ // Figure out where we're going to put this
+ int x = text_xpos + ( nLabelWidth - m_iconSecondaryAmmo->Width() ) / 2;
+ int y = text_ypos - ( nLabelHeight + ( m_iconSecondaryAmmo->Height() / 2 ) );
+
+ m_iconSecondaryAmmo->DrawSelf( x, y, GetFgColor() );
+ }
+#endif // HL2MP
+ }
+
+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;
+
+ // Get the icon we should be displaying
+ m_iconSecondaryAmmo = gWR.GetAmmoIconFromWeapon( m_hCurrentActiveWeapon->GetSecondaryAmmoType() );
+ }
+ }
+
+private:
+ CHandle< C_BaseCombatWeapon > m_hCurrentActiveWeapon;
+ CHudTexture *m_iconSecondaryAmmo;
+ int m_iAmmo;
+};
+
+DECLARE_HUDELEMENT( CHudSecondaryAmmo );
+
diff --git a/mp/src/game/client/hl2/hud_autoaim.cpp b/mp/src/game/client/hl2/hud_autoaim.cpp
index 6b1d4a33..3339a72f 100644
--- a/mp/src/game/client/hl2/hud_autoaim.cpp
+++ b/mp/src/game/client/hl2/hud_autoaim.cpp
@@ -1,470 +1,470 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-#include "cbase.h"
-#include "hud.h"
-#include "hudelement.h"
-#include "iclientmode.h"
-#include "c_basehlplayer.h"
-#include "view_scene.h"
-#include "engine/IEngineSound.h"
-#include "vgui_controls/AnimationController.h"
-#include "vgui_controls/Controls.h"
-#include "vgui_controls/Panel.h"
-#include "vgui/ISurface.h"
-#include "iviewrender.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-ConVar hud_draw_active_reticle("hud_draw_active_reticle", "0" );
-ConVar hud_draw_fixed_reticle("hud_draw_fixed_reticle", "0", FCVAR_ARCHIVE );
-ConVar hud_autoaim_scale_icon( "hud_autoaim_scale_icon", "0" );
-ConVar hud_autoaim_method( "hud_autoaim_method", "1" );
-
-ConVar hud_reticle_scale("hud_reticle_scale", "1.0" );
-ConVar hud_reticle_minalpha( "hud_reticle_minalpha", "125" );
-ConVar hud_reticle_maxalpha( "hud_reticle_maxalpha", "255" );
-ConVar hud_alpha_speed("hud_reticle_alpha_speed", "700" );
-ConVar hud_magnetism("hud_magnetism", "0.3" );
-
-enum
-{
- AUTOAIM_METHOD_RETICLE = 1,
- AUTOAIM_METHOD_DRIFT,
-};
-
-using namespace vgui;
-
-class CHUDAutoAim : public CHudElement, public vgui::Panel
-{
- DECLARE_CLASS_SIMPLE( CHUDAutoAim, vgui::Panel );
-public:
- CHUDAutoAim( const char *pElementName );
- virtual ~CHUDAutoAim( void );
-
- void ApplySchemeSettings( IScheme *scheme );
- void Init( void );
- void VidInit( void );
- bool ShouldDraw( void );
- virtual void OnThink();
- virtual void Paint();
-
-private:
- void ResetAlpha() { m_alpha = 0; }
- void ResetScale() { m_scale = 1.0f; }
-
- void ResetPosition()
- {
- m_vecPos.x = ScreenWidth() / 2;
- m_vecPos.y = ScreenHeight() / 2;
- m_vecPos.z = 0;
- }
-
- Vector m_vecPos;
- float m_alpha;
- float m_scale;
-
- float m_alphaFixed; // alpha value for the fixed element.
-
- int m_textureID_ActiveReticle;
- int m_textureID_FixedReticle;
-};
-
-DECLARE_HUDELEMENT( CHUDAutoAim );
-
-CHUDAutoAim::CHUDAutoAim( const char *pElementName ) :
- CHudElement( pElementName ), BaseClass( NULL, "HUDAutoAim" )
-{
- vgui::Panel *pParent = g_pClientMode->GetViewport();
- SetParent( pParent );
- SetHiddenBits( HIDEHUD_CROSSHAIR );
-
- m_textureID_ActiveReticle = -1;
- m_textureID_FixedReticle = -1;
-}
-
-CHUDAutoAim::~CHUDAutoAim( void )
-{
- if ( vgui::surface() )
- {
- if ( m_textureID_ActiveReticle != -1 )
- {
- vgui::surface()->DestroyTextureID( m_textureID_ActiveReticle );
- m_textureID_ActiveReticle = -1;
- }
-
- if ( m_textureID_FixedReticle != -1 )
- {
- vgui::surface()->DestroyTextureID( m_textureID_FixedReticle );
- m_textureID_FixedReticle = -1;
- }
- }
-}
-
-
-void CHUDAutoAim::ApplySchemeSettings( IScheme *scheme )
-{
- BaseClass::ApplySchemeSettings( scheme );
-
- SetPaintBackgroundEnabled( false );
-}
-
-void CHUDAutoAim::Init( void )
-{
- ResetPosition();
- ResetAlpha();
- ResetScale();
-}
-
-void CHUDAutoAim::VidInit( void )
-{
- SetAlpha( 255 );
- Init();
-
- if ( m_textureID_ActiveReticle == -1 )
- {
- m_textureID_ActiveReticle = vgui::surface()->CreateNewTextureID();
- vgui::surface()->DrawSetTextureFile( m_textureID_ActiveReticle, "vgui/hud/autoaim", true, false );
- }
-
- if ( m_textureID_FixedReticle == -1 )
- {
- m_textureID_FixedReticle = vgui::surface()->CreateNewTextureID();
- vgui::surface()->DrawSetTextureFile( m_textureID_FixedReticle, "vgui/hud/xbox_reticle", true, false );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Save CPU cycles by letting the HUD system early cull
-// costly traversal. Called per frame, return true if thinking and
-// painting need to occur.
-//-----------------------------------------------------------------------------
-bool CHUDAutoAim::ShouldDraw( void )
-{
- C_BaseHLPlayer *pLocalPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
- if ( pLocalPlayer )
- {
- if( !pLocalPlayer->m_HL2Local.m_bDisplayReticle )
- {
- return false;
- }
- }
-
- return ( (hud_draw_fixed_reticle.GetBool() || hud_draw_active_reticle.GetBool()) && CHudElement::ShouldDraw() && !engine->IsDrawingLoadingImage() );
-}
-
-#define AUTOAIM_ALPHA_UP_SPEED 1000
-#define AUTOAIM_ALPHA_DOWN_SPEED 300
-#define AUTOAIM_MAX_ALPHA 120
-#define AUTOAIM_MAX_SCALE 1.0f
-#define AUTOAIM_MIN_SCALE 0.5f
-#define AUTOAIM_SCALE_SPEED 10.0f
-#define AUTOAIM_ONTARGET_CROSSHAIR_SPEED (ScreenWidth() / 3) // Can cross the whole screen in 3 seconds.
-#define AUTOAIM_OFFTARGET_CROSSHAIR_SPEED (ScreenWidth() / 4)
-
-void CHUDAutoAim::OnThink()
-{
- int wide, tall;
- GetSize( wide, tall );
-
- BaseClass::OnThink();
-
- // Get the HL2 player
- C_BaseHLPlayer *pLocalPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
- if ( pLocalPlayer == NULL )
- {
- // Just turn the autoaim crosshair off.
- ResetPosition();
- ResetAlpha();
- ResetScale();
-
- m_alphaFixed = 0.0f;
- return;
- }
-
- // Get the autoaim target.
- CBaseEntity *pTarget = pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get();
-
- // Fixed element stuff
- float flFixedAlphaGoal;
-
- if( pTarget )
- {
- flFixedAlphaGoal = hud_reticle_maxalpha.GetFloat();
- }
- else
- {
- flFixedAlphaGoal = hud_reticle_minalpha.GetFloat();
- }
-
- if( pLocalPlayer->m_HL2Local.m_bZooming || pLocalPlayer->m_HL2Local.m_bWeaponLowered )
- {
- flFixedAlphaGoal = 0.0f;
- }
-
- m_alphaFixed = Approach( flFixedAlphaGoal, m_alphaFixed, (hud_alpha_speed.GetFloat() * gpGlobals->frametime) );
-
-
- switch( hud_autoaim_method.GetInt() )
- {
- case AUTOAIM_METHOD_RETICLE:
- {
- if( pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get() && pLocalPlayer->m_HL2Local.m_bStickyAutoAim )
- {
- if( !pLocalPlayer->IsInAVehicle() )
- {
- Vector vecLook;
- pLocalPlayer->EyeVectors( &vecLook, NULL, NULL );
-
- Vector vecMove = pLocalPlayer->GetAbsVelocity();
- float flSpeed = VectorNormalize( vecMove );
- float flDot = DotProduct( vecLook, vecMove );
-
- if( flSpeed >= 100 && fabs(flDot) <= 0.707f )
- {
- QAngle viewangles;
- QAngle targetangles;
- QAngle delta;
-
- engine->GetViewAngles( viewangles );
-
- Vector vecDir = pLocalPlayer->m_HL2Local.m_vecAutoAimPoint - pLocalPlayer->EyePosition();
- VectorNormalize(vecDir);
- VectorAngles( vecDir, targetangles );
-
- float magnetism = hud_magnetism.GetFloat();
-
- delta[0] = ApproachAngle( targetangles[0], viewangles[0], magnetism );
- delta[1] = ApproachAngle( targetangles[1], viewangles[1], magnetism );
- delta[2] = targetangles[2];
-
- //viewangles[PITCH] = clamp( viewangles[ PITCH ], -cl_pitchup.GetFloat(), cl_pitchdown.GetFloat() );
- engine->SetViewAngles( delta );
- }
- }
- }
-
-#if 0
- bool doScaling = hud_autoaim_scale_icon.GetBool();
-
- // These are the X & Y coords of where the crosshair should be. Default to
- // returning to the center of the screen if there is no target.
- int goalx = ScreenWidth() / 2;
- int goaly = ScreenHeight() / 2;
- int goalalpha = 0;
- float goalscale = AUTOAIM_MIN_SCALE;
- float speed = AUTOAIM_OFFTARGET_CROSSHAIR_SPEED;
-
- if( pTarget )
- {
- // Get the autoaim crosshair onto the target.
- Vector screen;
-
- // Center the crosshair on the entity.
- if( doScaling )
- {
- // Put the crosshair over the center of the target.
- ScreenTransform( pTarget->WorldSpaceCenter(), screen );
- }
- else
- {
- // Put the crosshair exactly where the player is aiming.
- ScreenTransform( pLocalPlayer->m_HL2Local.m_vecAutoAimPoint, screen );
- }
-
- // Set Goal Position and speed.
- goalx += 0.5f * screen[0] * ScreenWidth() + 0.5f;
- goaly -= 0.5f * screen[1] * ScreenHeight() + 0.5f;
- speed = AUTOAIM_ONTARGET_CROSSHAIR_SPEED;
-
- goalalpha = AUTOAIM_MAX_ALPHA;
-
- if( doScaling )
- {
- // Scale the crosshair to envelope the entity's bounds on screen.
- Vector vecMins, vecMaxs;
- Vector vecScreenMins, vecScreenMaxs;
-
- // Get mins and maxs in world space
- vecMins = pTarget->GetAbsOrigin() + pTarget->WorldAlignMins();
- vecMaxs = pTarget->GetAbsOrigin() + pTarget->WorldAlignMaxs();
-
- // Project them to screen
- ScreenTransform( vecMins, vecScreenMins );
- ScreenTransform( vecMaxs, vecScreenMaxs );
-
- vecScreenMins.y = (ScreenWidth()/2) - 0.5f * vecScreenMins.y * ScreenWidth() + 0.5f;
- vecScreenMaxs.y = (ScreenWidth()/2) - 0.5f * vecScreenMaxs.y * ScreenWidth() + 0.5f;
-
- float screenSize = vecScreenMins.y - vecScreenMaxs.y;
-
- // Set goal scale
- goalscale = screenSize / 64.0f; // 64 is the width of the crosshair art.
- }
- else
- {
- goalscale = 1.0f;
- }
- }
-
- // Now approach the goal, alpha, and scale
- Vector vecGoal( goalx, goaly, 0 );
- Vector vecDir = vecGoal - m_vecPos;
- float flDistRemaining = VectorNormalize( vecDir );
- m_vecPos += vecDir * min(flDistRemaining, (speed * gpGlobals->frametime) );
-
- // Lerp and Clamp scale
- float scaleDelta = fabs( goalscale - m_scale );
- float scaleMove = MIN( AUTOAIM_SCALE_SPEED * gpGlobals->frametime, scaleDelta );
- if( m_scale < goalscale )
- {
- m_scale += scaleMove;
- }
- else if( m_scale > goalscale )
- {
- m_scale -= scaleMove;
- }
- if( m_scale > AUTOAIM_MAX_SCALE )
- {
- m_scale = AUTOAIM_MAX_SCALE;
- }
- else if( m_scale < AUTOAIM_MIN_SCALE )
- {
- m_scale = AUTOAIM_MIN_SCALE;
- }
-
- if( goalalpha > m_alpha )
- {
- m_alpha += AUTOAIM_ALPHA_UP_SPEED * gpGlobals->frametime;
- }
- else if( goalalpha < m_alpha )
- {
- m_alpha -= AUTOAIM_ALPHA_DOWN_SPEED * gpGlobals->frametime;
- }
-
- // Clamp alpha
- if( m_alpha < 0 )
- {
- m_alpha = 0;
- }
- else if( m_alpha > AUTOAIM_MAX_ALPHA )
- {
- m_alpha = AUTOAIM_MAX_ALPHA;
- }
-#endif
- }
- break;
-
- case AUTOAIM_METHOD_DRIFT:
- {
- if( pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get() )
- {
- QAngle viewangles;
-
- engine->GetViewAngles( viewangles );
-
- Vector vecDir = pLocalPlayer->m_HL2Local.m_vecAutoAimPoint - pLocalPlayer->EyePosition();
- VectorNormalize(vecDir);
-
- VectorAngles( vecDir, viewangles );
-
- //viewangles[PITCH] = clamp( viewangles[ PITCH ], -cl_pitchup.GetFloat(), cl_pitchdown.GetFloat() );
- engine->SetViewAngles( viewangles );
- }
- }
- break;
- }
-}
-
-void CHUDAutoAim::Paint()
-{
- if( hud_draw_active_reticle.GetBool() )
- {
- int xCenter = m_vecPos.x;
- int yCenter = m_vecPos.y;
-
- int width, height;
- float xMod, yMod;
-
- vgui::surface()->DrawSetTexture( m_textureID_ActiveReticle );
- vgui::surface()->DrawSetColor( 255, 255, 255, m_alpha );
- vgui::surface()->DrawGetTextureSize( m_textureID_ActiveReticle, width, height );
-
- float uv1 = 0.5f / width, uv2 = 1.0f - uv1;
-
- vgui::Vertex_t vert[4];
-
- Vector2D uv11( uv1, uv1 );
- Vector2D uv12( uv1, uv2 );
- Vector2D uv21( uv2, uv1 );
- Vector2D uv22( uv2, uv2 );
-
- xMod = width;
- yMod = height;
-
- xMod *= m_scale;
- yMod *= m_scale;
-
- xMod /= 2;
- yMod /= 2;
-
- vert[0].Init( Vector2D( xCenter + xMod, yCenter + yMod ), uv21 );
- vert[1].Init( Vector2D( xCenter - xMod, yCenter + yMod ), uv11 );
- vert[2].Init( Vector2D( xCenter - xMod, yCenter - yMod ), uv12 );
- vert[3].Init( Vector2D( xCenter + xMod, yCenter - yMod ), uv22 );
- vgui::surface()->DrawTexturedPolygon( 4, vert );
- }
-
- if( hud_draw_fixed_reticle.GetBool() )
- {
- int width, height;
- float xMod, yMod;
-
- vgui::surface()->DrawSetTexture( m_textureID_FixedReticle );
- vgui::surface()->DrawGetTextureSize( m_textureID_FixedReticle, width, height );
-
- int xCenter = ScreenWidth() / 2;
- int yCenter = ScreenHeight() / 2;
-
- vgui::Vertex_t vert[4];
-
- Vector2D uv11( 0, 0 );
- Vector2D uv12( 0, 1 );
- Vector2D uv21( 1, 0 );
- Vector2D uv22( 1, 1 );
-
- xMod = width;
- yMod = height;
-
- xMod /= 2;
- yMod /= 2;
-
- vert[0].Init( Vector2D( xCenter + xMod, yCenter + yMod ), uv21 );
- vert[1].Init( Vector2D( xCenter - xMod, yCenter + yMod ), uv11 );
- vert[2].Init( Vector2D( xCenter - xMod, yCenter - yMod ), uv12 );
- vert[3].Init( Vector2D( xCenter + xMod, yCenter - yMod ), uv22 );
-
- Color clr;
- clr = gHUD.m_clrNormal;
- int r,g,b,a;
- clr.GetColor( r,g,b,a );
-
- C_BaseHLPlayer *pLocalPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
- if( pLocalPlayer && pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get() )
- {
- r = 250;
- g = 138;
- b = 4;
- }
-
- clr.SetColor( r,g,b,m_alphaFixed);
-
- vgui::surface()->DrawSetColor( clr );
- vgui::surface()->DrawTexturedPolygon( 4, vert );
- }
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#include "cbase.h"
+#include "hud.h"
+#include "hudelement.h"
+#include "iclientmode.h"
+#include "c_basehlplayer.h"
+#include "view_scene.h"
+#include "engine/IEngineSound.h"
+#include "vgui_controls/AnimationController.h"
+#include "vgui_controls/Controls.h"
+#include "vgui_controls/Panel.h"
+#include "vgui/ISurface.h"
+#include "iviewrender.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+ConVar hud_draw_active_reticle("hud_draw_active_reticle", "0" );
+ConVar hud_draw_fixed_reticle("hud_draw_fixed_reticle", "0", FCVAR_ARCHIVE );
+ConVar hud_autoaim_scale_icon( "hud_autoaim_scale_icon", "0" );
+ConVar hud_autoaim_method( "hud_autoaim_method", "1" );
+
+ConVar hud_reticle_scale("hud_reticle_scale", "1.0" );
+ConVar hud_reticle_minalpha( "hud_reticle_minalpha", "125" );
+ConVar hud_reticle_maxalpha( "hud_reticle_maxalpha", "255" );
+ConVar hud_alpha_speed("hud_reticle_alpha_speed", "700" );
+ConVar hud_magnetism("hud_magnetism", "0.3" );
+
+enum
+{
+ AUTOAIM_METHOD_RETICLE = 1,
+ AUTOAIM_METHOD_DRIFT,
+};
+
+using namespace vgui;
+
+class CHUDAutoAim : public CHudElement, public vgui::Panel
+{
+ DECLARE_CLASS_SIMPLE( CHUDAutoAim, vgui::Panel );
+public:
+ CHUDAutoAim( const char *pElementName );
+ virtual ~CHUDAutoAim( void );
+
+ void ApplySchemeSettings( IScheme *scheme );
+ void Init( void );
+ void VidInit( void );
+ bool ShouldDraw( void );
+ virtual void OnThink();
+ virtual void Paint();
+
+private:
+ void ResetAlpha() { m_alpha = 0; }
+ void ResetScale() { m_scale = 1.0f; }
+
+ void ResetPosition()
+ {
+ m_vecPos.x = ScreenWidth() / 2;
+ m_vecPos.y = ScreenHeight() / 2;
+ m_vecPos.z = 0;
+ }
+
+ Vector m_vecPos;
+ float m_alpha;
+ float m_scale;
+
+ float m_alphaFixed; // alpha value for the fixed element.
+
+ int m_textureID_ActiveReticle;
+ int m_textureID_FixedReticle;
+};
+
+DECLARE_HUDELEMENT( CHUDAutoAim );
+
+CHUDAutoAim::CHUDAutoAim( const char *pElementName ) :
+ CHudElement( pElementName ), BaseClass( NULL, "HUDAutoAim" )
+{
+ vgui::Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+ SetHiddenBits( HIDEHUD_CROSSHAIR );
+
+ m_textureID_ActiveReticle = -1;
+ m_textureID_FixedReticle = -1;
+}
+
+CHUDAutoAim::~CHUDAutoAim( void )
+{
+ if ( vgui::surface() )
+ {
+ if ( m_textureID_ActiveReticle != -1 )
+ {
+ vgui::surface()->DestroyTextureID( m_textureID_ActiveReticle );
+ m_textureID_ActiveReticle = -1;
+ }
+
+ if ( m_textureID_FixedReticle != -1 )
+ {
+ vgui::surface()->DestroyTextureID( m_textureID_FixedReticle );
+ m_textureID_FixedReticle = -1;
+ }
+ }
+}
+
+
+void CHUDAutoAim::ApplySchemeSettings( IScheme *scheme )
+{
+ BaseClass::ApplySchemeSettings( scheme );
+
+ SetPaintBackgroundEnabled( false );
+}
+
+void CHUDAutoAim::Init( void )
+{
+ ResetPosition();
+ ResetAlpha();
+ ResetScale();
+}
+
+void CHUDAutoAim::VidInit( void )
+{
+ SetAlpha( 255 );
+ Init();
+
+ if ( m_textureID_ActiveReticle == -1 )
+ {
+ m_textureID_ActiveReticle = vgui::surface()->CreateNewTextureID();
+ vgui::surface()->DrawSetTextureFile( m_textureID_ActiveReticle, "vgui/hud/autoaim", true, false );
+ }
+
+ if ( m_textureID_FixedReticle == -1 )
+ {
+ m_textureID_FixedReticle = vgui::surface()->CreateNewTextureID();
+ vgui::surface()->DrawSetTextureFile( m_textureID_FixedReticle, "vgui/hud/xbox_reticle", true, false );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Save CPU cycles by letting the HUD system early cull
+// costly traversal. Called per frame, return true if thinking and
+// painting need to occur.
+//-----------------------------------------------------------------------------
+bool CHUDAutoAim::ShouldDraw( void )
+{
+ C_BaseHLPlayer *pLocalPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
+ if ( pLocalPlayer )
+ {
+ if( !pLocalPlayer->m_HL2Local.m_bDisplayReticle )
+ {
+ return false;
+ }
+ }
+
+ return ( (hud_draw_fixed_reticle.GetBool() || hud_draw_active_reticle.GetBool()) && CHudElement::ShouldDraw() && !engine->IsDrawingLoadingImage() );
+}
+
+#define AUTOAIM_ALPHA_UP_SPEED 1000
+#define AUTOAIM_ALPHA_DOWN_SPEED 300
+#define AUTOAIM_MAX_ALPHA 120
+#define AUTOAIM_MAX_SCALE 1.0f
+#define AUTOAIM_MIN_SCALE 0.5f
+#define AUTOAIM_SCALE_SPEED 10.0f
+#define AUTOAIM_ONTARGET_CROSSHAIR_SPEED (ScreenWidth() / 3) // Can cross the whole screen in 3 seconds.
+#define AUTOAIM_OFFTARGET_CROSSHAIR_SPEED (ScreenWidth() / 4)
+
+void CHUDAutoAim::OnThink()
+{
+ int wide, tall;
+ GetSize( wide, tall );
+
+ BaseClass::OnThink();
+
+ // Get the HL2 player
+ C_BaseHLPlayer *pLocalPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
+ if ( pLocalPlayer == NULL )
+ {
+ // Just turn the autoaim crosshair off.
+ ResetPosition();
+ ResetAlpha();
+ ResetScale();
+
+ m_alphaFixed = 0.0f;
+ return;
+ }
+
+ // Get the autoaim target.
+ CBaseEntity *pTarget = pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get();
+
+ // Fixed element stuff
+ float flFixedAlphaGoal;
+
+ if( pTarget )
+ {
+ flFixedAlphaGoal = hud_reticle_maxalpha.GetFloat();
+ }
+ else
+ {
+ flFixedAlphaGoal = hud_reticle_minalpha.GetFloat();
+ }
+
+ if( pLocalPlayer->m_HL2Local.m_bZooming || pLocalPlayer->m_HL2Local.m_bWeaponLowered )
+ {
+ flFixedAlphaGoal = 0.0f;
+ }
+
+ m_alphaFixed = Approach( flFixedAlphaGoal, m_alphaFixed, (hud_alpha_speed.GetFloat() * gpGlobals->frametime) );
+
+
+ switch( hud_autoaim_method.GetInt() )
+ {
+ case AUTOAIM_METHOD_RETICLE:
+ {
+ if( pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get() && pLocalPlayer->m_HL2Local.m_bStickyAutoAim )
+ {
+ if( !pLocalPlayer->IsInAVehicle() )
+ {
+ Vector vecLook;
+ pLocalPlayer->EyeVectors( &vecLook, NULL, NULL );
+
+ Vector vecMove = pLocalPlayer->GetAbsVelocity();
+ float flSpeed = VectorNormalize( vecMove );
+ float flDot = DotProduct( vecLook, vecMove );
+
+ if( flSpeed >= 100 && fabs(flDot) <= 0.707f )
+ {
+ QAngle viewangles;
+ QAngle targetangles;
+ QAngle delta;
+
+ engine->GetViewAngles( viewangles );
+
+ Vector vecDir = pLocalPlayer->m_HL2Local.m_vecAutoAimPoint - pLocalPlayer->EyePosition();
+ VectorNormalize(vecDir);
+ VectorAngles( vecDir, targetangles );
+
+ float magnetism = hud_magnetism.GetFloat();
+
+ delta[0] = ApproachAngle( targetangles[0], viewangles[0], magnetism );
+ delta[1] = ApproachAngle( targetangles[1], viewangles[1], magnetism );
+ delta[2] = targetangles[2];
+
+ //viewangles[PITCH] = clamp( viewangles[ PITCH ], -cl_pitchup.GetFloat(), cl_pitchdown.GetFloat() );
+ engine->SetViewAngles( delta );
+ }
+ }
+ }
+
+#if 0
+ bool doScaling = hud_autoaim_scale_icon.GetBool();
+
+ // These are the X & Y coords of where the crosshair should be. Default to
+ // returning to the center of the screen if there is no target.
+ int goalx = ScreenWidth() / 2;
+ int goaly = ScreenHeight() / 2;
+ int goalalpha = 0;
+ float goalscale = AUTOAIM_MIN_SCALE;
+ float speed = AUTOAIM_OFFTARGET_CROSSHAIR_SPEED;
+
+ if( pTarget )
+ {
+ // Get the autoaim crosshair onto the target.
+ Vector screen;
+
+ // Center the crosshair on the entity.
+ if( doScaling )
+ {
+ // Put the crosshair over the center of the target.
+ ScreenTransform( pTarget->WorldSpaceCenter(), screen );
+ }
+ else
+ {
+ // Put the crosshair exactly where the player is aiming.
+ ScreenTransform( pLocalPlayer->m_HL2Local.m_vecAutoAimPoint, screen );
+ }
+
+ // Set Goal Position and speed.
+ goalx += 0.5f * screen[0] * ScreenWidth() + 0.5f;
+ goaly -= 0.5f * screen[1] * ScreenHeight() + 0.5f;
+ speed = AUTOAIM_ONTARGET_CROSSHAIR_SPEED;
+
+ goalalpha = AUTOAIM_MAX_ALPHA;
+
+ if( doScaling )
+ {
+ // Scale the crosshair to envelope the entity's bounds on screen.
+ Vector vecMins, vecMaxs;
+ Vector vecScreenMins, vecScreenMaxs;
+
+ // Get mins and maxs in world space
+ vecMins = pTarget->GetAbsOrigin() + pTarget->WorldAlignMins();
+ vecMaxs = pTarget->GetAbsOrigin() + pTarget->WorldAlignMaxs();
+
+ // Project them to screen
+ ScreenTransform( vecMins, vecScreenMins );
+ ScreenTransform( vecMaxs, vecScreenMaxs );
+
+ vecScreenMins.y = (ScreenWidth()/2) - 0.5f * vecScreenMins.y * ScreenWidth() + 0.5f;
+ vecScreenMaxs.y = (ScreenWidth()/2) - 0.5f * vecScreenMaxs.y * ScreenWidth() + 0.5f;
+
+ float screenSize = vecScreenMins.y - vecScreenMaxs.y;
+
+ // Set goal scale
+ goalscale = screenSize / 64.0f; // 64 is the width of the crosshair art.
+ }
+ else
+ {
+ goalscale = 1.0f;
+ }
+ }
+
+ // Now approach the goal, alpha, and scale
+ Vector vecGoal( goalx, goaly, 0 );
+ Vector vecDir = vecGoal - m_vecPos;
+ float flDistRemaining = VectorNormalize( vecDir );
+ m_vecPos += vecDir * min(flDistRemaining, (speed * gpGlobals->frametime) );
+
+ // Lerp and Clamp scale
+ float scaleDelta = fabs( goalscale - m_scale );
+ float scaleMove = MIN( AUTOAIM_SCALE_SPEED * gpGlobals->frametime, scaleDelta );
+ if( m_scale < goalscale )
+ {
+ m_scale += scaleMove;
+ }
+ else if( m_scale > goalscale )
+ {
+ m_scale -= scaleMove;
+ }
+ if( m_scale > AUTOAIM_MAX_SCALE )
+ {
+ m_scale = AUTOAIM_MAX_SCALE;
+ }
+ else if( m_scale < AUTOAIM_MIN_SCALE )
+ {
+ m_scale = AUTOAIM_MIN_SCALE;
+ }
+
+ if( goalalpha > m_alpha )
+ {
+ m_alpha += AUTOAIM_ALPHA_UP_SPEED * gpGlobals->frametime;
+ }
+ else if( goalalpha < m_alpha )
+ {
+ m_alpha -= AUTOAIM_ALPHA_DOWN_SPEED * gpGlobals->frametime;
+ }
+
+ // Clamp alpha
+ if( m_alpha < 0 )
+ {
+ m_alpha = 0;
+ }
+ else if( m_alpha > AUTOAIM_MAX_ALPHA )
+ {
+ m_alpha = AUTOAIM_MAX_ALPHA;
+ }
+#endif
+ }
+ break;
+
+ case AUTOAIM_METHOD_DRIFT:
+ {
+ if( pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get() )
+ {
+ QAngle viewangles;
+
+ engine->GetViewAngles( viewangles );
+
+ Vector vecDir = pLocalPlayer->m_HL2Local.m_vecAutoAimPoint - pLocalPlayer->EyePosition();
+ VectorNormalize(vecDir);
+
+ VectorAngles( vecDir, viewangles );
+
+ //viewangles[PITCH] = clamp( viewangles[ PITCH ], -cl_pitchup.GetFloat(), cl_pitchdown.GetFloat() );
+ engine->SetViewAngles( viewangles );
+ }
+ }
+ break;
+ }
+}
+
+void CHUDAutoAim::Paint()
+{
+ if( hud_draw_active_reticle.GetBool() )
+ {
+ int xCenter = m_vecPos.x;
+ int yCenter = m_vecPos.y;
+
+ int width, height;
+ float xMod, yMod;
+
+ vgui::surface()->DrawSetTexture( m_textureID_ActiveReticle );
+ vgui::surface()->DrawSetColor( 255, 255, 255, m_alpha );
+ vgui::surface()->DrawGetTextureSize( m_textureID_ActiveReticle, width, height );
+
+ float uv1 = 0.5f / width, uv2 = 1.0f - uv1;
+
+ vgui::Vertex_t vert[4];
+
+ Vector2D uv11( uv1, uv1 );
+ Vector2D uv12( uv1, uv2 );
+ Vector2D uv21( uv2, uv1 );
+ Vector2D uv22( uv2, uv2 );
+
+ xMod = width;
+ yMod = height;
+
+ xMod *= m_scale;
+ yMod *= m_scale;
+
+ xMod /= 2;
+ yMod /= 2;
+
+ vert[0].Init( Vector2D( xCenter + xMod, yCenter + yMod ), uv21 );
+ vert[1].Init( Vector2D( xCenter - xMod, yCenter + yMod ), uv11 );
+ vert[2].Init( Vector2D( xCenter - xMod, yCenter - yMod ), uv12 );
+ vert[3].Init( Vector2D( xCenter + xMod, yCenter - yMod ), uv22 );
+ vgui::surface()->DrawTexturedPolygon( 4, vert );
+ }
+
+ if( hud_draw_fixed_reticle.GetBool() )
+ {
+ int width, height;
+ float xMod, yMod;
+
+ vgui::surface()->DrawSetTexture( m_textureID_FixedReticle );
+ vgui::surface()->DrawGetTextureSize( m_textureID_FixedReticle, width, height );
+
+ int xCenter = ScreenWidth() / 2;
+ int yCenter = ScreenHeight() / 2;
+
+ vgui::Vertex_t vert[4];
+
+ Vector2D uv11( 0, 0 );
+ Vector2D uv12( 0, 1 );
+ Vector2D uv21( 1, 0 );
+ Vector2D uv22( 1, 1 );
+
+ xMod = width;
+ yMod = height;
+
+ xMod /= 2;
+ yMod /= 2;
+
+ vert[0].Init( Vector2D( xCenter + xMod, yCenter + yMod ), uv21 );
+ vert[1].Init( Vector2D( xCenter - xMod, yCenter + yMod ), uv11 );
+ vert[2].Init( Vector2D( xCenter - xMod, yCenter - yMod ), uv12 );
+ vert[3].Init( Vector2D( xCenter + xMod, yCenter - yMod ), uv22 );
+
+ Color clr;
+ clr = gHUD.m_clrNormal;
+ int r,g,b,a;
+ clr.GetColor( r,g,b,a );
+
+ C_BaseHLPlayer *pLocalPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
+ if( pLocalPlayer && pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get() )
+ {
+ r = 250;
+ g = 138;
+ b = 4;
+ }
+
+ clr.SetColor( r,g,b,m_alphaFixed);
+
+ vgui::surface()->DrawSetColor( clr );
+ vgui::surface()->DrawTexturedPolygon( 4, vert );
+ }
} \ No newline at end of file
diff --git a/mp/src/game/client/hl2/hud_battery.cpp b/mp/src/game/client/hl2/hud_battery.cpp
index 8fac219d..c07943c1 100644
--- a/mp/src/game/client/hl2/hud_battery.cpp
+++ b/mp/src/game/client/hl2/hud_battery.cpp
@@ -1,147 +1,147 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-//
-// battery.cpp
-//
-// implementation of CHudBattery class
-//
-#include "cbase.h"
-#include "hud.h"
-#include "hudelement.h"
-#include "hud_macros.h"
-#include "hud_numericdisplay.h"
-#include "iclientmode.h"
-
-#include "vgui_controls/AnimationController.h"
-#include "vgui/ILocalize.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-#define INIT_BAT -1
-
-//-----------------------------------------------------------------------------
-// Purpose: Displays suit power (armor) on hud
-//-----------------------------------------------------------------------------
-class CHudBattery : public CHudNumericDisplay, public CHudElement
-{
- DECLARE_CLASS_SIMPLE( CHudBattery, CHudNumericDisplay );
-
-public:
- CHudBattery( const char *pElementName );
- void Init( void );
- void Reset( void );
- void VidInit( void );
- void OnThink( void );
- void MsgFunc_Battery(bf_read &msg );
- bool ShouldDraw();
-
-private:
- int m_iBat;
- int m_iNewBat;
-};
-
-DECLARE_HUDELEMENT( CHudBattery );
-DECLARE_HUD_MESSAGE( CHudBattery, Battery );
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CHudBattery::CHudBattery( const char *pElementName ) : BaseClass(NULL, "HudSuit"), CHudElement( pElementName )
-{
- SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_NEEDSUIT );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudBattery::Init( void )
-{
- HOOK_HUD_MESSAGE( CHudBattery, Battery);
- Reset();
- m_iBat = INIT_BAT;
- m_iNewBat = 0;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudBattery::Reset( void )
-{
- SetLabelText(g_pVGuiLocalize->Find("#Valve_Hud_SUIT"));
- SetDisplayValue(m_iBat);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudBattery::VidInit( void )
-{
- Reset();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Save CPU cycles by letting the HUD system early cull
-// costly traversal. Called per frame, return true if thinking and
-// painting need to occur.
-//-----------------------------------------------------------------------------
-bool CHudBattery::ShouldDraw( void )
-{
- bool bNeedsDraw = ( m_iBat != m_iNewBat ) || ( GetAlpha() > 0 );
-
- return ( bNeedsDraw && CHudElement::ShouldDraw() );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudBattery::OnThink( void )
-{
- if ( m_iBat == m_iNewBat )
- return;
-
- if ( !m_iNewBat )
- {
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitPowerZero");
- }
- else if ( m_iNewBat < m_iBat )
- {
- // battery power has decreased, so play the damaged animation
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitDamageTaken");
-
- // play an extra animation if we're super low
- if ( m_iNewBat < 20 )
- {
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitArmorLow");
- }
- }
- else
- {
- // battery power has increased (if we had no previous armor, or if we just loaded the game, don't use alert state)
- if ( m_iBat == INIT_BAT || m_iBat == 0 || m_iNewBat >= 20)
- {
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitPowerIncreasedAbove20");
- }
- else
- {
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitPowerIncreasedBelow20");
- }
- }
-
- m_iBat = m_iNewBat;
-
- SetDisplayValue(m_iBat);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudBattery::MsgFunc_Battery( bf_read &msg )
-{
- m_iNewBat = msg.ReadShort();
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+//
+// battery.cpp
+//
+// implementation of CHudBattery class
+//
+#include "cbase.h"
+#include "hud.h"
+#include "hudelement.h"
+#include "hud_macros.h"
+#include "hud_numericdisplay.h"
+#include "iclientmode.h"
+
+#include "vgui_controls/AnimationController.h"
+#include "vgui/ILocalize.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#define INIT_BAT -1
+
+//-----------------------------------------------------------------------------
+// Purpose: Displays suit power (armor) on hud
+//-----------------------------------------------------------------------------
+class CHudBattery : public CHudNumericDisplay, public CHudElement
+{
+ DECLARE_CLASS_SIMPLE( CHudBattery, CHudNumericDisplay );
+
+public:
+ CHudBattery( const char *pElementName );
+ void Init( void );
+ void Reset( void );
+ void VidInit( void );
+ void OnThink( void );
+ void MsgFunc_Battery(bf_read &msg );
+ bool ShouldDraw();
+
+private:
+ int m_iBat;
+ int m_iNewBat;
+};
+
+DECLARE_HUDELEMENT( CHudBattery );
+DECLARE_HUD_MESSAGE( CHudBattery, Battery );
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CHudBattery::CHudBattery( const char *pElementName ) : BaseClass(NULL, "HudSuit"), CHudElement( pElementName )
+{
+ SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_NEEDSUIT );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudBattery::Init( void )
+{
+ HOOK_HUD_MESSAGE( CHudBattery, Battery);
+ Reset();
+ m_iBat = INIT_BAT;
+ m_iNewBat = 0;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudBattery::Reset( void )
+{
+ SetLabelText(g_pVGuiLocalize->Find("#Valve_Hud_SUIT"));
+ SetDisplayValue(m_iBat);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudBattery::VidInit( void )
+{
+ Reset();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Save CPU cycles by letting the HUD system early cull
+// costly traversal. Called per frame, return true if thinking and
+// painting need to occur.
+//-----------------------------------------------------------------------------
+bool CHudBattery::ShouldDraw( void )
+{
+ bool bNeedsDraw = ( m_iBat != m_iNewBat ) || ( GetAlpha() > 0 );
+
+ return ( bNeedsDraw && CHudElement::ShouldDraw() );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudBattery::OnThink( void )
+{
+ if ( m_iBat == m_iNewBat )
+ return;
+
+ if ( !m_iNewBat )
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitPowerZero");
+ }
+ else if ( m_iNewBat < m_iBat )
+ {
+ // battery power has decreased, so play the damaged animation
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitDamageTaken");
+
+ // play an extra animation if we're super low
+ if ( m_iNewBat < 20 )
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitArmorLow");
+ }
+ }
+ else
+ {
+ // battery power has increased (if we had no previous armor, or if we just loaded the game, don't use alert state)
+ if ( m_iBat == INIT_BAT || m_iBat == 0 || m_iNewBat >= 20)
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitPowerIncreasedAbove20");
+ }
+ else
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitPowerIncreasedBelow20");
+ }
+ }
+
+ m_iBat = m_iNewBat;
+
+ SetDisplayValue(m_iBat);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudBattery::MsgFunc_Battery( bf_read &msg )
+{
+ m_iNewBat = msg.ReadShort();
+}
diff --git a/mp/src/game/client/hl2/hud_blood.cpp b/mp/src/game/client/hl2/hud_blood.cpp
index 0123a9a7..e3528b5e 100644
--- a/mp/src/game/client/hl2/hud_blood.cpp
+++ b/mp/src/game/client/hl2/hud_blood.cpp
@@ -1,34 +1,34 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "clienteffectprecachesystem.h"
-#include "c_te_effect_dispatch.h"
-#include "hud.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-void BloodSplatCallback( const CEffectData & data )
-{
-/*
- Msg("SPLAT!\n");
-
- int x,y;
-
- // Find our screen position to start from
- x = XRES(320);
- y = YRES(240);
-
- // Draw the ammo label
- CHudTexture *pSplat = gHUD.GetIcon( "hud_blood1" );
-
- // FIXME: This can only occur during vgui::Paint() stuff
- pSplat->DrawSelf( x, y, gHUD.m_clrNormal);
-*/
-}
-
-DECLARE_CLIENT_EFFECT( "HudBloodSplat", BloodSplatCallback );
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "clienteffectprecachesystem.h"
+#include "c_te_effect_dispatch.h"
+#include "hud.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+void BloodSplatCallback( const CEffectData & data )
+{
+/*
+ Msg("SPLAT!\n");
+
+ int x,y;
+
+ // Find our screen position to start from
+ x = XRES(320);
+ y = YRES(240);
+
+ // Draw the ammo label
+ CHudTexture *pSplat = gHUD.GetIcon( "hud_blood1" );
+
+ // FIXME: This can only occur during vgui::Paint() stuff
+ pSplat->DrawSelf( x, y, gHUD.m_clrNormal);
+*/
+}
+
+DECLARE_CLIENT_EFFECT( "HudBloodSplat", BloodSplatCallback );
diff --git a/mp/src/game/client/hl2/hud_bonusprogress.cpp b/mp/src/game/client/hl2/hud_bonusprogress.cpp
index e02bd432..c7569e05 100644
--- a/mp/src/game/client/hl2/hud_bonusprogress.cpp
+++ b/mp/src/game/client/hl2/hud_bonusprogress.cpp
@@ -1,197 +1,197 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-//
-// BonusProgress.cpp
-//
-// implementation of CHudBonusProgress 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_BONUS_PROGRESS -1
-
-
-//-----------------------------------------------------------------------------
-// Purpose: BonusProgress panel
-//-----------------------------------------------------------------------------
-class CHudBonusProgress : public CHudElement, public CHudNumericDisplay
-{
- DECLARE_CLASS_SIMPLE( CHudBonusProgress, CHudNumericDisplay );
-
-public:
- CHudBonusProgress( const char *pElementName );
- virtual void Init( void );
- virtual void VidInit( void );
- virtual void Reset( void );
- virtual void OnThink();
-
-private:
- void SetChallengeLabel( void );
-
-private:
- // old variables
- int m_iBonusProgress;
-
- int m_iLastChallenge;
-};
-
-DECLARE_HUDELEMENT( CHudBonusProgress );
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CHudBonusProgress::CHudBonusProgress( const char *pElementName ) : CHudElement( pElementName ), CHudNumericDisplay(NULL, "HudBonusProgress")
-{
- SetHiddenBits( HIDEHUD_BONUS_PROGRESS );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudBonusProgress::Init()
-{
- Reset();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudBonusProgress::Reset()
-{
- m_iBonusProgress = INIT_BONUS_PROGRESS;
-
- C_BasePlayer *local = C_BasePlayer::GetLocalPlayer();
- if ( local )
- m_iLastChallenge = local->GetBonusChallenge();
-
- SetChallengeLabel();
-
- SetDisplayValue(m_iBonusProgress);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudBonusProgress::VidInit()
-{
- Reset();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudBonusProgress::OnThink()
-{
- C_GameRules *pGameRules = GameRules();
-
- if ( !pGameRules )
- {
- // Not ready to init!
- return;
- }
-
- int newBonusProgress = 0;
- int iBonusChallenge = 0;
-
- C_BasePlayer *local = C_BasePlayer::GetLocalPlayer();
- if ( !local )
- {
- // Not ready to init!
- return;
- }
-
- // Never below zero
- newBonusProgress = MAX( local->GetBonusProgress(), 0 );
- iBonusChallenge = local->GetBonusChallenge();
-
- // Only update the fade if we've changed bonusProgress
- if ( newBonusProgress == m_iBonusProgress && m_iLastChallenge == iBonusChallenge )
- {
- return;
- }
-
- m_iBonusProgress = newBonusProgress;
-
- if ( m_iLastChallenge != iBonusChallenge )
- {
- m_iLastChallenge = iBonusChallenge;
- SetChallengeLabel();
- }
-
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("BonusProgressFlash");
-
- if ( pGameRules->IsBonusChallengeTimeBased() )
- {
- SetIsTime( true );
- SetIndent( false );
- }
- else
- {
- SetIsTime( false );
- SetIndent( true );
- }
-
- SetDisplayValue(m_iBonusProgress);
-}
-
-void CHudBonusProgress::SetChallengeLabel( void )
-{
- // Blank for no challenge
- if ( m_iLastChallenge == 0 )
- {
- SetLabelText(L"");
- return;
- }
-
- char szBonusTextName[] = "#Valve_Hud_BONUS_PROGRESS00";
-
- int iStringLength = Q_strlen( szBonusTextName );
-
- szBonusTextName[ iStringLength - 2 ] = ( m_iLastChallenge / 10 ) + '0';
- szBonusTextName[ iStringLength - 1 ] = ( m_iLastChallenge % 10 ) + '0';
-
- wchar_t *tempString = g_pVGuiLocalize->Find(szBonusTextName);
-
- if (tempString)
- {
- SetLabelText(tempString);
- return;
- }
-
- // Couldn't find a special string for this challenge
- tempString = g_pVGuiLocalize->Find("#Valve_Hud_BONUS_PROGRESS");
- if (tempString)
- {
- SetLabelText(tempString);
- return;
- }
-
- // Couldn't find any localizable string
- SetLabelText(L"BONUS");
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+//
+// BonusProgress.cpp
+//
+// implementation of CHudBonusProgress 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_BONUS_PROGRESS -1
+
+
+//-----------------------------------------------------------------------------
+// Purpose: BonusProgress panel
+//-----------------------------------------------------------------------------
+class CHudBonusProgress : public CHudElement, public CHudNumericDisplay
+{
+ DECLARE_CLASS_SIMPLE( CHudBonusProgress, CHudNumericDisplay );
+
+public:
+ CHudBonusProgress( const char *pElementName );
+ virtual void Init( void );
+ virtual void VidInit( void );
+ virtual void Reset( void );
+ virtual void OnThink();
+
+private:
+ void SetChallengeLabel( void );
+
+private:
+ // old variables
+ int m_iBonusProgress;
+
+ int m_iLastChallenge;
+};
+
+DECLARE_HUDELEMENT( CHudBonusProgress );
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CHudBonusProgress::CHudBonusProgress( const char *pElementName ) : CHudElement( pElementName ), CHudNumericDisplay(NULL, "HudBonusProgress")
+{
+ SetHiddenBits( HIDEHUD_BONUS_PROGRESS );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudBonusProgress::Init()
+{
+ Reset();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudBonusProgress::Reset()
+{
+ m_iBonusProgress = INIT_BONUS_PROGRESS;
+
+ C_BasePlayer *local = C_BasePlayer::GetLocalPlayer();
+ if ( local )
+ m_iLastChallenge = local->GetBonusChallenge();
+
+ SetChallengeLabel();
+
+ SetDisplayValue(m_iBonusProgress);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudBonusProgress::VidInit()
+{
+ Reset();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudBonusProgress::OnThink()
+{
+ C_GameRules *pGameRules = GameRules();
+
+ if ( !pGameRules )
+ {
+ // Not ready to init!
+ return;
+ }
+
+ int newBonusProgress = 0;
+ int iBonusChallenge = 0;
+
+ C_BasePlayer *local = C_BasePlayer::GetLocalPlayer();
+ if ( !local )
+ {
+ // Not ready to init!
+ return;
+ }
+
+ // Never below zero
+ newBonusProgress = MAX( local->GetBonusProgress(), 0 );
+ iBonusChallenge = local->GetBonusChallenge();
+
+ // Only update the fade if we've changed bonusProgress
+ if ( newBonusProgress == m_iBonusProgress && m_iLastChallenge == iBonusChallenge )
+ {
+ return;
+ }
+
+ m_iBonusProgress = newBonusProgress;
+
+ if ( m_iLastChallenge != iBonusChallenge )
+ {
+ m_iLastChallenge = iBonusChallenge;
+ SetChallengeLabel();
+ }
+
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("BonusProgressFlash");
+
+ if ( pGameRules->IsBonusChallengeTimeBased() )
+ {
+ SetIsTime( true );
+ SetIndent( false );
+ }
+ else
+ {
+ SetIsTime( false );
+ SetIndent( true );
+ }
+
+ SetDisplayValue(m_iBonusProgress);
+}
+
+void CHudBonusProgress::SetChallengeLabel( void )
+{
+ // Blank for no challenge
+ if ( m_iLastChallenge == 0 )
+ {
+ SetLabelText(L"");
+ return;
+ }
+
+ char szBonusTextName[] = "#Valve_Hud_BONUS_PROGRESS00";
+
+ int iStringLength = Q_strlen( szBonusTextName );
+
+ szBonusTextName[ iStringLength - 2 ] = ( m_iLastChallenge / 10 ) + '0';
+ szBonusTextName[ iStringLength - 1 ] = ( m_iLastChallenge % 10 ) + '0';
+
+ wchar_t *tempString = g_pVGuiLocalize->Find(szBonusTextName);
+
+ if (tempString)
+ {
+ SetLabelText(tempString);
+ return;
+ }
+
+ // Couldn't find a special string for this challenge
+ tempString = g_pVGuiLocalize->Find("#Valve_Hud_BONUS_PROGRESS");
+ if (tempString)
+ {
+ SetLabelText(tempString);
+ return;
+ }
+
+ // Couldn't find any localizable string
+ SetLabelText(L"BONUS");
} \ No newline at end of file
diff --git a/mp/src/game/client/hl2/hud_credits.cpp b/mp/src/game/client/hl2/hud_credits.cpp
index 75fb8227..8021c49a 100644
--- a/mp/src/game/client/hl2/hud_credits.cpp
+++ b/mp/src/game/client/hl2/hud_credits.cpp
@@ -1,735 +1,735 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "hudelement.h"
-#include "hud_numericdisplay.h"
-#include <vgui_controls/Panel.h>
-#include "hud.h"
-#include "hud_suitpower.h"
-#include "hud_macros.h"
-#include "iclientmode.h"
-#include <vgui_controls/AnimationController.h>
-#include <vgui/ISurface.h>
-#include <vgui/ILocalize.h>
-#include "KeyValues.h"
-#include "filesystem.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-struct creditname_t
-{
- char szCreditName[256];
- char szFontName[256];
- float flYPos;
- float flXPos;
- bool bActive;
- float flTime;
- float flTimeAdd;
- float flTimeStart;
- int iSlot;
-};
-
-#define CREDITS_FILE "scripts/credits.txt"
-
-enum
-{
- LOGO_FADEIN = 0,
- LOGO_FADEHOLD,
- LOGO_FADEOUT,
- LOGO_FADEOFF,
-};
-
-#define CREDITS_LOGO 1
-#define CREDITS_INTRO 2
-#define CREDITS_OUTRO 3
-
-bool g_bRollingCredits = false;
-
-int g_iCreditsPixelHeight = 0;
-
-//-----------------------------------------------------------------------------
-// Purpose: Shows the flashlight icon
-//-----------------------------------------------------------------------------
-class CHudCredits : public CHudElement, public vgui::Panel
-{
- DECLARE_CLASS_SIMPLE( CHudCredits, vgui::Panel );
-
-public:
- CHudCredits( const char *pElementName );
- virtual void Init( void );
- virtual void LevelShutdown( void );
-
- int GetStringPixelWidth ( wchar_t *pString, vgui::HFont hFont );
-
- void MsgFunc_CreditsMsg( bf_read &msg );
- void MsgFunc_LogoTimeMsg( bf_read &msg );
-
- virtual bool ShouldDraw( void )
- {
- g_bRollingCredits = IsActive();
-
- if ( g_bRollingCredits && m_iCreditsType == CREDITS_INTRO )
- g_bRollingCredits = false;
-
- return IsActive();
- }
-
-protected:
- virtual void Paint();
- virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
-
-private:
-
- void Clear();
-
- void ReadNames( KeyValues *pKeyValue );
- void ReadParams( KeyValues *pKeyValue );
- void PrepareCredits( const char *pKeyName );
- void DrawOutroCreditsName( void );
- void DrawIntroCreditsName( void );
- void DrawLogo( void );
-
- void PrepareLogo( float flTime );
- void PrepareOutroCredits( void );
- void PrepareIntroCredits( void );
-
- float FadeBlend( float fadein, float fadeout, float hold, float localTime );
-
- void PrepareLine( vgui::HFont hFont, char const *pchLine );
-
- CPanelAnimationVar( vgui::HFont, m_hTextFont, "TextFont", "Default" );
- CPanelAnimationVar( Color, m_TextColor, "TextColor", "FgColor" );
-
- CUtlVector<creditname_t> m_CreditsList;
-
- float m_flScrollTime;
- float m_flSeparation;
- float m_flFadeTime;
- bool m_bLastOneInPlace;
- int m_Alpha;
-
- int m_iCreditsType;
- int m_iLogoState;
-
- float m_flFadeInTime;
- float m_flFadeHoldTime;
- float m_flFadeOutTime;
- float m_flNextStartTime;
- float m_flPauseBetweenWaves;
-
- float m_flLogoTimeMod;
- float m_flLogoTime;
- float m_flLogoDesiredLength;
-
- float m_flX;
- float m_flY;
-
- char m_szLogo[256];
- char m_szLogo2[256];
-
- Color m_cColor;
-};
-
-
-void CHudCredits::PrepareCredits( const char *pKeyName )
-{
- Clear();
-
- KeyValues *pKV= new KeyValues( "CreditsFile" );
- if ( !pKV->LoadFromFile( filesystem, CREDITS_FILE, "MOD" ) )
- {
- pKV->deleteThis();
-
- Assert( !"env_credits couldn't be initialized!" );
- return;
- }
-
- KeyValues *pKVSubkey;
- if ( pKeyName )
- {
- pKVSubkey = pKV->FindKey( pKeyName );
- ReadNames( pKVSubkey );
- }
-
- pKVSubkey = pKV->FindKey( "CreditsParams" );
- ReadParams( pKVSubkey );
-
- pKV->deleteThis();
-}
-
-using namespace vgui;
-
-DECLARE_HUDELEMENT( CHudCredits );
-DECLARE_HUD_MESSAGE( CHudCredits, CreditsMsg );
-DECLARE_HUD_MESSAGE( CHudCredits, LogoTimeMsg );
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CHudCredits::CHudCredits( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudCredits" )
-{
- vgui::Panel *pParent = g_pClientMode->GetViewport();
- SetParent( pParent );
-}
-
-void CHudCredits::LevelShutdown()
-{
- Clear();
-}
-
-void CHudCredits::Clear( void )
-{
- SetActive( false );
- m_CreditsList.RemoveAll();
- m_bLastOneInPlace = false;
- m_Alpha = m_TextColor[3];
- m_iLogoState = LOGO_FADEOFF;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudCredits::Init()
-{
- HOOK_HUD_MESSAGE( CHudCredits, CreditsMsg );
- HOOK_HUD_MESSAGE( CHudCredits, LogoTimeMsg );
- SetActive( false );
-}
-
-void CHudCredits::ReadNames( KeyValues *pKeyValue )
-{
- if ( pKeyValue == NULL )
- {
- Assert( !"CHudCredits couldn't be initialized!" );
- return;
- }
-
- // Now try and parse out each act busy anim
- KeyValues *pKVNames = pKeyValue->GetFirstSubKey();
-
- while ( pKVNames )
- {
- creditname_t Credits;
- Q_strcpy( Credits.szCreditName, pKVNames->GetName());
- Q_strcpy( Credits.szFontName, pKeyValue->GetString( Credits.szCreditName, "Default" ) );
-
- m_CreditsList.AddToTail( Credits );
- pKVNames = pKVNames->GetNextKey();
- }
-}
-
-void CHudCredits::ReadParams( KeyValues *pKeyValue )
-{
- if ( pKeyValue == NULL )
- {
- Assert( !"CHudCredits couldn't be initialized!" );
- return;
- }
-
- m_flScrollTime = pKeyValue->GetFloat( "scrolltime", 57 );
- m_flSeparation = pKeyValue->GetFloat( "separation", 5 );
-
- m_flFadeInTime = pKeyValue->GetFloat( "fadeintime", 1 );
- m_flFadeHoldTime = pKeyValue->GetFloat( "fadeholdtime", 3 );
- m_flFadeOutTime = pKeyValue->GetFloat( "fadeouttime", 2 );
- m_flNextStartTime = pKeyValue->GetFloat( "nextfadetime", 2 );
- m_flPauseBetweenWaves = pKeyValue->GetFloat( "pausebetweenwaves", 2 );
-
- m_flLogoTimeMod = pKeyValue->GetFloat( "logotime", 2 );
-
- m_flX = pKeyValue->GetFloat( "posx", 2 );
- m_flY = pKeyValue->GetFloat( "posy", 2 );
-
- m_cColor = pKeyValue->GetColor( "color" );
-
- Q_strncpy( m_szLogo, pKeyValue->GetString( "logo", "HALF-LIFE'" ), sizeof( m_szLogo ) );
- Q_strncpy( m_szLogo2, pKeyValue->GetString( "logo2", "" ), sizeof( m_szLogo2 ) );
-}
-
-int CHudCredits::GetStringPixelWidth( wchar_t *pString, vgui::HFont hFont )
-{
- int iLength = 0;
-
- for ( wchar_t *wch = pString; *wch != 0; wch++ )
- {
- iLength += surface()->GetCharacterWidth( hFont, *wch );
- }
-
- return iLength;
-}
-
-void CHudCredits::DrawOutroCreditsName( void )
-{
- if ( m_CreditsList.Count() == 0 )
- return;
-
- // fill the screen
- int iWidth, iTall;
- GetHudSize(iWidth, iTall);
- SetSize( iWidth, iTall );
-
- for ( int i = 0; i < m_CreditsList.Count(); i++ )
- {
- creditname_t *pCredit = &m_CreditsList[i];
-
- if ( pCredit == NULL )
- continue;
-
- vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
- vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName, true );
-
- int iFontTall = surface()->GetFontTall ( m_hTFont );
-
- if ( pCredit->flYPos < -iFontTall || pCredit->flYPos > iTall )
- {
- pCredit->bActive = false;
- }
- else
- {
- pCredit->bActive = true;
- }
-
- Color cColor = m_TextColor;
-
- //HACKHACK
- //Last one stays on screen and fades out
- if ( i == m_CreditsList.Count()-1 )
- {
- if ( m_bLastOneInPlace == false )
- {
- pCredit->flYPos -= gpGlobals->frametime * ( (float)g_iCreditsPixelHeight / m_flScrollTime );
-
- if ( (int)pCredit->flYPos + ( iFontTall / 2 ) <= iTall / 2 )
- {
- m_bLastOneInPlace = true;
-
- // 360 certification requires that we not hold a static image too long.
- m_flFadeTime = gpGlobals->curtime + ( IsConsole() ? 2.0f : 10.0f );
- }
- }
- else
- {
- if ( m_flFadeTime <= gpGlobals->curtime )
- {
- if ( m_Alpha > 0 )
- {
- m_Alpha -= gpGlobals->frametime * ( m_flScrollTime * 2 );
-
- if ( m_Alpha <= 0 )
- {
- pCredit->bActive = false;
- engine->ClientCmd( "creditsdone" );
- }
- }
- }
-
- cColor[3] = MAX( 0, m_Alpha );
- }
- }
- else
- {
- pCredit->flYPos -= gpGlobals->frametime * ( (float)g_iCreditsPixelHeight / m_flScrollTime );
- }
-
- if ( pCredit->bActive == false )
- continue;
-
- surface()->DrawSetTextFont( m_hTFont );
- surface()->DrawSetTextColor( cColor[0], cColor[1], cColor[2], cColor[3] );
-
- wchar_t unicode[256];
-
- if ( pCredit->szCreditName[0] == '#' )
- {
- g_pVGuiLocalize->ConstructString( unicode, sizeof(unicode), g_pVGuiLocalize->Find(pCredit->szCreditName), 0 );
- }
- else
- {
- g_pVGuiLocalize->ConvertANSIToUnicode( pCredit->szCreditName, unicode, sizeof( unicode ) );
- }
-
- int iStringWidth = GetStringPixelWidth( unicode, m_hTFont );
-
- surface()->DrawSetTextPos( ( iWidth / 2 ) - ( iStringWidth / 2 ), pCredit->flYPos );
- surface()->DrawUnicodeString( unicode );
- }
-}
-
-void CHudCredits::DrawLogo( void )
-{
- if( m_iLogoState == LOGO_FADEOFF )
- {
- SetActive( false );
- return;
- }
-
- switch( m_iLogoState )
- {
- case LOGO_FADEIN:
- {
- float flDeltaTime = ( m_flFadeTime - gpGlobals->curtime );
-
- m_Alpha = MAX( 0, RemapValClamped( flDeltaTime, 5.0f, 0, -128, 255 ) );
-
- if ( flDeltaTime <= 0.0f )
- {
- m_iLogoState = LOGO_FADEHOLD;
- m_flFadeTime = gpGlobals->curtime + m_flLogoDesiredLength;
- }
-
- break;
- }
-
- case LOGO_FADEHOLD:
- {
- if ( m_flFadeTime <= gpGlobals->curtime )
- {
- m_iLogoState = LOGO_FADEOUT;
- m_flFadeTime = gpGlobals->curtime + 2.0f;
- }
- break;
- }
-
- case LOGO_FADEOUT:
- {
- float flDeltaTime = ( m_flFadeTime - gpGlobals->curtime );
-
- m_Alpha = RemapValClamped( flDeltaTime, 0.0f, 2.0f, 0, 255 );
-
- if ( flDeltaTime <= 0.0f )
- {
- m_iLogoState = LOGO_FADEOFF;
- SetActive( false );
- }
-
- break;
- }
- }
-
- // fill the screen
- int iWidth, iTall;
- GetHudSize(iWidth, iTall);
- SetSize( iWidth, iTall );
-
- char szLogoFont[64];
-
- if ( IsXbox() )
- {
- Q_snprintf( szLogoFont, sizeof( szLogoFont ), "WeaponIcons_Small" );
- }
- else if ( hl2_episodic.GetBool() )
- {
- Q_snprintf( szLogoFont, sizeof( szLogoFont ), "ClientTitleFont" );
- }
- else
- {
- Q_snprintf( szLogoFont, sizeof( szLogoFont ), "WeaponIcons" );
- }
-
- vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
- vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( szLogoFont );
-
- int iFontTall = surface()->GetFontTall ( m_hTFont );
-
- Color cColor = m_TextColor;
- cColor[3] = m_Alpha;
-
- surface()->DrawSetTextFont( m_hTFont );
- surface()->DrawSetTextColor( cColor[0], cColor[1], cColor[2], cColor[3] );
-
- wchar_t unicode[256];
- g_pVGuiLocalize->ConvertANSIToUnicode( m_szLogo, unicode, sizeof( unicode ) );
-
- int iStringWidth = GetStringPixelWidth( unicode, m_hTFont );
-
- surface()->DrawSetTextPos( ( iWidth / 2 ) - ( iStringWidth / 2 ), ( iTall / 2 ) - ( iFontTall / 2 ) );
- surface()->DrawUnicodeString( unicode );
-
- if ( Q_strlen( m_szLogo2 ) > 0 )
- {
- g_pVGuiLocalize->ConvertANSIToUnicode( m_szLogo2, unicode, sizeof( unicode ) );
-
- iStringWidth = GetStringPixelWidth( unicode, m_hTFont );
-
- surface()->DrawSetTextPos( ( iWidth / 2 ) - ( iStringWidth / 2 ), ( iTall / 2 ) + ( iFontTall / 2 ));
- surface()->DrawUnicodeString( unicode );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-float CHudCredits::FadeBlend( float fadein, float fadeout, float hold, float localTime )
-{
- float fadeTime = fadein + hold;
- float fadeBlend;
-
- if ( localTime < 0 )
- return 0;
-
- if ( localTime < fadein )
- {
- fadeBlend = 1 - ((fadein - localTime) / fadein);
- }
- else if ( localTime > fadeTime )
- {
- if ( fadeout > 0 )
- fadeBlend = 1 - ((localTime - fadeTime) / fadeout);
- else
- fadeBlend = 0;
- }
- else
- fadeBlend = 1;
-
- if ( fadeBlend < 0 )
- fadeBlend = 0;
-
- return fadeBlend;
-}
-
-void CHudCredits::DrawIntroCreditsName( void )
-{
- if ( m_CreditsList.Count() == 0 )
- return;
-
- // fill the screen
- int iWidth, iTall;
- GetHudSize(iWidth, iTall);
- SetSize( iWidth, iTall );
-
- for ( int i = 0; i < m_CreditsList.Count(); i++ )
- {
- creditname_t *pCredit = &m_CreditsList[i];
-
- if ( pCredit == NULL )
- continue;
-
- if ( pCredit->bActive == false )
- continue;
-
- vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
- vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName );
-
- float localTime = gpGlobals->curtime - pCredit->flTimeStart;
-
- surface()->DrawSetTextFont( m_hTFont );
- surface()->DrawSetTextColor( m_cColor[0], m_cColor[1], m_cColor[2], FadeBlend( m_flFadeInTime, m_flFadeOutTime, m_flFadeHoldTime + pCredit->flTimeAdd, localTime ) * m_cColor[3] );
-
- wchar_t unicode[256];
- g_pVGuiLocalize->ConvertANSIToUnicode( pCredit->szCreditName, unicode, sizeof( unicode ) );
-
- surface()->DrawSetTextPos( XRES( pCredit->flXPos ), YRES( pCredit->flYPos ) );
- surface()->DrawUnicodeString( unicode );
-
- if ( m_flLogoTime > gpGlobals->curtime )
- continue;
-
- if ( pCredit->flTime - m_flNextStartTime <= gpGlobals->curtime )
- {
- if ( m_CreditsList.IsValidIndex( i + 3 ) )
- {
- creditname_t *pNextCredits = &m_CreditsList[i + 3];
-
- if ( pNextCredits && pNextCredits->flTime == 0.0f )
- {
- pNextCredits->bActive = true;
-
- if ( i < 3 )
- {
- pNextCredits->flTimeAdd = ( i + 1.0f );
- pNextCredits->flTime = gpGlobals->curtime + m_flFadeInTime + m_flFadeOutTime + m_flFadeHoldTime + pNextCredits->flTimeAdd;
- }
- else
- {
- pNextCredits->flTimeAdd = m_flPauseBetweenWaves;
- pNextCredits->flTime = gpGlobals->curtime + m_flFadeInTime + m_flFadeOutTime + m_flFadeHoldTime + pNextCredits->flTimeAdd;
- }
-
- pNextCredits->flTimeStart = gpGlobals->curtime;
-
- pNextCredits->iSlot = pCredit->iSlot;
- }
- }
- }
-
- if ( pCredit->flTime <= gpGlobals->curtime )
- {
- pCredit->bActive = false;
-
- if ( i == m_CreditsList.Count()-1 )
- {
- Clear();
- }
- }
- }
-}
-
-void CHudCredits::ApplySchemeSettings( IScheme *pScheme )
-{
- BaseClass::ApplySchemeSettings( pScheme );
-
- SetVisible( ShouldDraw() );
-
- SetBgColor( Color(0, 0, 0, 0) );
-}
-
-void CHudCredits::Paint()
-{
- if ( m_iCreditsType == CREDITS_LOGO )
- {
- DrawLogo();
- }
- else if ( m_iCreditsType == CREDITS_INTRO )
- {
- DrawIntroCreditsName();
- }
- else if ( m_iCreditsType == CREDITS_OUTRO )
- {
- DrawOutroCreditsName();
- }
-}
-
-void CHudCredits::PrepareLogo( float flTime )
-{
- // Only showing the logo. Just load the CreditsParams section.
- PrepareCredits( NULL );
-
- m_Alpha = 0;
- m_flLogoDesiredLength = flTime;
- m_flFadeTime = gpGlobals->curtime + 5.0f;
- m_iLogoState = LOGO_FADEIN;
- SetActive( true );
-}
-
-void CHudCredits::PrepareLine( vgui::HFont hFont, char const *pchLine )
-{
- Assert( pchLine );
-
- wchar_t unicode[256];
-
- if ( pchLine[0] == '#' )
- {
- g_pVGuiLocalize->ConstructString( unicode, sizeof(unicode), g_pVGuiLocalize->Find(pchLine), 0 );
- }
- else
- {
- g_pVGuiLocalize->ConvertANSIToUnicode( pchLine, unicode, sizeof( unicode ) );
- }
-
- surface()->PrecacheFontCharacters( hFont, unicode );
-}
-
-void CHudCredits::PrepareOutroCredits( void )
-{
- PrepareCredits( "OutroCreditsNames" );
-
- if ( m_CreditsList.Count() == 0 )
- return;
-
- // fill the screen
- int iWidth, iTall;
- GetHudSize(iWidth, iTall);
- SetSize( iWidth, iTall );
-
- int iHeight = iTall;
-
- for ( int i = 0; i < m_CreditsList.Count(); i++ )
- {
- creditname_t *pCredit = &m_CreditsList[i];
-
- if ( pCredit == NULL )
- continue;
-
- vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
- vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName, true );
-
- pCredit->flYPos = iHeight;
- pCredit->bActive = false;
-
- iHeight += surface()->GetFontTall ( m_hTFont ) + m_flSeparation;
-
- PrepareLine( m_hTFont, pCredit->szCreditName );
- }
-
- SetActive( true );
-
- g_iCreditsPixelHeight = iHeight;
-}
-
-void CHudCredits::PrepareIntroCredits( void )
-{
- PrepareCredits( "IntroCreditsNames" );
-
- int iSlot = 0;
-
- for ( int i = 0; i < m_CreditsList.Count(); i++ )
- {
- creditname_t *pCredit = &m_CreditsList[i];
-
- if ( pCredit == NULL )
- continue;
-
- vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
- vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName );
-
- pCredit->flYPos = m_flY + ( iSlot * surface()->GetFontTall ( m_hTFont ) );
- pCredit->flXPos = m_flX;
-
- if ( i < 3 )
- {
- pCredit->bActive = true;
- pCredit->iSlot = iSlot;
- pCredit->flTime = gpGlobals->curtime + m_flFadeInTime + m_flFadeOutTime + m_flFadeHoldTime;
- pCredit->flTimeStart = gpGlobals->curtime;
- m_flLogoTime = pCredit->flTime + m_flLogoTimeMod;
- }
- else
- {
- pCredit->bActive = false;
- pCredit->flTime = 0.0f;
- }
-
- iSlot = ( iSlot + 1 ) % 3;
-
- PrepareLine( m_hTFont, pCredit->szCreditName );
- }
-
- SetActive( true );
-}
-
-void CHudCredits::MsgFunc_CreditsMsg( bf_read &msg )
-{
- m_iCreditsType = msg.ReadByte();
-
- switch ( m_iCreditsType )
- {
- case CREDITS_LOGO:
- {
- PrepareLogo( 5.0f );
- break;
- }
- case CREDITS_INTRO:
- {
- PrepareIntroCredits();
- break;
- }
- case CREDITS_OUTRO:
- {
- PrepareOutroCredits();
- break;
- }
- }
-}
-
-void CHudCredits::MsgFunc_LogoTimeMsg( bf_read &msg )
-{
- m_iCreditsType = CREDITS_LOGO;
- PrepareLogo( msg.ReadFloat() );
-}
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "hudelement.h"
+#include "hud_numericdisplay.h"
+#include <vgui_controls/Panel.h>
+#include "hud.h"
+#include "hud_suitpower.h"
+#include "hud_macros.h"
+#include "iclientmode.h"
+#include <vgui_controls/AnimationController.h>
+#include <vgui/ISurface.h>
+#include <vgui/ILocalize.h>
+#include "KeyValues.h"
+#include "filesystem.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+struct creditname_t
+{
+ char szCreditName[256];
+ char szFontName[256];
+ float flYPos;
+ float flXPos;
+ bool bActive;
+ float flTime;
+ float flTimeAdd;
+ float flTimeStart;
+ int iSlot;
+};
+
+#define CREDITS_FILE "scripts/credits.txt"
+
+enum
+{
+ LOGO_FADEIN = 0,
+ LOGO_FADEHOLD,
+ LOGO_FADEOUT,
+ LOGO_FADEOFF,
+};
+
+#define CREDITS_LOGO 1
+#define CREDITS_INTRO 2
+#define CREDITS_OUTRO 3
+
+bool g_bRollingCredits = false;
+
+int g_iCreditsPixelHeight = 0;
+
+//-----------------------------------------------------------------------------
+// Purpose: Shows the flashlight icon
+//-----------------------------------------------------------------------------
+class CHudCredits : public CHudElement, public vgui::Panel
+{
+ DECLARE_CLASS_SIMPLE( CHudCredits, vgui::Panel );
+
+public:
+ CHudCredits( const char *pElementName );
+ virtual void Init( void );
+ virtual void LevelShutdown( void );
+
+ int GetStringPixelWidth ( wchar_t *pString, vgui::HFont hFont );
+
+ void MsgFunc_CreditsMsg( bf_read &msg );
+ void MsgFunc_LogoTimeMsg( bf_read &msg );
+
+ virtual bool ShouldDraw( void )
+ {
+ g_bRollingCredits = IsActive();
+
+ if ( g_bRollingCredits && m_iCreditsType == CREDITS_INTRO )
+ g_bRollingCredits = false;
+
+ return IsActive();
+ }
+
+protected:
+ virtual void Paint();
+ virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
+
+private:
+
+ void Clear();
+
+ void ReadNames( KeyValues *pKeyValue );
+ void ReadParams( KeyValues *pKeyValue );
+ void PrepareCredits( const char *pKeyName );
+ void DrawOutroCreditsName( void );
+ void DrawIntroCreditsName( void );
+ void DrawLogo( void );
+
+ void PrepareLogo( float flTime );
+ void PrepareOutroCredits( void );
+ void PrepareIntroCredits( void );
+
+ float FadeBlend( float fadein, float fadeout, float hold, float localTime );
+
+ void PrepareLine( vgui::HFont hFont, char const *pchLine );
+
+ CPanelAnimationVar( vgui::HFont, m_hTextFont, "TextFont", "Default" );
+ CPanelAnimationVar( Color, m_TextColor, "TextColor", "FgColor" );
+
+ CUtlVector<creditname_t> m_CreditsList;
+
+ float m_flScrollTime;
+ float m_flSeparation;
+ float m_flFadeTime;
+ bool m_bLastOneInPlace;
+ int m_Alpha;
+
+ int m_iCreditsType;
+ int m_iLogoState;
+
+ float m_flFadeInTime;
+ float m_flFadeHoldTime;
+ float m_flFadeOutTime;
+ float m_flNextStartTime;
+ float m_flPauseBetweenWaves;
+
+ float m_flLogoTimeMod;
+ float m_flLogoTime;
+ float m_flLogoDesiredLength;
+
+ float m_flX;
+ float m_flY;
+
+ char m_szLogo[256];
+ char m_szLogo2[256];
+
+ Color m_cColor;
+};
+
+
+void CHudCredits::PrepareCredits( const char *pKeyName )
+{
+ Clear();
+
+ KeyValues *pKV= new KeyValues( "CreditsFile" );
+ if ( !pKV->LoadFromFile( filesystem, CREDITS_FILE, "MOD" ) )
+ {
+ pKV->deleteThis();
+
+ Assert( !"env_credits couldn't be initialized!" );
+ return;
+ }
+
+ KeyValues *pKVSubkey;
+ if ( pKeyName )
+ {
+ pKVSubkey = pKV->FindKey( pKeyName );
+ ReadNames( pKVSubkey );
+ }
+
+ pKVSubkey = pKV->FindKey( "CreditsParams" );
+ ReadParams( pKVSubkey );
+
+ pKV->deleteThis();
+}
+
+using namespace vgui;
+
+DECLARE_HUDELEMENT( CHudCredits );
+DECLARE_HUD_MESSAGE( CHudCredits, CreditsMsg );
+DECLARE_HUD_MESSAGE( CHudCredits, LogoTimeMsg );
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CHudCredits::CHudCredits( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudCredits" )
+{
+ vgui::Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+}
+
+void CHudCredits::LevelShutdown()
+{
+ Clear();
+}
+
+void CHudCredits::Clear( void )
+{
+ SetActive( false );
+ m_CreditsList.RemoveAll();
+ m_bLastOneInPlace = false;
+ m_Alpha = m_TextColor[3];
+ m_iLogoState = LOGO_FADEOFF;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudCredits::Init()
+{
+ HOOK_HUD_MESSAGE( CHudCredits, CreditsMsg );
+ HOOK_HUD_MESSAGE( CHudCredits, LogoTimeMsg );
+ SetActive( false );
+}
+
+void CHudCredits::ReadNames( KeyValues *pKeyValue )
+{
+ if ( pKeyValue == NULL )
+ {
+ Assert( !"CHudCredits couldn't be initialized!" );
+ return;
+ }
+
+ // Now try and parse out each act busy anim
+ KeyValues *pKVNames = pKeyValue->GetFirstSubKey();
+
+ while ( pKVNames )
+ {
+ creditname_t Credits;
+ Q_strcpy( Credits.szCreditName, pKVNames->GetName());
+ Q_strcpy( Credits.szFontName, pKeyValue->GetString( Credits.szCreditName, "Default" ) );
+
+ m_CreditsList.AddToTail( Credits );
+ pKVNames = pKVNames->GetNextKey();
+ }
+}
+
+void CHudCredits::ReadParams( KeyValues *pKeyValue )
+{
+ if ( pKeyValue == NULL )
+ {
+ Assert( !"CHudCredits couldn't be initialized!" );
+ return;
+ }
+
+ m_flScrollTime = pKeyValue->GetFloat( "scrolltime", 57 );
+ m_flSeparation = pKeyValue->GetFloat( "separation", 5 );
+
+ m_flFadeInTime = pKeyValue->GetFloat( "fadeintime", 1 );
+ m_flFadeHoldTime = pKeyValue->GetFloat( "fadeholdtime", 3 );
+ m_flFadeOutTime = pKeyValue->GetFloat( "fadeouttime", 2 );
+ m_flNextStartTime = pKeyValue->GetFloat( "nextfadetime", 2 );
+ m_flPauseBetweenWaves = pKeyValue->GetFloat( "pausebetweenwaves", 2 );
+
+ m_flLogoTimeMod = pKeyValue->GetFloat( "logotime", 2 );
+
+ m_flX = pKeyValue->GetFloat( "posx", 2 );
+ m_flY = pKeyValue->GetFloat( "posy", 2 );
+
+ m_cColor = pKeyValue->GetColor( "color" );
+
+ Q_strncpy( m_szLogo, pKeyValue->GetString( "logo", "HALF-LIFE'" ), sizeof( m_szLogo ) );
+ Q_strncpy( m_szLogo2, pKeyValue->GetString( "logo2", "" ), sizeof( m_szLogo2 ) );
+}
+
+int CHudCredits::GetStringPixelWidth( wchar_t *pString, vgui::HFont hFont )
+{
+ int iLength = 0;
+
+ for ( wchar_t *wch = pString; *wch != 0; wch++ )
+ {
+ iLength += surface()->GetCharacterWidth( hFont, *wch );
+ }
+
+ return iLength;
+}
+
+void CHudCredits::DrawOutroCreditsName( void )
+{
+ if ( m_CreditsList.Count() == 0 )
+ return;
+
+ // fill the screen
+ int iWidth, iTall;
+ GetHudSize(iWidth, iTall);
+ SetSize( iWidth, iTall );
+
+ for ( int i = 0; i < m_CreditsList.Count(); i++ )
+ {
+ creditname_t *pCredit = &m_CreditsList[i];
+
+ if ( pCredit == NULL )
+ continue;
+
+ vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
+ vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName, true );
+
+ int iFontTall = surface()->GetFontTall ( m_hTFont );
+
+ if ( pCredit->flYPos < -iFontTall || pCredit->flYPos > iTall )
+ {
+ pCredit->bActive = false;
+ }
+ else
+ {
+ pCredit->bActive = true;
+ }
+
+ Color cColor = m_TextColor;
+
+ //HACKHACK
+ //Last one stays on screen and fades out
+ if ( i == m_CreditsList.Count()-1 )
+ {
+ if ( m_bLastOneInPlace == false )
+ {
+ pCredit->flYPos -= gpGlobals->frametime * ( (float)g_iCreditsPixelHeight / m_flScrollTime );
+
+ if ( (int)pCredit->flYPos + ( iFontTall / 2 ) <= iTall / 2 )
+ {
+ m_bLastOneInPlace = true;
+
+ // 360 certification requires that we not hold a static image too long.
+ m_flFadeTime = gpGlobals->curtime + ( IsConsole() ? 2.0f : 10.0f );
+ }
+ }
+ else
+ {
+ if ( m_flFadeTime <= gpGlobals->curtime )
+ {
+ if ( m_Alpha > 0 )
+ {
+ m_Alpha -= gpGlobals->frametime * ( m_flScrollTime * 2 );
+
+ if ( m_Alpha <= 0 )
+ {
+ pCredit->bActive = false;
+ engine->ClientCmd( "creditsdone" );
+ }
+ }
+ }
+
+ cColor[3] = MAX( 0, m_Alpha );
+ }
+ }
+ else
+ {
+ pCredit->flYPos -= gpGlobals->frametime * ( (float)g_iCreditsPixelHeight / m_flScrollTime );
+ }
+
+ if ( pCredit->bActive == false )
+ continue;
+
+ surface()->DrawSetTextFont( m_hTFont );
+ surface()->DrawSetTextColor( cColor[0], cColor[1], cColor[2], cColor[3] );
+
+ wchar_t unicode[256];
+
+ if ( pCredit->szCreditName[0] == '#' )
+ {
+ g_pVGuiLocalize->ConstructString( unicode, sizeof(unicode), g_pVGuiLocalize->Find(pCredit->szCreditName), 0 );
+ }
+ else
+ {
+ g_pVGuiLocalize->ConvertANSIToUnicode( pCredit->szCreditName, unicode, sizeof( unicode ) );
+ }
+
+ int iStringWidth = GetStringPixelWidth( unicode, m_hTFont );
+
+ surface()->DrawSetTextPos( ( iWidth / 2 ) - ( iStringWidth / 2 ), pCredit->flYPos );
+ surface()->DrawUnicodeString( unicode );
+ }
+}
+
+void CHudCredits::DrawLogo( void )
+{
+ if( m_iLogoState == LOGO_FADEOFF )
+ {
+ SetActive( false );
+ return;
+ }
+
+ switch( m_iLogoState )
+ {
+ case LOGO_FADEIN:
+ {
+ float flDeltaTime = ( m_flFadeTime - gpGlobals->curtime );
+
+ m_Alpha = MAX( 0, RemapValClamped( flDeltaTime, 5.0f, 0, -128, 255 ) );
+
+ if ( flDeltaTime <= 0.0f )
+ {
+ m_iLogoState = LOGO_FADEHOLD;
+ m_flFadeTime = gpGlobals->curtime + m_flLogoDesiredLength;
+ }
+
+ break;
+ }
+
+ case LOGO_FADEHOLD:
+ {
+ if ( m_flFadeTime <= gpGlobals->curtime )
+ {
+ m_iLogoState = LOGO_FADEOUT;
+ m_flFadeTime = gpGlobals->curtime + 2.0f;
+ }
+ break;
+ }
+
+ case LOGO_FADEOUT:
+ {
+ float flDeltaTime = ( m_flFadeTime - gpGlobals->curtime );
+
+ m_Alpha = RemapValClamped( flDeltaTime, 0.0f, 2.0f, 0, 255 );
+
+ if ( flDeltaTime <= 0.0f )
+ {
+ m_iLogoState = LOGO_FADEOFF;
+ SetActive( false );
+ }
+
+ break;
+ }
+ }
+
+ // fill the screen
+ int iWidth, iTall;
+ GetHudSize(iWidth, iTall);
+ SetSize( iWidth, iTall );
+
+ char szLogoFont[64];
+
+ if ( IsXbox() )
+ {
+ Q_snprintf( szLogoFont, sizeof( szLogoFont ), "WeaponIcons_Small" );
+ }
+ else if ( hl2_episodic.GetBool() )
+ {
+ Q_snprintf( szLogoFont, sizeof( szLogoFont ), "ClientTitleFont" );
+ }
+ else
+ {
+ Q_snprintf( szLogoFont, sizeof( szLogoFont ), "WeaponIcons" );
+ }
+
+ vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
+ vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( szLogoFont );
+
+ int iFontTall = surface()->GetFontTall ( m_hTFont );
+
+ Color cColor = m_TextColor;
+ cColor[3] = m_Alpha;
+
+ surface()->DrawSetTextFont( m_hTFont );
+ surface()->DrawSetTextColor( cColor[0], cColor[1], cColor[2], cColor[3] );
+
+ wchar_t unicode[256];
+ g_pVGuiLocalize->ConvertANSIToUnicode( m_szLogo, unicode, sizeof( unicode ) );
+
+ int iStringWidth = GetStringPixelWidth( unicode, m_hTFont );
+
+ surface()->DrawSetTextPos( ( iWidth / 2 ) - ( iStringWidth / 2 ), ( iTall / 2 ) - ( iFontTall / 2 ) );
+ surface()->DrawUnicodeString( unicode );
+
+ if ( Q_strlen( m_szLogo2 ) > 0 )
+ {
+ g_pVGuiLocalize->ConvertANSIToUnicode( m_szLogo2, unicode, sizeof( unicode ) );
+
+ iStringWidth = GetStringPixelWidth( unicode, m_hTFont );
+
+ surface()->DrawSetTextPos( ( iWidth / 2 ) - ( iStringWidth / 2 ), ( iTall / 2 ) + ( iFontTall / 2 ));
+ surface()->DrawUnicodeString( unicode );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+float CHudCredits::FadeBlend( float fadein, float fadeout, float hold, float localTime )
+{
+ float fadeTime = fadein + hold;
+ float fadeBlend;
+
+ if ( localTime < 0 )
+ return 0;
+
+ if ( localTime < fadein )
+ {
+ fadeBlend = 1 - ((fadein - localTime) / fadein);
+ }
+ else if ( localTime > fadeTime )
+ {
+ if ( fadeout > 0 )
+ fadeBlend = 1 - ((localTime - fadeTime) / fadeout);
+ else
+ fadeBlend = 0;
+ }
+ else
+ fadeBlend = 1;
+
+ if ( fadeBlend < 0 )
+ fadeBlend = 0;
+
+ return fadeBlend;
+}
+
+void CHudCredits::DrawIntroCreditsName( void )
+{
+ if ( m_CreditsList.Count() == 0 )
+ return;
+
+ // fill the screen
+ int iWidth, iTall;
+ GetHudSize(iWidth, iTall);
+ SetSize( iWidth, iTall );
+
+ for ( int i = 0; i < m_CreditsList.Count(); i++ )
+ {
+ creditname_t *pCredit = &m_CreditsList[i];
+
+ if ( pCredit == NULL )
+ continue;
+
+ if ( pCredit->bActive == false )
+ continue;
+
+ vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
+ vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName );
+
+ float localTime = gpGlobals->curtime - pCredit->flTimeStart;
+
+ surface()->DrawSetTextFont( m_hTFont );
+ surface()->DrawSetTextColor( m_cColor[0], m_cColor[1], m_cColor[2], FadeBlend( m_flFadeInTime, m_flFadeOutTime, m_flFadeHoldTime + pCredit->flTimeAdd, localTime ) * m_cColor[3] );
+
+ wchar_t unicode[256];
+ g_pVGuiLocalize->ConvertANSIToUnicode( pCredit->szCreditName, unicode, sizeof( unicode ) );
+
+ surface()->DrawSetTextPos( XRES( pCredit->flXPos ), YRES( pCredit->flYPos ) );
+ surface()->DrawUnicodeString( unicode );
+
+ if ( m_flLogoTime > gpGlobals->curtime )
+ continue;
+
+ if ( pCredit->flTime - m_flNextStartTime <= gpGlobals->curtime )
+ {
+ if ( m_CreditsList.IsValidIndex( i + 3 ) )
+ {
+ creditname_t *pNextCredits = &m_CreditsList[i + 3];
+
+ if ( pNextCredits && pNextCredits->flTime == 0.0f )
+ {
+ pNextCredits->bActive = true;
+
+ if ( i < 3 )
+ {
+ pNextCredits->flTimeAdd = ( i + 1.0f );
+ pNextCredits->flTime = gpGlobals->curtime + m_flFadeInTime + m_flFadeOutTime + m_flFadeHoldTime + pNextCredits->flTimeAdd;
+ }
+ else
+ {
+ pNextCredits->flTimeAdd = m_flPauseBetweenWaves;
+ pNextCredits->flTime = gpGlobals->curtime + m_flFadeInTime + m_flFadeOutTime + m_flFadeHoldTime + pNextCredits->flTimeAdd;
+ }
+
+ pNextCredits->flTimeStart = gpGlobals->curtime;
+
+ pNextCredits->iSlot = pCredit->iSlot;
+ }
+ }
+ }
+
+ if ( pCredit->flTime <= gpGlobals->curtime )
+ {
+ pCredit->bActive = false;
+
+ if ( i == m_CreditsList.Count()-1 )
+ {
+ Clear();
+ }
+ }
+ }
+}
+
+void CHudCredits::ApplySchemeSettings( IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ SetVisible( ShouldDraw() );
+
+ SetBgColor( Color(0, 0, 0, 0) );
+}
+
+void CHudCredits::Paint()
+{
+ if ( m_iCreditsType == CREDITS_LOGO )
+ {
+ DrawLogo();
+ }
+ else if ( m_iCreditsType == CREDITS_INTRO )
+ {
+ DrawIntroCreditsName();
+ }
+ else if ( m_iCreditsType == CREDITS_OUTRO )
+ {
+ DrawOutroCreditsName();
+ }
+}
+
+void CHudCredits::PrepareLogo( float flTime )
+{
+ // Only showing the logo. Just load the CreditsParams section.
+ PrepareCredits( NULL );
+
+ m_Alpha = 0;
+ m_flLogoDesiredLength = flTime;
+ m_flFadeTime = gpGlobals->curtime + 5.0f;
+ m_iLogoState = LOGO_FADEIN;
+ SetActive( true );
+}
+
+void CHudCredits::PrepareLine( vgui::HFont hFont, char const *pchLine )
+{
+ Assert( pchLine );
+
+ wchar_t unicode[256];
+
+ if ( pchLine[0] == '#' )
+ {
+ g_pVGuiLocalize->ConstructString( unicode, sizeof(unicode), g_pVGuiLocalize->Find(pchLine), 0 );
+ }
+ else
+ {
+ g_pVGuiLocalize->ConvertANSIToUnicode( pchLine, unicode, sizeof( unicode ) );
+ }
+
+ surface()->PrecacheFontCharacters( hFont, unicode );
+}
+
+void CHudCredits::PrepareOutroCredits( void )
+{
+ PrepareCredits( "OutroCreditsNames" );
+
+ if ( m_CreditsList.Count() == 0 )
+ return;
+
+ // fill the screen
+ int iWidth, iTall;
+ GetHudSize(iWidth, iTall);
+ SetSize( iWidth, iTall );
+
+ int iHeight = iTall;
+
+ for ( int i = 0; i < m_CreditsList.Count(); i++ )
+ {
+ creditname_t *pCredit = &m_CreditsList[i];
+
+ if ( pCredit == NULL )
+ continue;
+
+ vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
+ vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName, true );
+
+ pCredit->flYPos = iHeight;
+ pCredit->bActive = false;
+
+ iHeight += surface()->GetFontTall ( m_hTFont ) + m_flSeparation;
+
+ PrepareLine( m_hTFont, pCredit->szCreditName );
+ }
+
+ SetActive( true );
+
+ g_iCreditsPixelHeight = iHeight;
+}
+
+void CHudCredits::PrepareIntroCredits( void )
+{
+ PrepareCredits( "IntroCreditsNames" );
+
+ int iSlot = 0;
+
+ for ( int i = 0; i < m_CreditsList.Count(); i++ )
+ {
+ creditname_t *pCredit = &m_CreditsList[i];
+
+ if ( pCredit == NULL )
+ continue;
+
+ vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
+ vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName );
+
+ pCredit->flYPos = m_flY + ( iSlot * surface()->GetFontTall ( m_hTFont ) );
+ pCredit->flXPos = m_flX;
+
+ if ( i < 3 )
+ {
+ pCredit->bActive = true;
+ pCredit->iSlot = iSlot;
+ pCredit->flTime = gpGlobals->curtime + m_flFadeInTime + m_flFadeOutTime + m_flFadeHoldTime;
+ pCredit->flTimeStart = gpGlobals->curtime;
+ m_flLogoTime = pCredit->flTime + m_flLogoTimeMod;
+ }
+ else
+ {
+ pCredit->bActive = false;
+ pCredit->flTime = 0.0f;
+ }
+
+ iSlot = ( iSlot + 1 ) % 3;
+
+ PrepareLine( m_hTFont, pCredit->szCreditName );
+ }
+
+ SetActive( true );
+}
+
+void CHudCredits::MsgFunc_CreditsMsg( bf_read &msg )
+{
+ m_iCreditsType = msg.ReadByte();
+
+ switch ( m_iCreditsType )
+ {
+ case CREDITS_LOGO:
+ {
+ PrepareLogo( 5.0f );
+ break;
+ }
+ case CREDITS_INTRO:
+ {
+ PrepareIntroCredits();
+ break;
+ }
+ case CREDITS_OUTRO:
+ {
+ PrepareOutroCredits();
+ break;
+ }
+ }
+}
+
+void CHudCredits::MsgFunc_LogoTimeMsg( bf_read &msg )
+{
+ m_iCreditsType = CREDITS_LOGO;
+ PrepareLogo( msg.ReadFloat() );
+}
+
+
diff --git a/mp/src/game/client/hl2/hud_damageindicator.cpp b/mp/src/game/client/hl2/hud_damageindicator.cpp
index 3116a795..86debdf7 100644
--- a/mp/src/game/client/hl2/hud_damageindicator.cpp
+++ b/mp/src/game/client/hl2/hud_damageindicator.cpp
@@ -1,461 +1,461 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "hud.h"
-#include "text_message.h"
-#include "hud_macros.h"
-#include "iclientmode.h"
-#include "view.h"
-#include <KeyValues.h>
-#include <vgui_controls/AnimationController.h>
-#include <vgui/ISurface.h>
-#include "VGuiMatSurface/IMatSystemSurface.h"
-#include "materialsystem/imaterial.h"
-#include "materialsystem/imesh.h"
-#include "materialsystem/imaterialvar.h"
-#include "IEffects.h"
-#include "hudelement.h"
-#include "clienteffectprecachesystem.h"
-#include "headtrack/isourcevirtualreality.h"
-
-using namespace vgui;
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-
-//-----------------------------------------------------------------------------
-// Purpose: HDU Damage indication
-//-----------------------------------------------------------------------------
-class CHudDamageIndicator : public CHudElement, public vgui::Panel
-{
- DECLARE_CLASS_SIMPLE( CHudDamageIndicator, vgui::Panel );
-
-public:
- CHudDamageIndicator( const char *pElementName );
- void Init( void );
- void Reset( void );
- virtual bool ShouldDraw( void );
-
- // Handler for our message
- void MsgFunc_Damage( bf_read &msg );
-
-private:
- virtual void Paint();
- virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
-
-private:
- CPanelAnimationVarAliasType( float, m_flDmgX, "dmg_xpos", "10", "proportional_float" );
- CPanelAnimationVarAliasType( float, m_flDmgY, "dmg_ypos", "80", "proportional_float" );
- CPanelAnimationVarAliasType( float, m_flDmgWide, "dmg_wide", "30", "proportional_float" );
- CPanelAnimationVarAliasType( float, m_flDmgTall1, "dmg_tall1", "300", "proportional_float" );
- CPanelAnimationVarAliasType( float, m_flDmgTall2, "dmg_tall2", "240", "proportional_float" );
-
- CPanelAnimationVar( Color, m_DmgColorLeft, "DmgColorLeft", "255 0 0 0" );
- CPanelAnimationVar( Color, m_DmgColorRight, "DmgColorRight", "255 0 0 0" );
-
- CPanelAnimationVar( Color, m_DmgHighColorLeft, "DmgHighColorLeft", "255 0 0 0" );
- CPanelAnimationVar( Color, m_DmgHighColorRight, "DmgHighColorRight", "255 0 0 0" );
-
- CPanelAnimationVar( Color, m_DmgFullscreenColor, "DmgFullscreenColor", "255 0 0 0" );
-
- void DrawDamageIndicator(int side);
- void DrawFullscreenDamageIndicator();
- void GetDamagePosition( const Vector &vecDelta, float *flRotation );
-
- CMaterialReference m_WhiteAdditiveMaterial;
-};
-
-DECLARE_HUDELEMENT( CHudDamageIndicator );
-DECLARE_HUD_MESSAGE( CHudDamageIndicator, Damage );
-
-enum
-{
- DAMAGE_ANY,
- DAMAGE_LOW,
- DAMAGE_HIGH,
-};
-
-#define ANGLE_ANY 0.0f
-#define DMG_ANY 0
-
-struct DamageAnimation_t
-{
- const char *name;
- int bitsDamage;
- float angleMinimum;
- float angleMaximum;
- int damage;
-};
-
-//-----------------------------------------------------------------------------
-// Purpose: List of damage animations, finds first that matches criteria
-//-----------------------------------------------------------------------------
-static DamageAnimation_t g_DamageAnimations[] =
-{
- { "HudTakeDamageDrown", DMG_DROWN, ANGLE_ANY, ANGLE_ANY, DAMAGE_ANY },
- { "HudTakeDamagePoison", DMG_POISON, ANGLE_ANY, ANGLE_ANY, DAMAGE_ANY },
- { "HudTakeDamageBurn", DMG_BURN, ANGLE_ANY, ANGLE_ANY, DAMAGE_ANY },
- { "HudTakeDamageRadiation", DMG_RADIATION, ANGLE_ANY, ANGLE_ANY, DAMAGE_ANY },
- { "HudTakeDamageRadiation", DMG_ACID, ANGLE_ANY, ANGLE_ANY, DAMAGE_ANY },
-
- { "HudTakeDamageHighLeft", DMG_ANY, 45.0f, 135.0f, DAMAGE_HIGH },
- { "HudTakeDamageHighRight", DMG_ANY, 225.0f, 315.0f, DAMAGE_HIGH },
- { "HudTakeDamageHigh", DMG_ANY, ANGLE_ANY, ANGLE_ANY, DAMAGE_HIGH },
-
- { "HudTakeDamageLeft", DMG_ANY, 45.0f, 135.0f, DAMAGE_ANY },
- { "HudTakeDamageRight", DMG_ANY, 225.0f, 315.0f, DAMAGE_ANY },
- { "HudTakeDamageBehind", DMG_ANY, 135.0f, 225.0f, DAMAGE_ANY },
-
- // fall through to front damage
- { "HudTakeDamageFront", DMG_ANY, ANGLE_ANY, ANGLE_ANY, DAMAGE_ANY },
- { NULL },
-};
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CHudDamageIndicator::CHudDamageIndicator( const char *pElementName ) : CHudElement( pElementName ), BaseClass(NULL, "HudDamageIndicator")
-{
- vgui::Panel *pParent = g_pClientMode->GetViewport();
- SetParent( pParent );
-
- m_WhiteAdditiveMaterial.Init( "vgui/white_additive", TEXTURE_GROUP_VGUI );
-
- SetHiddenBits( HIDEHUD_HEALTH );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudDamageIndicator::Reset( void )
-{
- m_DmgColorLeft[3] = 0;
- m_DmgColorRight[3] = 0;
- m_DmgHighColorLeft[3] = 0;
- m_DmgHighColorRight[3] = 0;
- m_DmgFullscreenColor[3] = 0;
-}
-
-void CHudDamageIndicator::Init( void )
-{
- HOOK_HUD_MESSAGE( CHudDamageIndicator, Damage );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Save CPU cycles by letting the HUD system early cull
-// costly traversal. Called per frame, return true if thinking and
-// painting need to occur.
-//-----------------------------------------------------------------------------
-bool CHudDamageIndicator::ShouldDraw( void )
-{
- bool bNeedsDraw = m_DmgColorLeft[3] ||
- m_DmgColorRight[3] ||
- m_DmgHighColorLeft[3] ||
- m_DmgHighColorRight[3] ||
- m_DmgFullscreenColor[3];
-
- return ( bNeedsDraw && CHudElement::ShouldDraw() );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Draws a damage quad
-//-----------------------------------------------------------------------------
-void CHudDamageIndicator::DrawDamageIndicator(int side)
-{
- CMatRenderContextPtr pRenderContext( materials );
- IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_WhiteAdditiveMaterial );
-
- CMeshBuilder meshBuilder;
- meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
-
- int insetY = (m_flDmgTall1 - m_flDmgTall2) / 2;
-
- int x1 = m_flDmgX;
- int x2 = m_flDmgX + m_flDmgWide;
- int y[4] = { m_flDmgY, m_flDmgY + insetY, m_flDmgY + m_flDmgTall1 - insetY, m_flDmgY + m_flDmgTall1 };
- int alpha[4] = { 0.0f, 1.0f, 1.0f, 0.0f };
-
- // see if we're high damage
- bool bHighDamage = false;
- if ( m_DmgHighColorRight[3] > m_DmgColorRight[3] || m_DmgHighColorLeft[3] > m_DmgColorLeft[3] )
- {
- // make more of the screen be covered by damage
- x1 = GetWide() * 0.0f;
- x2 = GetWide() * 0.5f;
- y[0] = 0.0f;
- y[1] = 0.0f;
- y[2] = GetTall();
- y[3] = GetTall();
- alpha[0] = 1.0f;
- alpha[1] = 0.0f;
- alpha[2] = 0.0f;
- alpha[3] = 1.0f;
- bHighDamage = true;
- }
-
- int r, g, b, a;
- if (side == 1)
- {
- if ( bHighDamage )
- {
- r = m_DmgHighColorRight[0], g = m_DmgHighColorRight[1], b = m_DmgHighColorRight[2], a = m_DmgHighColorRight[3];
- }
- else
- {
- r = m_DmgColorRight[0], g = m_DmgColorRight[1], b = m_DmgColorRight[2], a = m_DmgColorRight[3];
- }
-
- // realign x coords
- x1 = GetWide() - x1;
- x2 = GetWide() - x2;
-
- meshBuilder.Color4ub( r, g, b, a * alpha[0]);
- meshBuilder.TexCoord2f( 0,0,0 );
- meshBuilder.Position3f( x1, y[0], 0 );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color4ub( r, g, b, a * alpha[3] );
- meshBuilder.TexCoord2f( 0,0,1 );
- meshBuilder.Position3f( x1, y[3], 0 );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color4ub( r, g, b, a * alpha[2] );
- meshBuilder.TexCoord2f( 0,1,1 );
- meshBuilder.Position3f( x2, y[2], 0 );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color4ub( r, g, b, a * alpha[1] );
- meshBuilder.TexCoord2f( 0,1,0 );
- meshBuilder.Position3f( x2, y[1], 0 );
- meshBuilder.AdvanceVertex();
- }
- else
- {
- if ( bHighDamage )
- {
- r = m_DmgHighColorLeft[0], g = m_DmgHighColorLeft[1], b = m_DmgHighColorLeft[2], a = m_DmgHighColorLeft[3];
- }
- else
- {
- r = m_DmgColorLeft[0], g = m_DmgColorLeft[1], b = m_DmgColorLeft[2], a = m_DmgColorLeft[3];
- }
-
- meshBuilder.Color4ub( r, g, b, a * alpha[0] );
- meshBuilder.TexCoord2f( 0,0,0 );
- meshBuilder.Position3f( x1, y[0], 0 );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color4ub( r, g, b, a * alpha[1] );
- meshBuilder.TexCoord2f( 0,1,0 );
- meshBuilder.Position3f( x2, y[1], 0 );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color4ub( r, g, b, a * alpha[2] );
- meshBuilder.TexCoord2f( 0,1,1 );
- meshBuilder.Position3f( x2, y[2], 0 );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color4ub( r, g, b, a * alpha[3] );
- meshBuilder.TexCoord2f( 0,0,1 );
- meshBuilder.Position3f( x1, y[3], 0 );
- meshBuilder.AdvanceVertex();
- }
-
- meshBuilder.End();
- pMesh->Draw();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Draws full screen damage fade
-//-----------------------------------------------------------------------------
-void CHudDamageIndicator::DrawFullscreenDamageIndicator()
-{
- CMatRenderContextPtr pRenderContext( materials );
- IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_WhiteAdditiveMaterial );
-
- CMeshBuilder meshBuilder;
- meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
- int r = m_DmgFullscreenColor[0], g = m_DmgFullscreenColor[1], b = m_DmgFullscreenColor[2], a = m_DmgFullscreenColor[3];
-
- float wide = GetWide(), tall = GetTall();
-
- meshBuilder.Color4ub( r, g, b, a );
- meshBuilder.TexCoord2f( 0,0,0 );
- meshBuilder.Position3f( 0.0f, 0.0f, 0 );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color4ub( r, g, b, a );
- meshBuilder.TexCoord2f( 0,1,0 );
- meshBuilder.Position3f( wide, 0.0f, 0 );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color4ub( r, g, b, a );
- meshBuilder.TexCoord2f( 0,1,1 );
- meshBuilder.Position3f( wide, tall, 0 );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color4ub( r, g, b, a );
- meshBuilder.TexCoord2f( 0,0,1 );
- meshBuilder.Position3f( 0.0f, tall, 0 );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.End();
- pMesh->Draw();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Paints the damage display
-//-----------------------------------------------------------------------------
-void CHudDamageIndicator::Paint()
-{
- // draw fullscreen damage indicators
- DrawFullscreenDamageIndicator();
-
- // draw side damage indicators
- DrawDamageIndicator(0);
- DrawDamageIndicator(1);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Message handler for Damage message
-//-----------------------------------------------------------------------------
-void CHudDamageIndicator::MsgFunc_Damage( bf_read &msg )
-{
- int armor = msg.ReadByte(); // armor
- int damageTaken = msg.ReadByte(); // health
- long bitsDamage = msg.ReadLong(); // damage bits
-
- Vector vecFrom;
-
- vecFrom.x = msg.ReadFloat();
- vecFrom.y = msg.ReadFloat();
- vecFrom.z = msg.ReadFloat();
-
- C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
- if ( !pPlayer )
- return;
-
- // player has just died, just run the dead damage animation
- if ( pPlayer->GetHealth() <= 0 )
- {
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudPlayerDeath" );
- return;
- }
-
- // ignore damage without direction
- // this should never happen, unless it's drowning damage,
- // or the player is forcibly killed, handled above
- if ( vecFrom == vec3_origin && !(bitsDamage & DMG_DROWN))
- return;
-
- Vector vecDelta = (vecFrom - MainViewOrigin());
- VectorNormalize( vecDelta );
-
- int highDamage = DAMAGE_LOW;
- if ( damageTaken > 25 )
- {
- highDamage = DAMAGE_HIGH;
- }
-
- // if we have no suit, all damage is high
- if ( !pPlayer->IsSuitEquipped() )
- {
- highDamage = DAMAGE_HIGH;
- }
-
- if ( damageTaken > 0 || armor > 0 )
- {
- // see which quandrant the effect is in
- float angle;
- GetDamagePosition( vecDelta, &angle );
-
- // see which effect to play
- DamageAnimation_t *dmgAnim = g_DamageAnimations;
- for ( ; dmgAnim->name != NULL; ++dmgAnim )
- {
- if ( dmgAnim->bitsDamage && !(bitsDamage & dmgAnim->bitsDamage) )
- continue;
-
- if ( dmgAnim->angleMinimum && angle < dmgAnim->angleMinimum )
- continue;
-
- if ( dmgAnim->angleMaximum && angle > dmgAnim->angleMaximum )
- continue;
-
- if ( dmgAnim->damage && dmgAnim->damage != highDamage )
- continue;
-
- // we have a match, break
- break;
- }
-
- if ( dmgAnim->name )
- {
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( dmgAnim->name );
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Convert a damage position in world units to the screen's units
-//-----------------------------------------------------------------------------
-void CHudDamageIndicator::GetDamagePosition( const Vector &vecDelta, float *flRotation )
-{
- float flRadius = 360.0f;
-
- // Player Data
- Vector playerPosition = MainViewOrigin();
- QAngle playerAngles = MainViewAngles();
-
- Vector forward, right, up(0,0,1);
- AngleVectors (playerAngles, &forward, NULL, NULL );
- forward.z = 0;
- VectorNormalize(forward);
- CrossProduct( up, forward, right );
- float front = DotProduct(vecDelta, forward);
- float side = DotProduct(vecDelta, right);
- float xpos = flRadius * -side;
- float ypos = flRadius * -front;
-
- // Get the rotation (yaw)
- *flRotation = atan2(xpos, ypos) + M_PI;
- *flRotation *= 180 / M_PI;
-
- float yawRadians = -(*flRotation) * M_PI / 180.0f;
- float ca = cos( yawRadians );
- float sa = sin( yawRadians );
-
- // Rotate it around the circle
- xpos = (int)((GetWide() / 2) + (flRadius * sa));
- ypos = (int)((GetTall() / 2) - (flRadius * ca));
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: hud scheme settings
-//-----------------------------------------------------------------------------
-void CHudDamageIndicator::ApplySchemeSettings(vgui::IScheme *pScheme)
-{
- BaseClass::ApplySchemeSettings(pScheme);
- SetPaintBackgroundEnabled(false);
-
- int vx, vy, vw, vh;
- vgui::surface()->GetFullscreenViewport( vx, vy, vw, vh );
-
- SetForceStereoRenderToFrameBuffer( true );
-
- if( UseVR() )
- {
- m_flDmgY = 0.125f * (float)vh;
- m_flDmgTall1 = 0.625f * (float)vh;
- m_flDmgTall2 = 0.4f * (float)vh;
- m_flDmgWide = 0.1f * (float)vw;
- }
-
- SetSize(vw, vh);
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "hud.h"
+#include "text_message.h"
+#include "hud_macros.h"
+#include "iclientmode.h"
+#include "view.h"
+#include <KeyValues.h>
+#include <vgui_controls/AnimationController.h>
+#include <vgui/ISurface.h>
+#include "VGuiMatSurface/IMatSystemSurface.h"
+#include "materialsystem/imaterial.h"
+#include "materialsystem/imesh.h"
+#include "materialsystem/imaterialvar.h"
+#include "IEffects.h"
+#include "hudelement.h"
+#include "clienteffectprecachesystem.h"
+#include "headtrack/isourcevirtualreality.h"
+
+using namespace vgui;
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+//-----------------------------------------------------------------------------
+// Purpose: HDU Damage indication
+//-----------------------------------------------------------------------------
+class CHudDamageIndicator : public CHudElement, public vgui::Panel
+{
+ DECLARE_CLASS_SIMPLE( CHudDamageIndicator, vgui::Panel );
+
+public:
+ CHudDamageIndicator( const char *pElementName );
+ void Init( void );
+ void Reset( void );
+ virtual bool ShouldDraw( void );
+
+ // Handler for our message
+ void MsgFunc_Damage( bf_read &msg );
+
+private:
+ virtual void Paint();
+ virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
+
+private:
+ CPanelAnimationVarAliasType( float, m_flDmgX, "dmg_xpos", "10", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flDmgY, "dmg_ypos", "80", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flDmgWide, "dmg_wide", "30", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flDmgTall1, "dmg_tall1", "300", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flDmgTall2, "dmg_tall2", "240", "proportional_float" );
+
+ CPanelAnimationVar( Color, m_DmgColorLeft, "DmgColorLeft", "255 0 0 0" );
+ CPanelAnimationVar( Color, m_DmgColorRight, "DmgColorRight", "255 0 0 0" );
+
+ CPanelAnimationVar( Color, m_DmgHighColorLeft, "DmgHighColorLeft", "255 0 0 0" );
+ CPanelAnimationVar( Color, m_DmgHighColorRight, "DmgHighColorRight", "255 0 0 0" );
+
+ CPanelAnimationVar( Color, m_DmgFullscreenColor, "DmgFullscreenColor", "255 0 0 0" );
+
+ void DrawDamageIndicator(int side);
+ void DrawFullscreenDamageIndicator();
+ void GetDamagePosition( const Vector &vecDelta, float *flRotation );
+
+ CMaterialReference m_WhiteAdditiveMaterial;
+};
+
+DECLARE_HUDELEMENT( CHudDamageIndicator );
+DECLARE_HUD_MESSAGE( CHudDamageIndicator, Damage );
+
+enum
+{
+ DAMAGE_ANY,
+ DAMAGE_LOW,
+ DAMAGE_HIGH,
+};
+
+#define ANGLE_ANY 0.0f
+#define DMG_ANY 0
+
+struct DamageAnimation_t
+{
+ const char *name;
+ int bitsDamage;
+ float angleMinimum;
+ float angleMaximum;
+ int damage;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: List of damage animations, finds first that matches criteria
+//-----------------------------------------------------------------------------
+static DamageAnimation_t g_DamageAnimations[] =
+{
+ { "HudTakeDamageDrown", DMG_DROWN, ANGLE_ANY, ANGLE_ANY, DAMAGE_ANY },
+ { "HudTakeDamagePoison", DMG_POISON, ANGLE_ANY, ANGLE_ANY, DAMAGE_ANY },
+ { "HudTakeDamageBurn", DMG_BURN, ANGLE_ANY, ANGLE_ANY, DAMAGE_ANY },
+ { "HudTakeDamageRadiation", DMG_RADIATION, ANGLE_ANY, ANGLE_ANY, DAMAGE_ANY },
+ { "HudTakeDamageRadiation", DMG_ACID, ANGLE_ANY, ANGLE_ANY, DAMAGE_ANY },
+
+ { "HudTakeDamageHighLeft", DMG_ANY, 45.0f, 135.0f, DAMAGE_HIGH },
+ { "HudTakeDamageHighRight", DMG_ANY, 225.0f, 315.0f, DAMAGE_HIGH },
+ { "HudTakeDamageHigh", DMG_ANY, ANGLE_ANY, ANGLE_ANY, DAMAGE_HIGH },
+
+ { "HudTakeDamageLeft", DMG_ANY, 45.0f, 135.0f, DAMAGE_ANY },
+ { "HudTakeDamageRight", DMG_ANY, 225.0f, 315.0f, DAMAGE_ANY },
+ { "HudTakeDamageBehind", DMG_ANY, 135.0f, 225.0f, DAMAGE_ANY },
+
+ // fall through to front damage
+ { "HudTakeDamageFront", DMG_ANY, ANGLE_ANY, ANGLE_ANY, DAMAGE_ANY },
+ { NULL },
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CHudDamageIndicator::CHudDamageIndicator( const char *pElementName ) : CHudElement( pElementName ), BaseClass(NULL, "HudDamageIndicator")
+{
+ vgui::Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+
+ m_WhiteAdditiveMaterial.Init( "vgui/white_additive", TEXTURE_GROUP_VGUI );
+
+ SetHiddenBits( HIDEHUD_HEALTH );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudDamageIndicator::Reset( void )
+{
+ m_DmgColorLeft[3] = 0;
+ m_DmgColorRight[3] = 0;
+ m_DmgHighColorLeft[3] = 0;
+ m_DmgHighColorRight[3] = 0;
+ m_DmgFullscreenColor[3] = 0;
+}
+
+void CHudDamageIndicator::Init( void )
+{
+ HOOK_HUD_MESSAGE( CHudDamageIndicator, Damage );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Save CPU cycles by letting the HUD system early cull
+// costly traversal. Called per frame, return true if thinking and
+// painting need to occur.
+//-----------------------------------------------------------------------------
+bool CHudDamageIndicator::ShouldDraw( void )
+{
+ bool bNeedsDraw = m_DmgColorLeft[3] ||
+ m_DmgColorRight[3] ||
+ m_DmgHighColorLeft[3] ||
+ m_DmgHighColorRight[3] ||
+ m_DmgFullscreenColor[3];
+
+ return ( bNeedsDraw && CHudElement::ShouldDraw() );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Draws a damage quad
+//-----------------------------------------------------------------------------
+void CHudDamageIndicator::DrawDamageIndicator(int side)
+{
+ CMatRenderContextPtr pRenderContext( materials );
+ IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_WhiteAdditiveMaterial );
+
+ CMeshBuilder meshBuilder;
+ meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
+
+ int insetY = (m_flDmgTall1 - m_flDmgTall2) / 2;
+
+ int x1 = m_flDmgX;
+ int x2 = m_flDmgX + m_flDmgWide;
+ int y[4] = { m_flDmgY, m_flDmgY + insetY, m_flDmgY + m_flDmgTall1 - insetY, m_flDmgY + m_flDmgTall1 };
+ int alpha[4] = { 0.0f, 1.0f, 1.0f, 0.0f };
+
+ // see if we're high damage
+ bool bHighDamage = false;
+ if ( m_DmgHighColorRight[3] > m_DmgColorRight[3] || m_DmgHighColorLeft[3] > m_DmgColorLeft[3] )
+ {
+ // make more of the screen be covered by damage
+ x1 = GetWide() * 0.0f;
+ x2 = GetWide() * 0.5f;
+ y[0] = 0.0f;
+ y[1] = 0.0f;
+ y[2] = GetTall();
+ y[3] = GetTall();
+ alpha[0] = 1.0f;
+ alpha[1] = 0.0f;
+ alpha[2] = 0.0f;
+ alpha[3] = 1.0f;
+ bHighDamage = true;
+ }
+
+ int r, g, b, a;
+ if (side == 1)
+ {
+ if ( bHighDamage )
+ {
+ r = m_DmgHighColorRight[0], g = m_DmgHighColorRight[1], b = m_DmgHighColorRight[2], a = m_DmgHighColorRight[3];
+ }
+ else
+ {
+ r = m_DmgColorRight[0], g = m_DmgColorRight[1], b = m_DmgColorRight[2], a = m_DmgColorRight[3];
+ }
+
+ // realign x coords
+ x1 = GetWide() - x1;
+ x2 = GetWide() - x2;
+
+ meshBuilder.Color4ub( r, g, b, a * alpha[0]);
+ meshBuilder.TexCoord2f( 0,0,0 );
+ meshBuilder.Position3f( x1, y[0], 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ub( r, g, b, a * alpha[3] );
+ meshBuilder.TexCoord2f( 0,0,1 );
+ meshBuilder.Position3f( x1, y[3], 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ub( r, g, b, a * alpha[2] );
+ meshBuilder.TexCoord2f( 0,1,1 );
+ meshBuilder.Position3f( x2, y[2], 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ub( r, g, b, a * alpha[1] );
+ meshBuilder.TexCoord2f( 0,1,0 );
+ meshBuilder.Position3f( x2, y[1], 0 );
+ meshBuilder.AdvanceVertex();
+ }
+ else
+ {
+ if ( bHighDamage )
+ {
+ r = m_DmgHighColorLeft[0], g = m_DmgHighColorLeft[1], b = m_DmgHighColorLeft[2], a = m_DmgHighColorLeft[3];
+ }
+ else
+ {
+ r = m_DmgColorLeft[0], g = m_DmgColorLeft[1], b = m_DmgColorLeft[2], a = m_DmgColorLeft[3];
+ }
+
+ meshBuilder.Color4ub( r, g, b, a * alpha[0] );
+ meshBuilder.TexCoord2f( 0,0,0 );
+ meshBuilder.Position3f( x1, y[0], 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ub( r, g, b, a * alpha[1] );
+ meshBuilder.TexCoord2f( 0,1,0 );
+ meshBuilder.Position3f( x2, y[1], 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ub( r, g, b, a * alpha[2] );
+ meshBuilder.TexCoord2f( 0,1,1 );
+ meshBuilder.Position3f( x2, y[2], 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ub( r, g, b, a * alpha[3] );
+ meshBuilder.TexCoord2f( 0,0,1 );
+ meshBuilder.Position3f( x1, y[3], 0 );
+ meshBuilder.AdvanceVertex();
+ }
+
+ meshBuilder.End();
+ pMesh->Draw();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Draws full screen damage fade
+//-----------------------------------------------------------------------------
+void CHudDamageIndicator::DrawFullscreenDamageIndicator()
+{
+ CMatRenderContextPtr pRenderContext( materials );
+ IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_WhiteAdditiveMaterial );
+
+ CMeshBuilder meshBuilder;
+ meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
+ int r = m_DmgFullscreenColor[0], g = m_DmgFullscreenColor[1], b = m_DmgFullscreenColor[2], a = m_DmgFullscreenColor[3];
+
+ float wide = GetWide(), tall = GetTall();
+
+ meshBuilder.Color4ub( r, g, b, a );
+ meshBuilder.TexCoord2f( 0,0,0 );
+ meshBuilder.Position3f( 0.0f, 0.0f, 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ub( r, g, b, a );
+ meshBuilder.TexCoord2f( 0,1,0 );
+ meshBuilder.Position3f( wide, 0.0f, 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ub( r, g, b, a );
+ meshBuilder.TexCoord2f( 0,1,1 );
+ meshBuilder.Position3f( wide, tall, 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color4ub( r, g, b, a );
+ meshBuilder.TexCoord2f( 0,0,1 );
+ meshBuilder.Position3f( 0.0f, tall, 0 );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.End();
+ pMesh->Draw();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Paints the damage display
+//-----------------------------------------------------------------------------
+void CHudDamageIndicator::Paint()
+{
+ // draw fullscreen damage indicators
+ DrawFullscreenDamageIndicator();
+
+ // draw side damage indicators
+ DrawDamageIndicator(0);
+ DrawDamageIndicator(1);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Message handler for Damage message
+//-----------------------------------------------------------------------------
+void CHudDamageIndicator::MsgFunc_Damage( bf_read &msg )
+{
+ int armor = msg.ReadByte(); // armor
+ int damageTaken = msg.ReadByte(); // health
+ long bitsDamage = msg.ReadLong(); // damage bits
+
+ Vector vecFrom;
+
+ vecFrom.x = msg.ReadFloat();
+ vecFrom.y = msg.ReadFloat();
+ vecFrom.z = msg.ReadFloat();
+
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ // player has just died, just run the dead damage animation
+ if ( pPlayer->GetHealth() <= 0 )
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudPlayerDeath" );
+ return;
+ }
+
+ // ignore damage without direction
+ // this should never happen, unless it's drowning damage,
+ // or the player is forcibly killed, handled above
+ if ( vecFrom == vec3_origin && !(bitsDamage & DMG_DROWN))
+ return;
+
+ Vector vecDelta = (vecFrom - MainViewOrigin());
+ VectorNormalize( vecDelta );
+
+ int highDamage = DAMAGE_LOW;
+ if ( damageTaken > 25 )
+ {
+ highDamage = DAMAGE_HIGH;
+ }
+
+ // if we have no suit, all damage is high
+ if ( !pPlayer->IsSuitEquipped() )
+ {
+ highDamage = DAMAGE_HIGH;
+ }
+
+ if ( damageTaken > 0 || armor > 0 )
+ {
+ // see which quandrant the effect is in
+ float angle;
+ GetDamagePosition( vecDelta, &angle );
+
+ // see which effect to play
+ DamageAnimation_t *dmgAnim = g_DamageAnimations;
+ for ( ; dmgAnim->name != NULL; ++dmgAnim )
+ {
+ if ( dmgAnim->bitsDamage && !(bitsDamage & dmgAnim->bitsDamage) )
+ continue;
+
+ if ( dmgAnim->angleMinimum && angle < dmgAnim->angleMinimum )
+ continue;
+
+ if ( dmgAnim->angleMaximum && angle > dmgAnim->angleMaximum )
+ continue;
+
+ if ( dmgAnim->damage && dmgAnim->damage != highDamage )
+ continue;
+
+ // we have a match, break
+ break;
+ }
+
+ if ( dmgAnim->name )
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( dmgAnim->name );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Convert a damage position in world units to the screen's units
+//-----------------------------------------------------------------------------
+void CHudDamageIndicator::GetDamagePosition( const Vector &vecDelta, float *flRotation )
+{
+ float flRadius = 360.0f;
+
+ // Player Data
+ Vector playerPosition = MainViewOrigin();
+ QAngle playerAngles = MainViewAngles();
+
+ Vector forward, right, up(0,0,1);
+ AngleVectors (playerAngles, &forward, NULL, NULL );
+ forward.z = 0;
+ VectorNormalize(forward);
+ CrossProduct( up, forward, right );
+ float front = DotProduct(vecDelta, forward);
+ float side = DotProduct(vecDelta, right);
+ float xpos = flRadius * -side;
+ float ypos = flRadius * -front;
+
+ // Get the rotation (yaw)
+ *flRotation = atan2(xpos, ypos) + M_PI;
+ *flRotation *= 180 / M_PI;
+
+ float yawRadians = -(*flRotation) * M_PI / 180.0f;
+ float ca = cos( yawRadians );
+ float sa = sin( yawRadians );
+
+ // Rotate it around the circle
+ xpos = (int)((GetWide() / 2) + (flRadius * sa));
+ ypos = (int)((GetTall() / 2) - (flRadius * ca));
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: hud scheme settings
+//-----------------------------------------------------------------------------
+void CHudDamageIndicator::ApplySchemeSettings(vgui::IScheme *pScheme)
+{
+ BaseClass::ApplySchemeSettings(pScheme);
+ SetPaintBackgroundEnabled(false);
+
+ int vx, vy, vw, vh;
+ vgui::surface()->GetFullscreenViewport( vx, vy, vw, vh );
+
+ SetForceStereoRenderToFrameBuffer( true );
+
+ if( UseVR() )
+ {
+ m_flDmgY = 0.125f * (float)vh;
+ m_flDmgTall1 = 0.625f * (float)vh;
+ m_flDmgTall2 = 0.4f * (float)vh;
+ m_flDmgWide = 0.1f * (float)vw;
+ }
+
+ SetSize(vw, vh);
+}
diff --git a/mp/src/game/client/hl2/hud_filmdemo.cpp b/mp/src/game/client/hl2/hud_filmdemo.cpp
index 29a1dd6f..ca21a855 100644
--- a/mp/src/game/client/hl2/hud_filmdemo.cpp
+++ b/mp/src/game/client/hl2/hud_filmdemo.cpp
@@ -1,190 +1,190 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//===========================================================================//
-#include "cbase.h"
-#include "c_baseentity.h"
-#include "hud.h"
-#include "hudelement.h"
-#include "clientmode.h"
-#include <vgui_controls/Panel.h>
-#include <vgui/IScheme.h>
-#include <vgui/ISurface.h>
-#include <vgui/ILocalize.h>
-#include <vgui_controls/AnimationController.h>
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-class CHudFilmDemo : public CHudElement, public vgui::Panel
-{
- DECLARE_CLASS_SIMPLE( CHudFilmDemo, vgui::Panel );
-public:
- CHudFilmDemo( const char *name );
-
- // vgui overrides
- virtual void ApplySchemeSettings(vgui::IScheme *pScheme );
- virtual void Paint( void );
- virtual bool ShouldDraw( void );
-
- void SetFilmDemoActive( bool bActive );
-
- void SetLeftStringID( const char *id );
- void SetRightStringID( const char *id );
-
-private:
- bool m_bFilmDemoActive;
-
- char m_pLeftStringID[ 256 ];
- char m_pRightStringID[ 256 ];
-
- // Painting
- //CPanelAnimationVar( float, m_flAlphaOverride, "Alpha", "0" );
- CPanelAnimationVar( Color, m_BorderColor, "BorderColor", "0 0 0 255" );
- CPanelAnimationVar( Color, m_TextColor, "TextColor", "255 255 255 255" );
- CPanelAnimationVarAliasType( int, m_iBorderLeft, "BorderLeft", "8", "proportional_int" );
- CPanelAnimationVarAliasType( int, m_iBorderRight, "BorderRight", "8", "proportional_int" );
- CPanelAnimationVarAliasType( int, m_iBorderTop, "BorderTop", "8", "proportional_int" );
- CPanelAnimationVarAliasType( int, m_iBorderBottom, "BorderBottom", "48", "proportional_int" );
- CPanelAnimationVarAliasType( int, m_iBorderCenter, "BorderCenter", "8", "proportional_int" );
-
- CPanelAnimationVarAliasType( int, m_iLeftY, "LeftTitleY", "440", "proportional_int" );
- CPanelAnimationVarAliasType( int, m_iRightY, "RightTitleY", "440", "proportional_int" );
-};
-
-DECLARE_HUDELEMENT( CHudFilmDemo );
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-CHudFilmDemo::CHudFilmDemo( const char *name ) : vgui::Panel( NULL, "HudHDRDemo" ), CHudElement( name )
-{
- vgui::Panel *pParent = g_pClientMode->GetViewport();
- SetParent( pParent );
-
- SetPaintBorderEnabled( false );
- SetPaintBackgroundEnabled( false );
-
- m_bFilmDemoActive = false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudFilmDemo::ApplySchemeSettings( vgui::IScheme *pScheme )
-{
- BaseClass::ApplySchemeSettings(pScheme);
- SetSize( ScreenWidth(), ScreenHeight() );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudFilmDemo::Paint()
-{
- int x, y, wide, tall;
- GetBounds( x, y, wide, tall );
-
- // Draw the borders
- vgui::surface()->DrawSetColor( m_BorderColor );
- vgui::surface()->DrawFilledRect( 0, 0, m_iBorderLeft, tall ); // Left
- vgui::surface()->DrawFilledRect( wide-m_iBorderRight, 0, wide, tall ); // Right
- vgui::surface()->DrawFilledRect( m_iBorderLeft, 0, wide-m_iBorderRight, m_iBorderTop ); // Top
- vgui::surface()->DrawFilledRect( m_iBorderLeft, tall-m_iBorderBottom, wide-m_iBorderRight, tall ); // Bottom
- vgui::surface()->DrawFilledRect( ((wide-m_iBorderCenter)/2), m_iBorderTop, ((wide+m_iBorderCenter)/2), tall-m_iBorderBottom ); // Center
-
- // Get our scheme and font information
- vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
- vgui::HFont hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "MenuTitle" );
- vgui::surface()->DrawSetTextFont( hFont );
- vgui::surface()->DrawSetTextColor( m_TextColor );
-
- wchar_t *tempString = g_pVGuiLocalize->Find( m_pLeftStringID );
- if( tempString )
- {
- int iLength = 0;
- for ( wchar_t *wch = tempString; *wch != 0; wch++ )
- {
- iLength += vgui::surface()->GetCharacterWidth( hFont, *wch );
- }
- vgui::surface()->DrawSetTextPos( floor(wide * 0.25) - (iLength / 2), m_iLeftY );
- vgui::surface()->DrawPrintText( tempString, wcslen(tempString) );
- }
-
- tempString = g_pVGuiLocalize->Find( m_pRightStringID );
- if( tempString )
- {
- int iLength = 0;
- for ( wchar_t *wch = tempString; *wch != 0; wch++ )
- {
- iLength += vgui::surface()->GetCharacterWidth( hFont, *wch );
- }
- vgui::surface()->DrawSetTextPos( ceil(wide * 0.75) - (iLength / 2), m_iRightY );
- vgui::surface()->DrawPrintText( tempString, wcslen(tempString) );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool CHudFilmDemo::ShouldDraw()
-{
- return ( m_bFilmDemoActive ); //&& m_flAlphaOverride > 0 );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : bActive -
-//-----------------------------------------------------------------------------
-void CHudFilmDemo::SetFilmDemoActive( bool bActive )
-{
- if ( bActive && !m_bFilmDemoActive )
- {
- ConVarRef hideHud( "hidehud" );
- hideHud.SetValue( 15 );
- }
- else if ( !bActive && m_bFilmDemoActive )
- {
- ConVarRef hideHud( "hidehud" );
- hideHud.SetValue( 0 );
- }
-
- m_bFilmDemoActive = bActive;
-}
-
-void CHudFilmDemo::SetLeftStringID( const char *id )
-{
- Q_strcpy( m_pLeftStringID, id );
-}
-
-void CHudFilmDemo::SetRightStringID( const char *id )
-{
- Q_strcpy( m_pRightStringID, id );
-}
-
-void EnableHUDFilmDemo( bool bEnable, const char *left_string_id, const char *right_string_id )
-{
- CHudFilmDemo *pHudDemo = (CHudFilmDemo*)GET_HUDELEMENT( CHudFilmDemo );
- if ( pHudDemo )
- {
- if( left_string_id )
- {
- pHudDemo->SetLeftStringID( left_string_id );
- }
-
- if( right_string_id )
- {
- pHudDemo->SetRightStringID( right_string_id );
- }
-
- pHudDemo->SetFilmDemoActive( bEnable );
- }
-}
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//===========================================================================//
+#include "cbase.h"
+#include "c_baseentity.h"
+#include "hud.h"
+#include "hudelement.h"
+#include "clientmode.h"
+#include <vgui_controls/Panel.h>
+#include <vgui/IScheme.h>
+#include <vgui/ISurface.h>
+#include <vgui/ILocalize.h>
+#include <vgui_controls/AnimationController.h>
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class CHudFilmDemo : public CHudElement, public vgui::Panel
+{
+ DECLARE_CLASS_SIMPLE( CHudFilmDemo, vgui::Panel );
+public:
+ CHudFilmDemo( const char *name );
+
+ // vgui overrides
+ virtual void ApplySchemeSettings(vgui::IScheme *pScheme );
+ virtual void Paint( void );
+ virtual bool ShouldDraw( void );
+
+ void SetFilmDemoActive( bool bActive );
+
+ void SetLeftStringID( const char *id );
+ void SetRightStringID( const char *id );
+
+private:
+ bool m_bFilmDemoActive;
+
+ char m_pLeftStringID[ 256 ];
+ char m_pRightStringID[ 256 ];
+
+ // Painting
+ //CPanelAnimationVar( float, m_flAlphaOverride, "Alpha", "0" );
+ CPanelAnimationVar( Color, m_BorderColor, "BorderColor", "0 0 0 255" );
+ CPanelAnimationVar( Color, m_TextColor, "TextColor", "255 255 255 255" );
+ CPanelAnimationVarAliasType( int, m_iBorderLeft, "BorderLeft", "8", "proportional_int" );
+ CPanelAnimationVarAliasType( int, m_iBorderRight, "BorderRight", "8", "proportional_int" );
+ CPanelAnimationVarAliasType( int, m_iBorderTop, "BorderTop", "8", "proportional_int" );
+ CPanelAnimationVarAliasType( int, m_iBorderBottom, "BorderBottom", "48", "proportional_int" );
+ CPanelAnimationVarAliasType( int, m_iBorderCenter, "BorderCenter", "8", "proportional_int" );
+
+ CPanelAnimationVarAliasType( int, m_iLeftY, "LeftTitleY", "440", "proportional_int" );
+ CPanelAnimationVarAliasType( int, m_iRightY, "RightTitleY", "440", "proportional_int" );
+};
+
+DECLARE_HUDELEMENT( CHudFilmDemo );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CHudFilmDemo::CHudFilmDemo( const char *name ) : vgui::Panel( NULL, "HudHDRDemo" ), CHudElement( name )
+{
+ vgui::Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+
+ SetPaintBorderEnabled( false );
+ SetPaintBackgroundEnabled( false );
+
+ m_bFilmDemoActive = false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudFilmDemo::ApplySchemeSettings( vgui::IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings(pScheme);
+ SetSize( ScreenWidth(), ScreenHeight() );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudFilmDemo::Paint()
+{
+ int x, y, wide, tall;
+ GetBounds( x, y, wide, tall );
+
+ // Draw the borders
+ vgui::surface()->DrawSetColor( m_BorderColor );
+ vgui::surface()->DrawFilledRect( 0, 0, m_iBorderLeft, tall ); // Left
+ vgui::surface()->DrawFilledRect( wide-m_iBorderRight, 0, wide, tall ); // Right
+ vgui::surface()->DrawFilledRect( m_iBorderLeft, 0, wide-m_iBorderRight, m_iBorderTop ); // Top
+ vgui::surface()->DrawFilledRect( m_iBorderLeft, tall-m_iBorderBottom, wide-m_iBorderRight, tall ); // Bottom
+ vgui::surface()->DrawFilledRect( ((wide-m_iBorderCenter)/2), m_iBorderTop, ((wide+m_iBorderCenter)/2), tall-m_iBorderBottom ); // Center
+
+ // Get our scheme and font information
+ vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
+ vgui::HFont hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "MenuTitle" );
+ vgui::surface()->DrawSetTextFont( hFont );
+ vgui::surface()->DrawSetTextColor( m_TextColor );
+
+ wchar_t *tempString = g_pVGuiLocalize->Find( m_pLeftStringID );
+ if( tempString )
+ {
+ int iLength = 0;
+ for ( wchar_t *wch = tempString; *wch != 0; wch++ )
+ {
+ iLength += vgui::surface()->GetCharacterWidth( hFont, *wch );
+ }
+ vgui::surface()->DrawSetTextPos( floor(wide * 0.25) - (iLength / 2), m_iLeftY );
+ vgui::surface()->DrawPrintText( tempString, wcslen(tempString) );
+ }
+
+ tempString = g_pVGuiLocalize->Find( m_pRightStringID );
+ if( tempString )
+ {
+ int iLength = 0;
+ for ( wchar_t *wch = tempString; *wch != 0; wch++ )
+ {
+ iLength += vgui::surface()->GetCharacterWidth( hFont, *wch );
+ }
+ vgui::surface()->DrawSetTextPos( ceil(wide * 0.75) - (iLength / 2), m_iRightY );
+ vgui::surface()->DrawPrintText( tempString, wcslen(tempString) );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CHudFilmDemo::ShouldDraw()
+{
+ return ( m_bFilmDemoActive ); //&& m_flAlphaOverride > 0 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : bActive -
+//-----------------------------------------------------------------------------
+void CHudFilmDemo::SetFilmDemoActive( bool bActive )
+{
+ if ( bActive && !m_bFilmDemoActive )
+ {
+ ConVarRef hideHud( "hidehud" );
+ hideHud.SetValue( 15 );
+ }
+ else if ( !bActive && m_bFilmDemoActive )
+ {
+ ConVarRef hideHud( "hidehud" );
+ hideHud.SetValue( 0 );
+ }
+
+ m_bFilmDemoActive = bActive;
+}
+
+void CHudFilmDemo::SetLeftStringID( const char *id )
+{
+ Q_strcpy( m_pLeftStringID, id );
+}
+
+void CHudFilmDemo::SetRightStringID( const char *id )
+{
+ Q_strcpy( m_pRightStringID, id );
+}
+
+void EnableHUDFilmDemo( bool bEnable, const char *left_string_id, const char *right_string_id )
+{
+ CHudFilmDemo *pHudDemo = (CHudFilmDemo*)GET_HUDELEMENT( CHudFilmDemo );
+ if ( pHudDemo )
+ {
+ if( left_string_id )
+ {
+ pHudDemo->SetLeftStringID( left_string_id );
+ }
+
+ if( right_string_id )
+ {
+ pHudDemo->SetRightStringID( right_string_id );
+ }
+
+ pHudDemo->SetFilmDemoActive( bEnable );
+ }
+}
+
+
diff --git a/mp/src/game/client/hl2/hud_flashlight.cpp b/mp/src/game/client/hl2/hud_flashlight.cpp
index 922a0d0b..7c63f7a7 100644
--- a/mp/src/game/client/hl2/hud_flashlight.cpp
+++ b/mp/src/game/client/hl2/hud_flashlight.cpp
@@ -1,162 +1,162 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "hudelement.h"
-#include "hud_numericdisplay.h"
-#include <vgui_controls/Panel.h>
-#include "hud.h"
-#include "hud_suitpower.h"
-#include "hud_macros.h"
-#include "iclientmode.h"
-#include <vgui_controls/AnimationController.h>
-#include <vgui/ISurface.h>
-#include "c_basehlplayer.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//-----------------------------------------------------------------------------
-// Purpose: Shows the flashlight icon
-//-----------------------------------------------------------------------------
-class CHudFlashlight : public CHudElement, public vgui::Panel
-{
- DECLARE_CLASS_SIMPLE( CHudFlashlight, vgui::Panel );
-
-public:
- CHudFlashlight( const char *pElementName );
- virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
-
-protected:
- virtual void Paint();
-
-private:
- void SetFlashlightState( bool flashlightOn );
- void Reset( void );
-
- bool m_bFlashlightOn;
- CPanelAnimationVar( vgui::HFont, m_hFont, "Font", "WeaponIconsSmall" );
- CPanelAnimationVarAliasType( float, m_IconX, "icon_xpos", "4", "proportional_float" );
- CPanelAnimationVarAliasType( float, m_IconY, "icon_ypos", "4", "proportional_float" );
-
- CPanelAnimationVarAliasType( float, m_flBarInsetX, "BarInsetX", "2", "proportional_float" );
- CPanelAnimationVarAliasType( float, m_flBarInsetY, "BarInsetY", "18", "proportional_float" );
-
- CPanelAnimationVarAliasType( float, m_flBarWidth, "BarWidth", "28", "proportional_float" );
- CPanelAnimationVarAliasType( float, m_flBarHeight, "BarHeight", "2", "proportional_float" );
- CPanelAnimationVarAliasType( float, m_flBarChunkWidth, "BarChunkWidth", "2", "proportional_float" );
- CPanelAnimationVarAliasType( float, m_flBarChunkGap, "BarChunkGap", "2", "proportional_float" );
-};
-
-using namespace vgui;
-
-#ifdef HL2_EPISODIC
-DECLARE_HUDELEMENT( CHudFlashlight );
-#endif // HL2_EPISODIC
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CHudFlashlight::CHudFlashlight( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudFlashlight" )
-{
- vgui::Panel *pParent = g_pClientMode->GetViewport();
- SetParent( pParent );
-
- SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pScheme -
-//-----------------------------------------------------------------------------
-void CHudFlashlight::ApplySchemeSettings( vgui::IScheme *pScheme )
-{
- BaseClass::ApplySchemeSettings(pScheme);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Start with our background off
-//-----------------------------------------------------------------------------
-void CHudFlashlight::Reset( void )
-{
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "SuitFlashlightOn" );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: data accessor
-//-----------------------------------------------------------------------------
-void CHudFlashlight::SetFlashlightState( bool flashlightOn )
-{
- if ( m_bFlashlightOn == flashlightOn )
- return;
-
- m_bFlashlightOn = flashlightOn;
-}
-
-#define WCHAR_FLASHLIGHT_ON 169
-#define WCHAR_FLASHLIGHT_OFF 174
-
-//-----------------------------------------------------------------------------
-// Purpose: draws the flashlight icon
-//-----------------------------------------------------------------------------
-void CHudFlashlight::Paint()
-{
-#ifdef HL2_EPISODIC
- C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
- if ( !pPlayer )
- return;
-
- // Only paint if we're using the new flashlight code
- if ( pPlayer->m_HL2Local.m_flFlashBattery < 0.0f )
- {
- SetPaintBackgroundEnabled( false );
- return;
- }
-
- bool bIsOn = pPlayer->IsEffectActive( EF_DIMLIGHT );
- SetFlashlightState( bIsOn );
-
- // get bar chunks
- int chunkCount = m_flBarWidth / (m_flBarChunkWidth + m_flBarChunkGap);
- int enabledChunks = (int)((float)chunkCount * (pPlayer->m_HL2Local.m_flFlashBattery * 1.0f/100.0f) + 0.5f );
-
- Color clrFlashlight;
- clrFlashlight = ( enabledChunks < ( chunkCount / 4 ) ) ? gHUD.m_clrCaution : gHUD.m_clrNormal;
- clrFlashlight[3] = ( bIsOn ) ? 255: 32;
-
- // Pick the right character given our current state
- wchar_t pState = ( bIsOn ) ? WCHAR_FLASHLIGHT_ON : WCHAR_FLASHLIGHT_OFF;
-
- surface()->DrawSetTextFont( m_hFont );
- surface()->DrawSetTextColor( clrFlashlight );
- surface()->DrawSetTextPos( m_IconX, m_IconY );
- surface()->DrawUnicodeChar( pState );
-
- // Don't draw the progress bar is we're fully charged
- if ( bIsOn == false && chunkCount == enabledChunks )
- return;
-
- // draw the suit power bar
- surface()->DrawSetColor( clrFlashlight );
- int xpos = m_flBarInsetX, ypos = m_flBarInsetY;
- for (int i = 0; i < enabledChunks; i++)
- {
- surface()->DrawFilledRect( xpos, ypos, xpos + m_flBarChunkWidth, ypos + m_flBarHeight );
- xpos += (m_flBarChunkWidth + m_flBarChunkGap);
- }
-
- // Be even less transparent than we already are
- clrFlashlight[3] = clrFlashlight[3] / 8;
-
- // draw the exhausted portion of the bar.
- surface()->DrawSetColor( clrFlashlight );
- for (int i = enabledChunks; i < chunkCount; i++)
- {
- surface()->DrawFilledRect( xpos, ypos, xpos + m_flBarChunkWidth, ypos + m_flBarHeight );
- xpos += (m_flBarChunkWidth + m_flBarChunkGap);
- }
-#endif // HL2_EPISODIC
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "hudelement.h"
+#include "hud_numericdisplay.h"
+#include <vgui_controls/Panel.h>
+#include "hud.h"
+#include "hud_suitpower.h"
+#include "hud_macros.h"
+#include "iclientmode.h"
+#include <vgui_controls/AnimationController.h>
+#include <vgui/ISurface.h>
+#include "c_basehlplayer.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: Shows the flashlight icon
+//-----------------------------------------------------------------------------
+class CHudFlashlight : public CHudElement, public vgui::Panel
+{
+ DECLARE_CLASS_SIMPLE( CHudFlashlight, vgui::Panel );
+
+public:
+ CHudFlashlight( const char *pElementName );
+ virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
+
+protected:
+ virtual void Paint();
+
+private:
+ void SetFlashlightState( bool flashlightOn );
+ void Reset( void );
+
+ bool m_bFlashlightOn;
+ CPanelAnimationVar( vgui::HFont, m_hFont, "Font", "WeaponIconsSmall" );
+ CPanelAnimationVarAliasType( float, m_IconX, "icon_xpos", "4", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_IconY, "icon_ypos", "4", "proportional_float" );
+
+ CPanelAnimationVarAliasType( float, m_flBarInsetX, "BarInsetX", "2", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flBarInsetY, "BarInsetY", "18", "proportional_float" );
+
+ CPanelAnimationVarAliasType( float, m_flBarWidth, "BarWidth", "28", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flBarHeight, "BarHeight", "2", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flBarChunkWidth, "BarChunkWidth", "2", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flBarChunkGap, "BarChunkGap", "2", "proportional_float" );
+};
+
+using namespace vgui;
+
+#ifdef HL2_EPISODIC
+DECLARE_HUDELEMENT( CHudFlashlight );
+#endif // HL2_EPISODIC
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CHudFlashlight::CHudFlashlight( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudFlashlight" )
+{
+ vgui::Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+
+ SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pScheme -
+//-----------------------------------------------------------------------------
+void CHudFlashlight::ApplySchemeSettings( vgui::IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings(pScheme);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Start with our background off
+//-----------------------------------------------------------------------------
+void CHudFlashlight::Reset( void )
+{
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "SuitFlashlightOn" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: data accessor
+//-----------------------------------------------------------------------------
+void CHudFlashlight::SetFlashlightState( bool flashlightOn )
+{
+ if ( m_bFlashlightOn == flashlightOn )
+ return;
+
+ m_bFlashlightOn = flashlightOn;
+}
+
+#define WCHAR_FLASHLIGHT_ON 169
+#define WCHAR_FLASHLIGHT_OFF 174
+
+//-----------------------------------------------------------------------------
+// Purpose: draws the flashlight icon
+//-----------------------------------------------------------------------------
+void CHudFlashlight::Paint()
+{
+#ifdef HL2_EPISODIC
+ C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ // Only paint if we're using the new flashlight code
+ if ( pPlayer->m_HL2Local.m_flFlashBattery < 0.0f )
+ {
+ SetPaintBackgroundEnabled( false );
+ return;
+ }
+
+ bool bIsOn = pPlayer->IsEffectActive( EF_DIMLIGHT );
+ SetFlashlightState( bIsOn );
+
+ // get bar chunks
+ int chunkCount = m_flBarWidth / (m_flBarChunkWidth + m_flBarChunkGap);
+ int enabledChunks = (int)((float)chunkCount * (pPlayer->m_HL2Local.m_flFlashBattery * 1.0f/100.0f) + 0.5f );
+
+ Color clrFlashlight;
+ clrFlashlight = ( enabledChunks < ( chunkCount / 4 ) ) ? gHUD.m_clrCaution : gHUD.m_clrNormal;
+ clrFlashlight[3] = ( bIsOn ) ? 255: 32;
+
+ // Pick the right character given our current state
+ wchar_t pState = ( bIsOn ) ? WCHAR_FLASHLIGHT_ON : WCHAR_FLASHLIGHT_OFF;
+
+ surface()->DrawSetTextFont( m_hFont );
+ surface()->DrawSetTextColor( clrFlashlight );
+ surface()->DrawSetTextPos( m_IconX, m_IconY );
+ surface()->DrawUnicodeChar( pState );
+
+ // Don't draw the progress bar is we're fully charged
+ if ( bIsOn == false && chunkCount == enabledChunks )
+ return;
+
+ // draw the suit power bar
+ surface()->DrawSetColor( clrFlashlight );
+ int xpos = m_flBarInsetX, ypos = m_flBarInsetY;
+ for (int i = 0; i < enabledChunks; i++)
+ {
+ surface()->DrawFilledRect( xpos, ypos, xpos + m_flBarChunkWidth, ypos + m_flBarHeight );
+ xpos += (m_flBarChunkWidth + m_flBarChunkGap);
+ }
+
+ // Be even less transparent than we already are
+ clrFlashlight[3] = clrFlashlight[3] / 8;
+
+ // draw the exhausted portion of the bar.
+ surface()->DrawSetColor( clrFlashlight );
+ for (int i = enabledChunks; i < chunkCount; i++)
+ {
+ surface()->DrawFilledRect( xpos, ypos, xpos + m_flBarChunkWidth, ypos + m_flBarHeight );
+ xpos += (m_flBarChunkWidth + m_flBarChunkGap);
+ }
+#endif // HL2_EPISODIC
+}
diff --git a/mp/src/game/client/hl2/hud_hdrdemo.cpp b/mp/src/game/client/hl2/hud_hdrdemo.cpp
index 6001b11f..eaaaf1fe 100644
--- a/mp/src/game/client/hl2/hud_hdrdemo.cpp
+++ b/mp/src/game/client/hl2/hud_hdrdemo.cpp
@@ -1,174 +1,174 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-#include "cbase.h"
-#include "c_baseentity.h"
-#include "hud.h"
-#include "hudelement.h"
-#include "clientmode.h"
-#include <vgui_controls/Panel.h>
-#include <vgui/IScheme.h>
-#include <vgui/ISurface.h>
-#include <vgui/ILocalize.h>
-#include <vgui_controls/AnimationController.h>
-#include "materialsystem/imaterialsystemhardwareconfig.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-class CHudHDRDemo : public CHudElement, public vgui::Panel
-{
- DECLARE_CLASS_SIMPLE( CHudHDRDemo, vgui::Panel );
-public:
- CHudHDRDemo( const char *name );
-
- // vgui overrides
- virtual void ApplySchemeSettings(vgui::IScheme *pScheme );
- virtual void Paint( void );
- virtual bool ShouldDraw( void );
-
- void SetHDRDemoActive( bool bActive );
-
-private:
- bool m_bHDRDemoActive;
-
- // Painting
- //CPanelAnimationVar( float, m_flAlphaOverride, "Alpha", "0" );
- CPanelAnimationVar( Color, m_BorderColor, "BorderColor", "0 0 0 255" );
- CPanelAnimationVar( Color, m_TextColor, "TextColor", "255 255 255 255" );
- CPanelAnimationVarAliasType( int, m_iBorderLeft, "BorderLeft", "8", "proportional_int" );
- CPanelAnimationVarAliasType( int, m_iBorderRight, "BorderRight", "8", "proportional_int" );
- CPanelAnimationVarAliasType( int, m_iBorderTop, "BorderTop", "8", "proportional_int" );
- CPanelAnimationVarAliasType( int, m_iBorderBottom, "BorderBottom", "8", "proportional_int" );
- CPanelAnimationVarAliasType( int, m_iBorderCenter, "BorderCenter", "8", "proportional_int" );
-
- CPanelAnimationVarAliasType( int, m_iLeftY, "LeftTitleY", "8", "proportional_int" );
- CPanelAnimationVarAliasType( int, m_iRightY, "RightTitleY", "8", "proportional_int" );
-};
-
-DECLARE_HUDELEMENT( CHudHDRDemo );
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-CHudHDRDemo::CHudHDRDemo( const char *name ) : vgui::Panel( NULL, "HudHDRDemo" ), CHudElement( name )
-{
- vgui::Panel *pParent = g_pClientMode->GetViewport();
- SetParent( pParent );
-
- SetPaintBorderEnabled( false );
- SetPaintBackgroundEnabled( false );
-
- m_bHDRDemoActive = false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudHDRDemo::ApplySchemeSettings( vgui::IScheme *pScheme )
-{
- BaseClass::ApplySchemeSettings(pScheme);
- SetSize( ScreenWidth(), ScreenHeight() );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudHDRDemo::Paint()
-{
- int x, y, wide, tall;
- GetBounds( x, y, wide, tall );
-
- // Draw the borders
- vgui::surface()->DrawSetColor( m_BorderColor );
- vgui::surface()->DrawFilledRect( 0, 0, m_iBorderLeft, tall ); // Left
- vgui::surface()->DrawFilledRect( wide-m_iBorderRight, 0, wide, tall ); // Right
- vgui::surface()->DrawFilledRect( m_iBorderLeft, 0, wide-m_iBorderRight, m_iBorderTop ); // Top
- vgui::surface()->DrawFilledRect( m_iBorderLeft, tall-m_iBorderBottom, wide-m_iBorderRight, tall ); // Bottom
- vgui::surface()->DrawFilledRect( ((wide-m_iBorderCenter)/2), m_iBorderTop, ((wide+m_iBorderCenter)/2), tall-m_iBorderBottom ); // Center
-
- // Get our scheme and font information
- vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
- vgui::HFont hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "HDRDemoText" );
- vgui::surface()->DrawSetTextFont( hFont );
- vgui::surface()->DrawSetTextColor( m_TextColor );
-
- // Left Title
- wchar_t *tempString = g_pVGuiLocalize->Find("#Valve_HDRDEMO_LeftTitle");
- if (tempString)
- {
- int iLength = 0;
- for ( wchar_t *wch = tempString; *wch != 0; wch++ )
- {
- iLength += vgui::surface()->GetCharacterWidth( hFont, *wch );
- }
- vgui::surface()->DrawSetTextPos( floor(wide * 0.25) - (iLength / 2), m_iLeftY );
- vgui::surface()->DrawPrintText(tempString, wcslen(tempString));
- }
-
- // Right Title
- tempString = g_pVGuiLocalize->Find("#Valve_HDRDEMO_RightTitle");
- if (tempString)
- {
- int iLength = 0;
- for ( wchar_t *wch = tempString; *wch != 0; wch++ )
- {
- iLength += vgui::surface()->GetCharacterWidth( hFont, *wch );
- }
- vgui::surface()->DrawSetTextPos( ceil(wide * 0.75) - (iLength / 2), m_iRightY );
- vgui::surface()->DrawPrintText(tempString, wcslen(tempString));
- }
-
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool CHudHDRDemo::ShouldDraw()
-{
- return (
- // no split screen hud if not hdr
- (g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE) &&
- m_bHDRDemoActive
- ); //&& m_flAlphaOverride > 0 );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : bActive -
-//-----------------------------------------------------------------------------
-void CHudHDRDemo::SetHDRDemoActive( bool bActive )
-{
- if ( bActive && !m_bHDRDemoActive )
- {
- ConVarRef pHideHud( "hidehud" );
- pHideHud.SetValue( 15 );
- }
- else if ( !bActive && m_bHDRDemoActive )
- {
- ConVarRef pHideHud( "hidehud" );
- pHideHud.SetValue( 0 );
- }
-
- m_bHDRDemoActive = bActive;
-}
-
-//=======================================================================================================
-// CONVAR to toggle this hud element
-void mat_show_ab_hdr_hudelement_changed( IConVar *pConVar, const char *pOldString, float flOldValue )
-{
- CHudHDRDemo *pHudDemo = (CHudHDRDemo*)GET_HUDELEMENT( CHudHDRDemo );
- if ( pHudDemo )
- {
- ConVarRef var( pConVar );
- pHudDemo->SetHDRDemoActive( var.GetBool() );
- }
-}
-ConVar mat_show_ab_hdr_hudelement( "mat_show_ab_hdr_hudelement", "0", FCVAR_CHEAT, "HDR Demo HUD Element toggle.", mat_show_ab_hdr_hudelement_changed );
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#include "cbase.h"
+#include "c_baseentity.h"
+#include "hud.h"
+#include "hudelement.h"
+#include "clientmode.h"
+#include <vgui_controls/Panel.h>
+#include <vgui/IScheme.h>
+#include <vgui/ISurface.h>
+#include <vgui/ILocalize.h>
+#include <vgui_controls/AnimationController.h>
+#include "materialsystem/imaterialsystemhardwareconfig.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class CHudHDRDemo : public CHudElement, public vgui::Panel
+{
+ DECLARE_CLASS_SIMPLE( CHudHDRDemo, vgui::Panel );
+public:
+ CHudHDRDemo( const char *name );
+
+ // vgui overrides
+ virtual void ApplySchemeSettings(vgui::IScheme *pScheme );
+ virtual void Paint( void );
+ virtual bool ShouldDraw( void );
+
+ void SetHDRDemoActive( bool bActive );
+
+private:
+ bool m_bHDRDemoActive;
+
+ // Painting
+ //CPanelAnimationVar( float, m_flAlphaOverride, "Alpha", "0" );
+ CPanelAnimationVar( Color, m_BorderColor, "BorderColor", "0 0 0 255" );
+ CPanelAnimationVar( Color, m_TextColor, "TextColor", "255 255 255 255" );
+ CPanelAnimationVarAliasType( int, m_iBorderLeft, "BorderLeft", "8", "proportional_int" );
+ CPanelAnimationVarAliasType( int, m_iBorderRight, "BorderRight", "8", "proportional_int" );
+ CPanelAnimationVarAliasType( int, m_iBorderTop, "BorderTop", "8", "proportional_int" );
+ CPanelAnimationVarAliasType( int, m_iBorderBottom, "BorderBottom", "8", "proportional_int" );
+ CPanelAnimationVarAliasType( int, m_iBorderCenter, "BorderCenter", "8", "proportional_int" );
+
+ CPanelAnimationVarAliasType( int, m_iLeftY, "LeftTitleY", "8", "proportional_int" );
+ CPanelAnimationVarAliasType( int, m_iRightY, "RightTitleY", "8", "proportional_int" );
+};
+
+DECLARE_HUDELEMENT( CHudHDRDemo );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CHudHDRDemo::CHudHDRDemo( const char *name ) : vgui::Panel( NULL, "HudHDRDemo" ), CHudElement( name )
+{
+ vgui::Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+
+ SetPaintBorderEnabled( false );
+ SetPaintBackgroundEnabled( false );
+
+ m_bHDRDemoActive = false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudHDRDemo::ApplySchemeSettings( vgui::IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings(pScheme);
+ SetSize( ScreenWidth(), ScreenHeight() );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudHDRDemo::Paint()
+{
+ int x, y, wide, tall;
+ GetBounds( x, y, wide, tall );
+
+ // Draw the borders
+ vgui::surface()->DrawSetColor( m_BorderColor );
+ vgui::surface()->DrawFilledRect( 0, 0, m_iBorderLeft, tall ); // Left
+ vgui::surface()->DrawFilledRect( wide-m_iBorderRight, 0, wide, tall ); // Right
+ vgui::surface()->DrawFilledRect( m_iBorderLeft, 0, wide-m_iBorderRight, m_iBorderTop ); // Top
+ vgui::surface()->DrawFilledRect( m_iBorderLeft, tall-m_iBorderBottom, wide-m_iBorderRight, tall ); // Bottom
+ vgui::surface()->DrawFilledRect( ((wide-m_iBorderCenter)/2), m_iBorderTop, ((wide+m_iBorderCenter)/2), tall-m_iBorderBottom ); // Center
+
+ // Get our scheme and font information
+ vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
+ vgui::HFont hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "HDRDemoText" );
+ vgui::surface()->DrawSetTextFont( hFont );
+ vgui::surface()->DrawSetTextColor( m_TextColor );
+
+ // Left Title
+ wchar_t *tempString = g_pVGuiLocalize->Find("#Valve_HDRDEMO_LeftTitle");
+ if (tempString)
+ {
+ int iLength = 0;
+ for ( wchar_t *wch = tempString; *wch != 0; wch++ )
+ {
+ iLength += vgui::surface()->GetCharacterWidth( hFont, *wch );
+ }
+ vgui::surface()->DrawSetTextPos( floor(wide * 0.25) - (iLength / 2), m_iLeftY );
+ vgui::surface()->DrawPrintText(tempString, wcslen(tempString));
+ }
+
+ // Right Title
+ tempString = g_pVGuiLocalize->Find("#Valve_HDRDEMO_RightTitle");
+ if (tempString)
+ {
+ int iLength = 0;
+ for ( wchar_t *wch = tempString; *wch != 0; wch++ )
+ {
+ iLength += vgui::surface()->GetCharacterWidth( hFont, *wch );
+ }
+ vgui::surface()->DrawSetTextPos( ceil(wide * 0.75) - (iLength / 2), m_iRightY );
+ vgui::surface()->DrawPrintText(tempString, wcslen(tempString));
+ }
+
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CHudHDRDemo::ShouldDraw()
+{
+ return (
+ // no split screen hud if not hdr
+ (g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE) &&
+ m_bHDRDemoActive
+ ); //&& m_flAlphaOverride > 0 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : bActive -
+//-----------------------------------------------------------------------------
+void CHudHDRDemo::SetHDRDemoActive( bool bActive )
+{
+ if ( bActive && !m_bHDRDemoActive )
+ {
+ ConVarRef pHideHud( "hidehud" );
+ pHideHud.SetValue( 15 );
+ }
+ else if ( !bActive && m_bHDRDemoActive )
+ {
+ ConVarRef pHideHud( "hidehud" );
+ pHideHud.SetValue( 0 );
+ }
+
+ m_bHDRDemoActive = bActive;
+}
+
+//=======================================================================================================
+// CONVAR to toggle this hud element
+void mat_show_ab_hdr_hudelement_changed( IConVar *pConVar, const char *pOldString, float flOldValue )
+{
+ CHudHDRDemo *pHudDemo = (CHudHDRDemo*)GET_HUDELEMENT( CHudHDRDemo );
+ if ( pHudDemo )
+ {
+ ConVarRef var( pConVar );
+ pHudDemo->SetHDRDemoActive( var.GetBool() );
+ }
+}
+ConVar mat_show_ab_hdr_hudelement( "mat_show_ab_hdr_hudelement", "0", FCVAR_CHEAT, "HDR Demo HUD Element toggle.", mat_show_ab_hdr_hudelement_changed );
diff --git a/mp/src/game/client/hl2/hud_health.cpp b/mp/src/game/client/hl2/hud_health.cpp
index 00911a3d..c25da7b9 100644
--- a/mp/src/game/client/hl2/hud_health.cpp
+++ b/mp/src/game/client/hl2/hud_health.cpp
@@ -1,170 +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");
- }
- }
+//========= 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/mp/src/game/client/hl2/hud_locator.cpp b/mp/src/game/client/hl2/hud_locator.cpp
index 5709fce5..2b8dd880 100644
--- a/mp/src/game/client/hl2/hud_locator.cpp
+++ b/mp/src/game/client/hl2/hud_locator.cpp
@@ -1,319 +1,319 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Hud locator element, helps direct the player to objects in the world
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "hudelement.h"
-#include "hud_numericdisplay.h"
-#include <vgui_controls/Panel.h>
-#include "hud.h"
-#include "hud_suitpower.h"
-#include "hud_macros.h"
-#include "iclientmode.h"
-#include <vgui_controls/AnimationController.h>
-#include <vgui/ISurface.h>
-#include "c_basehlplayer.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-#define LOCATOR_MATERIAL_JALOPY "vgui/icons/icon_jalopy"
-#define LOCATOR_MATERIAL_BIG_TICK "vgui/icons/tick_long"
-#define LOCATOR_MATERIAL_SMALL_TICK "vgui/icons/tick_short"
-
-ConVar hud_locator_alpha( "hud_locator_alpha", "230" );
-ConVar hud_locator_fov("hud_locator_fov", "350" );
-
-//-----------------------------------------------------------------------------
-// Purpose: Shows positions of objects relative to the player.
-//-----------------------------------------------------------------------------
-class CHudLocator : public CHudElement, public vgui::Panel
-{
- DECLARE_CLASS_SIMPLE( CHudLocator, vgui::Panel );
-
-public:
- CHudLocator( const char *pElementName );
- virtual ~CHudLocator( void );
-
- virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
- void VidInit( void );
- bool ShouldDraw();
-
-protected:
- void FillRect( int x, int y, int w, int h );
- float LocatorXPositionForYawDiff( float yawDiff );
- void DrawGraduations( float flYawPlayerFacing );
- virtual void Paint();
-
-private:
- void Reset( void );
-
- int m_textureID_IconJalopy;
- int m_textureID_IconBigTick;
- int m_textureID_IconSmallTick;
-
- Vector m_vecLocation;
-};
-
-using namespace vgui;
-
-#ifdef HL2_EPISODIC
-DECLARE_HUDELEMENT( CHudLocator );
-#endif
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CHudLocator::CHudLocator( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudLocator" )
-{
- vgui::Panel *pParent = g_pClientMode->GetViewport();
- SetParent( pParent );
-
- SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
-
- m_textureID_IconJalopy = -1;
- m_textureID_IconSmallTick = -1;
- m_textureID_IconBigTick = -1;
-}
-
-CHudLocator::~CHudLocator( void )
-{
- if ( vgui::surface() )
- {
- if ( m_textureID_IconJalopy != -1 )
- {
- vgui::surface()->DestroyTextureID( m_textureID_IconJalopy );
- m_textureID_IconJalopy = -1;
- }
-
- if ( m_textureID_IconSmallTick != -1 )
- {
- vgui::surface()->DestroyTextureID( m_textureID_IconSmallTick );
- m_textureID_IconSmallTick = -1;
- }
-
- if ( m_textureID_IconBigTick != -1 )
- {
- vgui::surface()->DestroyTextureID( m_textureID_IconBigTick );
- m_textureID_IconBigTick = -1;
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pScheme -
-//-----------------------------------------------------------------------------
-void CHudLocator::ApplySchemeSettings( vgui::IScheme *pScheme )
-{
- BaseClass::ApplySchemeSettings(pScheme);
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void CHudLocator::VidInit( void )
-{
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-bool CHudLocator::ShouldDraw( void )
-{
- C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
- if ( !pPlayer )
- return false;
-
- if( pPlayer->GetVehicle() )
- return false;
-
- if( pPlayer->m_HL2Local.m_vecLocatorOrigin == vec3_invalid )
- return false;
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Start with our background off
-//-----------------------------------------------------------------------------
-void CHudLocator::Reset( void )
-{
- m_vecLocation = Vector( 0, 0, 0 );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Make it a bit more convenient to do a filled rect.
-//-----------------------------------------------------------------------------
-void CHudLocator::FillRect( int x, int y, int w, int h )
-{
- int panel_x, panel_y, panel_w, panel_h;
- GetBounds( panel_x, panel_y, panel_w, panel_h );
- vgui::surface()->DrawFilledRect( x, y, x+w, y+h );
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-float CHudLocator::LocatorXPositionForYawDiff( float yawDiff )
-{
- float fov = hud_locator_fov.GetFloat() / 2;
- float remappedAngle = RemapVal( yawDiff, -fov, fov, -90, 90 );
- float cosine = sin(DEG2RAD(remappedAngle));
- int element_wide = GetWide();
-
- float position = (element_wide>>1) + ((element_wide>>1) * cosine);
-
- return position;
-}
-
-//-----------------------------------------------------------------------------
-// Draw the tickmarks on the locator
-//-----------------------------------------------------------------------------
-#define NUM_GRADUATIONS 16.0f
-void CHudLocator::DrawGraduations( float flYawPlayerFacing )
-{
- int icon_wide, icon_tall;
- int xPos, yPos;
- float fov = hud_locator_fov.GetFloat() / 2;
-
- if( m_textureID_IconBigTick == -1 )
- {
- m_textureID_IconBigTick = vgui::surface()->CreateNewTextureID();
- vgui::surface()->DrawSetTextureFile( m_textureID_IconBigTick, LOCATOR_MATERIAL_BIG_TICK, true, false );
- }
-
- if( m_textureID_IconSmallTick == -1 )
- {
- m_textureID_IconSmallTick = vgui::surface()->CreateNewTextureID();
- vgui::surface()->DrawSetTextureFile( m_textureID_IconSmallTick, LOCATOR_MATERIAL_SMALL_TICK, true, false );
- }
-
- int element_tall = GetTall(); // Height of the VGUI element
-
- surface()->DrawSetColor( 255, 255, 255, 255 );
-
- // Tick Icons
-
- float angleStep = 360.0f / NUM_GRADUATIONS;
- bool tallLine = true;
-
- for( float angle = -180 ; angle <= 180 ; angle += angleStep )
- {
- yPos = (element_tall>>1);
-
- if( tallLine )
- {
- vgui::surface()->DrawSetTexture( m_textureID_IconBigTick );
- vgui::surface()->DrawGetTextureSize( m_textureID_IconBigTick, icon_wide, icon_tall );
- tallLine = false;
- }
- else
- {
- vgui::surface()->DrawSetTexture( m_textureID_IconSmallTick );
- vgui::surface()->DrawGetTextureSize( m_textureID_IconSmallTick, icon_wide, icon_tall );
- tallLine = true;
- }
-
- float flDiff = UTIL_AngleDiff( flYawPlayerFacing, angle );
-
- if( fabs(flDiff) > fov )
- continue;
-
- float xPosition = LocatorXPositionForYawDiff( flDiff );
-
- xPos = (int)xPosition;
- xPos -= (icon_wide>>1);
-
- vgui::surface()->DrawTexturedRect(xPos, yPos, xPos+icon_wide, yPos+icon_tall);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: draws the locator icons on the VGUI element.
-//-----------------------------------------------------------------------------
-void CHudLocator::Paint()
-{
-#ifdef HL2_EPISODIC
-
- if( m_textureID_IconJalopy == -1 )
- {
- m_textureID_IconJalopy = vgui::surface()->CreateNewTextureID();
- vgui::surface()->DrawSetTextureFile( m_textureID_IconJalopy, LOCATOR_MATERIAL_JALOPY, true, false );
- }
-
- int alpha = hud_locator_alpha.GetInt();
-
- SetAlpha( alpha );
-
- C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
- if ( !pPlayer )
- return;
-
- if( pPlayer->m_HL2Local.m_vecLocatorOrigin == vec3_origin )
- return;
-
- int element_tall = GetTall(); // Height of the VGUI element
-
- float fov = (hud_locator_fov.GetFloat()) / 2.0f;
-
- // Compute the relative position of objects we're tracking
- // We'll need the player's yaw for comparison.
- float flYawPlayerForward = pPlayer->EyeAngles().y;
-
- // Copy this value out of the member variable in case we decide to expand this
- // feature later and want to iterate some kind of list.
- Vector vecLocation = pPlayer->m_HL2Local.m_vecLocatorOrigin;
-
- Vector vecToLocation = vecLocation - pPlayer->GetAbsOrigin();
- QAngle locationAngles;
-
- VectorAngles( vecToLocation, locationAngles );
- float yawDiff = UTIL_AngleDiff( flYawPlayerForward, locationAngles.y );
- bool bObjectInFOV = (yawDiff > -fov && yawDiff < fov);
-
- // Draw the icons!
- int icon_wide, icon_tall;
- int xPos, yPos;
- surface()->DrawSetColor( 255, 255, 255, 255 );
-
- DrawGraduations( flYawPlayerForward );
-
- if( bObjectInFOV )
- {
- // The object's location maps to a valid position along the tape, so draw an icon.
- float tapePosition = LocatorXPositionForYawDiff(yawDiff);
-
- // derive a scale for the locator icon
- yawDiff = fabs(yawDiff);
- float scale = 1.0f;
- scale = RemapValClamped( yawDiff, (fov/4), fov, 1.0f, 0.25f );
-
- vgui::surface()->DrawSetTexture( m_textureID_IconJalopy );
- vgui::surface()->DrawGetTextureSize( m_textureID_IconJalopy, icon_wide, icon_tall );
-
- float flIconWide = ((float)element_tall * 1.25f);
- float flIconTall = ((float)element_tall * 1.25f);
-
- // Scale the icon as desired...
-
- // Put back into ints
- icon_wide = (int)flIconWide;
- icon_tall = (int)flIconTall;
-
- icon_wide *= scale;
-
- //Msg("yawDiff:%f xPos:%d scale:%f\n", yawDiff, xPos, scale );
-
- // Center the icon around its position.
- xPos = (int)tapePosition;
- xPos -= (icon_wide >> 1);
- yPos = (element_tall>>1) - (icon_tall >> 1);
-
- //Msg("Drawing at %f %f\n", x, y );
- vgui::surface()->DrawTexturedRect(xPos, yPos, xPos+icon_wide, yPos+icon_tall);
- }
-
-#endif // HL2_EPISODIC
-}
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Hud locator element, helps direct the player to objects in the world
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "hudelement.h"
+#include "hud_numericdisplay.h"
+#include <vgui_controls/Panel.h>
+#include "hud.h"
+#include "hud_suitpower.h"
+#include "hud_macros.h"
+#include "iclientmode.h"
+#include <vgui_controls/AnimationController.h>
+#include <vgui/ISurface.h>
+#include "c_basehlplayer.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#define LOCATOR_MATERIAL_JALOPY "vgui/icons/icon_jalopy"
+#define LOCATOR_MATERIAL_BIG_TICK "vgui/icons/tick_long"
+#define LOCATOR_MATERIAL_SMALL_TICK "vgui/icons/tick_short"
+
+ConVar hud_locator_alpha( "hud_locator_alpha", "230" );
+ConVar hud_locator_fov("hud_locator_fov", "350" );
+
+//-----------------------------------------------------------------------------
+// Purpose: Shows positions of objects relative to the player.
+//-----------------------------------------------------------------------------
+class CHudLocator : public CHudElement, public vgui::Panel
+{
+ DECLARE_CLASS_SIMPLE( CHudLocator, vgui::Panel );
+
+public:
+ CHudLocator( const char *pElementName );
+ virtual ~CHudLocator( void );
+
+ virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
+ void VidInit( void );
+ bool ShouldDraw();
+
+protected:
+ void FillRect( int x, int y, int w, int h );
+ float LocatorXPositionForYawDiff( float yawDiff );
+ void DrawGraduations( float flYawPlayerFacing );
+ virtual void Paint();
+
+private:
+ void Reset( void );
+
+ int m_textureID_IconJalopy;
+ int m_textureID_IconBigTick;
+ int m_textureID_IconSmallTick;
+
+ Vector m_vecLocation;
+};
+
+using namespace vgui;
+
+#ifdef HL2_EPISODIC
+DECLARE_HUDELEMENT( CHudLocator );
+#endif
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CHudLocator::CHudLocator( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudLocator" )
+{
+ vgui::Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+
+ SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
+
+ m_textureID_IconJalopy = -1;
+ m_textureID_IconSmallTick = -1;
+ m_textureID_IconBigTick = -1;
+}
+
+CHudLocator::~CHudLocator( void )
+{
+ if ( vgui::surface() )
+ {
+ if ( m_textureID_IconJalopy != -1 )
+ {
+ vgui::surface()->DestroyTextureID( m_textureID_IconJalopy );
+ m_textureID_IconJalopy = -1;
+ }
+
+ if ( m_textureID_IconSmallTick != -1 )
+ {
+ vgui::surface()->DestroyTextureID( m_textureID_IconSmallTick );
+ m_textureID_IconSmallTick = -1;
+ }
+
+ if ( m_textureID_IconBigTick != -1 )
+ {
+ vgui::surface()->DestroyTextureID( m_textureID_IconBigTick );
+ m_textureID_IconBigTick = -1;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pScheme -
+//-----------------------------------------------------------------------------
+void CHudLocator::ApplySchemeSettings( vgui::IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings(pScheme);
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CHudLocator::VidInit( void )
+{
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+bool CHudLocator::ShouldDraw( void )
+{
+ C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return false;
+
+ if( pPlayer->GetVehicle() )
+ return false;
+
+ if( pPlayer->m_HL2Local.m_vecLocatorOrigin == vec3_invalid )
+ return false;
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Start with our background off
+//-----------------------------------------------------------------------------
+void CHudLocator::Reset( void )
+{
+ m_vecLocation = Vector( 0, 0, 0 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Make it a bit more convenient to do a filled rect.
+//-----------------------------------------------------------------------------
+void CHudLocator::FillRect( int x, int y, int w, int h )
+{
+ int panel_x, panel_y, panel_w, panel_h;
+ GetBounds( panel_x, panel_y, panel_w, panel_h );
+ vgui::surface()->DrawFilledRect( x, y, x+w, y+h );
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+float CHudLocator::LocatorXPositionForYawDiff( float yawDiff )
+{
+ float fov = hud_locator_fov.GetFloat() / 2;
+ float remappedAngle = RemapVal( yawDiff, -fov, fov, -90, 90 );
+ float cosine = sin(DEG2RAD(remappedAngle));
+ int element_wide = GetWide();
+
+ float position = (element_wide>>1) + ((element_wide>>1) * cosine);
+
+ return position;
+}
+
+//-----------------------------------------------------------------------------
+// Draw the tickmarks on the locator
+//-----------------------------------------------------------------------------
+#define NUM_GRADUATIONS 16.0f
+void CHudLocator::DrawGraduations( float flYawPlayerFacing )
+{
+ int icon_wide, icon_tall;
+ int xPos, yPos;
+ float fov = hud_locator_fov.GetFloat() / 2;
+
+ if( m_textureID_IconBigTick == -1 )
+ {
+ m_textureID_IconBigTick = vgui::surface()->CreateNewTextureID();
+ vgui::surface()->DrawSetTextureFile( m_textureID_IconBigTick, LOCATOR_MATERIAL_BIG_TICK, true, false );
+ }
+
+ if( m_textureID_IconSmallTick == -1 )
+ {
+ m_textureID_IconSmallTick = vgui::surface()->CreateNewTextureID();
+ vgui::surface()->DrawSetTextureFile( m_textureID_IconSmallTick, LOCATOR_MATERIAL_SMALL_TICK, true, false );
+ }
+
+ int element_tall = GetTall(); // Height of the VGUI element
+
+ surface()->DrawSetColor( 255, 255, 255, 255 );
+
+ // Tick Icons
+
+ float angleStep = 360.0f / NUM_GRADUATIONS;
+ bool tallLine = true;
+
+ for( float angle = -180 ; angle <= 180 ; angle += angleStep )
+ {
+ yPos = (element_tall>>1);
+
+ if( tallLine )
+ {
+ vgui::surface()->DrawSetTexture( m_textureID_IconBigTick );
+ vgui::surface()->DrawGetTextureSize( m_textureID_IconBigTick, icon_wide, icon_tall );
+ tallLine = false;
+ }
+ else
+ {
+ vgui::surface()->DrawSetTexture( m_textureID_IconSmallTick );
+ vgui::surface()->DrawGetTextureSize( m_textureID_IconSmallTick, icon_wide, icon_tall );
+ tallLine = true;
+ }
+
+ float flDiff = UTIL_AngleDiff( flYawPlayerFacing, angle );
+
+ if( fabs(flDiff) > fov )
+ continue;
+
+ float xPosition = LocatorXPositionForYawDiff( flDiff );
+
+ xPos = (int)xPosition;
+ xPos -= (icon_wide>>1);
+
+ vgui::surface()->DrawTexturedRect(xPos, yPos, xPos+icon_wide, yPos+icon_tall);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: draws the locator icons on the VGUI element.
+//-----------------------------------------------------------------------------
+void CHudLocator::Paint()
+{
+#ifdef HL2_EPISODIC
+
+ if( m_textureID_IconJalopy == -1 )
+ {
+ m_textureID_IconJalopy = vgui::surface()->CreateNewTextureID();
+ vgui::surface()->DrawSetTextureFile( m_textureID_IconJalopy, LOCATOR_MATERIAL_JALOPY, true, false );
+ }
+
+ int alpha = hud_locator_alpha.GetInt();
+
+ SetAlpha( alpha );
+
+ C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ if( pPlayer->m_HL2Local.m_vecLocatorOrigin == vec3_origin )
+ return;
+
+ int element_tall = GetTall(); // Height of the VGUI element
+
+ float fov = (hud_locator_fov.GetFloat()) / 2.0f;
+
+ // Compute the relative position of objects we're tracking
+ // We'll need the player's yaw for comparison.
+ float flYawPlayerForward = pPlayer->EyeAngles().y;
+
+ // Copy this value out of the member variable in case we decide to expand this
+ // feature later and want to iterate some kind of list.
+ Vector vecLocation = pPlayer->m_HL2Local.m_vecLocatorOrigin;
+
+ Vector vecToLocation = vecLocation - pPlayer->GetAbsOrigin();
+ QAngle locationAngles;
+
+ VectorAngles( vecToLocation, locationAngles );
+ float yawDiff = UTIL_AngleDiff( flYawPlayerForward, locationAngles.y );
+ bool bObjectInFOV = (yawDiff > -fov && yawDiff < fov);
+
+ // Draw the icons!
+ int icon_wide, icon_tall;
+ int xPos, yPos;
+ surface()->DrawSetColor( 255, 255, 255, 255 );
+
+ DrawGraduations( flYawPlayerForward );
+
+ if( bObjectInFOV )
+ {
+ // The object's location maps to a valid position along the tape, so draw an icon.
+ float tapePosition = LocatorXPositionForYawDiff(yawDiff);
+
+ // derive a scale for the locator icon
+ yawDiff = fabs(yawDiff);
+ float scale = 1.0f;
+ scale = RemapValClamped( yawDiff, (fov/4), fov, 1.0f, 0.25f );
+
+ vgui::surface()->DrawSetTexture( m_textureID_IconJalopy );
+ vgui::surface()->DrawGetTextureSize( m_textureID_IconJalopy, icon_wide, icon_tall );
+
+ float flIconWide = ((float)element_tall * 1.25f);
+ float flIconTall = ((float)element_tall * 1.25f);
+
+ // Scale the icon as desired...
+
+ // Put back into ints
+ icon_wide = (int)flIconWide;
+ icon_tall = (int)flIconTall;
+
+ icon_wide *= scale;
+
+ //Msg("yawDiff:%f xPos:%d scale:%f\n", yawDiff, xPos, scale );
+
+ // Center the icon around its position.
+ xPos = (int)tapePosition;
+ xPos -= (icon_wide >> 1);
+ yPos = (element_tall>>1) - (icon_tall >> 1);
+
+ //Msg("Drawing at %f %f\n", x, y );
+ vgui::surface()->DrawTexturedRect(xPos, yPos, xPos+icon_wide, yPos+icon_tall);
+ }
+
+#endif // HL2_EPISODIC
+}
+
+
diff --git a/mp/src/game/client/hl2/hud_poisondamageindicator.cpp b/mp/src/game/client/hl2/hud_poisondamageindicator.cpp
index 310138e7..f0ed7ea6 100644
--- a/mp/src/game/client/hl2/hud_poisondamageindicator.cpp
+++ b/mp/src/game/client/hl2/hud_poisondamageindicator.cpp
@@ -1,155 +1,155 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "hud.h"
-#include "text_message.h"
-#include "hud_macros.h"
-#include "iclientmode.h"
-#include "view.h"
-#include "KeyValues.h"
-#include "vgui_controls/AnimationController.h"
-#include "vgui/ILocalize.h"
-#include "vgui/ISurface.h"
-#include "VGuiMatSurface/IMatSystemSurface.h"
-#include "materialsystem/imaterial.h"
-#include "materialsystem/imesh.h"
-#include "materialsystem/imaterialvar.h"
-#include "IEffects.h"
-#include "hudelement.h"
-
-using namespace vgui;
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//-----------------------------------------------------------------------------
-// Purpose: HDU Damage indication
-//-----------------------------------------------------------------------------
-class CHudPoisonDamageIndicator : public CHudElement, public vgui::Panel
-{
- DECLARE_CLASS_SIMPLE( CHudPoisonDamageIndicator, vgui::Panel );
-
-public:
- CHudPoisonDamageIndicator( const char *pElementName );
- void Reset( void );
- virtual bool ShouldDraw( void );
-
-private:
- virtual void OnThink();
- virtual void Paint();
- virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
-
-private:
- CPanelAnimationVar( vgui::HFont, m_hTextFont, "TextFont", "Default" );
- CPanelAnimationVar( Color, m_TextColor, "TextColor", "FgColor" );
- CPanelAnimationVarAliasType( float, text_xpos, "text_xpos", "8", "proportional_float" );
- CPanelAnimationVarAliasType( float, text_ypos, "text_ypos", "8", "proportional_float" );
- CPanelAnimationVarAliasType( float, text_ygap, "text_ygap", "14", "proportional_float" );
-
- bool m_bDamageIndicatorVisible;
-};
-
-DECLARE_HUDELEMENT( CHudPoisonDamageIndicator );
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CHudPoisonDamageIndicator::CHudPoisonDamageIndicator( const char *pElementName ) : CHudElement( pElementName ), BaseClass(NULL, "HudPoisonDamageIndicator")
-{
- vgui::Panel *pParent = g_pClientMode->GetViewport();
- SetParent( pParent );
-
- SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudPoisonDamageIndicator::Reset( void )
-{
- SetAlpha( 0 );
- m_bDamageIndicatorVisible = false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Save CPU cycles by letting the HUD system early cull
-// costly traversal. Called per frame, return true if thinking and
-// painting need to occur.
-//-----------------------------------------------------------------------------
-bool CHudPoisonDamageIndicator::ShouldDraw( void )
-{
- C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
- if ( !pPlayer )
- return false;
-
- bool bNeedsDraw = ( ( pPlayer->IsPoisoned() != m_bDamageIndicatorVisible ) || ( GetAlpha() > 0 ) );
-
- return ( bNeedsDraw && CHudElement::ShouldDraw() );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: updates poison damage
-//-----------------------------------------------------------------------------
-void CHudPoisonDamageIndicator::OnThink()
-{
- C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
- if ( !pPlayer )
- return;
-
- // update poison damage indicator
- bool bShouldIndicatorBeVisible = pPlayer->IsPoisoned();
- if (bShouldIndicatorBeVisible == m_bDamageIndicatorVisible)
- return;
-
- // state change
- m_bDamageIndicatorVisible = bShouldIndicatorBeVisible;
-
- if (m_bDamageIndicatorVisible)
- {
- SetVisible(true);
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "PoisonDamageTaken" );
- }
- else
- {
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "PoisonDamageCured" );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Paints the damage display
-//-----------------------------------------------------------------------------
-void CHudPoisonDamageIndicator::Paint()
-{
- // draw the text
- surface()->DrawSetTextFont( m_hTextFont );
- surface()->DrawSetTextColor( m_TextColor );
- surface()->DrawSetTextPos(text_xpos, text_ypos);
- int ypos = text_ypos;
-
- const wchar_t *labelText = g_pVGuiLocalize->Find("Valve_HudPoisonDamage");
- Assert( labelText );
- for (const wchar_t *wch = labelText; wch && *wch != 0; wch++)
- {
- if (*wch == '\n')
- {
- ypos += text_ygap;
- surface()->DrawSetTextPos(text_xpos, ypos);
- }
- else
- {
- surface()->DrawUnicodeChar(*wch);
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: hud scheme settings
-//-----------------------------------------------------------------------------
-void CHudPoisonDamageIndicator::ApplySchemeSettings(vgui::IScheme *pScheme)
-{
- BaseClass::ApplySchemeSettings(pScheme);
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "hud.h"
+#include "text_message.h"
+#include "hud_macros.h"
+#include "iclientmode.h"
+#include "view.h"
+#include "KeyValues.h"
+#include "vgui_controls/AnimationController.h"
+#include "vgui/ILocalize.h"
+#include "vgui/ISurface.h"
+#include "VGuiMatSurface/IMatSystemSurface.h"
+#include "materialsystem/imaterial.h"
+#include "materialsystem/imesh.h"
+#include "materialsystem/imaterialvar.h"
+#include "IEffects.h"
+#include "hudelement.h"
+
+using namespace vgui;
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: HDU Damage indication
+//-----------------------------------------------------------------------------
+class CHudPoisonDamageIndicator : public CHudElement, public vgui::Panel
+{
+ DECLARE_CLASS_SIMPLE( CHudPoisonDamageIndicator, vgui::Panel );
+
+public:
+ CHudPoisonDamageIndicator( const char *pElementName );
+ void Reset( void );
+ virtual bool ShouldDraw( void );
+
+private:
+ virtual void OnThink();
+ virtual void Paint();
+ virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
+
+private:
+ CPanelAnimationVar( vgui::HFont, m_hTextFont, "TextFont", "Default" );
+ CPanelAnimationVar( Color, m_TextColor, "TextColor", "FgColor" );
+ CPanelAnimationVarAliasType( float, text_xpos, "text_xpos", "8", "proportional_float" );
+ CPanelAnimationVarAliasType( float, text_ypos, "text_ypos", "8", "proportional_float" );
+ CPanelAnimationVarAliasType( float, text_ygap, "text_ygap", "14", "proportional_float" );
+
+ bool m_bDamageIndicatorVisible;
+};
+
+DECLARE_HUDELEMENT( CHudPoisonDamageIndicator );
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CHudPoisonDamageIndicator::CHudPoisonDamageIndicator( const char *pElementName ) : CHudElement( pElementName ), BaseClass(NULL, "HudPoisonDamageIndicator")
+{
+ vgui::Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+
+ SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudPoisonDamageIndicator::Reset( void )
+{
+ SetAlpha( 0 );
+ m_bDamageIndicatorVisible = false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Save CPU cycles by letting the HUD system early cull
+// costly traversal. Called per frame, return true if thinking and
+// painting need to occur.
+//-----------------------------------------------------------------------------
+bool CHudPoisonDamageIndicator::ShouldDraw( void )
+{
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return false;
+
+ bool bNeedsDraw = ( ( pPlayer->IsPoisoned() != m_bDamageIndicatorVisible ) || ( GetAlpha() > 0 ) );
+
+ return ( bNeedsDraw && CHudElement::ShouldDraw() );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: updates poison damage
+//-----------------------------------------------------------------------------
+void CHudPoisonDamageIndicator::OnThink()
+{
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ // update poison damage indicator
+ bool bShouldIndicatorBeVisible = pPlayer->IsPoisoned();
+ if (bShouldIndicatorBeVisible == m_bDamageIndicatorVisible)
+ return;
+
+ // state change
+ m_bDamageIndicatorVisible = bShouldIndicatorBeVisible;
+
+ if (m_bDamageIndicatorVisible)
+ {
+ SetVisible(true);
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "PoisonDamageTaken" );
+ }
+ else
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "PoisonDamageCured" );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Paints the damage display
+//-----------------------------------------------------------------------------
+void CHudPoisonDamageIndicator::Paint()
+{
+ // draw the text
+ surface()->DrawSetTextFont( m_hTextFont );
+ surface()->DrawSetTextColor( m_TextColor );
+ surface()->DrawSetTextPos(text_xpos, text_ypos);
+ int ypos = text_ypos;
+
+ const wchar_t *labelText = g_pVGuiLocalize->Find("Valve_HudPoisonDamage");
+ Assert( labelText );
+ for (const wchar_t *wch = labelText; wch && *wch != 0; wch++)
+ {
+ if (*wch == '\n')
+ {
+ ypos += text_ygap;
+ surface()->DrawSetTextPos(text_xpos, ypos);
+ }
+ else
+ {
+ surface()->DrawUnicodeChar(*wch);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: hud scheme settings
+//-----------------------------------------------------------------------------
+void CHudPoisonDamageIndicator::ApplySchemeSettings(vgui::IScheme *pScheme)
+{
+ BaseClass::ApplySchemeSettings(pScheme);
+}
diff --git a/mp/src/game/client/hl2/hud_quickinfo.cpp b/mp/src/game/client/hl2/hud_quickinfo.cpp
index d426616e..37db4c31 100644
--- a/mp/src/game/client/hl2/hud_quickinfo.cpp
+++ b/mp/src/game/client/hl2/hud_quickinfo.cpp
@@ -1,408 +1,408 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-#include "cbase.h"
-#include "hud.h"
-#include "hudelement.h"
-#include "iclientmode.h"
-#include "engine/IEngineSound.h"
-#include "vgui_controls/AnimationController.h"
-#include "vgui_controls/Controls.h"
-#include "vgui_controls/Panel.h"
-#include "vgui/ISurface.h"
-#include "../hud_crosshair.h"
-#include "VGuiMatSurface/IMatSystemSurface.h"
-
-#ifdef SIXENSE
-#include "sixense/in_sixense.h"
-#include "view.h"
-int ScreenTransform( const Vector& point, Vector& screen );
-#endif
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-#define HEALTH_WARNING_THRESHOLD 25
-
-static ConVar hud_quickinfo( "hud_quickinfo", "1", FCVAR_ARCHIVE );
-
-extern ConVar crosshair;
-
-#define QUICKINFO_EVENT_DURATION 1.0f
-#define QUICKINFO_BRIGHTNESS_FULL 255
-#define QUICKINFO_BRIGHTNESS_DIM 64
-#define QUICKINFO_FADE_IN_TIME 0.5f
-#define QUICKINFO_FADE_OUT_TIME 2.0f
-
-/*
-==================================================
-CHUDQuickInfo
-==================================================
-*/
-
-using namespace vgui;
-
-class CHUDQuickInfo : public CHudElement, public vgui::Panel
-{
- DECLARE_CLASS_SIMPLE( CHUDQuickInfo, vgui::Panel );
-public:
- CHUDQuickInfo( const char *pElementName );
- void Init( void );
- void VidInit( void );
- bool ShouldDraw( void );
- virtual void OnThink();
- virtual void Paint();
-
- virtual void ApplySchemeSettings( IScheme *scheme );
-private:
-
- void DrawWarning( int x, int y, CHudTexture *icon, float &time );
- void UpdateEventTime( void );
- bool EventTimeElapsed( void );
-
- int m_lastAmmo;
- int m_lastHealth;
-
- float m_ammoFade;
- float m_healthFade;
-
- bool m_warnAmmo;
- bool m_warnHealth;
-
- bool m_bFadedOut;
-
- bool m_bDimmed; // Whether or not we are dimmed down
- float m_flLastEventTime; // Last active event (controls dimmed state)
-
- CHudTexture *m_icon_c;
-
- CHudTexture *m_icon_rbn; // right bracket
- CHudTexture *m_icon_lbn; // left bracket
-
- CHudTexture *m_icon_rb; // right bracket, full
- CHudTexture *m_icon_lb; // left bracket, full
- CHudTexture *m_icon_rbe; // right bracket, empty
- CHudTexture *m_icon_lbe; // left bracket, empty
-};
-
-DECLARE_HUDELEMENT( CHUDQuickInfo );
-
-CHUDQuickInfo::CHUDQuickInfo( const char *pElementName ) :
- CHudElement( pElementName ), BaseClass( NULL, "HUDQuickInfo" )
-{
- vgui::Panel *pParent = g_pClientMode->GetViewport();
- SetParent( pParent );
-
- SetHiddenBits( HIDEHUD_CROSSHAIR );
-}
-
-void CHUDQuickInfo::ApplySchemeSettings( IScheme *scheme )
-{
- BaseClass::ApplySchemeSettings( scheme );
-
- SetPaintBackgroundEnabled( false );
- SetForceStereoRenderToFrameBuffer( true );
-}
-
-
-void CHUDQuickInfo::Init( void )
-{
- m_ammoFade = 0.0f;
- m_healthFade = 0.0f;
-
- m_lastAmmo = 0;
- m_lastHealth = 100;
-
- m_warnAmmo = false;
- m_warnHealth = false;
-
- m_bFadedOut = false;
- m_bDimmed = false;
- m_flLastEventTime = 0.0f;
-}
-
-
-void CHUDQuickInfo::VidInit( void )
-{
- Init();
-
- m_icon_c = gHUD.GetIcon( "crosshair" );
- m_icon_rb = gHUD.GetIcon( "crosshair_right_full" );
- m_icon_lb = gHUD.GetIcon( "crosshair_left_full" );
- m_icon_rbe = gHUD.GetIcon( "crosshair_right_empty" );
- m_icon_lbe = gHUD.GetIcon( "crosshair_left_empty" );
- m_icon_rbn = gHUD.GetIcon( "crosshair_right" );
- m_icon_lbn = gHUD.GetIcon( "crosshair_left" );
-}
-
-
-void CHUDQuickInfo::DrawWarning( int x, int y, CHudTexture *icon, float &time )
-{
- float scale = (int)( fabs(sin(gpGlobals->curtime*8.0f)) * 128.0);
-
- // Only fade out at the low point of our blink
- if ( time <= (gpGlobals->frametime * 200.0f) )
- {
- if ( scale < 40 )
- {
- time = 0.0f;
- return;
- }
- else
- {
- // Counteract the offset below to survive another frame
- time += (gpGlobals->frametime * 200.0f);
- }
- }
-
- // Update our time
- time -= (gpGlobals->frametime * 200.0f);
- Color caution = gHUD.m_clrCaution;
- caution[3] = scale * 255;
-
- icon->DrawSelf( x, y, caution );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Save CPU cycles by letting the HUD system early cull
-// costly traversal. Called per frame, return true if thinking and
-// painting need to occur.
-//-----------------------------------------------------------------------------
-bool CHUDQuickInfo::ShouldDraw( void )
-{
- if ( !m_icon_c || !m_icon_rb || !m_icon_rbe || !m_icon_lb || !m_icon_lbe )
- return false;
-
- C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
- if ( player == NULL )
- return false;
-
- if ( !crosshair.GetBool() && !IsX360() )
- return false;
-
- return ( CHudElement::ShouldDraw() && !engine->IsDrawingLoadingImage() );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Checks if the hud element needs to fade out
-//-----------------------------------------------------------------------------
-void CHUDQuickInfo::OnThink()
-{
- BaseClass::OnThink();
-
- C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
- if ( player == NULL )
- return;
-
- // see if we should fade in/out
- bool bFadeOut = player->IsZoomed();
-
- // check if the state has changed
- if ( m_bFadedOut != bFadeOut )
- {
- m_bFadedOut = bFadeOut;
-
- m_bDimmed = false;
-
- if ( bFadeOut )
- {
- g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( this, "Alpha", 0.0f, 0.0f, 0.25f, vgui::AnimationController::INTERPOLATOR_LINEAR );
- }
- else
- {
- g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( this, "Alpha", QUICKINFO_BRIGHTNESS_FULL, 0.0f, QUICKINFO_FADE_IN_TIME, vgui::AnimationController::INTERPOLATOR_LINEAR );
- }
- }
- else if ( !m_bFadedOut )
- {
- // If we're dormant, fade out
- if ( EventTimeElapsed() )
- {
- if ( !m_bDimmed )
- {
- m_bDimmed = true;
- g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( this, "Alpha", QUICKINFO_BRIGHTNESS_DIM, 0.0f, QUICKINFO_FADE_OUT_TIME, vgui::AnimationController::INTERPOLATOR_LINEAR );
- }
- }
- else if ( m_bDimmed )
- {
- // Fade back up, we're active
- m_bDimmed = false;
- g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( this, "Alpha", QUICKINFO_BRIGHTNESS_FULL, 0.0f, QUICKINFO_FADE_IN_TIME, vgui::AnimationController::INTERPOLATOR_LINEAR );
- }
- }
-}
-
-void CHUDQuickInfo::Paint()
-{
- C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
- if ( player == NULL )
- return;
-
- C_BaseCombatWeapon *pWeapon = GetActiveWeapon();
- if ( pWeapon == NULL )
- return;
-
- float fX, fY;
- bool bBehindCamera = false;
- CHudCrosshair::GetDrawPosition( &fX, &fY, &bBehindCamera );
-
- // if the crosshair is behind the camera, don't draw it
- if( bBehindCamera )
- return;
-
- int xCenter = (int)fX;
- int yCenter = (int)fY - m_icon_lb->Height() / 2;
-
- float scalar = 138.0f/255.0f;
-
- // Check our health for a warning
- int health = player->GetHealth();
- if ( health != m_lastHealth )
- {
- UpdateEventTime();
- m_lastHealth = health;
-
- if ( health <= HEALTH_WARNING_THRESHOLD )
- {
- if ( m_warnHealth == false )
- {
- m_healthFade = 255;
- m_warnHealth = true;
-
- CLocalPlayerFilter filter;
- C_BaseEntity::EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, "HUDQuickInfo.LowHealth" );
- }
- }
- else
- {
- m_warnHealth = false;
- }
- }
-
- // Check our ammo for a warning
- int ammo = pWeapon->Clip1();
- if ( ammo != m_lastAmmo )
- {
- UpdateEventTime();
- m_lastAmmo = ammo;
-
- // Find how far through the current clip we are
- float ammoPerc = (float) ammo / (float) pWeapon->GetMaxClip1();
-
- // Warn if we're below a certain percentage of our clip's size
- if (( pWeapon->GetMaxClip1() > 1 ) && ( ammoPerc <= ( 1.0f - CLIP_PERC_THRESHOLD )))
- {
- if ( m_warnAmmo == false )
- {
- m_ammoFade = 255;
- m_warnAmmo = true;
-
- CLocalPlayerFilter filter;
- C_BaseEntity::EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, "HUDQuickInfo.LowAmmo" );
- }
- }
- else
- {
- m_warnAmmo = false;
- }
- }
-
- Color clrNormal = gHUD.m_clrNormal;
- clrNormal[3] = 255 * scalar;
- m_icon_c->DrawSelf( xCenter, yCenter, clrNormal );
-
- if( IsX360() )
- {
- // Because the fixed reticle draws on half-texels, this rather unsightly hack really helps
- // center the appearance of the quickinfo on 360 displays.
- xCenter += 1;
- }
-
- if ( !hud_quickinfo.GetInt() )
- return;
-
- int sinScale = (int)( fabs(sin(gpGlobals->curtime*8.0f)) * 128.0f );
-
- // Update our health
- if ( m_healthFade > 0.0f )
- {
- DrawWarning( xCenter - (m_icon_lb->Width() * 2), yCenter, m_icon_lb, m_healthFade );
- }
- else
- {
- float healthPerc = (float) health / 100.0f;
- healthPerc = clamp( healthPerc, 0.0f, 1.0f );
-
- Color healthColor = m_warnHealth ? gHUD.m_clrCaution : gHUD.m_clrNormal;
-
- if ( m_warnHealth )
- {
- healthColor[3] = 255 * sinScale;
- }
- else
- {
- healthColor[3] = 255 * scalar;
- }
-
- gHUD.DrawIconProgressBar( xCenter - (m_icon_lb->Width() * 2), yCenter, m_icon_lb, m_icon_lbe, ( 1.0f - healthPerc ), healthColor, CHud::HUDPB_VERTICAL );
- }
-
- // Update our ammo
- if ( m_ammoFade > 0.0f )
- {
- DrawWarning( xCenter + m_icon_rb->Width(), yCenter, m_icon_rb, m_ammoFade );
- }
- else
- {
- float ammoPerc;
-
- if ( pWeapon->GetMaxClip1() <= 0 )
- {
- ammoPerc = 0.0f;
- }
- else
- {
- ammoPerc = 1.0f - ( (float) ammo / (float) pWeapon->GetMaxClip1() );
- ammoPerc = clamp( ammoPerc, 0.0f, 1.0f );
- }
-
- Color ammoColor = m_warnAmmo ? gHUD.m_clrCaution : gHUD.m_clrNormal;
-
- if ( m_warnAmmo )
- {
- ammoColor[3] = 255 * sinScale;
- }
- else
- {
- ammoColor[3] = 255 * scalar;
- }
-
- gHUD.DrawIconProgressBar( xCenter + m_icon_rb->Width(), yCenter, m_icon_rb, m_icon_rbe, ammoPerc, ammoColor, CHud::HUDPB_VERTICAL );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHUDQuickInfo::UpdateEventTime( void )
-{
- m_flLastEventTime = gpGlobals->curtime;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool CHUDQuickInfo::EventTimeElapsed( void )
-{
- if (( gpGlobals->curtime - m_flLastEventTime ) > QUICKINFO_EVENT_DURATION )
- return true;
-
- return false;
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#include "cbase.h"
+#include "hud.h"
+#include "hudelement.h"
+#include "iclientmode.h"
+#include "engine/IEngineSound.h"
+#include "vgui_controls/AnimationController.h"
+#include "vgui_controls/Controls.h"
+#include "vgui_controls/Panel.h"
+#include "vgui/ISurface.h"
+#include "../hud_crosshair.h"
+#include "VGuiMatSurface/IMatSystemSurface.h"
+
+#ifdef SIXENSE
+#include "sixense/in_sixense.h"
+#include "view.h"
+int ScreenTransform( const Vector& point, Vector& screen );
+#endif
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#define HEALTH_WARNING_THRESHOLD 25
+
+static ConVar hud_quickinfo( "hud_quickinfo", "1", FCVAR_ARCHIVE );
+
+extern ConVar crosshair;
+
+#define QUICKINFO_EVENT_DURATION 1.0f
+#define QUICKINFO_BRIGHTNESS_FULL 255
+#define QUICKINFO_BRIGHTNESS_DIM 64
+#define QUICKINFO_FADE_IN_TIME 0.5f
+#define QUICKINFO_FADE_OUT_TIME 2.0f
+
+/*
+==================================================
+CHUDQuickInfo
+==================================================
+*/
+
+using namespace vgui;
+
+class CHUDQuickInfo : public CHudElement, public vgui::Panel
+{
+ DECLARE_CLASS_SIMPLE( CHUDQuickInfo, vgui::Panel );
+public:
+ CHUDQuickInfo( const char *pElementName );
+ void Init( void );
+ void VidInit( void );
+ bool ShouldDraw( void );
+ virtual void OnThink();
+ virtual void Paint();
+
+ virtual void ApplySchemeSettings( IScheme *scheme );
+private:
+
+ void DrawWarning( int x, int y, CHudTexture *icon, float &time );
+ void UpdateEventTime( void );
+ bool EventTimeElapsed( void );
+
+ int m_lastAmmo;
+ int m_lastHealth;
+
+ float m_ammoFade;
+ float m_healthFade;
+
+ bool m_warnAmmo;
+ bool m_warnHealth;
+
+ bool m_bFadedOut;
+
+ bool m_bDimmed; // Whether or not we are dimmed down
+ float m_flLastEventTime; // Last active event (controls dimmed state)
+
+ CHudTexture *m_icon_c;
+
+ CHudTexture *m_icon_rbn; // right bracket
+ CHudTexture *m_icon_lbn; // left bracket
+
+ CHudTexture *m_icon_rb; // right bracket, full
+ CHudTexture *m_icon_lb; // left bracket, full
+ CHudTexture *m_icon_rbe; // right bracket, empty
+ CHudTexture *m_icon_lbe; // left bracket, empty
+};
+
+DECLARE_HUDELEMENT( CHUDQuickInfo );
+
+CHUDQuickInfo::CHUDQuickInfo( const char *pElementName ) :
+ CHudElement( pElementName ), BaseClass( NULL, "HUDQuickInfo" )
+{
+ vgui::Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+
+ SetHiddenBits( HIDEHUD_CROSSHAIR );
+}
+
+void CHUDQuickInfo::ApplySchemeSettings( IScheme *scheme )
+{
+ BaseClass::ApplySchemeSettings( scheme );
+
+ SetPaintBackgroundEnabled( false );
+ SetForceStereoRenderToFrameBuffer( true );
+}
+
+
+void CHUDQuickInfo::Init( void )
+{
+ m_ammoFade = 0.0f;
+ m_healthFade = 0.0f;
+
+ m_lastAmmo = 0;
+ m_lastHealth = 100;
+
+ m_warnAmmo = false;
+ m_warnHealth = false;
+
+ m_bFadedOut = false;
+ m_bDimmed = false;
+ m_flLastEventTime = 0.0f;
+}
+
+
+void CHUDQuickInfo::VidInit( void )
+{
+ Init();
+
+ m_icon_c = gHUD.GetIcon( "crosshair" );
+ m_icon_rb = gHUD.GetIcon( "crosshair_right_full" );
+ m_icon_lb = gHUD.GetIcon( "crosshair_left_full" );
+ m_icon_rbe = gHUD.GetIcon( "crosshair_right_empty" );
+ m_icon_lbe = gHUD.GetIcon( "crosshair_left_empty" );
+ m_icon_rbn = gHUD.GetIcon( "crosshair_right" );
+ m_icon_lbn = gHUD.GetIcon( "crosshair_left" );
+}
+
+
+void CHUDQuickInfo::DrawWarning( int x, int y, CHudTexture *icon, float &time )
+{
+ float scale = (int)( fabs(sin(gpGlobals->curtime*8.0f)) * 128.0);
+
+ // Only fade out at the low point of our blink
+ if ( time <= (gpGlobals->frametime * 200.0f) )
+ {
+ if ( scale < 40 )
+ {
+ time = 0.0f;
+ return;
+ }
+ else
+ {
+ // Counteract the offset below to survive another frame
+ time += (gpGlobals->frametime * 200.0f);
+ }
+ }
+
+ // Update our time
+ time -= (gpGlobals->frametime * 200.0f);
+ Color caution = gHUD.m_clrCaution;
+ caution[3] = scale * 255;
+
+ icon->DrawSelf( x, y, caution );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Save CPU cycles by letting the HUD system early cull
+// costly traversal. Called per frame, return true if thinking and
+// painting need to occur.
+//-----------------------------------------------------------------------------
+bool CHUDQuickInfo::ShouldDraw( void )
+{
+ if ( !m_icon_c || !m_icon_rb || !m_icon_rbe || !m_icon_lb || !m_icon_lbe )
+ return false;
+
+ C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
+ if ( player == NULL )
+ return false;
+
+ if ( !crosshair.GetBool() && !IsX360() )
+ return false;
+
+ return ( CHudElement::ShouldDraw() && !engine->IsDrawingLoadingImage() );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Checks if the hud element needs to fade out
+//-----------------------------------------------------------------------------
+void CHUDQuickInfo::OnThink()
+{
+ BaseClass::OnThink();
+
+ C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
+ if ( player == NULL )
+ return;
+
+ // see if we should fade in/out
+ bool bFadeOut = player->IsZoomed();
+
+ // check if the state has changed
+ if ( m_bFadedOut != bFadeOut )
+ {
+ m_bFadedOut = bFadeOut;
+
+ m_bDimmed = false;
+
+ if ( bFadeOut )
+ {
+ g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( this, "Alpha", 0.0f, 0.0f, 0.25f, vgui::AnimationController::INTERPOLATOR_LINEAR );
+ }
+ else
+ {
+ g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( this, "Alpha", QUICKINFO_BRIGHTNESS_FULL, 0.0f, QUICKINFO_FADE_IN_TIME, vgui::AnimationController::INTERPOLATOR_LINEAR );
+ }
+ }
+ else if ( !m_bFadedOut )
+ {
+ // If we're dormant, fade out
+ if ( EventTimeElapsed() )
+ {
+ if ( !m_bDimmed )
+ {
+ m_bDimmed = true;
+ g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( this, "Alpha", QUICKINFO_BRIGHTNESS_DIM, 0.0f, QUICKINFO_FADE_OUT_TIME, vgui::AnimationController::INTERPOLATOR_LINEAR );
+ }
+ }
+ else if ( m_bDimmed )
+ {
+ // Fade back up, we're active
+ m_bDimmed = false;
+ g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( this, "Alpha", QUICKINFO_BRIGHTNESS_FULL, 0.0f, QUICKINFO_FADE_IN_TIME, vgui::AnimationController::INTERPOLATOR_LINEAR );
+ }
+ }
+}
+
+void CHUDQuickInfo::Paint()
+{
+ C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
+ if ( player == NULL )
+ return;
+
+ C_BaseCombatWeapon *pWeapon = GetActiveWeapon();
+ if ( pWeapon == NULL )
+ return;
+
+ float fX, fY;
+ bool bBehindCamera = false;
+ CHudCrosshair::GetDrawPosition( &fX, &fY, &bBehindCamera );
+
+ // if the crosshair is behind the camera, don't draw it
+ if( bBehindCamera )
+ return;
+
+ int xCenter = (int)fX;
+ int yCenter = (int)fY - m_icon_lb->Height() / 2;
+
+ float scalar = 138.0f/255.0f;
+
+ // Check our health for a warning
+ int health = player->GetHealth();
+ if ( health != m_lastHealth )
+ {
+ UpdateEventTime();
+ m_lastHealth = health;
+
+ if ( health <= HEALTH_WARNING_THRESHOLD )
+ {
+ if ( m_warnHealth == false )
+ {
+ m_healthFade = 255;
+ m_warnHealth = true;
+
+ CLocalPlayerFilter filter;
+ C_BaseEntity::EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, "HUDQuickInfo.LowHealth" );
+ }
+ }
+ else
+ {
+ m_warnHealth = false;
+ }
+ }
+
+ // Check our ammo for a warning
+ int ammo = pWeapon->Clip1();
+ if ( ammo != m_lastAmmo )
+ {
+ UpdateEventTime();
+ m_lastAmmo = ammo;
+
+ // Find how far through the current clip we are
+ float ammoPerc = (float) ammo / (float) pWeapon->GetMaxClip1();
+
+ // Warn if we're below a certain percentage of our clip's size
+ if (( pWeapon->GetMaxClip1() > 1 ) && ( ammoPerc <= ( 1.0f - CLIP_PERC_THRESHOLD )))
+ {
+ if ( m_warnAmmo == false )
+ {
+ m_ammoFade = 255;
+ m_warnAmmo = true;
+
+ CLocalPlayerFilter filter;
+ C_BaseEntity::EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, "HUDQuickInfo.LowAmmo" );
+ }
+ }
+ else
+ {
+ m_warnAmmo = false;
+ }
+ }
+
+ Color clrNormal = gHUD.m_clrNormal;
+ clrNormal[3] = 255 * scalar;
+ m_icon_c->DrawSelf( xCenter, yCenter, clrNormal );
+
+ if( IsX360() )
+ {
+ // Because the fixed reticle draws on half-texels, this rather unsightly hack really helps
+ // center the appearance of the quickinfo on 360 displays.
+ xCenter += 1;
+ }
+
+ if ( !hud_quickinfo.GetInt() )
+ return;
+
+ int sinScale = (int)( fabs(sin(gpGlobals->curtime*8.0f)) * 128.0f );
+
+ // Update our health
+ if ( m_healthFade > 0.0f )
+ {
+ DrawWarning( xCenter - (m_icon_lb->Width() * 2), yCenter, m_icon_lb, m_healthFade );
+ }
+ else
+ {
+ float healthPerc = (float) health / 100.0f;
+ healthPerc = clamp( healthPerc, 0.0f, 1.0f );
+
+ Color healthColor = m_warnHealth ? gHUD.m_clrCaution : gHUD.m_clrNormal;
+
+ if ( m_warnHealth )
+ {
+ healthColor[3] = 255 * sinScale;
+ }
+ else
+ {
+ healthColor[3] = 255 * scalar;
+ }
+
+ gHUD.DrawIconProgressBar( xCenter - (m_icon_lb->Width() * 2), yCenter, m_icon_lb, m_icon_lbe, ( 1.0f - healthPerc ), healthColor, CHud::HUDPB_VERTICAL );
+ }
+
+ // Update our ammo
+ if ( m_ammoFade > 0.0f )
+ {
+ DrawWarning( xCenter + m_icon_rb->Width(), yCenter, m_icon_rb, m_ammoFade );
+ }
+ else
+ {
+ float ammoPerc;
+
+ if ( pWeapon->GetMaxClip1() <= 0 )
+ {
+ ammoPerc = 0.0f;
+ }
+ else
+ {
+ ammoPerc = 1.0f - ( (float) ammo / (float) pWeapon->GetMaxClip1() );
+ ammoPerc = clamp( ammoPerc, 0.0f, 1.0f );
+ }
+
+ Color ammoColor = m_warnAmmo ? gHUD.m_clrCaution : gHUD.m_clrNormal;
+
+ if ( m_warnAmmo )
+ {
+ ammoColor[3] = 255 * sinScale;
+ }
+ else
+ {
+ ammoColor[3] = 255 * scalar;
+ }
+
+ gHUD.DrawIconProgressBar( xCenter + m_icon_rb->Width(), yCenter, m_icon_rb, m_icon_rbe, ammoPerc, ammoColor, CHud::HUDPB_VERTICAL );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHUDQuickInfo::UpdateEventTime( void )
+{
+ m_flLastEventTime = gpGlobals->curtime;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CHUDQuickInfo::EventTimeElapsed( void )
+{
+ if (( gpGlobals->curtime - m_flLastEventTime ) > QUICKINFO_EVENT_DURATION )
+ return true;
+
+ return false;
+}
+
diff --git a/mp/src/game/client/hl2/hud_radar.cpp b/mp/src/game/client/hl2/hud_radar.cpp
index 0f9087fb..2f0fd7e9 100644
--- a/mp/src/game/client/hl2/hud_radar.cpp
+++ b/mp/src/game/client/hl2/hud_radar.cpp
@@ -1,587 +1,587 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include <vgui/ISurface.h>
-#include "hud_numericdisplay.h"
-#include "iclientmode.h"
-#include <coordsize.h>
-#include "hud_macros.h"
-#include "vgui/IVGui.h"
-#include "vgui/ILocalize.h"
-#include "mapoverview.h"
-#include "hud_radar.h"
-#include "iclientvehicle.h"
-
-#define RADAR_DOT_NORMAL 0
-#define RADAR_IGNORE_Z (1<<6) //always draw this item as if it was at the same Z as the player
-#define RADAR_MAX_GHOST_ALPHA 25
-
-DECLARE_VGUI_SCREEN_FACTORY( CHudRadar, "jalopy_radar_panel" );
-
-#define RADAR_PANEL_MATERIAL "vgui/screens/radar"
-#define RADAR_CONTACT_LAMBDA_MATERIAL "vgui/icons/icon_lambda" // Lambda cache
-#define RADAR_CONTACT_BUSTER_MATERIAL "vgui/icons/icon_buster" // Striderbuster
-#define RADAR_CONTACT_STRIDER_MATERIAL "vgui/icons/icon_strider" // Strider
-#define RADAR_CONTACT_DOG_MATERIAL "vgui/icons/icon_dog" // Dog
-#define RADAR_CONTACT_BASE_MATERIAL "vgui/icons/icon_base" // Ally base
-
-static CHudRadar *s_Radar = NULL;
-
-CHudRadar *GetHudRadar()
-{
- return s_Radar;
-}
-
-DECLARE_HUDELEMENT( CMapOverview );
-
-//---------------------------------------------------------
-//---------------------------------------------------------
-CHudRadar::CHudRadar( vgui::Panel *parent, const char *panelName ) : BaseClass( parent, panelName )
-{
- m_pVehicle = NULL;
- m_iImageID = -1;
- m_textureID_IconLambda = -1;
- m_textureID_IconBuster = -1;
- m_textureID_IconStrider = -1;
- m_textureID_IconDog = -1;
- m_textureID_IconBase = -1;
-}
-
-//---------------------------------------------------------
-//---------------------------------------------------------
-CHudRadar::~CHudRadar()
-{
- s_Radar = NULL;
-
-#if defined(_X360)
- if( m_iImageID != -1 )
- {
- vgui::surface()->DestroyTextureID( m_iImageID );
- m_iImageID = -1;
- }
-
- if( m_textureID_IconLambda != -1 )
- {
- vgui::surface()->DestroyTextureID( m_textureID_IconLambda );
- m_textureID_IconLambda = -1;
- }
-
- if( m_textureID_IconBuster != -1 )
- {
- vgui::surface()->DestroyTextureID( m_textureID_IconBuster );
- m_textureID_IconBuster = -1;
- }
-
- if( m_textureID_IconStrider != -1 )
- {
- vgui::surface()->DestroyTextureID( m_textureID_IconStrider );
- m_textureID_IconStrider = -1;
- }
-
- if( m_textureID_IconDog != -1 )
- {
- vgui::surface()->DestroyTextureID( m_textureID_IconDog );
- m_textureID_IconDog = -1;
- }
-
- if( m_textureID_IconBase != -1 )
- {
- vgui::surface()->DestroyTextureID( m_textureID_IconBase );
- m_textureID_IconBase = -1;
- }
-#endif//_X360
-}
-
-//---------------------------------------------------------
-//---------------------------------------------------------
-bool CHudRadar::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
-{
- bool result = BaseClass::Init( pKeyValues, pInitData );
- ClearAllRadarContacts();
- s_Radar = this;
-
- m_ghostAlpha = 0;
- m_flTimeStartGhosting = gpGlobals->curtime + 1.0f;
-
- return result;
-}
-
-//---------------------------------------------------------
-//---------------------------------------------------------
-void CHudRadar::VidInit(void)
-{
-}
-
-//---------------------------------------------------------
-//---------------------------------------------------------
-void CHudRadar::MsgFunc_UpdateRadar(bf_read &msg )
-{
-}
-
-//---------------------------------------------------------
-// Purpose: Register a radar contact in the list of contacts
-//---------------------------------------------------------
-void CHudRadar::AddRadarContact( const Vector &vecOrigin, int iType, float flTimeToLive )
-{
- if( m_iNumRadarContacts == RADAR_MAX_CONTACTS )
- return;
-
- Vector v = vecOrigin;
- int iExistingContact = FindRadarContact( vecOrigin );
-
- if( iExistingContact > -1 )
- {
- // Just update this contact.
- m_radarContacts[iExistingContact].m_flTimeToRemove = gpGlobals->curtime + flTimeToLive;
- return;
- }
-
- m_radarContacts[m_iNumRadarContacts].m_vecOrigin = vecOrigin;
- m_radarContacts[m_iNumRadarContacts].m_iType = iType;
- m_radarContacts[m_iNumRadarContacts].m_flTimeToRemove = gpGlobals->curtime + flTimeToLive;
- m_iNumRadarContacts++;
-}
-
-//---------------------------------------------------------
-// Purpose: Search the contact list for a specific contact
-//---------------------------------------------------------
-int CHudRadar::FindRadarContact( const Vector &vecOrigin )
-{
- for( int i = 0 ; i < m_iNumRadarContacts ; i++ )
- {
- if( m_radarContacts[ i ].m_vecOrigin == vecOrigin )
- return i;
- }
-
- return -1;
-}
-
-//---------------------------------------------------------
-// Purpose: Go through all radar targets and see if any
-// have expired. If yes, remove them from the
-// list.
-//---------------------------------------------------------
-void CHudRadar::MaintainRadarContacts()
-{
- bool bKeepWorking = true;
- while( bKeepWorking )
- {
- bKeepWorking = false;
- for( int i = 0 ; i < m_iNumRadarContacts ; i++ )
- {
- CRadarContact *pContact = &m_radarContacts[ i ];
- if( gpGlobals->curtime >= pContact->m_flTimeToRemove )
- {
- // Time for this guy to go. Easiest thing is just to copy the last element
- // into this element's spot and then decrement the count of entities.
- bKeepWorking = true;
-
- m_radarContacts[ i ] = m_radarContacts[ m_iNumRadarContacts - 1 ];
- m_iNumRadarContacts--;
- break;
- }
- }
- }
-}
-
-//---------------------------------------------------------
-//---------------------------------------------------------
-void CHudRadar::SetVisible(bool state)
-{
- BaseClass::SetVisible(state);
-
- if( g_pMapOverview && g_pMapOverview->GetMode() == CMapOverview::MAP_MODE_RADAR )
- {
- // We are the hud element still, but he is in charge of the new style now.
- g_pMapOverview->SetVisible( state );
- }
-}
-
-#define RADAR_BLIP_FADE_TIME 1.0f
-#define RADAR_USE_ICONS 1
-//---------------------------------------------------------
-// Purpose: Draw the radar panel.
-// We're probably doing too much other work in here
-//---------------------------------------------------------
-void CHudRadar::Paint()
-{
- if (m_iImageID == -1 )
- {
- // Set up the image ID's if they've somehow gone bad.
- m_textureID_IconLambda = vgui::surface()->CreateNewTextureID();
- vgui::surface()->DrawSetTextureFile( m_textureID_IconLambda, RADAR_CONTACT_LAMBDA_MATERIAL, true, false );
-
- m_textureID_IconBuster = vgui::surface()->CreateNewTextureID();
- vgui::surface()->DrawSetTextureFile( m_textureID_IconBuster, RADAR_CONTACT_BUSTER_MATERIAL, true, false );
-
- m_textureID_IconStrider = vgui::surface()->CreateNewTextureID();
- vgui::surface()->DrawSetTextureFile( m_textureID_IconStrider, RADAR_CONTACT_STRIDER_MATERIAL, true, false );
-
- m_textureID_IconDog = vgui::surface()->CreateNewTextureID();
- vgui::surface()->DrawSetTextureFile( m_textureID_IconDog, RADAR_CONTACT_DOG_MATERIAL, true, false );
-
- m_textureID_IconBase = vgui::surface()->CreateNewTextureID();
- vgui::surface()->DrawSetTextureFile( m_textureID_IconBase, RADAR_CONTACT_BASE_MATERIAL, true, false );
-
- m_iImageID = vgui::surface()->CreateNewTextureID();
- vgui::surface()->DrawSetTextureFile( m_iImageID, RADAR_PANEL_MATERIAL, true, false );
- }
-
- // Draw the radar background.
- int wide, tall;
- GetSize(wide, tall);
- int alpha = 255;
- vgui::surface()->DrawSetColor(255, 255, 255, alpha);
- vgui::surface()->DrawSetTexture(m_iImageID);
- vgui::surface()->DrawTexturedRect(0, 0, wide, tall);
-
- // Manage the CRT 'ghosting' effect
- if( gpGlobals->curtime > m_flTimeStartGhosting )
- {
- if( m_ghostAlpha < RADAR_MAX_GHOST_ALPHA )
- {
- m_ghostAlpha++;
- }
- else
- {
- m_flTimeStartGhosting = FLT_MAX;
- m_flTimeStopGhosting = gpGlobals->curtime + RandomFloat( 1.0f, 2.0f );// How long to ghost for
- }
- }
- else if( gpGlobals->curtime > m_flTimeStopGhosting )
- {
- // We're supposed to stop ghosting now.
- if( m_ghostAlpha > 0 )
- {
- // Still fading the effects.
- m_ghostAlpha--;
- }
- else
- {
- // DONE fading the effects. Now stop ghosting for a short while
- m_flTimeStartGhosting = gpGlobals->curtime + RandomFloat( 2.0f, 3.0f );// how long between ghosts
- m_flTimeStopGhosting = FLT_MAX;
- }
- }
-
- // Now go through the list of radar targets and represent them on the radar screen
- // by drawing their icons on top of the background.
- C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
-
- for( int i = 0 ; i < m_iNumRadarContacts ; i++ )
- {
- int alpha = 90;
- CRadarContact *pContact = &m_radarContacts[ i ];
- float deltaT = pContact->m_flTimeToRemove - gpGlobals->curtime;
- if ( deltaT < RADAR_BLIP_FADE_TIME )
- {
- float factor = deltaT / RADAR_BLIP_FADE_TIME;
-
- alpha = (int) ( ((float)alpha) * factor );
-
- if( alpha < 10 )
- alpha = 10;
- }
-
- if( RADAR_USE_ICONS )
- {
- int flicker = RandomInt( 0, 30 );
- DrawIconOnRadar( pContact->m_vecOrigin, pLocalPlayer, pContact->m_iType, RADAR_IGNORE_Z, 255, 255, 255, alpha + flicker );
- }
- else
- {
- DrawPositionOnRadar( pContact->m_vecOrigin, pLocalPlayer, pContact->m_iType, RADAR_IGNORE_Z, 255, 255, 255, alpha );
- }
- }
-
- MaintainRadarContacts();
-}
-
-ConVar radar_range("radar_range", "3000" ); // 180 feet
-//---------------------------------------------------------
-// Scale maps the distance of the target from the radar
-// source.
-//
-// 1.0 = target at or beyond radar range.
-// 0.5 = target at (radar_range * 0.5) units distance
-// 0.25 = target at (radar_range * 0.25) units distance
-// -etc-
-//---------------------------------------------------------
-bool CHudRadar::WorldToRadar( const Vector location, const Vector origin, const QAngle angles, float &x, float &y, float &z_delta, float &scale )
-{
- bool bInRange = true;
-
- float x_diff = location.x - origin.x;
- float y_diff = location.y - origin.y;
-
- // Supply epsilon values to avoid divide-by-zero
- if(x_diff == 0)
- x_diff = 0.00001f;
-
- if(y_diff == 0)
- y_diff = 0.00001f;
-
- int iRadarRadius = GetWide(); //width of the panel
- float fRange = radar_range.GetFloat();
-
- // This magic /2.15 makes the radar scale seem smaller than the VGUI panel so the icons clamp
- // to the outer ring in the radar graphic, not the very edge of the panel itself.
- float fScale = (iRadarRadius/2.15f) / fRange;
-
- float flOffset = atan(y_diff/x_diff);
- flOffset *= 180;
- flOffset /= M_PI;
-
- if ((x_diff < 0) && (y_diff >= 0))
- flOffset = 180 + flOffset;
- else if ((x_diff < 0) && (y_diff < 0))
- flOffset = 180 + flOffset;
- else if ((x_diff >= 0) && (y_diff < 0))
- flOffset = 360 + flOffset;
-
- y_diff = -1*(sqrt((x_diff)*(x_diff) + (y_diff)*(y_diff)));
- x_diff = 0;
-
- flOffset = angles.y - flOffset;
-
- flOffset *= M_PI;
- flOffset /= 180; // now theta is in radians
-
- // Transform relative to radar source
- float xnew_diff = x_diff * cos(flOffset) - y_diff * sin(flOffset);
- float ynew_diff = x_diff * sin(flOffset) + y_diff * cos(flOffset);
-
- if ( (-1 * y_diff) > fRange )
- {
- float flScale;
-
- flScale = ( -1 * y_diff) / fRange;
-
- xnew_diff /= (flScale);
- ynew_diff /= (flScale);
-
- bInRange = false;
-
- scale = 1.0f;
- }
- else
- {
- // scale
- float flDist = sqrt( ((xnew_diff)*(xnew_diff) + (ynew_diff)*(ynew_diff)) );
- scale = flDist / fRange;
- }
-
-
- // Scale the dot's position to match radar scale
- xnew_diff *= fScale;
- ynew_diff *= fScale;
-
- // Translate to screen coordinates
- x = (iRadarRadius/2) + (int)xnew_diff;
- y = (iRadarRadius/2) + (int)ynew_diff;
- z_delta = 0.0f;
-
- return bInRange;
-}
-
-void CHudRadar::DrawPositionOnRadar( Vector vecPos, C_BasePlayer *pLocalPlayer, int type, int flags, int r, int g, int b, int a )
-{
- float x, y, z_delta;
- int iBaseDotSize = 3;
-
- QAngle viewAngle = pLocalPlayer->EyeAngles();
-
- if( m_pVehicle != NULL )
- {
- viewAngle = m_pVehicle->GetAbsAngles();
- viewAngle.y += 90.0f;
- }
-
- float flScale;
-
- WorldToRadar( vecPos, pLocalPlayer->GetAbsOrigin(), viewAngle, x, y, z_delta, flScale );
-
- if( flags & RADAR_IGNORE_Z )
- z_delta = 0;
-
- switch( type )
- {
- case RADAR_CONTACT_GENERIC:
- r = 255; g = 170; b = 0;
- iBaseDotSize *= 2;
- break;
- case RADAR_CONTACT_MAGNUSSEN_RDU:
- r = 0; g = 200; b = 255;
- iBaseDotSize *= 2;
- break;
- case RADAR_CONTACT_ENEMY:
- r = 255; g = 0; b = 0;
- iBaseDotSize *= 2;
- break;
- case RADAR_CONTACT_LARGE_ENEMY:
- r = 255; g = 0; b = 0;
- iBaseDotSize *= 3;
- break;
- }
-
- DrawRadarDot( x, y, z_delta, iBaseDotSize, flags, r, g, b, a );
-}
-
-//---------------------------------------------------------
-// Purpose: Compute the proper position on the radar screen
-// for this object's position relative to the player.
-// Then draw the icon in the proper location on the
-// radar screen.
-//---------------------------------------------------------
-#define RADAR_ICON_MIN_SCALE 0.75f
-#define RADAR_ICON_MAX_SCALE 1.0f
-void CHudRadar::DrawIconOnRadar( Vector vecPos, C_BasePlayer *pLocalPlayer, int type, int flags, int r, int g, int b, int a )
-{
- float x, y, z_delta;
- int wide, tall;
-
- // for 'ghosting' CRT effects:
- int xmod;
- int ymod;
- int xoffset;
- int yoffset;
-
- // Assume we're going to use the player's location and orientation
- QAngle viewAngle = pLocalPlayer->EyeAngles();
- Vector viewOrigin = pLocalPlayer->GetAbsOrigin();
-
- // However, happily use those of the vehicle if available!
- if( m_pVehicle != NULL )
- {
- viewAngle = m_pVehicle->GetAbsAngles();
- viewAngle.y += 90.0f;
- viewOrigin = m_pVehicle->WorldSpaceCenter();
- }
-
- float flScale;
-
- WorldToRadar( vecPos, viewOrigin, viewAngle, x, y, z_delta, flScale );
-
- flScale = RemapVal( flScale, 1.0f, 0.0f, RADAR_ICON_MIN_SCALE, RADAR_ICON_MAX_SCALE );
-
- // Get the correct icon for this type of contact
- int iTextureID_Icon = -1;
-
- switch( type )
- {
- case RADAR_CONTACT_GENERIC:
- iTextureID_Icon = m_textureID_IconLambda;
- break;
- case RADAR_CONTACT_MAGNUSSEN_RDU:
- iTextureID_Icon = m_textureID_IconBuster;
- break;
- case RADAR_CONTACT_LARGE_ENEMY:
- case RADAR_CONTACT_ENEMY:
- iTextureID_Icon = m_textureID_IconStrider;
- break;
- case RADAR_CONTACT_DOG:
- iTextureID_Icon = m_textureID_IconDog;
- break;
- case RADAR_CONTACT_ALLY_INSTALLATION:
- iTextureID_Icon = m_textureID_IconBase;
- break;
- default:
- return;
- break;
- }
-
- vgui::surface()->DrawSetColor( r, g, b, a );
- vgui::surface()->DrawSetTexture( iTextureID_Icon );
- vgui::surface()->DrawGetTextureSize( iTextureID_Icon, wide, tall );
-
- wide = ( int((float)wide * flScale) );
- tall = ( int((float)tall * flScale) );
-
- if( type == RADAR_CONTACT_LARGE_ENEMY )
- {
- wide *= 2;
- tall *= 2;
- }
-
- // Center the icon around its position.
- x -= (wide >> 1);
- y -= (tall >> 1);
-
- vgui::surface()->DrawTexturedRect(x, y, x+wide, y+tall);
-
- // Draw the crt 'ghost' if the icon is not pegged to the outer rim
- if( flScale > RADAR_ICON_MIN_SCALE && m_ghostAlpha > 0 )
- {
- vgui::surface()->DrawSetColor( r, g, b, m_ghostAlpha );
- xmod = RandomInt( 1, 4 );
- ymod = RandomInt( 1, 4 );
- xoffset = RandomInt( -1, 1 );
- yoffset = RandomInt( -1, 1 );
- x -= (xmod - xoffset);
- y -= (ymod - yoffset);
- wide += (xmod + xoffset);
- tall += (ymod + yoffset);
- vgui::surface()->DrawTexturedRect(x, y, x+wide, y+tall);
- }
-}
-
-void CHudRadar::FillRect( int x, int y, int w, int h )
-{
- int panel_x, panel_y, panel_w, panel_h;
- GetBounds( panel_x, panel_y, panel_w, panel_h );
- vgui::surface()->DrawFilledRect( x, y, x+w, y+h );
-}
-
-void CHudRadar::DrawRadarDot( int x, int y, float z_diff, int iBaseDotSize, int flags, int r, int g, int b, int a )
-{
- vgui::surface()->DrawSetColor( r, g, b, a );
-
- if ( z_diff < -128 ) // below the player
- {
- z_diff *= -1;
-
- if ( z_diff > 3096 )
- {
- z_diff = 3096;
- }
-
- int iBar = (int)( z_diff / 400 ) + 2;
-
- // Draw an upside-down T shape to symbolize the dot is below the player.
-
- iBaseDotSize /= 2;
-
- //horiz
- FillRect( x-(2*iBaseDotSize), y, 5*iBaseDotSize, iBaseDotSize );
-
- //vert
- FillRect( x, y - iBar*iBaseDotSize, iBaseDotSize, iBar*iBaseDotSize );
- }
- else if ( z_diff > 128 ) // above the player
- {
- if ( z_diff > 3096 )
- {
- z_diff = 3096;
- }
-
- int iBar = (int)( z_diff / 400 ) + 2;
-
- iBaseDotSize /= 2;
-
- // Draw a T shape to symbolize the dot is above the player.
-
- //horiz
- FillRect( x-(2*iBaseDotSize), y, 5*iBaseDotSize, iBaseDotSize );
-
- //vert
- FillRect( x, y, iBaseDotSize, iBar*iBaseDotSize );
- }
- else
- {
- FillRect( x, y, iBaseDotSize, iBaseDotSize );
- }
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include <vgui/ISurface.h>
+#include "hud_numericdisplay.h"
+#include "iclientmode.h"
+#include <coordsize.h>
+#include "hud_macros.h"
+#include "vgui/IVGui.h"
+#include "vgui/ILocalize.h"
+#include "mapoverview.h"
+#include "hud_radar.h"
+#include "iclientvehicle.h"
+
+#define RADAR_DOT_NORMAL 0
+#define RADAR_IGNORE_Z (1<<6) //always draw this item as if it was at the same Z as the player
+#define RADAR_MAX_GHOST_ALPHA 25
+
+DECLARE_VGUI_SCREEN_FACTORY( CHudRadar, "jalopy_radar_panel" );
+
+#define RADAR_PANEL_MATERIAL "vgui/screens/radar"
+#define RADAR_CONTACT_LAMBDA_MATERIAL "vgui/icons/icon_lambda" // Lambda cache
+#define RADAR_CONTACT_BUSTER_MATERIAL "vgui/icons/icon_buster" // Striderbuster
+#define RADAR_CONTACT_STRIDER_MATERIAL "vgui/icons/icon_strider" // Strider
+#define RADAR_CONTACT_DOG_MATERIAL "vgui/icons/icon_dog" // Dog
+#define RADAR_CONTACT_BASE_MATERIAL "vgui/icons/icon_base" // Ally base
+
+static CHudRadar *s_Radar = NULL;
+
+CHudRadar *GetHudRadar()
+{
+ return s_Radar;
+}
+
+DECLARE_HUDELEMENT( CMapOverview );
+
+//---------------------------------------------------------
+//---------------------------------------------------------
+CHudRadar::CHudRadar( vgui::Panel *parent, const char *panelName ) : BaseClass( parent, panelName )
+{
+ m_pVehicle = NULL;
+ m_iImageID = -1;
+ m_textureID_IconLambda = -1;
+ m_textureID_IconBuster = -1;
+ m_textureID_IconStrider = -1;
+ m_textureID_IconDog = -1;
+ m_textureID_IconBase = -1;
+}
+
+//---------------------------------------------------------
+//---------------------------------------------------------
+CHudRadar::~CHudRadar()
+{
+ s_Radar = NULL;
+
+#if defined(_X360)
+ if( m_iImageID != -1 )
+ {
+ vgui::surface()->DestroyTextureID( m_iImageID );
+ m_iImageID = -1;
+ }
+
+ if( m_textureID_IconLambda != -1 )
+ {
+ vgui::surface()->DestroyTextureID( m_textureID_IconLambda );
+ m_textureID_IconLambda = -1;
+ }
+
+ if( m_textureID_IconBuster != -1 )
+ {
+ vgui::surface()->DestroyTextureID( m_textureID_IconBuster );
+ m_textureID_IconBuster = -1;
+ }
+
+ if( m_textureID_IconStrider != -1 )
+ {
+ vgui::surface()->DestroyTextureID( m_textureID_IconStrider );
+ m_textureID_IconStrider = -1;
+ }
+
+ if( m_textureID_IconDog != -1 )
+ {
+ vgui::surface()->DestroyTextureID( m_textureID_IconDog );
+ m_textureID_IconDog = -1;
+ }
+
+ if( m_textureID_IconBase != -1 )
+ {
+ vgui::surface()->DestroyTextureID( m_textureID_IconBase );
+ m_textureID_IconBase = -1;
+ }
+#endif//_X360
+}
+
+//---------------------------------------------------------
+//---------------------------------------------------------
+bool CHudRadar::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
+{
+ bool result = BaseClass::Init( pKeyValues, pInitData );
+ ClearAllRadarContacts();
+ s_Radar = this;
+
+ m_ghostAlpha = 0;
+ m_flTimeStartGhosting = gpGlobals->curtime + 1.0f;
+
+ return result;
+}
+
+//---------------------------------------------------------
+//---------------------------------------------------------
+void CHudRadar::VidInit(void)
+{
+}
+
+//---------------------------------------------------------
+//---------------------------------------------------------
+void CHudRadar::MsgFunc_UpdateRadar(bf_read &msg )
+{
+}
+
+//---------------------------------------------------------
+// Purpose: Register a radar contact in the list of contacts
+//---------------------------------------------------------
+void CHudRadar::AddRadarContact( const Vector &vecOrigin, int iType, float flTimeToLive )
+{
+ if( m_iNumRadarContacts == RADAR_MAX_CONTACTS )
+ return;
+
+ Vector v = vecOrigin;
+ int iExistingContact = FindRadarContact( vecOrigin );
+
+ if( iExistingContact > -1 )
+ {
+ // Just update this contact.
+ m_radarContacts[iExistingContact].m_flTimeToRemove = gpGlobals->curtime + flTimeToLive;
+ return;
+ }
+
+ m_radarContacts[m_iNumRadarContacts].m_vecOrigin = vecOrigin;
+ m_radarContacts[m_iNumRadarContacts].m_iType = iType;
+ m_radarContacts[m_iNumRadarContacts].m_flTimeToRemove = gpGlobals->curtime + flTimeToLive;
+ m_iNumRadarContacts++;
+}
+
+//---------------------------------------------------------
+// Purpose: Search the contact list for a specific contact
+//---------------------------------------------------------
+int CHudRadar::FindRadarContact( const Vector &vecOrigin )
+{
+ for( int i = 0 ; i < m_iNumRadarContacts ; i++ )
+ {
+ if( m_radarContacts[ i ].m_vecOrigin == vecOrigin )
+ return i;
+ }
+
+ return -1;
+}
+
+//---------------------------------------------------------
+// Purpose: Go through all radar targets and see if any
+// have expired. If yes, remove them from the
+// list.
+//---------------------------------------------------------
+void CHudRadar::MaintainRadarContacts()
+{
+ bool bKeepWorking = true;
+ while( bKeepWorking )
+ {
+ bKeepWorking = false;
+ for( int i = 0 ; i < m_iNumRadarContacts ; i++ )
+ {
+ CRadarContact *pContact = &m_radarContacts[ i ];
+ if( gpGlobals->curtime >= pContact->m_flTimeToRemove )
+ {
+ // Time for this guy to go. Easiest thing is just to copy the last element
+ // into this element's spot and then decrement the count of entities.
+ bKeepWorking = true;
+
+ m_radarContacts[ i ] = m_radarContacts[ m_iNumRadarContacts - 1 ];
+ m_iNumRadarContacts--;
+ break;
+ }
+ }
+ }
+}
+
+//---------------------------------------------------------
+//---------------------------------------------------------
+void CHudRadar::SetVisible(bool state)
+{
+ BaseClass::SetVisible(state);
+
+ if( g_pMapOverview && g_pMapOverview->GetMode() == CMapOverview::MAP_MODE_RADAR )
+ {
+ // We are the hud element still, but he is in charge of the new style now.
+ g_pMapOverview->SetVisible( state );
+ }
+}
+
+#define RADAR_BLIP_FADE_TIME 1.0f
+#define RADAR_USE_ICONS 1
+//---------------------------------------------------------
+// Purpose: Draw the radar panel.
+// We're probably doing too much other work in here
+//---------------------------------------------------------
+void CHudRadar::Paint()
+{
+ if (m_iImageID == -1 )
+ {
+ // Set up the image ID's if they've somehow gone bad.
+ m_textureID_IconLambda = vgui::surface()->CreateNewTextureID();
+ vgui::surface()->DrawSetTextureFile( m_textureID_IconLambda, RADAR_CONTACT_LAMBDA_MATERIAL, true, false );
+
+ m_textureID_IconBuster = vgui::surface()->CreateNewTextureID();
+ vgui::surface()->DrawSetTextureFile( m_textureID_IconBuster, RADAR_CONTACT_BUSTER_MATERIAL, true, false );
+
+ m_textureID_IconStrider = vgui::surface()->CreateNewTextureID();
+ vgui::surface()->DrawSetTextureFile( m_textureID_IconStrider, RADAR_CONTACT_STRIDER_MATERIAL, true, false );
+
+ m_textureID_IconDog = vgui::surface()->CreateNewTextureID();
+ vgui::surface()->DrawSetTextureFile( m_textureID_IconDog, RADAR_CONTACT_DOG_MATERIAL, true, false );
+
+ m_textureID_IconBase = vgui::surface()->CreateNewTextureID();
+ vgui::surface()->DrawSetTextureFile( m_textureID_IconBase, RADAR_CONTACT_BASE_MATERIAL, true, false );
+
+ m_iImageID = vgui::surface()->CreateNewTextureID();
+ vgui::surface()->DrawSetTextureFile( m_iImageID, RADAR_PANEL_MATERIAL, true, false );
+ }
+
+ // Draw the radar background.
+ int wide, tall;
+ GetSize(wide, tall);
+ int alpha = 255;
+ vgui::surface()->DrawSetColor(255, 255, 255, alpha);
+ vgui::surface()->DrawSetTexture(m_iImageID);
+ vgui::surface()->DrawTexturedRect(0, 0, wide, tall);
+
+ // Manage the CRT 'ghosting' effect
+ if( gpGlobals->curtime > m_flTimeStartGhosting )
+ {
+ if( m_ghostAlpha < RADAR_MAX_GHOST_ALPHA )
+ {
+ m_ghostAlpha++;
+ }
+ else
+ {
+ m_flTimeStartGhosting = FLT_MAX;
+ m_flTimeStopGhosting = gpGlobals->curtime + RandomFloat( 1.0f, 2.0f );// How long to ghost for
+ }
+ }
+ else if( gpGlobals->curtime > m_flTimeStopGhosting )
+ {
+ // We're supposed to stop ghosting now.
+ if( m_ghostAlpha > 0 )
+ {
+ // Still fading the effects.
+ m_ghostAlpha--;
+ }
+ else
+ {
+ // DONE fading the effects. Now stop ghosting for a short while
+ m_flTimeStartGhosting = gpGlobals->curtime + RandomFloat( 2.0f, 3.0f );// how long between ghosts
+ m_flTimeStopGhosting = FLT_MAX;
+ }
+ }
+
+ // Now go through the list of radar targets and represent them on the radar screen
+ // by drawing their icons on top of the background.
+ C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
+
+ for( int i = 0 ; i < m_iNumRadarContacts ; i++ )
+ {
+ int alpha = 90;
+ CRadarContact *pContact = &m_radarContacts[ i ];
+ float deltaT = pContact->m_flTimeToRemove - gpGlobals->curtime;
+ if ( deltaT < RADAR_BLIP_FADE_TIME )
+ {
+ float factor = deltaT / RADAR_BLIP_FADE_TIME;
+
+ alpha = (int) ( ((float)alpha) * factor );
+
+ if( alpha < 10 )
+ alpha = 10;
+ }
+
+ if( RADAR_USE_ICONS )
+ {
+ int flicker = RandomInt( 0, 30 );
+ DrawIconOnRadar( pContact->m_vecOrigin, pLocalPlayer, pContact->m_iType, RADAR_IGNORE_Z, 255, 255, 255, alpha + flicker );
+ }
+ else
+ {
+ DrawPositionOnRadar( pContact->m_vecOrigin, pLocalPlayer, pContact->m_iType, RADAR_IGNORE_Z, 255, 255, 255, alpha );
+ }
+ }
+
+ MaintainRadarContacts();
+}
+
+ConVar radar_range("radar_range", "3000" ); // 180 feet
+//---------------------------------------------------------
+// Scale maps the distance of the target from the radar
+// source.
+//
+// 1.0 = target at or beyond radar range.
+// 0.5 = target at (radar_range * 0.5) units distance
+// 0.25 = target at (radar_range * 0.25) units distance
+// -etc-
+//---------------------------------------------------------
+bool CHudRadar::WorldToRadar( const Vector location, const Vector origin, const QAngle angles, float &x, float &y, float &z_delta, float &scale )
+{
+ bool bInRange = true;
+
+ float x_diff = location.x - origin.x;
+ float y_diff = location.y - origin.y;
+
+ // Supply epsilon values to avoid divide-by-zero
+ if(x_diff == 0)
+ x_diff = 0.00001f;
+
+ if(y_diff == 0)
+ y_diff = 0.00001f;
+
+ int iRadarRadius = GetWide(); //width of the panel
+ float fRange = radar_range.GetFloat();
+
+ // This magic /2.15 makes the radar scale seem smaller than the VGUI panel so the icons clamp
+ // to the outer ring in the radar graphic, not the very edge of the panel itself.
+ float fScale = (iRadarRadius/2.15f) / fRange;
+
+ float flOffset = atan(y_diff/x_diff);
+ flOffset *= 180;
+ flOffset /= M_PI;
+
+ if ((x_diff < 0) && (y_diff >= 0))
+ flOffset = 180 + flOffset;
+ else if ((x_diff < 0) && (y_diff < 0))
+ flOffset = 180 + flOffset;
+ else if ((x_diff >= 0) && (y_diff < 0))
+ flOffset = 360 + flOffset;
+
+ y_diff = -1*(sqrt((x_diff)*(x_diff) + (y_diff)*(y_diff)));
+ x_diff = 0;
+
+ flOffset = angles.y - flOffset;
+
+ flOffset *= M_PI;
+ flOffset /= 180; // now theta is in radians
+
+ // Transform relative to radar source
+ float xnew_diff = x_diff * cos(flOffset) - y_diff * sin(flOffset);
+ float ynew_diff = x_diff * sin(flOffset) + y_diff * cos(flOffset);
+
+ if ( (-1 * y_diff) > fRange )
+ {
+ float flScale;
+
+ flScale = ( -1 * y_diff) / fRange;
+
+ xnew_diff /= (flScale);
+ ynew_diff /= (flScale);
+
+ bInRange = false;
+
+ scale = 1.0f;
+ }
+ else
+ {
+ // scale
+ float flDist = sqrt( ((xnew_diff)*(xnew_diff) + (ynew_diff)*(ynew_diff)) );
+ scale = flDist / fRange;
+ }
+
+
+ // Scale the dot's position to match radar scale
+ xnew_diff *= fScale;
+ ynew_diff *= fScale;
+
+ // Translate to screen coordinates
+ x = (iRadarRadius/2) + (int)xnew_diff;
+ y = (iRadarRadius/2) + (int)ynew_diff;
+ z_delta = 0.0f;
+
+ return bInRange;
+}
+
+void CHudRadar::DrawPositionOnRadar( Vector vecPos, C_BasePlayer *pLocalPlayer, int type, int flags, int r, int g, int b, int a )
+{
+ float x, y, z_delta;
+ int iBaseDotSize = 3;
+
+ QAngle viewAngle = pLocalPlayer->EyeAngles();
+
+ if( m_pVehicle != NULL )
+ {
+ viewAngle = m_pVehicle->GetAbsAngles();
+ viewAngle.y += 90.0f;
+ }
+
+ float flScale;
+
+ WorldToRadar( vecPos, pLocalPlayer->GetAbsOrigin(), viewAngle, x, y, z_delta, flScale );
+
+ if( flags & RADAR_IGNORE_Z )
+ z_delta = 0;
+
+ switch( type )
+ {
+ case RADAR_CONTACT_GENERIC:
+ r = 255; g = 170; b = 0;
+ iBaseDotSize *= 2;
+ break;
+ case RADAR_CONTACT_MAGNUSSEN_RDU:
+ r = 0; g = 200; b = 255;
+ iBaseDotSize *= 2;
+ break;
+ case RADAR_CONTACT_ENEMY:
+ r = 255; g = 0; b = 0;
+ iBaseDotSize *= 2;
+ break;
+ case RADAR_CONTACT_LARGE_ENEMY:
+ r = 255; g = 0; b = 0;
+ iBaseDotSize *= 3;
+ break;
+ }
+
+ DrawRadarDot( x, y, z_delta, iBaseDotSize, flags, r, g, b, a );
+}
+
+//---------------------------------------------------------
+// Purpose: Compute the proper position on the radar screen
+// for this object's position relative to the player.
+// Then draw the icon in the proper location on the
+// radar screen.
+//---------------------------------------------------------
+#define RADAR_ICON_MIN_SCALE 0.75f
+#define RADAR_ICON_MAX_SCALE 1.0f
+void CHudRadar::DrawIconOnRadar( Vector vecPos, C_BasePlayer *pLocalPlayer, int type, int flags, int r, int g, int b, int a )
+{
+ float x, y, z_delta;
+ int wide, tall;
+
+ // for 'ghosting' CRT effects:
+ int xmod;
+ int ymod;
+ int xoffset;
+ int yoffset;
+
+ // Assume we're going to use the player's location and orientation
+ QAngle viewAngle = pLocalPlayer->EyeAngles();
+ Vector viewOrigin = pLocalPlayer->GetAbsOrigin();
+
+ // However, happily use those of the vehicle if available!
+ if( m_pVehicle != NULL )
+ {
+ viewAngle = m_pVehicle->GetAbsAngles();
+ viewAngle.y += 90.0f;
+ viewOrigin = m_pVehicle->WorldSpaceCenter();
+ }
+
+ float flScale;
+
+ WorldToRadar( vecPos, viewOrigin, viewAngle, x, y, z_delta, flScale );
+
+ flScale = RemapVal( flScale, 1.0f, 0.0f, RADAR_ICON_MIN_SCALE, RADAR_ICON_MAX_SCALE );
+
+ // Get the correct icon for this type of contact
+ int iTextureID_Icon = -1;
+
+ switch( type )
+ {
+ case RADAR_CONTACT_GENERIC:
+ iTextureID_Icon = m_textureID_IconLambda;
+ break;
+ case RADAR_CONTACT_MAGNUSSEN_RDU:
+ iTextureID_Icon = m_textureID_IconBuster;
+ break;
+ case RADAR_CONTACT_LARGE_ENEMY:
+ case RADAR_CONTACT_ENEMY:
+ iTextureID_Icon = m_textureID_IconStrider;
+ break;
+ case RADAR_CONTACT_DOG:
+ iTextureID_Icon = m_textureID_IconDog;
+ break;
+ case RADAR_CONTACT_ALLY_INSTALLATION:
+ iTextureID_Icon = m_textureID_IconBase;
+ break;
+ default:
+ return;
+ break;
+ }
+
+ vgui::surface()->DrawSetColor( r, g, b, a );
+ vgui::surface()->DrawSetTexture( iTextureID_Icon );
+ vgui::surface()->DrawGetTextureSize( iTextureID_Icon, wide, tall );
+
+ wide = ( int((float)wide * flScale) );
+ tall = ( int((float)tall * flScale) );
+
+ if( type == RADAR_CONTACT_LARGE_ENEMY )
+ {
+ wide *= 2;
+ tall *= 2;
+ }
+
+ // Center the icon around its position.
+ x -= (wide >> 1);
+ y -= (tall >> 1);
+
+ vgui::surface()->DrawTexturedRect(x, y, x+wide, y+tall);
+
+ // Draw the crt 'ghost' if the icon is not pegged to the outer rim
+ if( flScale > RADAR_ICON_MIN_SCALE && m_ghostAlpha > 0 )
+ {
+ vgui::surface()->DrawSetColor( r, g, b, m_ghostAlpha );
+ xmod = RandomInt( 1, 4 );
+ ymod = RandomInt( 1, 4 );
+ xoffset = RandomInt( -1, 1 );
+ yoffset = RandomInt( -1, 1 );
+ x -= (xmod - xoffset);
+ y -= (ymod - yoffset);
+ wide += (xmod + xoffset);
+ tall += (ymod + yoffset);
+ vgui::surface()->DrawTexturedRect(x, y, x+wide, y+tall);
+ }
+}
+
+void CHudRadar::FillRect( int x, int y, int w, int h )
+{
+ int panel_x, panel_y, panel_w, panel_h;
+ GetBounds( panel_x, panel_y, panel_w, panel_h );
+ vgui::surface()->DrawFilledRect( x, y, x+w, y+h );
+}
+
+void CHudRadar::DrawRadarDot( int x, int y, float z_diff, int iBaseDotSize, int flags, int r, int g, int b, int a )
+{
+ vgui::surface()->DrawSetColor( r, g, b, a );
+
+ if ( z_diff < -128 ) // below the player
+ {
+ z_diff *= -1;
+
+ if ( z_diff > 3096 )
+ {
+ z_diff = 3096;
+ }
+
+ int iBar = (int)( z_diff / 400 ) + 2;
+
+ // Draw an upside-down T shape to symbolize the dot is below the player.
+
+ iBaseDotSize /= 2;
+
+ //horiz
+ FillRect( x-(2*iBaseDotSize), y, 5*iBaseDotSize, iBaseDotSize );
+
+ //vert
+ FillRect( x, y - iBar*iBaseDotSize, iBaseDotSize, iBar*iBaseDotSize );
+ }
+ else if ( z_diff > 128 ) // above the player
+ {
+ if ( z_diff > 3096 )
+ {
+ z_diff = 3096;
+ }
+
+ int iBar = (int)( z_diff / 400 ) + 2;
+
+ iBaseDotSize /= 2;
+
+ // Draw a T shape to symbolize the dot is above the player.
+
+ //horiz
+ FillRect( x-(2*iBaseDotSize), y, 5*iBaseDotSize, iBaseDotSize );
+
+ //vert
+ FillRect( x, y, iBaseDotSize, iBar*iBaseDotSize );
+ }
+ else
+ {
+ FillRect( x, y, iBaseDotSize, iBaseDotSize );
+ }
+}
diff --git a/mp/src/game/client/hl2/hud_radar.h b/mp/src/game/client/hl2/hud_radar.h
index 408abfa0..81134cae 100644
--- a/mp/src/game/client/hl2/hud_radar.h
+++ b/mp/src/game/client/hl2/hud_radar.h
@@ -1,78 +1,78 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#ifndef HUD_RADAR_H
-#define HUD_RADAR_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include <vgui_controls/Panel.h>
-#include <vgui_controls/Label.h>
-#include "hl2_vehicle_radar.h"
-#include "c_vguiscreen.h"
-
-class CRadarContact
-{
-public:
- Vector m_vecOrigin;
- int m_iType;
- float m_flTimeToRemove;
-};
-
-class CHudRadar : public CVGuiScreenPanel
-{
-public:
- DECLARE_CLASS_SIMPLE( CHudRadar, CVGuiScreenPanel );
-
-
- CHudRadar( vgui::Panel *parent, const char *panelName );
- ~CHudRadar();
-
- virtual void Paint();
- void VidInit(void);
- virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
- virtual void SetVisible(bool state);
-
- void MsgFunc_UpdateRadar(bf_read &msg );
- void SetVehicle( C_BaseEntity *pVehicle ) { m_pVehicle = pVehicle; }
-
- void AddRadarContact( const Vector &vecOrigin, int iType, float flTimeToLive );
- int FindRadarContact( const Vector &vecOrigin );
- void MaintainRadarContacts();
-
-
- void ClearAllRadarContacts() { m_iNumRadarContacts = 0; }
-
-public:
- bool m_bUseFastUpdate;
- int m_ghostAlpha; // How intense the alpha channel is for CRT ghosts
- float m_flTimeStopGhosting;
- float m_flTimeStartGhosting;
-
-private:
-
- bool WorldToRadar( const Vector location, const Vector origin, const QAngle angles, float &x, float &y, float &z_delta, float &scale );
-
- void DrawPositionOnRadar( Vector vecPos, C_BasePlayer *pLocalPlayer, int type, int flags, int r, int g, int b, int a );
- void DrawIconOnRadar( Vector vecPos, C_BasePlayer *pLocalPlayer, int type, int flags, int r, int g, int b, int a );
-
- void FillRect( int x, int y, int w, int h );
- void DrawRadarDot( int x, int y, float z_diff, int iBaseDotSize, int flags, int r, int g, int b, int a );
-
- CRadarContact m_radarContacts[RADAR_MAX_CONTACTS];
- int m_iNumRadarContacts;
- C_BaseEntity *m_pVehicle;
- int m_iImageID;
- int m_textureID_IconLambda;
- int m_textureID_IconBuster;
- int m_textureID_IconStrider;
- int m_textureID_IconDog;
- int m_textureID_IconBase;
-};
-
-extern CHudRadar *GetHudRadar();
-#endif // HUD_RADAR_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef HUD_RADAR_H
+#define HUD_RADAR_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <vgui_controls/Panel.h>
+#include <vgui_controls/Label.h>
+#include "hl2_vehicle_radar.h"
+#include "c_vguiscreen.h"
+
+class CRadarContact
+{
+public:
+ Vector m_vecOrigin;
+ int m_iType;
+ float m_flTimeToRemove;
+};
+
+class CHudRadar : public CVGuiScreenPanel
+{
+public:
+ DECLARE_CLASS_SIMPLE( CHudRadar, CVGuiScreenPanel );
+
+
+ CHudRadar( vgui::Panel *parent, const char *panelName );
+ ~CHudRadar();
+
+ virtual void Paint();
+ void VidInit(void);
+ virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
+ virtual void SetVisible(bool state);
+
+ void MsgFunc_UpdateRadar(bf_read &msg );
+ void SetVehicle( C_BaseEntity *pVehicle ) { m_pVehicle = pVehicle; }
+
+ void AddRadarContact( const Vector &vecOrigin, int iType, float flTimeToLive );
+ int FindRadarContact( const Vector &vecOrigin );
+ void MaintainRadarContacts();
+
+
+ void ClearAllRadarContacts() { m_iNumRadarContacts = 0; }
+
+public:
+ bool m_bUseFastUpdate;
+ int m_ghostAlpha; // How intense the alpha channel is for CRT ghosts
+ float m_flTimeStopGhosting;
+ float m_flTimeStartGhosting;
+
+private:
+
+ bool WorldToRadar( const Vector location, const Vector origin, const QAngle angles, float &x, float &y, float &z_delta, float &scale );
+
+ void DrawPositionOnRadar( Vector vecPos, C_BasePlayer *pLocalPlayer, int type, int flags, int r, int g, int b, int a );
+ void DrawIconOnRadar( Vector vecPos, C_BasePlayer *pLocalPlayer, int type, int flags, int r, int g, int b, int a );
+
+ void FillRect( int x, int y, int w, int h );
+ void DrawRadarDot( int x, int y, float z_diff, int iBaseDotSize, int flags, int r, int g, int b, int a );
+
+ CRadarContact m_radarContacts[RADAR_MAX_CONTACTS];
+ int m_iNumRadarContacts;
+ C_BaseEntity *m_pVehicle;
+ int m_iImageID;
+ int m_textureID_IconLambda;
+ int m_textureID_IconBuster;
+ int m_textureID_IconStrider;
+ int m_textureID_IconDog;
+ int m_textureID_IconBase;
+};
+
+extern CHudRadar *GetHudRadar();
+#endif // HUD_RADAR_H
diff --git a/mp/src/game/client/hl2/hud_suitpower.cpp b/mp/src/game/client/hl2/hud_suitpower.cpp
index f6745ab4..416c9300 100644
--- a/mp/src/game/client/hl2/hud_suitpower.cpp
+++ b/mp/src/game/client/hl2/hud_suitpower.cpp
@@ -1,257 +1,257 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#include "cbase.h"
-#include "hud.h"
-#include "hud_suitpower.h"
-#include "hud_macros.h"
-#include "c_basehlplayer.h"
-#include "iclientmode.h"
-#include <vgui_controls/AnimationController.h>
-#include <vgui/ISurface.h>
-#include <vgui/ILocalize.h>
-
-using namespace vgui;
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-DECLARE_HUDELEMENT( CHudSuitPower );
-
-#define SUITPOWER_INIT -1
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CHudSuitPower::CHudSuitPower( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudSuitPower" )
-{
- vgui::Panel *pParent = g_pClientMode->GetViewport();
- SetParent( pParent );
-
- SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudSuitPower::Init( void )
-{
- m_flSuitPower = SUITPOWER_INIT;
- m_nSuitPowerLow = -1;
- m_iActiveSuitDevices = 0;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudSuitPower::Reset( void )
-{
- Init();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Save CPU cycles by letting the HUD system early cull
-// costly traversal. Called per frame, return true if thinking and
-// painting need to occur.
-//-----------------------------------------------------------------------------
-bool CHudSuitPower::ShouldDraw()
-{
- bool bNeedsDraw = false;
-
- C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
- if ( !pPlayer )
- return false;
-
- // needs draw if suit power changed or animation in progress
- bNeedsDraw = ( ( pPlayer->m_HL2Local.m_flSuitPower != m_flSuitPower ) || ( m_AuxPowerColor[3] > 0 ) );
-
- return ( bNeedsDraw && CHudElement::ShouldDraw() );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudSuitPower::OnThink( void )
-{
- float flCurrentPower = 0;
- C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
- if ( !pPlayer )
- return;
-
- flCurrentPower = pPlayer->m_HL2Local.m_flSuitPower;
-
- // Only update if we've changed suit power
- if ( flCurrentPower == m_flSuitPower )
- return;
-
- if ( flCurrentPower >= 100.0f && m_flSuitPower < 100.0f )
- {
- // we've reached max power
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerMax");
- }
- else if ( flCurrentPower < 100.0f && (m_flSuitPower >= 100.0f || m_flSuitPower == SUITPOWER_INIT) )
- {
- // we've lost power
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerNotMax");
- }
-
- bool flashlightActive = pPlayer->IsFlashlightActive();
- bool sprintActive = pPlayer->IsSprinting();
- bool breatherActive = pPlayer->IsBreatherActive();
- int activeDevices = (int)flashlightActive + (int)sprintActive + (int)breatherActive;
-
- if (activeDevices != m_iActiveSuitDevices)
- {
- m_iActiveSuitDevices = activeDevices;
-
- switch ( m_iActiveSuitDevices )
- {
- default:
- case 3:
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerThreeItemsActive");
- break;
- case 2:
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerTwoItemsActive");
- break;
- case 1:
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerOneItemActive");
- break;
- case 0:
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerNoItemsActive");
- break;
- }
- }
-
- m_flSuitPower = flCurrentPower;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: draws the power bar
-//-----------------------------------------------------------------------------
-void CHudSuitPower::Paint()
-{
- C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
- if ( !pPlayer )
- return;
-
- // get bar chunks
- int chunkCount = m_flBarWidth / (m_flBarChunkWidth + m_flBarChunkGap);
- int enabledChunks = (int)((float)chunkCount * (m_flSuitPower * 1.0f/100.0f) + 0.5f );
-
- // see if we've changed power state
- int lowPower = 0;
- if (enabledChunks <= (chunkCount / 4))
- {
- lowPower = 1;
- }
- if (m_nSuitPowerLow != lowPower)
- {
- if (m_iActiveSuitDevices || m_flSuitPower < 100.0f)
- {
- if (lowPower)
- {
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerDecreasedBelow25");
- }
- else
- {
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerIncreasedAbove25");
- }
- m_nSuitPowerLow = lowPower;
- }
- }
-
- // draw the suit power bar
- surface()->DrawSetColor( m_AuxPowerColor );
- int xpos = m_flBarInsetX, ypos = m_flBarInsetY;
- for (int i = 0; i < enabledChunks; i++)
- {
- surface()->DrawFilledRect( xpos, ypos, xpos + m_flBarChunkWidth, ypos + m_flBarHeight );
- xpos += (m_flBarChunkWidth + m_flBarChunkGap);
- }
- // draw the exhausted portion of the bar.
- surface()->DrawSetColor( Color( m_AuxPowerColor[0], m_AuxPowerColor[1], m_AuxPowerColor[2], m_iAuxPowerDisabledAlpha ) );
- for (int i = enabledChunks; i < chunkCount; i++)
- {
- surface()->DrawFilledRect( xpos, ypos, xpos + m_flBarChunkWidth, ypos + m_flBarHeight );
- xpos += (m_flBarChunkWidth + m_flBarChunkGap);
- }
-
- // draw our name
- surface()->DrawSetTextFont(m_hTextFont);
- surface()->DrawSetTextColor(m_AuxPowerColor);
- surface()->DrawSetTextPos(text_xpos, text_ypos);
-
- wchar_t *tempString = g_pVGuiLocalize->Find("#Valve_Hud_AUX_POWER");
-
- if (tempString)
- {
- surface()->DrawPrintText(tempString, wcslen(tempString));
- }
- else
- {
- surface()->DrawPrintText(L"AUX POWER", wcslen(L"AUX POWER"));
- }
-
- if ( m_iActiveSuitDevices )
- {
- // draw the additional text
- int ypos = text2_ypos;
-
- if (pPlayer->IsBreatherActive())
- {
- tempString = g_pVGuiLocalize->Find("#Valve_Hud_OXYGEN");
-
- surface()->DrawSetTextPos(text2_xpos, ypos);
-
- if (tempString)
- {
- surface()->DrawPrintText(tempString, wcslen(tempString));
- }
- else
- {
- surface()->DrawPrintText(L"OXYGEN", wcslen(L"OXYGEN"));
- }
- ypos += text2_gap;
- }
-
- if (pPlayer->IsFlashlightActive())
- {
- tempString = g_pVGuiLocalize->Find("#Valve_Hud_FLASHLIGHT");
-
- surface()->DrawSetTextPos(text2_xpos, ypos);
-
- if (tempString)
- {
- surface()->DrawPrintText(tempString, wcslen(tempString));
- }
- else
- {
- surface()->DrawPrintText(L"FLASHLIGHT", wcslen(L"FLASHLIGHT"));
- }
- ypos += text2_gap;
- }
-
- if (pPlayer->IsSprinting())
- {
- tempString = g_pVGuiLocalize->Find("#Valve_Hud_SPRINT");
-
- surface()->DrawSetTextPos(text2_xpos, ypos);
-
- if (tempString)
- {
- surface()->DrawPrintText(tempString, wcslen(tempString));
- }
- else
- {
- surface()->DrawPrintText(L"SPRINT", wcslen(L"SPRINT"));
- }
- ypos += text2_gap;
- }
- }
-}
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "hud.h"
+#include "hud_suitpower.h"
+#include "hud_macros.h"
+#include "c_basehlplayer.h"
+#include "iclientmode.h"
+#include <vgui_controls/AnimationController.h>
+#include <vgui/ISurface.h>
+#include <vgui/ILocalize.h>
+
+using namespace vgui;
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+DECLARE_HUDELEMENT( CHudSuitPower );
+
+#define SUITPOWER_INIT -1
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CHudSuitPower::CHudSuitPower( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudSuitPower" )
+{
+ vgui::Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+
+ SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudSuitPower::Init( void )
+{
+ m_flSuitPower = SUITPOWER_INIT;
+ m_nSuitPowerLow = -1;
+ m_iActiveSuitDevices = 0;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudSuitPower::Reset( void )
+{
+ Init();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Save CPU cycles by letting the HUD system early cull
+// costly traversal. Called per frame, return true if thinking and
+// painting need to occur.
+//-----------------------------------------------------------------------------
+bool CHudSuitPower::ShouldDraw()
+{
+ bool bNeedsDraw = false;
+
+ C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return false;
+
+ // needs draw if suit power changed or animation in progress
+ bNeedsDraw = ( ( pPlayer->m_HL2Local.m_flSuitPower != m_flSuitPower ) || ( m_AuxPowerColor[3] > 0 ) );
+
+ return ( bNeedsDraw && CHudElement::ShouldDraw() );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudSuitPower::OnThink( void )
+{
+ float flCurrentPower = 0;
+ C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ flCurrentPower = pPlayer->m_HL2Local.m_flSuitPower;
+
+ // Only update if we've changed suit power
+ if ( flCurrentPower == m_flSuitPower )
+ return;
+
+ if ( flCurrentPower >= 100.0f && m_flSuitPower < 100.0f )
+ {
+ // we've reached max power
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerMax");
+ }
+ else if ( flCurrentPower < 100.0f && (m_flSuitPower >= 100.0f || m_flSuitPower == SUITPOWER_INIT) )
+ {
+ // we've lost power
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerNotMax");
+ }
+
+ bool flashlightActive = pPlayer->IsFlashlightActive();
+ bool sprintActive = pPlayer->IsSprinting();
+ bool breatherActive = pPlayer->IsBreatherActive();
+ int activeDevices = (int)flashlightActive + (int)sprintActive + (int)breatherActive;
+
+ if (activeDevices != m_iActiveSuitDevices)
+ {
+ m_iActiveSuitDevices = activeDevices;
+
+ switch ( m_iActiveSuitDevices )
+ {
+ default:
+ case 3:
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerThreeItemsActive");
+ break;
+ case 2:
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerTwoItemsActive");
+ break;
+ case 1:
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerOneItemActive");
+ break;
+ case 0:
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerNoItemsActive");
+ break;
+ }
+ }
+
+ m_flSuitPower = flCurrentPower;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: draws the power bar
+//-----------------------------------------------------------------------------
+void CHudSuitPower::Paint()
+{
+ C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ // get bar chunks
+ int chunkCount = m_flBarWidth / (m_flBarChunkWidth + m_flBarChunkGap);
+ int enabledChunks = (int)((float)chunkCount * (m_flSuitPower * 1.0f/100.0f) + 0.5f );
+
+ // see if we've changed power state
+ int lowPower = 0;
+ if (enabledChunks <= (chunkCount / 4))
+ {
+ lowPower = 1;
+ }
+ if (m_nSuitPowerLow != lowPower)
+ {
+ if (m_iActiveSuitDevices || m_flSuitPower < 100.0f)
+ {
+ if (lowPower)
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerDecreasedBelow25");
+ }
+ else
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerIncreasedAbove25");
+ }
+ m_nSuitPowerLow = lowPower;
+ }
+ }
+
+ // draw the suit power bar
+ surface()->DrawSetColor( m_AuxPowerColor );
+ int xpos = m_flBarInsetX, ypos = m_flBarInsetY;
+ for (int i = 0; i < enabledChunks; i++)
+ {
+ surface()->DrawFilledRect( xpos, ypos, xpos + m_flBarChunkWidth, ypos + m_flBarHeight );
+ xpos += (m_flBarChunkWidth + m_flBarChunkGap);
+ }
+ // draw the exhausted portion of the bar.
+ surface()->DrawSetColor( Color( m_AuxPowerColor[0], m_AuxPowerColor[1], m_AuxPowerColor[2], m_iAuxPowerDisabledAlpha ) );
+ for (int i = enabledChunks; i < chunkCount; i++)
+ {
+ surface()->DrawFilledRect( xpos, ypos, xpos + m_flBarChunkWidth, ypos + m_flBarHeight );
+ xpos += (m_flBarChunkWidth + m_flBarChunkGap);
+ }
+
+ // draw our name
+ surface()->DrawSetTextFont(m_hTextFont);
+ surface()->DrawSetTextColor(m_AuxPowerColor);
+ surface()->DrawSetTextPos(text_xpos, text_ypos);
+
+ wchar_t *tempString = g_pVGuiLocalize->Find("#Valve_Hud_AUX_POWER");
+
+ if (tempString)
+ {
+ surface()->DrawPrintText(tempString, wcslen(tempString));
+ }
+ else
+ {
+ surface()->DrawPrintText(L"AUX POWER", wcslen(L"AUX POWER"));
+ }
+
+ if ( m_iActiveSuitDevices )
+ {
+ // draw the additional text
+ int ypos = text2_ypos;
+
+ if (pPlayer->IsBreatherActive())
+ {
+ tempString = g_pVGuiLocalize->Find("#Valve_Hud_OXYGEN");
+
+ surface()->DrawSetTextPos(text2_xpos, ypos);
+
+ if (tempString)
+ {
+ surface()->DrawPrintText(tempString, wcslen(tempString));
+ }
+ else
+ {
+ surface()->DrawPrintText(L"OXYGEN", wcslen(L"OXYGEN"));
+ }
+ ypos += text2_gap;
+ }
+
+ if (pPlayer->IsFlashlightActive())
+ {
+ tempString = g_pVGuiLocalize->Find("#Valve_Hud_FLASHLIGHT");
+
+ surface()->DrawSetTextPos(text2_xpos, ypos);
+
+ if (tempString)
+ {
+ surface()->DrawPrintText(tempString, wcslen(tempString));
+ }
+ else
+ {
+ surface()->DrawPrintText(L"FLASHLIGHT", wcslen(L"FLASHLIGHT"));
+ }
+ ypos += text2_gap;
+ }
+
+ if (pPlayer->IsSprinting())
+ {
+ tempString = g_pVGuiLocalize->Find("#Valve_Hud_SPRINT");
+
+ surface()->DrawSetTextPos(text2_xpos, ypos);
+
+ if (tempString)
+ {
+ surface()->DrawPrintText(tempString, wcslen(tempString));
+ }
+ else
+ {
+ surface()->DrawPrintText(L"SPRINT", wcslen(L"SPRINT"));
+ }
+ ypos += text2_gap;
+ }
+ }
+}
+
+
diff --git a/mp/src/game/client/hl2/hud_suitpower.h b/mp/src/game/client/hl2/hud_suitpower.h
index a7ea69cc..83af2be1 100644
--- a/mp/src/game/client/hl2/hud_suitpower.h
+++ b/mp/src/game/client/hl2/hud_suitpower.h
@@ -1,57 +1,57 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#if !defined( HUD_SUITPOWER_H )
-#define HUD_SUITPOWER_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "hudelement.h"
-#include "hud_numericdisplay.h"
-#include <vgui_controls/Panel.h>
-
-//-----------------------------------------------------------------------------
-// Purpose: Shows the sprint power bar
-//-----------------------------------------------------------------------------
-class CHudSuitPower : public CHudElement, public vgui::Panel
-{
- DECLARE_CLASS_SIMPLE( CHudSuitPower, vgui::Panel );
-
-public:
- CHudSuitPower( const char *pElementName );
- virtual void Init( void );
- virtual void Reset( void );
- virtual void OnThink( void );
- bool ShouldDraw( void );
-
-protected:
- virtual void Paint();
-
-private:
- CPanelAnimationVar( Color, m_AuxPowerColor, "AuxPowerColor", "255 0 0 255" );
- CPanelAnimationVar( int, m_iAuxPowerDisabledAlpha, "AuxPowerDisabledAlpha", "70" );
-
- CPanelAnimationVarAliasType( float, m_flBarInsetX, "BarInsetX", "8", "proportional_float" );
- CPanelAnimationVarAliasType( float, m_flBarInsetY, "BarInsetY", "8", "proportional_float" );
- CPanelAnimationVarAliasType( float, m_flBarWidth, "BarWidth", "80", "proportional_float" );
- CPanelAnimationVarAliasType( float, m_flBarHeight, "BarHeight", "10", "proportional_float" );
- CPanelAnimationVarAliasType( float, m_flBarChunkWidth, "BarChunkWidth", "10", "proportional_float" );
- CPanelAnimationVarAliasType( float, m_flBarChunkGap, "BarChunkGap", "2", "proportional_float" );
-
- CPanelAnimationVar( vgui::HFont, m_hTextFont, "TextFont", "Default" );
- CPanelAnimationVarAliasType( float, text_xpos, "text_xpos", "8", "proportional_float" );
- CPanelAnimationVarAliasType( float, text_ypos, "text_ypos", "20", "proportional_float" );
- CPanelAnimationVarAliasType( float, text2_xpos, "text2_xpos", "8", "proportional_float" );
- CPanelAnimationVarAliasType( float, text2_ypos, "text2_ypos", "40", "proportional_float" );
- CPanelAnimationVarAliasType( float, text2_gap, "text2_gap", "10", "proportional_float" );
-
- float m_flSuitPower;
- int m_nSuitPowerLow;
- int m_iActiveSuitDevices;
-};
-
-#endif // HUD_SUITPOWER_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#if !defined( HUD_SUITPOWER_H )
+#define HUD_SUITPOWER_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "hudelement.h"
+#include "hud_numericdisplay.h"
+#include <vgui_controls/Panel.h>
+
+//-----------------------------------------------------------------------------
+// Purpose: Shows the sprint power bar
+//-----------------------------------------------------------------------------
+class CHudSuitPower : public CHudElement, public vgui::Panel
+{
+ DECLARE_CLASS_SIMPLE( CHudSuitPower, vgui::Panel );
+
+public:
+ CHudSuitPower( const char *pElementName );
+ virtual void Init( void );
+ virtual void Reset( void );
+ virtual void OnThink( void );
+ bool ShouldDraw( void );
+
+protected:
+ virtual void Paint();
+
+private:
+ CPanelAnimationVar( Color, m_AuxPowerColor, "AuxPowerColor", "255 0 0 255" );
+ CPanelAnimationVar( int, m_iAuxPowerDisabledAlpha, "AuxPowerDisabledAlpha", "70" );
+
+ CPanelAnimationVarAliasType( float, m_flBarInsetX, "BarInsetX", "8", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flBarInsetY, "BarInsetY", "8", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flBarWidth, "BarWidth", "80", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flBarHeight, "BarHeight", "10", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flBarChunkWidth, "BarChunkWidth", "10", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flBarChunkGap, "BarChunkGap", "2", "proportional_float" );
+
+ CPanelAnimationVar( vgui::HFont, m_hTextFont, "TextFont", "Default" );
+ CPanelAnimationVarAliasType( float, text_xpos, "text_xpos", "8", "proportional_float" );
+ CPanelAnimationVarAliasType( float, text_ypos, "text_ypos", "20", "proportional_float" );
+ CPanelAnimationVarAliasType( float, text2_xpos, "text2_xpos", "8", "proportional_float" );
+ CPanelAnimationVarAliasType( float, text2_ypos, "text2_ypos", "40", "proportional_float" );
+ CPanelAnimationVarAliasType( float, text2_gap, "text2_gap", "10", "proportional_float" );
+
+ float m_flSuitPower;
+ int m_nSuitPowerLow;
+ int m_iActiveSuitDevices;
+};
+
+#endif // HUD_SUITPOWER_H
diff --git a/mp/src/game/client/hl2/hud_weaponselection.cpp b/mp/src/game/client/hl2/hud_weaponselection.cpp
index c98bb1ca..3d857e99 100644
--- a/mp/src/game/client/hl2/hud_weaponselection.cpp
+++ b/mp/src/game/client/hl2/hud_weaponselection.cpp
@@ -1,1511 +1,1511 @@
-//========= 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 "../hud_crosshair.h"
-
-#include "VGuiMatSurface/IMatSystemSurface.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"
-
-ConVar hud_showemptyweaponslots( "hud_showemptyweaponslots", "1", FCVAR_ARCHIVE, "Shows slots for missing weapons when recieving weapons out of order" );
-
-#define SELECTION_TIMEOUT_THRESHOLD 0.5f // Seconds
-#define SELECTION_FADEOUT_TIME 0.75f
-
-#define PLUS_DISPLAY_TIMEOUT 0.5f // Seconds
-#define PLUS_FADEOUT_TIME 0.75f
-
-#define FASTSWITCH_DISPLAY_TIMEOUT 1.5f
-#define FASTSWITCH_FADEOUT_TIME 1.5f
-
-#define CAROUSEL_SMALL_DISPLAY_ALPHA 200.0f
-#define FASTSWITCH_SMALL_DISPLAY_ALPHA 160.0f
-
-#define MAX_CAROUSEL_SLOTS 5
-
-//-----------------------------------------------------------------------------
-// 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;
- }
-
- virtual void SetWeaponSelected()
- {
- CBaseHudWeaponSelection::SetWeaponSelected();
-
- switch( hud_fastswitch.GetInt() )
- {
- case HUDTYPE_FASTSWITCH:
- case HUDTYPE_CAROUSEL:
- ActivateFastswitchWeaponDisplay( GetSelectedWeapon() );
- break;
- case HUDTYPE_PLUS:
- ActivateWeaponHighlight( GetSelectedWeapon() );
- break;
- default:
- // do nothing
- break;
- }
- }
-
-private:
- C_BaseCombatWeapon *FindNextWeaponInWeaponSelection(int iCurrentSlot, int iCurrentPosition);
- C_BaseCombatWeapon *FindPrevWeaponInWeaponSelection(int iCurrentSlot, int iCurrentPosition);
-
- void DrawLargeWeaponBox( C_BaseCombatWeapon *pWeapon, bool bSelected, int x, int y, int wide, int tall, Color color, float alpha, int number );
- void ActivateFastswitchWeaponDisplay( C_BaseCombatWeapon *pWeapon );
- void ActivateWeaponHighlight( C_BaseCombatWeapon *pWeapon );
- float GetWeaponBoxAlpha( bool bSelected );
- int GetLastPosInSlot( int iSlot ) const;
-
- void FastWeaponSwitch( int iWeaponSlot );
- void PlusTypeFastWeaponSwitch( int iWeaponSlot );
-
- virtual void SetSelectedWeapon( C_BaseCombatWeapon *pWeapon )
- {
- m_hSelectedWeapon = pWeapon;
- }
-
- virtual void SetSelectedSlot( int slot )
- {
- m_iSelectedSlot = slot;
- }
-
- void SetSelectedSlideDir( int dir )
- {
- m_iSelectedSlideDir = dir;
- }
-
- 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" );
- CPanelAnimationVar( float, m_flBlur, "Blur", "0" );
-
- 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_flMediumBoxWide, "MediumBoxWide", "75", "proportional_float" );
- CPanelAnimationVarAliasType( float, m_flMediumBoxTall, "MediumBoxTall", "50", "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", "0" );
- CPanelAnimationVar( float, m_flSelectionAlphaOverride, "SelectionAlpha", "0" );
-
- 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, "SelectedBoxColor", "SelectionSelectedBoxBg" );
- CPanelAnimationVar( Color, m_SelectedFgColor, "SelectedFgColor", "FgColor" );
- CPanelAnimationVar( Color, m_BrightBoxColor, "SelectedFgColor", "BgColor" );
-
- CPanelAnimationVar( float, m_flWeaponPickupGrowTime, "SelectionGrowTime", "0.1" );
-
- CPanelAnimationVar( float, m_flTextScan, "TextScan", "1.0" );
-
- bool m_bFadingOut;
-
- // fastswitch weapon display
- struct WeaponBox_t
- {
- int m_iSlot;
- int m_iSlotPos;
- };
- CUtlVector<WeaponBox_t> m_WeaponBoxes;
- int m_iSelectedWeaponBox;
- int m_iSelectedSlideDir;
- int m_iSelectedBoxPosition;
- int m_iSelectedSlot;
- C_BaseCombatWeapon *m_pLastWeapon;
- CPanelAnimationVar( float, m_flHorizWeaponSelectOffsetPoint, "WeaponBoxOffset", "0" );
-};
-
-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 );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: updates animation status
-//-----------------------------------------------------------------------------
-void CHudWeaponSelection::OnThink( void )
-{
- float flSelectionTimeout = SELECTION_TIMEOUT_THRESHOLD;
- float flSelectionFadeoutTime = SELECTION_FADEOUT_TIME;
- if ( hud_fastswitch.GetBool() )
- {
- flSelectionTimeout = FASTSWITCH_DISPLAY_TIMEOUT;
- flSelectionFadeoutTime = FASTSWITCH_FADEOUT_TIME;
- }
-
- // Time out after awhile of inactivity
- if ( ( gpGlobals->curtime - m_flSelectionTime ) > flSelectionTimeout )
- {
- if (!m_bFadingOut)
- {
- // start fading out
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "FadeOutWeaponSelectionMenu" );
- m_bFadingOut = true;
- }
- else if ( gpGlobals->curtime - m_flSelectionTime > flSelectionTimeout + flSelectionFadeoutTime )
- {
- // 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;
-
- // draw weapon selection a little longer if in fastswitch so we can see what we've selected
- if ( hud_fastswitch.GetBool() && ( gpGlobals->curtime - m_flSelectionTime ) < (FASTSWITCH_DISPLAY_TIMEOUT + FASTSWITCH_FADEOUT_TIME) )
- return true;
-
- return ( m_bSelectionVisible ) ? true : false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudWeaponSelection::LevelInit()
-{
- CHudElement::LevelInit();
-
- m_iSelectedWeaponBox = -1;
- m_iSelectedSlideDir = 0;
- m_pLastWeapon = NULL;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: starts animating the center of the draw point to the newly selected weapon
-//-----------------------------------------------------------------------------
-void CHudWeaponSelection::ActivateFastswitchWeaponDisplay( C_BaseCombatWeapon *pSelectedWeapon )
-{
- C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
- if ( !pPlayer )
- return;
-
- // make sure all our configuration data is read
- MakeReadyForUse();
-
- m_WeaponBoxes.RemoveAll();
- m_iSelectedWeaponBox = 0;
-
- // find out where our selected weapon is in the full list
- int cWeapons = 0;
- int iLastSelectedWeaponBox = -1;
- for ( int i = 0; i < MAX_WEAPON_SLOTS; i++ )
- {
- for (int slotpos = 0; slotpos < MAX_WEAPON_POSITIONS; slotpos++)
- {
- C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( i, slotpos );
- if ( !pWeapon )
- continue;
-
- WeaponBox_t box = { i, slotpos };
- m_WeaponBoxes.AddToTail( box );
-
- if ( pWeapon == pSelectedWeapon )
- {
- m_iSelectedWeaponBox = cWeapons;
- }
- if ( pWeapon == m_pLastWeapon )
- {
- iLastSelectedWeaponBox = cWeapons;
- }
- cWeapons++;
- }
- }
-
- if ( iLastSelectedWeaponBox == -1 )
- {
- // unexpected failure, no last weapon to scroll from, default to snap behavior
- m_pLastWeapon = NULL;
- }
-
- // calculate where we would have to start drawing for this weapon to slide into center
- float flStart, flStop, flTime;
- if ( !m_pLastWeapon || m_iSelectedSlideDir == 0 || m_flHorizWeaponSelectOffsetPoint != 0 )
- {
- // no previous weapon or weapon selected directly or selection during slide, snap to exact position
- m_pLastWeapon = pSelectedWeapon;
- flStart = flStop = flTime = 0;
- }
- else
- {
- // offset display for a scroll
- // causing selected weapon to slide into position
- // scroll direction based on user's "previous" or "next" selection
- int numIcons = 0;
- int start = iLastSelectedWeaponBox;
- for (int i=0; i<cWeapons; i++)
- {
- // count icons in direction of slide to destination
- if ( start == m_iSelectedWeaponBox )
- break;
- if ( m_iSelectedSlideDir < 0 )
- {
- start--;
- }
- else
- {
- start++;
- }
- // handle wraparound in either direction
- start = ( start + cWeapons ) % cWeapons;
- numIcons++;
- }
-
- flStart = numIcons * (m_flLargeBoxWide + m_flBoxGap);
- if ( m_iSelectedSlideDir < 0 )
- flStart *= -1;
- flStop = 0;
-
- // shorten duration for scrolling when desired weapon is farther away
- // otherwise a large skip in the same duration causes the scroll to fly too fast
- flTime = numIcons * 0.20f;
- if ( numIcons > 1 )
- flTime *= 0.5f;
- }
- m_flHorizWeaponSelectOffsetPoint = flStart;
- g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( this, "WeaponBoxOffset", flStop, 0, flTime, AnimationController::INTERPOLATOR_LINEAR );
-
- // start the highlight after the scroll completes
- m_flBlur = 7.f;
- g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( this, "Blur", 0, flTime, 0.75f, AnimationController::INTERPOLATOR_DEACCEL );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: starts animating the highlight for the selected weapon
-//-----------------------------------------------------------------------------
-void CHudWeaponSelection::ActivateWeaponHighlight( C_BaseCombatWeapon *pSelectedWeapon )
-{
- C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
- if ( !pPlayer )
- return;
-
- // make sure all our configuration data is read
- MakeReadyForUse();
-
- C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( m_iSelectedSlot, m_iSelectedBoxPosition );
- if ( !pWeapon )
- return;
-
- // start the highlight after the scroll completes
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "WeaponHighlight" );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: returns an (per frame animating) alpha value for different weapon boxes
-//-----------------------------------------------------------------------------
-float CHudWeaponSelection::GetWeaponBoxAlpha( bool bSelected )
-{
- float alpha;
- if ( bSelected )
- {
- alpha = m_flSelectionAlphaOverride;
- }
- else
- {
- alpha = m_flSelectionAlphaOverride * (m_flAlphaOverride / 255.0f);
- }
- return alpha;
-}
-
-
-//-------------------------------------------------------------------------
-// Purpose: draws the selection area
-//-------------------------------------------------------------------------
-void CHudWeaponSelection::Paint()
-{
- int width;
- int xpos;
- int ypos;
-
- if (!ShouldDraw())
- return;
-
- C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
- if ( !pPlayer )
- return;
-
- // find and display our current selection
- C_BaseCombatWeapon *pSelectedWeapon = NULL;
- switch ( hud_fastswitch.GetInt() )
- {
- case HUDTYPE_FASTSWITCH:
- case HUDTYPE_CAROUSEL:
- pSelectedWeapon = pPlayer->GetActiveWeapon();
- break;
- default:
- pSelectedWeapon = GetSelectedWeapon();
- break;
- }
- if ( !pSelectedWeapon )
- return;
-
- // 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);
- }
-
- switch ( hud_fastswitch.GetInt() )
- {
- case HUDTYPE_CAROUSEL:
- {
- // carousel style - flat line of items
- ypos = 0;
- if ( m_iSelectedWeaponBox == -1 || m_WeaponBoxes.Count() <= 1 )
- {
- // nothing to do
- return;
- }
- else if ( m_WeaponBoxes.Count() < MAX_CAROUSEL_SLOTS )
- {
- // draw the selected weapon as a 1 of n style
- width = (m_WeaponBoxes.Count()-1) * (m_flLargeBoxWide+m_flBoxGap) + m_flLargeBoxWide;
- xpos = (GetWide() - width)/2;
- for ( int i=0; i<m_WeaponBoxes.Count(); i++ )
- {
- C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( m_WeaponBoxes[i].m_iSlot, m_WeaponBoxes[i].m_iSlotPos );
- if ( !pWeapon )
- break;
-
- float alpha = GetWeaponBoxAlpha( i == m_iSelectedWeaponBox );
- if ( i == m_iSelectedWeaponBox )
- {
- // draw selected in highlighted style
- DrawLargeWeaponBox( pWeapon, true, xpos, ypos, m_flLargeBoxWide, m_flLargeBoxTall, selectedColor, alpha, -1 );
- }
- else
- {
- DrawLargeWeaponBox( pWeapon, false, xpos, ypos, m_flLargeBoxWide, m_flLargeBoxTall / 1.5f, m_BoxColor, alpha, -1 );
- }
-
- xpos += (m_flLargeBoxWide + m_flBoxGap);
- }
- }
- else
- {
- // draw the selected weapon in the center, as a continuous scrolling carosuel
- // draw at center the current selected and all items to its right
- xpos = GetWide()/2 + m_flHorizWeaponSelectOffsetPoint - largeBoxWide/2;
- int i = m_iSelectedWeaponBox;
- while ( 1 )
- {
- C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( m_WeaponBoxes[i].m_iSlot, m_WeaponBoxes[i].m_iSlotPos );
- if ( !pWeapon )
- break;
-
- float alpha;
- if ( i == m_iSelectedWeaponBox && !m_flHorizWeaponSelectOffsetPoint )
- {
- // draw selected in highlighted style
- alpha = GetWeaponBoxAlpha( true );
- DrawLargeWeaponBox( pWeapon, true, xpos, ypos, largeBoxWide, largeBoxTall, selectedColor, alpha, -1 );
- }
- else
- {
- alpha = GetWeaponBoxAlpha( false );
- DrawLargeWeaponBox( pWeapon, false, xpos, ypos, largeBoxWide, largeBoxTall / 1.5f, m_BoxColor, alpha, -1 );
- }
-
- // advance until past edge
- xpos += (largeBoxWide + m_flBoxGap);
- if ( xpos >= GetWide() )
- break;
-
- ++i;
- if ( i >= m_WeaponBoxes.Count() )
- {
- // wraparound
- i = 0;
- }
- }
-
- // draw all items left of center
- xpos = GetWide()/2 + m_flHorizWeaponSelectOffsetPoint - (3*largeBoxWide/2 + m_flBoxGap);
- i = m_iSelectedWeaponBox - 1;
- while ( 1 )
- {
- if ( i < 0 )
- {
- // wraparound
- i = m_WeaponBoxes.Count() - 1;
- }
-
- C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( m_WeaponBoxes[i].m_iSlot, m_WeaponBoxes[i].m_iSlotPos );
- if ( !pWeapon )
- break;
-
- float alpha;
- if ( i == m_iSelectedWeaponBox && !m_flHorizWeaponSelectOffsetPoint )
- {
- // draw selected in highlighted style
- alpha = GetWeaponBoxAlpha( true );
- DrawLargeWeaponBox( pWeapon, true, xpos, ypos, largeBoxWide, largeBoxTall, selectedColor, alpha, -1 );
- }
- else
- {
- alpha = GetWeaponBoxAlpha( false );
- DrawLargeWeaponBox( pWeapon, false, xpos, ypos, largeBoxWide, largeBoxTall / 1.5f, m_BoxColor, alpha, -1 );
- }
-
- // retreat until past edge
- xpos -= (largeBoxWide + m_flBoxGap);
- if ( xpos + largeBoxWide <= 0 )
- break;
-
- --i;
- }
- }
- }
- break;
-
- case HUDTYPE_PLUS:
- {
- float fCenterX, fCenterY;
- bool bBehindCamera = false;
- CHudCrosshair::GetDrawPosition( &fCenterX, &fCenterY, &bBehindCamera );
-
- // if the crosshair is behind the camera, don't draw it
- if( bBehindCamera )
- return;
-
- // bucket style
- int screenCenterX = (int) fCenterX;
- int screenCenterY = (int) fCenterY - 15; // Height isn't quite screen height, so adjust for center alignement
-
- // Modifiers for the four directions. Used to change the x and y offsets
- // of each box based on which bucket we're drawing. Bucket directions are
- // 0 = UP, 1 = RIGHT, 2 = DOWN, 3 = LEFT
- int xModifiers[] = { 0, 1, 0, -1 };
- int yModifiers[] = { -1, 0, 1, 0 };
-
- // Draw the four buckets
- for ( int i = 0; i < MAX_WEAPON_SLOTS; ++i )
- {
- // Set the top left corner so the first box would be centered in the screen.
- int xPos = screenCenterX -( m_flMediumBoxWide / 2 );
- int yPos = screenCenterY -( m_flMediumBoxTall / 2 );
-
- // Find out how many positions to draw - an empty position should still
- // be drawn if there is an active weapon in any slots past it.
- int lastSlotPos = -1;
- for ( int slotPos = 0; slotPos < MAX_WEAPON_POSITIONS; ++slotPos )
- {
- C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( i, slotPos );
- if ( pWeapon )
- {
- lastSlotPos = slotPos;
- }
- }
-
- // Draw the weapons in this bucket
- for ( int slotPos = 0; slotPos <= lastSlotPos; ++slotPos )
- {
- // Offset the box position
- xPos += ( m_flMediumBoxWide + 5 ) * xModifiers[ i ];
- yPos += ( m_flMediumBoxTall + 5 ) * yModifiers[ i ];
-
- int boxWide = m_flMediumBoxWide;
- int boxTall = m_flMediumBoxTall;
- int x = xPos;
- int y = yPos;
-
- C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( i, slotPos );
- bool selectedWeapon = false;
- if ( i == m_iSelectedSlot && slotPos == m_iSelectedBoxPosition )
- {
- // This is a bit of a misnomer... we really are asking "Is this the selected slot"?
- selectedWeapon = true;
- }
-
- // Draw the box with the appropriate icon
- DrawLargeWeaponBox( pWeapon,
- selectedWeapon,
- x,
- y,
- boxWide,
- boxTall,
- selectedWeapon ? selectedColor : m_BoxColor,
- GetWeaponBoxAlpha( selectedWeapon ),
- -1 );
- }
- }
- }
- break;
-
- case HUDTYPE_BUCKETS:
- {
- // bucket style
- width = (MAX_WEAPON_SLOTS - 1) * (m_flSmallBoxSize + m_flBoxGap) + largeBoxWide;
- xpos = (GetWide() - width) / 2;
- ypos = 0;
-
- int iActiveSlot = (pSelectedWeapon ? pSelectedWeapon->GetSlot() : -1);
-
- // draw the bucket set
- // iterate over all the weapon slots
- for ( int i = 0; i < MAX_WEAPON_SLOTS; i++ )
- {
- if ( i == iActiveSlot )
- {
- bool bDrawBucketNumber = true;
- int iLastPos = GetLastPosInSlot( i );
-
- for (int slotpos = 0; slotpos <= iLastPos; slotpos++)
- {
- C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( i, slotpos );
- if ( !pWeapon )
- {
- if ( !hud_showemptyweaponslots.GetBool() )
- continue;
- DrawBox( xpos, ypos, largeBoxWide, largeBoxTall, m_EmptyBoxColor, m_flAlphaOverride, bDrawBucketNumber ? i + 1 : -1 );
- }
- else
- {
- bool bSelected = (pWeapon == pSelectedWeapon);
- DrawLargeWeaponBox( pWeapon,
- bSelected,
- xpos,
- ypos,
- largeBoxWide,
- largeBoxTall,
- bSelected ? selectedColor : m_BoxColor,
- GetWeaponBoxAlpha( bSelected ),
- bDrawBucketNumber ? i + 1 : -1 );
- }
-
- // move down to the next bucket
- ypos += (largeBoxTall + m_flBoxGap);
- bDrawBucketNumber = 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;
- }
- }
- break;
-
- default:
- {
- // do nothing
- }
- break;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: draws a single weapon selection box
-//-----------------------------------------------------------------------------
-void CHudWeaponSelection::DrawLargeWeaponBox( C_BaseCombatWeapon *pWeapon, bool bSelected, int xpos, int ypos, int boxWide, int boxTall, Color selectedColor, float alpha, int number )
-{
- Color col = bSelected ? m_SelectedFgColor : GetFgColor();
-
- switch ( hud_fastswitch.GetInt() )
- {
- case HUDTYPE_BUCKETS:
- {
- // draw box for selected weapon
- DrawBox( xpos, ypos, boxWide, boxTall, selectedColor, alpha, number );
-
- // draw icon
- col[3] *= (alpha / 255.0f);
- 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 = (boxWide - iconWidth) / 2;
-
- int y_offs;
- if ( bSelected && hud_fastswitch.GetInt() != 0 )
- {
- // place the icon aligned with the non-selected version
- y_offs = (boxTall / 1.5f - iconHeight) / 2;
- }
- else
- {
- y_offs = (boxTall - iconHeight) / 2;
- }
-
- if (!pWeapon->CanBeSelected())
- {
- // unselectable weapon, display as such
- col = Color(255, 0, 0, col[3]);
- }
- else if (bSelected)
- {
- // currently selected weapon, display brighter
- col[3] = alpha;
-
- // 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 );
- }
- }
- break;
-
- case HUDTYPE_PLUS:
- case HUDTYPE_CAROUSEL:
- {
- if ( !pWeapon )
- {
- // draw red box for an empty bubble
- if( bSelected )
- {
- selectedColor.SetColor( 255, 0, 0, 40 );
- }
-
- DrawBox( xpos, ypos, boxWide, boxTall, selectedColor, alpha, number );
- return;
- }
- else
- {
- // draw box for selected weapon
- DrawBox( xpos, ypos, boxWide, boxTall, selectedColor, alpha, number );
- }
-
- int iconWidth;
- int iconHeight;
- int x_offs;
- int y_offs;
-
- // draw icon
- col[3] *= (alpha / 255.0f);
-
- if ( pWeapon->GetSpriteInactive() )
- {
- iconWidth = pWeapon->GetSpriteInactive()->Width();
- iconHeight = pWeapon->GetSpriteInactive()->Height();
-
- x_offs = (boxWide - iconWidth) / 2;
- if ( bSelected && HUDTYPE_CAROUSEL == hud_fastswitch.GetInt() )
- {
- // place the icon aligned with the non-selected version
- y_offs = (boxTall/1.5f - iconHeight) / 2;
- }
- else
- {
- y_offs = (boxTall - iconHeight) / 2;
- }
-
- if ( !pWeapon->CanBeSelected() )
- {
- // unselectable weapon, display as such
- col = Color(255, 0, 0, col[3]);
- }
-
- // draw the inactive version
- pWeapon->GetSpriteInactive()->DrawSelf( xpos + x_offs, ypos + y_offs, iconWidth, iconHeight, col );
- }
-
- if ( bSelected && pWeapon->GetSpriteActive() )
- {
- // find the center of the box to draw in
- iconWidth = pWeapon->GetSpriteActive()->Width();
- iconHeight = pWeapon->GetSpriteActive()->Height();
-
- x_offs = (boxWide - iconWidth) / 2;
- if ( HUDTYPE_CAROUSEL == hud_fastswitch.GetInt() )
- {
- // place the icon aligned with the non-selected version
- y_offs = (boxTall/1.5f - iconHeight) / 2;
- }
- else
- {
- y_offs = (boxTall - iconHeight) / 2;
- }
-
- col[3] = 255;
- for (float fl = m_flBlur; fl > 0.0f; fl -= 1.0f)
- {
- if (fl >= 1.0f)
- {
- pWeapon->GetSpriteActive()->DrawSelf( xpos + x_offs, ypos + y_offs, col );
- }
- else
- {
- // draw a percentage of the last one
- col[3] *= fl;
- pWeapon->GetSpriteActive()->DrawSelf( xpos + x_offs, ypos + y_offs, col );
- }
- }
- }
- }
- break;
-
- default:
- {
- // do nothing
- }
- break;
- }
-
- if ( HUDTYPE_PLUS == hud_fastswitch.GetInt() )
- {
- // No text in plus bucket method
- return;
- }
-
- // draw text
- col = m_TextColor;
- const FileWeaponInfo_t &weaponInfo = pWeapon->GetWpnData();
-
- if ( bSelected )
- {
- 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 + ((m_flLargeBoxWide - 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 + ((boxWide - slen) / 2), ty + (surface()->GetFontTall(m_hTextFont) * 1.1f));
- }
- else if (*pch == '\r')
- {
- // do nothing
- }
- else
- {
- surface()->DrawUnicodeChar(*pch);
- charCount--;
- }
- }
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// 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);
-
- if ( hud_fastswitch.GetInt() == HUDTYPE_CAROUSEL )
- {
- // need bounds to be exact width for proper clipping during scroll
- int width = MAX_CAROUSEL_SLOTS*m_flLargeBoxWide + (MAX_CAROUSEL_SLOTS-1)*m_flBoxGap;
- SetBounds( (screenWide-width)/2, y, width, screenTall - y);
- }
- else
- {
- SetBounds( x, y, screenWide - x, screenTall - y );
- }
-
- SetForceStereoRenderToFrameBuffer( true );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Opens weapon selection control
-//-----------------------------------------------------------------------------
-void CHudWeaponSelection::OpenSelection( void )
-{
- Assert(!IsInSelectionMode());
-
- CBaseHudWeaponSelection::OpenSelection();
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("OpenWeaponSelectionMenu");
- m_iSelectedBoxPosition = 0;
- m_iSelectedSlot = -1;
-}
-
-//-----------------------------------------------------------------------------
-// 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 ( CanBeSelectedInHUD( pWeapon ) )
- {
- 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 ( CanBeSelectedInHUD( pWeapon ) )
- {
- 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;
-
- m_pLastWeapon = pPlayer->GetActiveWeapon();
-
- 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 );
- SetSelectedSlideDir( 1 );
-
- 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;
-
- m_pLastWeapon = pPlayer->GetActiveWeapon();
-
- 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 );
- SetSelectedSlideDir( -1 );
-
- if ( !IsInSelectionMode() )
- {
- OpenSelection();
- }
-
- // Play the "cycle to next weapon" sound
- pPlayer->EmitSound( "Player.WeaponSelectionMoveSlot" );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: returns the # of the last weapon in the specified slot
-//-----------------------------------------------------------------------------
-int CHudWeaponSelection::GetLastPosInSlot( int iSlot ) const
-{
- C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
- int iMaxSlotPos;
-
- if ( !player )
- return -1;
-
- iMaxSlotPos = -1;
- for ( int i = 0; i < MAX_WEAPONS; i++ )
- {
- C_BaseCombatWeapon *pWeapon = player->GetWeapon(i);
-
- if ( pWeapon == NULL )
- continue;
-
- if ( pWeapon->GetSlot() == iSlot && pWeapon->GetPosition() > iMaxSlotPos )
- iMaxSlotPos = pWeapon->GetPosition();
- }
-
- return iMaxSlotPos;
-}
-
-//-----------------------------------------------------------------------------
-// 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;
-
- m_pLastWeapon = NULL;
-
- // 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" );
- }
-
- if ( HUDTYPE_CAROUSEL != hud_fastswitch.GetInt() )
- {
- // kill any fastswitch display
- m_flSelectionTime = 0.0f;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Opens the next weapon in the slot
-//-----------------------------------------------------------------------------
-void CHudWeaponSelection::PlusTypeFastWeaponSwitch( int iWeaponSlot )
-{
- // get the slot the player's weapon is in
- C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
- if ( !pPlayer )
- return;
-
- m_pLastWeapon = NULL;
- int newSlot = m_iSelectedSlot;
-
- // Changing slot number does not necessarily mean we need to change the slot - the player could be
- // scrolling through the same slot but in the opposite direction. Slot pairs are 0,2 and 1,3 - so
- // compare the 0 bits to see if we're within a pair. Otherwise, reset the box to the zero position.
- if ( -1 == m_iSelectedSlot || ( ( m_iSelectedSlot ^ iWeaponSlot ) & 1 ) )
- {
- // Changing vertical/horizontal direction. Reset the selected box position to zero.
- m_iSelectedBoxPosition = 0;
- m_iSelectedSlot = iWeaponSlot;
- }
- else
- {
- // Still in the same horizontal/vertical direction. Determine which way we're moving in the slot.
- int increment = 1;
- if ( m_iSelectedSlot != iWeaponSlot )
- {
- // Decrementing within the slot. If we're at the zero position in this slot,
- // jump to the zero position of the opposite slot. This also counts as our increment.
- increment = -1;
- if ( 0 == m_iSelectedBoxPosition )
- {
- newSlot = ( m_iSelectedSlot + 2 ) % 4;
- increment = 0;
- }
- }
-
- // Find out of the box position is at the end of the slot
- int lastSlotPos = -1;
- for ( int slotPos = 0; slotPos < MAX_WEAPON_POSITIONS; ++slotPos )
- {
- C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( newSlot, slotPos );
- if ( pWeapon )
- {
- lastSlotPos = slotPos;
- }
- }
-
- // Increment/Decrement the selected box position
- if ( m_iSelectedBoxPosition + increment <= lastSlotPos )
- {
- m_iSelectedBoxPosition += increment;
- m_iSelectedSlot = newSlot;
- }
- else
- {
- // error sound
- pPlayer->EmitSound( "Player.DenyWeaponSelection" );
- return;
- }
- }
-
- // Select the weapon in this position
- bool bWeaponSelected = false;
- C_BaseCombatWeapon *pActiveWeapon = pPlayer->GetActiveWeapon();
- C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( m_iSelectedSlot, m_iSelectedBoxPosition );
- if ( pWeapon )
- {
- if ( pWeapon != pActiveWeapon )
- {
- // Select the new weapon
- ::input->MakeWeaponSelection( pWeapon );
- SetSelectedWeapon( pWeapon );
- bWeaponSelected = true;
- }
- }
-
- if ( !bWeaponSelected )
- {
- // Still need to set this to make hud display appear
- SetSelectedWeapon( pPlayer->GetActiveWeapon() );
- }
-}
-
-//-----------------------------------------------------------------------------
-// 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;
-
- switch( hud_fastswitch.GetInt() )
- {
- case HUDTYPE_FASTSWITCH:
- case HUDTYPE_CAROUSEL:
- {
- FastWeaponSwitch( iSlot );
- return;
- }
-
- case HUDTYPE_PLUS:
- {
- if ( !IsInSelectionMode() )
- {
- // open the weapon selection
- OpenSelection();
- }
-
- PlusTypeFastWeaponSwitch( iSlot );
- ActivateWeaponHighlight( GetSelectedWeapon() );
- }
- break;
-
- case HUDTYPE_BUCKETS:
- {
- 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 );
- SetSelectedSlideDir( 0 );
- }
- }
-
- default:
- {
- // do nothing
- }
- break;
- }
-
- pPlayer->EmitSound( "Player.WeaponSelectionMoveSlot" );
-}
+//========= 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 "../hud_crosshair.h"
+
+#include "VGuiMatSurface/IMatSystemSurface.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"
+
+ConVar hud_showemptyweaponslots( "hud_showemptyweaponslots", "1", FCVAR_ARCHIVE, "Shows slots for missing weapons when recieving weapons out of order" );
+
+#define SELECTION_TIMEOUT_THRESHOLD 0.5f // Seconds
+#define SELECTION_FADEOUT_TIME 0.75f
+
+#define PLUS_DISPLAY_TIMEOUT 0.5f // Seconds
+#define PLUS_FADEOUT_TIME 0.75f
+
+#define FASTSWITCH_DISPLAY_TIMEOUT 1.5f
+#define FASTSWITCH_FADEOUT_TIME 1.5f
+
+#define CAROUSEL_SMALL_DISPLAY_ALPHA 200.0f
+#define FASTSWITCH_SMALL_DISPLAY_ALPHA 160.0f
+
+#define MAX_CAROUSEL_SLOTS 5
+
+//-----------------------------------------------------------------------------
+// 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;
+ }
+
+ virtual void SetWeaponSelected()
+ {
+ CBaseHudWeaponSelection::SetWeaponSelected();
+
+ switch( hud_fastswitch.GetInt() )
+ {
+ case HUDTYPE_FASTSWITCH:
+ case HUDTYPE_CAROUSEL:
+ ActivateFastswitchWeaponDisplay( GetSelectedWeapon() );
+ break;
+ case HUDTYPE_PLUS:
+ ActivateWeaponHighlight( GetSelectedWeapon() );
+ break;
+ default:
+ // do nothing
+ break;
+ }
+ }
+
+private:
+ C_BaseCombatWeapon *FindNextWeaponInWeaponSelection(int iCurrentSlot, int iCurrentPosition);
+ C_BaseCombatWeapon *FindPrevWeaponInWeaponSelection(int iCurrentSlot, int iCurrentPosition);
+
+ void DrawLargeWeaponBox( C_BaseCombatWeapon *pWeapon, bool bSelected, int x, int y, int wide, int tall, Color color, float alpha, int number );
+ void ActivateFastswitchWeaponDisplay( C_BaseCombatWeapon *pWeapon );
+ void ActivateWeaponHighlight( C_BaseCombatWeapon *pWeapon );
+ float GetWeaponBoxAlpha( bool bSelected );
+ int GetLastPosInSlot( int iSlot ) const;
+
+ void FastWeaponSwitch( int iWeaponSlot );
+ void PlusTypeFastWeaponSwitch( int iWeaponSlot );
+
+ virtual void SetSelectedWeapon( C_BaseCombatWeapon *pWeapon )
+ {
+ m_hSelectedWeapon = pWeapon;
+ }
+
+ virtual void SetSelectedSlot( int slot )
+ {
+ m_iSelectedSlot = slot;
+ }
+
+ void SetSelectedSlideDir( int dir )
+ {
+ m_iSelectedSlideDir = dir;
+ }
+
+ 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" );
+ CPanelAnimationVar( float, m_flBlur, "Blur", "0" );
+
+ 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_flMediumBoxWide, "MediumBoxWide", "75", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flMediumBoxTall, "MediumBoxTall", "50", "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", "0" );
+ CPanelAnimationVar( float, m_flSelectionAlphaOverride, "SelectionAlpha", "0" );
+
+ 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, "SelectedBoxColor", "SelectionSelectedBoxBg" );
+ CPanelAnimationVar( Color, m_SelectedFgColor, "SelectedFgColor", "FgColor" );
+ CPanelAnimationVar( Color, m_BrightBoxColor, "SelectedFgColor", "BgColor" );
+
+ CPanelAnimationVar( float, m_flWeaponPickupGrowTime, "SelectionGrowTime", "0.1" );
+
+ CPanelAnimationVar( float, m_flTextScan, "TextScan", "1.0" );
+
+ bool m_bFadingOut;
+
+ // fastswitch weapon display
+ struct WeaponBox_t
+ {
+ int m_iSlot;
+ int m_iSlotPos;
+ };
+ CUtlVector<WeaponBox_t> m_WeaponBoxes;
+ int m_iSelectedWeaponBox;
+ int m_iSelectedSlideDir;
+ int m_iSelectedBoxPosition;
+ int m_iSelectedSlot;
+ C_BaseCombatWeapon *m_pLastWeapon;
+ CPanelAnimationVar( float, m_flHorizWeaponSelectOffsetPoint, "WeaponBoxOffset", "0" );
+};
+
+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 );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: updates animation status
+//-----------------------------------------------------------------------------
+void CHudWeaponSelection::OnThink( void )
+{
+ float flSelectionTimeout = SELECTION_TIMEOUT_THRESHOLD;
+ float flSelectionFadeoutTime = SELECTION_FADEOUT_TIME;
+ if ( hud_fastswitch.GetBool() )
+ {
+ flSelectionTimeout = FASTSWITCH_DISPLAY_TIMEOUT;
+ flSelectionFadeoutTime = FASTSWITCH_FADEOUT_TIME;
+ }
+
+ // Time out after awhile of inactivity
+ if ( ( gpGlobals->curtime - m_flSelectionTime ) > flSelectionTimeout )
+ {
+ if (!m_bFadingOut)
+ {
+ // start fading out
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "FadeOutWeaponSelectionMenu" );
+ m_bFadingOut = true;
+ }
+ else if ( gpGlobals->curtime - m_flSelectionTime > flSelectionTimeout + flSelectionFadeoutTime )
+ {
+ // 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;
+
+ // draw weapon selection a little longer if in fastswitch so we can see what we've selected
+ if ( hud_fastswitch.GetBool() && ( gpGlobals->curtime - m_flSelectionTime ) < (FASTSWITCH_DISPLAY_TIMEOUT + FASTSWITCH_FADEOUT_TIME) )
+ return true;
+
+ return ( m_bSelectionVisible ) ? true : false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudWeaponSelection::LevelInit()
+{
+ CHudElement::LevelInit();
+
+ m_iSelectedWeaponBox = -1;
+ m_iSelectedSlideDir = 0;
+ m_pLastWeapon = NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: starts animating the center of the draw point to the newly selected weapon
+//-----------------------------------------------------------------------------
+void CHudWeaponSelection::ActivateFastswitchWeaponDisplay( C_BaseCombatWeapon *pSelectedWeapon )
+{
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ // make sure all our configuration data is read
+ MakeReadyForUse();
+
+ m_WeaponBoxes.RemoveAll();
+ m_iSelectedWeaponBox = 0;
+
+ // find out where our selected weapon is in the full list
+ int cWeapons = 0;
+ int iLastSelectedWeaponBox = -1;
+ for ( int i = 0; i < MAX_WEAPON_SLOTS; i++ )
+ {
+ for (int slotpos = 0; slotpos < MAX_WEAPON_POSITIONS; slotpos++)
+ {
+ C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( i, slotpos );
+ if ( !pWeapon )
+ continue;
+
+ WeaponBox_t box = { i, slotpos };
+ m_WeaponBoxes.AddToTail( box );
+
+ if ( pWeapon == pSelectedWeapon )
+ {
+ m_iSelectedWeaponBox = cWeapons;
+ }
+ if ( pWeapon == m_pLastWeapon )
+ {
+ iLastSelectedWeaponBox = cWeapons;
+ }
+ cWeapons++;
+ }
+ }
+
+ if ( iLastSelectedWeaponBox == -1 )
+ {
+ // unexpected failure, no last weapon to scroll from, default to snap behavior
+ m_pLastWeapon = NULL;
+ }
+
+ // calculate where we would have to start drawing for this weapon to slide into center
+ float flStart, flStop, flTime;
+ if ( !m_pLastWeapon || m_iSelectedSlideDir == 0 || m_flHorizWeaponSelectOffsetPoint != 0 )
+ {
+ // no previous weapon or weapon selected directly or selection during slide, snap to exact position
+ m_pLastWeapon = pSelectedWeapon;
+ flStart = flStop = flTime = 0;
+ }
+ else
+ {
+ // offset display for a scroll
+ // causing selected weapon to slide into position
+ // scroll direction based on user's "previous" or "next" selection
+ int numIcons = 0;
+ int start = iLastSelectedWeaponBox;
+ for (int i=0; i<cWeapons; i++)
+ {
+ // count icons in direction of slide to destination
+ if ( start == m_iSelectedWeaponBox )
+ break;
+ if ( m_iSelectedSlideDir < 0 )
+ {
+ start--;
+ }
+ else
+ {
+ start++;
+ }
+ // handle wraparound in either direction
+ start = ( start + cWeapons ) % cWeapons;
+ numIcons++;
+ }
+
+ flStart = numIcons * (m_flLargeBoxWide + m_flBoxGap);
+ if ( m_iSelectedSlideDir < 0 )
+ flStart *= -1;
+ flStop = 0;
+
+ // shorten duration for scrolling when desired weapon is farther away
+ // otherwise a large skip in the same duration causes the scroll to fly too fast
+ flTime = numIcons * 0.20f;
+ if ( numIcons > 1 )
+ flTime *= 0.5f;
+ }
+ m_flHorizWeaponSelectOffsetPoint = flStart;
+ g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( this, "WeaponBoxOffset", flStop, 0, flTime, AnimationController::INTERPOLATOR_LINEAR );
+
+ // start the highlight after the scroll completes
+ m_flBlur = 7.f;
+ g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( this, "Blur", 0, flTime, 0.75f, AnimationController::INTERPOLATOR_DEACCEL );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: starts animating the highlight for the selected weapon
+//-----------------------------------------------------------------------------
+void CHudWeaponSelection::ActivateWeaponHighlight( C_BaseCombatWeapon *pSelectedWeapon )
+{
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ // make sure all our configuration data is read
+ MakeReadyForUse();
+
+ C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( m_iSelectedSlot, m_iSelectedBoxPosition );
+ if ( !pWeapon )
+ return;
+
+ // start the highlight after the scroll completes
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "WeaponHighlight" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns an (per frame animating) alpha value for different weapon boxes
+//-----------------------------------------------------------------------------
+float CHudWeaponSelection::GetWeaponBoxAlpha( bool bSelected )
+{
+ float alpha;
+ if ( bSelected )
+ {
+ alpha = m_flSelectionAlphaOverride;
+ }
+ else
+ {
+ alpha = m_flSelectionAlphaOverride * (m_flAlphaOverride / 255.0f);
+ }
+ return alpha;
+}
+
+
+//-------------------------------------------------------------------------
+// Purpose: draws the selection area
+//-------------------------------------------------------------------------
+void CHudWeaponSelection::Paint()
+{
+ int width;
+ int xpos;
+ int ypos;
+
+ if (!ShouldDraw())
+ return;
+
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ // find and display our current selection
+ C_BaseCombatWeapon *pSelectedWeapon = NULL;
+ switch ( hud_fastswitch.GetInt() )
+ {
+ case HUDTYPE_FASTSWITCH:
+ case HUDTYPE_CAROUSEL:
+ pSelectedWeapon = pPlayer->GetActiveWeapon();
+ break;
+ default:
+ pSelectedWeapon = GetSelectedWeapon();
+ break;
+ }
+ if ( !pSelectedWeapon )
+ return;
+
+ // 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);
+ }
+
+ switch ( hud_fastswitch.GetInt() )
+ {
+ case HUDTYPE_CAROUSEL:
+ {
+ // carousel style - flat line of items
+ ypos = 0;
+ if ( m_iSelectedWeaponBox == -1 || m_WeaponBoxes.Count() <= 1 )
+ {
+ // nothing to do
+ return;
+ }
+ else if ( m_WeaponBoxes.Count() < MAX_CAROUSEL_SLOTS )
+ {
+ // draw the selected weapon as a 1 of n style
+ width = (m_WeaponBoxes.Count()-1) * (m_flLargeBoxWide+m_flBoxGap) + m_flLargeBoxWide;
+ xpos = (GetWide() - width)/2;
+ for ( int i=0; i<m_WeaponBoxes.Count(); i++ )
+ {
+ C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( m_WeaponBoxes[i].m_iSlot, m_WeaponBoxes[i].m_iSlotPos );
+ if ( !pWeapon )
+ break;
+
+ float alpha = GetWeaponBoxAlpha( i == m_iSelectedWeaponBox );
+ if ( i == m_iSelectedWeaponBox )
+ {
+ // draw selected in highlighted style
+ DrawLargeWeaponBox( pWeapon, true, xpos, ypos, m_flLargeBoxWide, m_flLargeBoxTall, selectedColor, alpha, -1 );
+ }
+ else
+ {
+ DrawLargeWeaponBox( pWeapon, false, xpos, ypos, m_flLargeBoxWide, m_flLargeBoxTall / 1.5f, m_BoxColor, alpha, -1 );
+ }
+
+ xpos += (m_flLargeBoxWide + m_flBoxGap);
+ }
+ }
+ else
+ {
+ // draw the selected weapon in the center, as a continuous scrolling carosuel
+ // draw at center the current selected and all items to its right
+ xpos = GetWide()/2 + m_flHorizWeaponSelectOffsetPoint - largeBoxWide/2;
+ int i = m_iSelectedWeaponBox;
+ while ( 1 )
+ {
+ C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( m_WeaponBoxes[i].m_iSlot, m_WeaponBoxes[i].m_iSlotPos );
+ if ( !pWeapon )
+ break;
+
+ float alpha;
+ if ( i == m_iSelectedWeaponBox && !m_flHorizWeaponSelectOffsetPoint )
+ {
+ // draw selected in highlighted style
+ alpha = GetWeaponBoxAlpha( true );
+ DrawLargeWeaponBox( pWeapon, true, xpos, ypos, largeBoxWide, largeBoxTall, selectedColor, alpha, -1 );
+ }
+ else
+ {
+ alpha = GetWeaponBoxAlpha( false );
+ DrawLargeWeaponBox( pWeapon, false, xpos, ypos, largeBoxWide, largeBoxTall / 1.5f, m_BoxColor, alpha, -1 );
+ }
+
+ // advance until past edge
+ xpos += (largeBoxWide + m_flBoxGap);
+ if ( xpos >= GetWide() )
+ break;
+
+ ++i;
+ if ( i >= m_WeaponBoxes.Count() )
+ {
+ // wraparound
+ i = 0;
+ }
+ }
+
+ // draw all items left of center
+ xpos = GetWide()/2 + m_flHorizWeaponSelectOffsetPoint - (3*largeBoxWide/2 + m_flBoxGap);
+ i = m_iSelectedWeaponBox - 1;
+ while ( 1 )
+ {
+ if ( i < 0 )
+ {
+ // wraparound
+ i = m_WeaponBoxes.Count() - 1;
+ }
+
+ C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( m_WeaponBoxes[i].m_iSlot, m_WeaponBoxes[i].m_iSlotPos );
+ if ( !pWeapon )
+ break;
+
+ float alpha;
+ if ( i == m_iSelectedWeaponBox && !m_flHorizWeaponSelectOffsetPoint )
+ {
+ // draw selected in highlighted style
+ alpha = GetWeaponBoxAlpha( true );
+ DrawLargeWeaponBox( pWeapon, true, xpos, ypos, largeBoxWide, largeBoxTall, selectedColor, alpha, -1 );
+ }
+ else
+ {
+ alpha = GetWeaponBoxAlpha( false );
+ DrawLargeWeaponBox( pWeapon, false, xpos, ypos, largeBoxWide, largeBoxTall / 1.5f, m_BoxColor, alpha, -1 );
+ }
+
+ // retreat until past edge
+ xpos -= (largeBoxWide + m_flBoxGap);
+ if ( xpos + largeBoxWide <= 0 )
+ break;
+
+ --i;
+ }
+ }
+ }
+ break;
+
+ case HUDTYPE_PLUS:
+ {
+ float fCenterX, fCenterY;
+ bool bBehindCamera = false;
+ CHudCrosshair::GetDrawPosition( &fCenterX, &fCenterY, &bBehindCamera );
+
+ // if the crosshair is behind the camera, don't draw it
+ if( bBehindCamera )
+ return;
+
+ // bucket style
+ int screenCenterX = (int) fCenterX;
+ int screenCenterY = (int) fCenterY - 15; // Height isn't quite screen height, so adjust for center alignement
+
+ // Modifiers for the four directions. Used to change the x and y offsets
+ // of each box based on which bucket we're drawing. Bucket directions are
+ // 0 = UP, 1 = RIGHT, 2 = DOWN, 3 = LEFT
+ int xModifiers[] = { 0, 1, 0, -1 };
+ int yModifiers[] = { -1, 0, 1, 0 };
+
+ // Draw the four buckets
+ for ( int i = 0; i < MAX_WEAPON_SLOTS; ++i )
+ {
+ // Set the top left corner so the first box would be centered in the screen.
+ int xPos = screenCenterX -( m_flMediumBoxWide / 2 );
+ int yPos = screenCenterY -( m_flMediumBoxTall / 2 );
+
+ // Find out how many positions to draw - an empty position should still
+ // be drawn if there is an active weapon in any slots past it.
+ int lastSlotPos = -1;
+ for ( int slotPos = 0; slotPos < MAX_WEAPON_POSITIONS; ++slotPos )
+ {
+ C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( i, slotPos );
+ if ( pWeapon )
+ {
+ lastSlotPos = slotPos;
+ }
+ }
+
+ // Draw the weapons in this bucket
+ for ( int slotPos = 0; slotPos <= lastSlotPos; ++slotPos )
+ {
+ // Offset the box position
+ xPos += ( m_flMediumBoxWide + 5 ) * xModifiers[ i ];
+ yPos += ( m_flMediumBoxTall + 5 ) * yModifiers[ i ];
+
+ int boxWide = m_flMediumBoxWide;
+ int boxTall = m_flMediumBoxTall;
+ int x = xPos;
+ int y = yPos;
+
+ C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( i, slotPos );
+ bool selectedWeapon = false;
+ if ( i == m_iSelectedSlot && slotPos == m_iSelectedBoxPosition )
+ {
+ // This is a bit of a misnomer... we really are asking "Is this the selected slot"?
+ selectedWeapon = true;
+ }
+
+ // Draw the box with the appropriate icon
+ DrawLargeWeaponBox( pWeapon,
+ selectedWeapon,
+ x,
+ y,
+ boxWide,
+ boxTall,
+ selectedWeapon ? selectedColor : m_BoxColor,
+ GetWeaponBoxAlpha( selectedWeapon ),
+ -1 );
+ }
+ }
+ }
+ break;
+
+ case HUDTYPE_BUCKETS:
+ {
+ // bucket style
+ width = (MAX_WEAPON_SLOTS - 1) * (m_flSmallBoxSize + m_flBoxGap) + largeBoxWide;
+ xpos = (GetWide() - width) / 2;
+ ypos = 0;
+
+ int iActiveSlot = (pSelectedWeapon ? pSelectedWeapon->GetSlot() : -1);
+
+ // draw the bucket set
+ // iterate over all the weapon slots
+ for ( int i = 0; i < MAX_WEAPON_SLOTS; i++ )
+ {
+ if ( i == iActiveSlot )
+ {
+ bool bDrawBucketNumber = true;
+ int iLastPos = GetLastPosInSlot( i );
+
+ for (int slotpos = 0; slotpos <= iLastPos; slotpos++)
+ {
+ C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( i, slotpos );
+ if ( !pWeapon )
+ {
+ if ( !hud_showemptyweaponslots.GetBool() )
+ continue;
+ DrawBox( xpos, ypos, largeBoxWide, largeBoxTall, m_EmptyBoxColor, m_flAlphaOverride, bDrawBucketNumber ? i + 1 : -1 );
+ }
+ else
+ {
+ bool bSelected = (pWeapon == pSelectedWeapon);
+ DrawLargeWeaponBox( pWeapon,
+ bSelected,
+ xpos,
+ ypos,
+ largeBoxWide,
+ largeBoxTall,
+ bSelected ? selectedColor : m_BoxColor,
+ GetWeaponBoxAlpha( bSelected ),
+ bDrawBucketNumber ? i + 1 : -1 );
+ }
+
+ // move down to the next bucket
+ ypos += (largeBoxTall + m_flBoxGap);
+ bDrawBucketNumber = 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;
+ }
+ }
+ break;
+
+ default:
+ {
+ // do nothing
+ }
+ break;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: draws a single weapon selection box
+//-----------------------------------------------------------------------------
+void CHudWeaponSelection::DrawLargeWeaponBox( C_BaseCombatWeapon *pWeapon, bool bSelected, int xpos, int ypos, int boxWide, int boxTall, Color selectedColor, float alpha, int number )
+{
+ Color col = bSelected ? m_SelectedFgColor : GetFgColor();
+
+ switch ( hud_fastswitch.GetInt() )
+ {
+ case HUDTYPE_BUCKETS:
+ {
+ // draw box for selected weapon
+ DrawBox( xpos, ypos, boxWide, boxTall, selectedColor, alpha, number );
+
+ // draw icon
+ col[3] *= (alpha / 255.0f);
+ 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 = (boxWide - iconWidth) / 2;
+
+ int y_offs;
+ if ( bSelected && hud_fastswitch.GetInt() != 0 )
+ {
+ // place the icon aligned with the non-selected version
+ y_offs = (boxTall / 1.5f - iconHeight) / 2;
+ }
+ else
+ {
+ y_offs = (boxTall - iconHeight) / 2;
+ }
+
+ if (!pWeapon->CanBeSelected())
+ {
+ // unselectable weapon, display as such
+ col = Color(255, 0, 0, col[3]);
+ }
+ else if (bSelected)
+ {
+ // currently selected weapon, display brighter
+ col[3] = alpha;
+
+ // 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 );
+ }
+ }
+ break;
+
+ case HUDTYPE_PLUS:
+ case HUDTYPE_CAROUSEL:
+ {
+ if ( !pWeapon )
+ {
+ // draw red box for an empty bubble
+ if( bSelected )
+ {
+ selectedColor.SetColor( 255, 0, 0, 40 );
+ }
+
+ DrawBox( xpos, ypos, boxWide, boxTall, selectedColor, alpha, number );
+ return;
+ }
+ else
+ {
+ // draw box for selected weapon
+ DrawBox( xpos, ypos, boxWide, boxTall, selectedColor, alpha, number );
+ }
+
+ int iconWidth;
+ int iconHeight;
+ int x_offs;
+ int y_offs;
+
+ // draw icon
+ col[3] *= (alpha / 255.0f);
+
+ if ( pWeapon->GetSpriteInactive() )
+ {
+ iconWidth = pWeapon->GetSpriteInactive()->Width();
+ iconHeight = pWeapon->GetSpriteInactive()->Height();
+
+ x_offs = (boxWide - iconWidth) / 2;
+ if ( bSelected && HUDTYPE_CAROUSEL == hud_fastswitch.GetInt() )
+ {
+ // place the icon aligned with the non-selected version
+ y_offs = (boxTall/1.5f - iconHeight) / 2;
+ }
+ else
+ {
+ y_offs = (boxTall - iconHeight) / 2;
+ }
+
+ if ( !pWeapon->CanBeSelected() )
+ {
+ // unselectable weapon, display as such
+ col = Color(255, 0, 0, col[3]);
+ }
+
+ // draw the inactive version
+ pWeapon->GetSpriteInactive()->DrawSelf( xpos + x_offs, ypos + y_offs, iconWidth, iconHeight, col );
+ }
+
+ if ( bSelected && pWeapon->GetSpriteActive() )
+ {
+ // find the center of the box to draw in
+ iconWidth = pWeapon->GetSpriteActive()->Width();
+ iconHeight = pWeapon->GetSpriteActive()->Height();
+
+ x_offs = (boxWide - iconWidth) / 2;
+ if ( HUDTYPE_CAROUSEL == hud_fastswitch.GetInt() )
+ {
+ // place the icon aligned with the non-selected version
+ y_offs = (boxTall/1.5f - iconHeight) / 2;
+ }
+ else
+ {
+ y_offs = (boxTall - iconHeight) / 2;
+ }
+
+ col[3] = 255;
+ for (float fl = m_flBlur; fl > 0.0f; fl -= 1.0f)
+ {
+ if (fl >= 1.0f)
+ {
+ pWeapon->GetSpriteActive()->DrawSelf( xpos + x_offs, ypos + y_offs, col );
+ }
+ else
+ {
+ // draw a percentage of the last one
+ col[3] *= fl;
+ pWeapon->GetSpriteActive()->DrawSelf( xpos + x_offs, ypos + y_offs, col );
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ {
+ // do nothing
+ }
+ break;
+ }
+
+ if ( HUDTYPE_PLUS == hud_fastswitch.GetInt() )
+ {
+ // No text in plus bucket method
+ return;
+ }
+
+ // draw text
+ col = m_TextColor;
+ const FileWeaponInfo_t &weaponInfo = pWeapon->GetWpnData();
+
+ if ( bSelected )
+ {
+ 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 + ((m_flLargeBoxWide - 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 + ((boxWide - slen) / 2), ty + (surface()->GetFontTall(m_hTextFont) * 1.1f));
+ }
+ else if (*pch == '\r')
+ {
+ // do nothing
+ }
+ else
+ {
+ surface()->DrawUnicodeChar(*pch);
+ charCount--;
+ }
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// 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);
+
+ if ( hud_fastswitch.GetInt() == HUDTYPE_CAROUSEL )
+ {
+ // need bounds to be exact width for proper clipping during scroll
+ int width = MAX_CAROUSEL_SLOTS*m_flLargeBoxWide + (MAX_CAROUSEL_SLOTS-1)*m_flBoxGap;
+ SetBounds( (screenWide-width)/2, y, width, screenTall - y);
+ }
+ else
+ {
+ SetBounds( x, y, screenWide - x, screenTall - y );
+ }
+
+ SetForceStereoRenderToFrameBuffer( true );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Opens weapon selection control
+//-----------------------------------------------------------------------------
+void CHudWeaponSelection::OpenSelection( void )
+{
+ Assert(!IsInSelectionMode());
+
+ CBaseHudWeaponSelection::OpenSelection();
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("OpenWeaponSelectionMenu");
+ m_iSelectedBoxPosition = 0;
+ m_iSelectedSlot = -1;
+}
+
+//-----------------------------------------------------------------------------
+// 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 ( CanBeSelectedInHUD( pWeapon ) )
+ {
+ 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 ( CanBeSelectedInHUD( pWeapon ) )
+ {
+ 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;
+
+ m_pLastWeapon = pPlayer->GetActiveWeapon();
+
+ 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 );
+ SetSelectedSlideDir( 1 );
+
+ 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;
+
+ m_pLastWeapon = pPlayer->GetActiveWeapon();
+
+ 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 );
+ SetSelectedSlideDir( -1 );
+
+ if ( !IsInSelectionMode() )
+ {
+ OpenSelection();
+ }
+
+ // Play the "cycle to next weapon" sound
+ pPlayer->EmitSound( "Player.WeaponSelectionMoveSlot" );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns the # of the last weapon in the specified slot
+//-----------------------------------------------------------------------------
+int CHudWeaponSelection::GetLastPosInSlot( int iSlot ) const
+{
+ C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
+ int iMaxSlotPos;
+
+ if ( !player )
+ return -1;
+
+ iMaxSlotPos = -1;
+ for ( int i = 0; i < MAX_WEAPONS; i++ )
+ {
+ C_BaseCombatWeapon *pWeapon = player->GetWeapon(i);
+
+ if ( pWeapon == NULL )
+ continue;
+
+ if ( pWeapon->GetSlot() == iSlot && pWeapon->GetPosition() > iMaxSlotPos )
+ iMaxSlotPos = pWeapon->GetPosition();
+ }
+
+ return iMaxSlotPos;
+}
+
+//-----------------------------------------------------------------------------
+// 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;
+
+ m_pLastWeapon = NULL;
+
+ // 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" );
+ }
+
+ if ( HUDTYPE_CAROUSEL != hud_fastswitch.GetInt() )
+ {
+ // kill any fastswitch display
+ m_flSelectionTime = 0.0f;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Opens the next weapon in the slot
+//-----------------------------------------------------------------------------
+void CHudWeaponSelection::PlusTypeFastWeaponSwitch( int iWeaponSlot )
+{
+ // get the slot the player's weapon is in
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ m_pLastWeapon = NULL;
+ int newSlot = m_iSelectedSlot;
+
+ // Changing slot number does not necessarily mean we need to change the slot - the player could be
+ // scrolling through the same slot but in the opposite direction. Slot pairs are 0,2 and 1,3 - so
+ // compare the 0 bits to see if we're within a pair. Otherwise, reset the box to the zero position.
+ if ( -1 == m_iSelectedSlot || ( ( m_iSelectedSlot ^ iWeaponSlot ) & 1 ) )
+ {
+ // Changing vertical/horizontal direction. Reset the selected box position to zero.
+ m_iSelectedBoxPosition = 0;
+ m_iSelectedSlot = iWeaponSlot;
+ }
+ else
+ {
+ // Still in the same horizontal/vertical direction. Determine which way we're moving in the slot.
+ int increment = 1;
+ if ( m_iSelectedSlot != iWeaponSlot )
+ {
+ // Decrementing within the slot. If we're at the zero position in this slot,
+ // jump to the zero position of the opposite slot. This also counts as our increment.
+ increment = -1;
+ if ( 0 == m_iSelectedBoxPosition )
+ {
+ newSlot = ( m_iSelectedSlot + 2 ) % 4;
+ increment = 0;
+ }
+ }
+
+ // Find out of the box position is at the end of the slot
+ int lastSlotPos = -1;
+ for ( int slotPos = 0; slotPos < MAX_WEAPON_POSITIONS; ++slotPos )
+ {
+ C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( newSlot, slotPos );
+ if ( pWeapon )
+ {
+ lastSlotPos = slotPos;
+ }
+ }
+
+ // Increment/Decrement the selected box position
+ if ( m_iSelectedBoxPosition + increment <= lastSlotPos )
+ {
+ m_iSelectedBoxPosition += increment;
+ m_iSelectedSlot = newSlot;
+ }
+ else
+ {
+ // error sound
+ pPlayer->EmitSound( "Player.DenyWeaponSelection" );
+ return;
+ }
+ }
+
+ // Select the weapon in this position
+ bool bWeaponSelected = false;
+ C_BaseCombatWeapon *pActiveWeapon = pPlayer->GetActiveWeapon();
+ C_BaseCombatWeapon *pWeapon = GetWeaponInSlot( m_iSelectedSlot, m_iSelectedBoxPosition );
+ if ( pWeapon )
+ {
+ if ( pWeapon != pActiveWeapon )
+ {
+ // Select the new weapon
+ ::input->MakeWeaponSelection( pWeapon );
+ SetSelectedWeapon( pWeapon );
+ bWeaponSelected = true;
+ }
+ }
+
+ if ( !bWeaponSelected )
+ {
+ // Still need to set this to make hud display appear
+ SetSelectedWeapon( pPlayer->GetActiveWeapon() );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// 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;
+
+ switch( hud_fastswitch.GetInt() )
+ {
+ case HUDTYPE_FASTSWITCH:
+ case HUDTYPE_CAROUSEL:
+ {
+ FastWeaponSwitch( iSlot );
+ return;
+ }
+
+ case HUDTYPE_PLUS:
+ {
+ if ( !IsInSelectionMode() )
+ {
+ // open the weapon selection
+ OpenSelection();
+ }
+
+ PlusTypeFastWeaponSwitch( iSlot );
+ ActivateWeaponHighlight( GetSelectedWeapon() );
+ }
+ break;
+
+ case HUDTYPE_BUCKETS:
+ {
+ 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 );
+ SetSelectedSlideDir( 0 );
+ }
+ }
+
+ default:
+ {
+ // do nothing
+ }
+ break;
+ }
+
+ pPlayer->EmitSound( "Player.WeaponSelectionMoveSlot" );
+}
diff --git a/mp/src/game/client/hl2/hud_zoom.cpp b/mp/src/game/client/hl2/hud_zoom.cpp
index e26e9ac2..8b47e879 100644
--- a/mp/src/game/client/hl2/hud_zoom.cpp
+++ b/mp/src/game/client/hl2/hud_zoom.cpp
@@ -1,272 +1,272 @@
-//========= 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 "c_basehlplayer.h"
-#include "VGuiMatSurface/IMatSystemSurface.h"
-#include "materialsystem/imaterial.h"
-#include "materialsystem/imesh.h"
-#include "materialsystem/imaterialvar.h"
-#include "../hud_crosshair.h"
-
-#include <vgui/IScheme.h>
-#include <vgui/ISurface.h>
-#include <KeyValues.h>
-#include <vgui_controls/AnimationController.h>
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//-----------------------------------------------------------------------------
-// Purpose: Draws the zoom screen
-//-----------------------------------------------------------------------------
-class CHudZoom : public vgui::Panel, public CHudElement
-{
- DECLARE_CLASS_SIMPLE( CHudZoom, vgui::Panel );
-
-public:
- CHudZoom( const char *pElementName );
-
- bool ShouldDraw( void );
- void Init( void );
- void LevelInit( void );
-
-protected:
- virtual void ApplySchemeSettings(vgui::IScheme *scheme);
- virtual void Paint( void );
-
-private:
- bool m_bZoomOn;
- float m_flZoomStartTime;
- bool m_bPainted;
-
- CPanelAnimationVarAliasType( float, m_flCircle1Radius, "Circle1Radius", "66", "proportional_float" );
- CPanelAnimationVarAliasType( float, m_flCircle2Radius, "Circle2Radius", "74", "proportional_float" );
- CPanelAnimationVarAliasType( float, m_flDashGap, "DashGap", "16", "proportional_float" );
- CPanelAnimationVarAliasType( float, m_flDashHeight, "DashHeight", "4", "proportional_float" );
-
- CMaterialReference m_ZoomMaterial;
-};
-
-DECLARE_HUDELEMENT( CHudZoom );
-
-using namespace vgui;
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CHudZoom::CHudZoom( const char *pElementName ) : CHudElement(pElementName), BaseClass(NULL, "HudZoom")
-{
- vgui::Panel *pParent = g_pClientMode->GetViewport();
- SetParent( pParent );
-
- SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: standard hud element init function
-//-----------------------------------------------------------------------------
-void CHudZoom::Init( void )
-{
- m_bZoomOn = false;
- m_bPainted = false;
- m_flZoomStartTime = -999.0f;
- m_ZoomMaterial.Init( "vgui/zoom", TEXTURE_GROUP_VGUI );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: standard hud element init function
-//-----------------------------------------------------------------------------
-void CHudZoom::LevelInit( void )
-{
- Init();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: sets scheme colors
-//-----------------------------------------------------------------------------
-void CHudZoom::ApplySchemeSettings( vgui::IScheme *scheme )
-{
- BaseClass::ApplySchemeSettings(scheme);
-
- SetPaintBackgroundEnabled(false);
- SetPaintBorderEnabled(false);
- SetFgColor(scheme->GetColor("ZoomReticleColor", GetFgColor()));
-
- SetForceStereoRenderToFrameBuffer( true );
- int x, y;
- int screenWide, screenTall;
- surface()->GetFullscreenViewport( x, y, screenWide, screenTall );
- SetBounds(0, 0, screenWide, screenTall);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Save CPU cycles by letting the HUD system early cull
-// costly traversal. Called per frame, return true if thinking and
-// painting need to occur.
-//-----------------------------------------------------------------------------
-bool CHudZoom::ShouldDraw( void )
-{
- bool bNeedsDraw = false;
-
- C_BaseHLPlayer *pPlayer = dynamic_cast<C_BaseHLPlayer *>(C_BasePlayer::GetLocalPlayer());
- if ( pPlayer == NULL )
- return false;
-
- if ( pPlayer->m_HL2Local.m_bZooming )
- {
- // need to paint
- bNeedsDraw = true;
- }
- else if ( m_bPainted )
- {
- // keep painting until state is finished
- bNeedsDraw = true;
- }
-
- return ( bNeedsDraw && CHudElement::ShouldDraw() );
-}
-
-#define ZOOM_FADE_TIME 0.4f
-//-----------------------------------------------------------------------------
-// Purpose: draws the zoom effect
-//-----------------------------------------------------------------------------
-void CHudZoom::Paint( void )
-{
- m_bPainted = false;
-
- // see if we're zoomed any
- C_BaseHLPlayer *pPlayer = dynamic_cast<C_BaseHLPlayer *>(C_BasePlayer::GetLocalPlayer());
- if ( pPlayer == NULL )
- return;
-
- if ( pPlayer->m_HL2Local.m_bZooming && m_bZoomOn == false )
- {
- m_bZoomOn = true;
- m_flZoomStartTime = gpGlobals->curtime;
- }
- else if ( pPlayer->m_HL2Local.m_bZooming == false && m_bZoomOn )
- {
- m_bZoomOn = false;
- m_flZoomStartTime = gpGlobals->curtime;
- }
-
- // draw the appropriately scaled zoom animation
- float deltaTime = ( gpGlobals->curtime - m_flZoomStartTime );
- float scale = clamp( deltaTime / ZOOM_FADE_TIME, 0.0f, 1.0f );
-
- float alpha;
-
- if ( m_bZoomOn )
- {
- alpha = scale;
- }
- else
- {
- if ( scale >= 1.0f )
- return;
-
- alpha = ( 1.0f - scale ) * 0.25f;
- scale = 1.0f - ( scale * 0.5f );
- }
-
- Color col = GetFgColor();
- col[3] = alpha * 64;
-
- surface()->DrawSetColor( col );
-
- // draw zoom circles
- float fX, fY;
- bool bBehindCamera = false;
- CHudCrosshair::GetDrawPosition( &fX, &fY, &bBehindCamera );
- if( bBehindCamera )
- return;
- int xCrosshair = (int)fX;
- int yCrosshair = (int)fY;
- int wide, tall;
- GetSize( wide, tall );
-
- surface()->DrawOutlinedCircle( xCrosshair, yCrosshair, m_flCircle1Radius * scale, 48);
- surface()->DrawOutlinedCircle( xCrosshair, yCrosshair, m_flCircle2Radius * scale, 64);
-
- // draw dashed lines
- int dashCount = 2;
- int ypos = yCrosshair - m_flDashHeight / 2.f;
- float fGap = m_flDashGap * MAX(scale,0.1f);
- int dashMax = Max(fX, (float)wide - fX ) / fGap;
- while ( dashCount < dashMax )
- {
- int xpos = (int)(fX - fGap * dashCount + 0.5f);
- surface()->DrawFilledRect(xpos, ypos, xpos + 1, ypos + m_flDashHeight);
- xpos = (int)(fX + fGap * dashCount + 0.5f);
- surface()->DrawFilledRect(xpos, ypos, xpos + 1, ypos + m_flDashHeight);
- dashCount++;
- }
-
- // draw the darkened edges, with a rotated texture in the four corners
- CMatRenderContextPtr pRenderContext( materials );
- pRenderContext->Bind( m_ZoomMaterial );
- IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, NULL );
-
- float x0 = 0.0f, x1 = fX, x2 = wide;
- float y0 = 0.0f, y1 = fY, y2 = tall;
-
- float uv1 = 1.0f - (1.0f / 255.0f);
- float uv2 = 0.0f + (1.0f / 255.0f);
-
- struct coord_t
- {
- float x, y;
- float u, v;
- };
- coord_t coords[16] =
- {
- // top-left
- { x0, y0, uv1, uv2 },
- { x1, y0, uv2, uv2 },
- { x1, y1, uv2, uv1 },
- { x0, y1, uv1, uv1 },
-
- // top-right
- { x1, y0, uv2, uv2 },
- { x2, y0, uv1, uv2 },
- { x2, y1, uv1, uv1 },
- { x1, y1, uv2, uv1 },
-
- // bottom-right
- { x1, y1, uv2, uv1 },
- { x2, y1, uv1, uv1 },
- { x2, y2, uv1, uv2 },
- { x1, y2, uv2, uv2 },
-
- // bottom-left
- { x0, y1, uv1, uv1 },
- { x1, y1, uv2, uv1 },
- { x1, y2, uv2, uv2 },
- { x0, y2, uv1, uv2 },
- };
-
- CMeshBuilder meshBuilder;
- meshBuilder.Begin( pMesh, MATERIAL_QUADS, 4 );
-
- for (int i = 0; i < 16; i++)
- {
- meshBuilder.Color4f( 0.0, 0.0, 0.0, alpha );
- meshBuilder.TexCoord2f( 0, coords[i].u, coords[i].v );
- meshBuilder.Position3f( coords[i].x, coords[i].y, 0.0f );
- meshBuilder.AdvanceVertex();
- }
-
- meshBuilder.End();
- pMesh->Draw();
-
- m_bPainted = true;
-}
+//========= 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 "c_basehlplayer.h"
+#include "VGuiMatSurface/IMatSystemSurface.h"
+#include "materialsystem/imaterial.h"
+#include "materialsystem/imesh.h"
+#include "materialsystem/imaterialvar.h"
+#include "../hud_crosshair.h"
+
+#include <vgui/IScheme.h>
+#include <vgui/ISurface.h>
+#include <KeyValues.h>
+#include <vgui_controls/AnimationController.h>
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: Draws the zoom screen
+//-----------------------------------------------------------------------------
+class CHudZoom : public vgui::Panel, public CHudElement
+{
+ DECLARE_CLASS_SIMPLE( CHudZoom, vgui::Panel );
+
+public:
+ CHudZoom( const char *pElementName );
+
+ bool ShouldDraw( void );
+ void Init( void );
+ void LevelInit( void );
+
+protected:
+ virtual void ApplySchemeSettings(vgui::IScheme *scheme);
+ virtual void Paint( void );
+
+private:
+ bool m_bZoomOn;
+ float m_flZoomStartTime;
+ bool m_bPainted;
+
+ CPanelAnimationVarAliasType( float, m_flCircle1Radius, "Circle1Radius", "66", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flCircle2Radius, "Circle2Radius", "74", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flDashGap, "DashGap", "16", "proportional_float" );
+ CPanelAnimationVarAliasType( float, m_flDashHeight, "DashHeight", "4", "proportional_float" );
+
+ CMaterialReference m_ZoomMaterial;
+};
+
+DECLARE_HUDELEMENT( CHudZoom );
+
+using namespace vgui;
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CHudZoom::CHudZoom( const char *pElementName ) : CHudElement(pElementName), BaseClass(NULL, "HudZoom")
+{
+ vgui::Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+
+ SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: standard hud element init function
+//-----------------------------------------------------------------------------
+void CHudZoom::Init( void )
+{
+ m_bZoomOn = false;
+ m_bPainted = false;
+ m_flZoomStartTime = -999.0f;
+ m_ZoomMaterial.Init( "vgui/zoom", TEXTURE_GROUP_VGUI );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: standard hud element init function
+//-----------------------------------------------------------------------------
+void CHudZoom::LevelInit( void )
+{
+ Init();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: sets scheme colors
+//-----------------------------------------------------------------------------
+void CHudZoom::ApplySchemeSettings( vgui::IScheme *scheme )
+{
+ BaseClass::ApplySchemeSettings(scheme);
+
+ SetPaintBackgroundEnabled(false);
+ SetPaintBorderEnabled(false);
+ SetFgColor(scheme->GetColor("ZoomReticleColor", GetFgColor()));
+
+ SetForceStereoRenderToFrameBuffer( true );
+ int x, y;
+ int screenWide, screenTall;
+ surface()->GetFullscreenViewport( x, y, screenWide, screenTall );
+ SetBounds(0, 0, screenWide, screenTall);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Save CPU cycles by letting the HUD system early cull
+// costly traversal. Called per frame, return true if thinking and
+// painting need to occur.
+//-----------------------------------------------------------------------------
+bool CHudZoom::ShouldDraw( void )
+{
+ bool bNeedsDraw = false;
+
+ C_BaseHLPlayer *pPlayer = dynamic_cast<C_BaseHLPlayer *>(C_BasePlayer::GetLocalPlayer());
+ if ( pPlayer == NULL )
+ return false;
+
+ if ( pPlayer->m_HL2Local.m_bZooming )
+ {
+ // need to paint
+ bNeedsDraw = true;
+ }
+ else if ( m_bPainted )
+ {
+ // keep painting until state is finished
+ bNeedsDraw = true;
+ }
+
+ return ( bNeedsDraw && CHudElement::ShouldDraw() );
+}
+
+#define ZOOM_FADE_TIME 0.4f
+//-----------------------------------------------------------------------------
+// Purpose: draws the zoom effect
+//-----------------------------------------------------------------------------
+void CHudZoom::Paint( void )
+{
+ m_bPainted = false;
+
+ // see if we're zoomed any
+ C_BaseHLPlayer *pPlayer = dynamic_cast<C_BaseHLPlayer *>(C_BasePlayer::GetLocalPlayer());
+ if ( pPlayer == NULL )
+ return;
+
+ if ( pPlayer->m_HL2Local.m_bZooming && m_bZoomOn == false )
+ {
+ m_bZoomOn = true;
+ m_flZoomStartTime = gpGlobals->curtime;
+ }
+ else if ( pPlayer->m_HL2Local.m_bZooming == false && m_bZoomOn )
+ {
+ m_bZoomOn = false;
+ m_flZoomStartTime = gpGlobals->curtime;
+ }
+
+ // draw the appropriately scaled zoom animation
+ float deltaTime = ( gpGlobals->curtime - m_flZoomStartTime );
+ float scale = clamp( deltaTime / ZOOM_FADE_TIME, 0.0f, 1.0f );
+
+ float alpha;
+
+ if ( m_bZoomOn )
+ {
+ alpha = scale;
+ }
+ else
+ {
+ if ( scale >= 1.0f )
+ return;
+
+ alpha = ( 1.0f - scale ) * 0.25f;
+ scale = 1.0f - ( scale * 0.5f );
+ }
+
+ Color col = GetFgColor();
+ col[3] = alpha * 64;
+
+ surface()->DrawSetColor( col );
+
+ // draw zoom circles
+ float fX, fY;
+ bool bBehindCamera = false;
+ CHudCrosshair::GetDrawPosition( &fX, &fY, &bBehindCamera );
+ if( bBehindCamera )
+ return;
+ int xCrosshair = (int)fX;
+ int yCrosshair = (int)fY;
+ int wide, tall;
+ GetSize( wide, tall );
+
+ surface()->DrawOutlinedCircle( xCrosshair, yCrosshair, m_flCircle1Radius * scale, 48);
+ surface()->DrawOutlinedCircle( xCrosshair, yCrosshair, m_flCircle2Radius * scale, 64);
+
+ // draw dashed lines
+ int dashCount = 2;
+ int ypos = yCrosshair - m_flDashHeight / 2.f;
+ float fGap = m_flDashGap * MAX(scale,0.1f);
+ int dashMax = Max(fX, (float)wide - fX ) / fGap;
+ while ( dashCount < dashMax )
+ {
+ int xpos = (int)(fX - fGap * dashCount + 0.5f);
+ surface()->DrawFilledRect(xpos, ypos, xpos + 1, ypos + m_flDashHeight);
+ xpos = (int)(fX + fGap * dashCount + 0.5f);
+ surface()->DrawFilledRect(xpos, ypos, xpos + 1, ypos + m_flDashHeight);
+ dashCount++;
+ }
+
+ // draw the darkened edges, with a rotated texture in the four corners
+ CMatRenderContextPtr pRenderContext( materials );
+ pRenderContext->Bind( m_ZoomMaterial );
+ IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, NULL );
+
+ float x0 = 0.0f, x1 = fX, x2 = wide;
+ float y0 = 0.0f, y1 = fY, y2 = tall;
+
+ float uv1 = 1.0f - (1.0f / 255.0f);
+ float uv2 = 0.0f + (1.0f / 255.0f);
+
+ struct coord_t
+ {
+ float x, y;
+ float u, v;
+ };
+ coord_t coords[16] =
+ {
+ // top-left
+ { x0, y0, uv1, uv2 },
+ { x1, y0, uv2, uv2 },
+ { x1, y1, uv2, uv1 },
+ { x0, y1, uv1, uv1 },
+
+ // top-right
+ { x1, y0, uv2, uv2 },
+ { x2, y0, uv1, uv2 },
+ { x2, y1, uv1, uv1 },
+ { x1, y1, uv2, uv1 },
+
+ // bottom-right
+ { x1, y1, uv2, uv1 },
+ { x2, y1, uv1, uv1 },
+ { x2, y2, uv1, uv2 },
+ { x1, y2, uv2, uv2 },
+
+ // bottom-left
+ { x0, y1, uv1, uv1 },
+ { x1, y1, uv2, uv1 },
+ { x1, y2, uv2, uv2 },
+ { x0, y2, uv1, uv2 },
+ };
+
+ CMeshBuilder meshBuilder;
+ meshBuilder.Begin( pMesh, MATERIAL_QUADS, 4 );
+
+ for (int i = 0; i < 16; i++)
+ {
+ meshBuilder.Color4f( 0.0, 0.0, 0.0, alpha );
+ meshBuilder.TexCoord2f( 0, coords[i].u, coords[i].v );
+ meshBuilder.Position3f( coords[i].x, coords[i].y, 0.0f );
+ meshBuilder.AdvanceVertex();
+ }
+
+ meshBuilder.End();
+ pMesh->Draw();
+
+ m_bPainted = true;
+}
diff --git a/mp/src/game/client/hl2/shieldproxy.cpp b/mp/src/game/client/hl2/shieldproxy.cpp
index 745c1a38..ff3a5820 100644
--- a/mp/src/game/client/hl2/shieldproxy.cpp
+++ b/mp/src/game/client/hl2/shieldproxy.cpp
@@ -1,110 +1,110 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "proxyentity.h"
-#include "materialsystem/imaterial.h"
-#include "materialsystem/imaterialvar.h"
-#include "materialsystem/imaterialsystem.h"
-#include <KeyValues.h>
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-// $sineVar : name of variable that controls the alpha level (float)
-class CShieldProxy : public CEntityMaterialProxy
-{
-public:
- CShieldProxy();
- virtual ~CShieldProxy();
- virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
- virtual void OnBind( C_BaseEntity *pC_BaseEntity );
- virtual IMaterial *GetMaterial();
-
-private:
- IMaterialVar *m_AlphaVar;
- IMaterialVar *m_pTextureScrollVar;
- float m_ScrollRate;
- float m_ScrollAngle;
-};
-
-CShieldProxy::CShieldProxy()
-{
- m_AlphaVar = NULL;
- m_pTextureScrollVar = NULL;
- m_ScrollRate = 0;
- m_ScrollAngle = 0;
-}
-
-CShieldProxy::~CShieldProxy()
-{
-}
-
-
-bool CShieldProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
-{
- bool foundVar;
-
- m_AlphaVar = pMaterial->FindVar( "$translucency", &foundVar, false );
- if( !foundVar )
- return false;
-
- char const* pScrollVarName = pKeyValues->GetString( "textureScrollVar" );
- if (!pScrollVarName)
- return false;
-
- m_pTextureScrollVar = pMaterial->FindVar( pScrollVarName, &foundVar, false );
- if( !foundVar )
- return false;
-
- m_ScrollRate = pKeyValues->GetFloat( "textureScrollRate", 1 );
- m_ScrollAngle = pKeyValues->GetFloat( "textureScrollAngle", 0 );
- return true;
-}
-
-void CShieldProxy::OnBind( C_BaseEntity *pEnt )
-{
- if (m_AlphaVar)
- {
- m_AlphaVar->SetFloatValue( pEnt->m_clrRender->a );
- }
-
- if( !m_pTextureScrollVar )
- {
- return;
- }
-
- float sOffset, tOffset;
-
- sOffset = gpGlobals->curtime * sin( m_ScrollAngle * ( M_PI / 180.0f ) ) * m_ScrollRate;
- tOffset = gpGlobals->curtime * cos( m_ScrollAngle * ( M_PI / 180.0f ) ) * m_ScrollRate;
-
- // make sure that we are positive
- if( sOffset < 0.0f )
- {
- sOffset += 1.0f + -( int )sOffset;
- }
- if( tOffset < 0.0f )
- {
- tOffset += 1.0f + -( int )tOffset;
- }
-
- // make sure that we are in a [0,1] range
- sOffset = sOffset - ( int )sOffset;
- tOffset = tOffset - ( int )tOffset;
-
- m_pTextureScrollVar->SetVecValue( sOffset, tOffset, 0.0f );
-}
-
-IMaterial *CShieldProxy::GetMaterial()
-{
- if ( !m_AlphaVar )
- return NULL;
-
- return m_AlphaVar->GetOwningMaterial();
-}
-
-EXPOSE_INTERFACE( CShieldProxy, IMaterialProxy, "Shield" IMATERIAL_PROXY_INTERFACE_VERSION );
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "proxyentity.h"
+#include "materialsystem/imaterial.h"
+#include "materialsystem/imaterialvar.h"
+#include "materialsystem/imaterialsystem.h"
+#include <KeyValues.h>
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+// $sineVar : name of variable that controls the alpha level (float)
+class CShieldProxy : public CEntityMaterialProxy
+{
+public:
+ CShieldProxy();
+ virtual ~CShieldProxy();
+ virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
+ virtual void OnBind( C_BaseEntity *pC_BaseEntity );
+ virtual IMaterial *GetMaterial();
+
+private:
+ IMaterialVar *m_AlphaVar;
+ IMaterialVar *m_pTextureScrollVar;
+ float m_ScrollRate;
+ float m_ScrollAngle;
+};
+
+CShieldProxy::CShieldProxy()
+{
+ m_AlphaVar = NULL;
+ m_pTextureScrollVar = NULL;
+ m_ScrollRate = 0;
+ m_ScrollAngle = 0;
+}
+
+CShieldProxy::~CShieldProxy()
+{
+}
+
+
+bool CShieldProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
+{
+ bool foundVar;
+
+ m_AlphaVar = pMaterial->FindVar( "$translucency", &foundVar, false );
+ if( !foundVar )
+ return false;
+
+ char const* pScrollVarName = pKeyValues->GetString( "textureScrollVar" );
+ if (!pScrollVarName)
+ return false;
+
+ m_pTextureScrollVar = pMaterial->FindVar( pScrollVarName, &foundVar, false );
+ if( !foundVar )
+ return false;
+
+ m_ScrollRate = pKeyValues->GetFloat( "textureScrollRate", 1 );
+ m_ScrollAngle = pKeyValues->GetFloat( "textureScrollAngle", 0 );
+ return true;
+}
+
+void CShieldProxy::OnBind( C_BaseEntity *pEnt )
+{
+ if (m_AlphaVar)
+ {
+ m_AlphaVar->SetFloatValue( pEnt->m_clrRender->a );
+ }
+
+ if( !m_pTextureScrollVar )
+ {
+ return;
+ }
+
+ float sOffset, tOffset;
+
+ sOffset = gpGlobals->curtime * sin( m_ScrollAngle * ( M_PI / 180.0f ) ) * m_ScrollRate;
+ tOffset = gpGlobals->curtime * cos( m_ScrollAngle * ( M_PI / 180.0f ) ) * m_ScrollRate;
+
+ // make sure that we are positive
+ if( sOffset < 0.0f )
+ {
+ sOffset += 1.0f + -( int )sOffset;
+ }
+ if( tOffset < 0.0f )
+ {
+ tOffset += 1.0f + -( int )tOffset;
+ }
+
+ // make sure that we are in a [0,1] range
+ sOffset = sOffset - ( int )sOffset;
+ tOffset = tOffset - ( int )tOffset;
+
+ m_pTextureScrollVar->SetVecValue( sOffset, tOffset, 0.0f );
+}
+
+IMaterial *CShieldProxy::GetMaterial()
+{
+ if ( !m_AlphaVar )
+ return NULL;
+
+ return m_AlphaVar->GetOwningMaterial();
+}
+
+EXPOSE_INTERFACE( CShieldProxy, IMaterialProxy, "Shield" IMATERIAL_PROXY_INTERFACE_VERSION );
diff --git a/mp/src/game/client/hl2/vgui_rootpanel_hl2.cpp b/mp/src/game/client/hl2/vgui_rootpanel_hl2.cpp
index 6d322237..fbb952d7 100644
--- a/mp/src/game/client/hl2/vgui_rootpanel_hl2.cpp
+++ b/mp/src/game/client/hl2/vgui_rootpanel_hl2.cpp
@@ -1,37 +1,37 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "vgui_int.h"
-#include "ienginevgui.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void VGUI_CreateClientDLLRootPanel( void )
-{
- // Just using PANEL_ROOT in HL2 right now
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void VGUI_DestroyClientDLLRootPanel( void )
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Game specific root panel
-// Output : vgui::Panel
-//-----------------------------------------------------------------------------
-vgui::VPANEL VGui_GetClientDLLRootPanel( void )
-{
- vgui::VPANEL root = enginevgui->GetPanel( PANEL_CLIENTDLL );
- return root;
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "vgui_int.h"
+#include "ienginevgui.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void VGUI_CreateClientDLLRootPanel( void )
+{
+ // Just using PANEL_ROOT in HL2 right now
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void VGUI_DestroyClientDLLRootPanel( void )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Game specific root panel
+// Output : vgui::Panel
+//-----------------------------------------------------------------------------
+vgui::VPANEL VGui_GetClientDLLRootPanel( void )
+{
+ vgui::VPANEL root = enginevgui->GetPanel( PANEL_CLIENTDLL );
+ return root;
+}