From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/game/server/EnvShake.cpp | 826 ++++++++++++++++++++-------------------- 1 file changed, 413 insertions(+), 413 deletions(-) (limited to 'mp/src/game/server/EnvShake.cpp') diff --git a/mp/src/game/server/EnvShake.cpp b/mp/src/game/server/EnvShake.cpp index 01b83a06..14d4a514 100644 --- a/mp/src/game/server/EnvShake.cpp +++ b/mp/src/game/server/EnvShake.cpp @@ -1,413 +1,413 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Implements a screen shake effect that can also shake physics objects. -// -// NOTE: UTIL_ScreenShake() will only shake players who are on the ground -// -// $NoKeywords: $ -//=============================================================================// - -#include "cbase.h" -#include "shake.h" -#include "physics_saverestore.h" -#include "rope.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -class CPhysicsShake : public IMotionEvent -{ - DECLARE_SIMPLE_DATADESC(); - -public: - virtual simresult_e Simulate( IPhysicsMotionController *pController, IPhysicsObject *pObject, float deltaTime, Vector &linear, AngularImpulse &angular ) - { - Vector contact; - if ( !pObject->GetContactPoint( &contact, NULL ) ) - return SIM_NOTHING; - - // fudge the force a bit to make it more dramatic - pObject->CalculateForceOffset( m_force * (1.0f + pObject->GetMass()*0.4f), contact, &linear, &angular ); - - return SIM_LOCAL_FORCE; - } - - Vector m_force; -}; - -BEGIN_SIMPLE_DATADESC( CPhysicsShake ) - DEFINE_FIELD( m_force, FIELD_VECTOR ), -END_DATADESC() - - -class CEnvShake : public CPointEntity -{ -private: - float m_Amplitude; - float m_Frequency; - float m_Duration; - float m_Radius; // radius of 0 means all players - float m_stopTime; - float m_nextShake; - float m_currentAmp; - - Vector m_maxForce; - - IPhysicsMotionController *m_pShakeController; - CPhysicsShake m_shakeCallback; - - DECLARE_DATADESC(); - -public: - DECLARE_CLASS( CEnvShake, CPointEntity ); - - ~CEnvShake( void ); - virtual void Spawn( void ); - virtual void OnRestore( void ); - - inline float Amplitude( void ) { return m_Amplitude; } - inline float Frequency( void ) { return m_Frequency; } - inline float Duration( void ) { return m_Duration; } - float Radius( bool bPlayers = true ); - inline void SetAmplitude( float amplitude ) { m_Amplitude = amplitude; } - inline void SetFrequency( float frequency ) { m_Frequency = frequency; } - inline void SetDuration( float duration ) { m_Duration = duration; } - inline void SetRadius( float radius ) { m_Radius = radius; } - - int DrawDebugTextOverlays(void); - - // Input handlers - void InputStartShake( inputdata_t &inputdata ); - void InputStopShake( inputdata_t &inputdata ); - void InputAmplitude( inputdata_t &inputdata ); - void InputFrequency( inputdata_t &inputdata ); - - // Causes the camera/physics shakes to happen: - void ApplyShake( ShakeCommand_t command ); - void Think( void ); -}; - -LINK_ENTITY_TO_CLASS( env_shake, CEnvShake ); - -BEGIN_DATADESC( CEnvShake ) - - DEFINE_KEYFIELD( m_Amplitude, FIELD_FLOAT, "amplitude" ), - DEFINE_KEYFIELD( m_Frequency, FIELD_FLOAT, "frequency" ), - DEFINE_KEYFIELD( m_Duration, FIELD_FLOAT, "duration" ), - DEFINE_KEYFIELD( m_Radius, FIELD_FLOAT, "radius" ), - DEFINE_FIELD( m_stopTime, FIELD_TIME ), - DEFINE_FIELD( m_nextShake, FIELD_TIME ), - DEFINE_FIELD( m_currentAmp, FIELD_FLOAT ), - DEFINE_FIELD( m_maxForce, FIELD_VECTOR ), - DEFINE_PHYSPTR( m_pShakeController ), - DEFINE_EMBEDDED( m_shakeCallback ), - - DEFINE_INPUTFUNC( FIELD_VOID, "StartShake", InputStartShake ), - DEFINE_INPUTFUNC( FIELD_VOID, "StopShake", InputStopShake ), - DEFINE_INPUTFUNC( FIELD_FLOAT, "Amplitude", InputAmplitude ), - DEFINE_INPUTFUNC( FIELD_FLOAT, "Frequency", InputFrequency ), - -END_DATADESC() - - - -#define SF_SHAKE_EVERYONE 0x0001 // Don't check radius -#define SF_SHAKE_INAIR 0x0004 // Shake players in air -#define SF_SHAKE_PHYSICS 0x0008 // Shake physically (not just camera) -#define SF_SHAKE_ROPES 0x0010 // Shake ropes too. -#define SF_SHAKE_NO_VIEW 0x0020 // DON'T shake the view (only ropes and/or physics objects) -#define SF_SHAKE_NO_RUMBLE 0x0040 // DON'T Rumble the XBox Controller - - -//----------------------------------------------------------------------------- -// Purpose: Destructor. -//----------------------------------------------------------------------------- -CEnvShake::~CEnvShake( void ) -{ - if ( m_pShakeController ) - { - physenv->DestroyMotionController( m_pShakeController ); - } -} - - -float CEnvShake::Radius(bool bPlayers) -{ - // The radius for players is zero if SF_SHAKE_EVERYONE is set - if ( bPlayers && HasSpawnFlags(SF_SHAKE_EVERYONE)) - return 0; - return m_Radius; -} - - -//----------------------------------------------------------------------------- -// Purpose: Sets default member values when spawning. -//----------------------------------------------------------------------------- -void CEnvShake::Spawn( void ) -{ - SetSolid( SOLID_NONE ); - SetMoveType( MOVETYPE_NONE ); - - if ( GetSpawnFlags() & SF_SHAKE_EVERYONE ) - { - m_Radius = 0; - } - - if ( HasSpawnFlags( SF_SHAKE_NO_VIEW ) && !HasSpawnFlags( SF_SHAKE_PHYSICS ) && !HasSpawnFlags( SF_SHAKE_ROPES ) ) - { - DevWarning( "env_shake %s with \"Don't shake view\" spawnflag set without \"Shake physics\" or \"Shake ropes\" spawnflags set.", GetDebugName() ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: Restore the motion controller -//----------------------------------------------------------------------------- -void CEnvShake::OnRestore( void ) -{ - BaseClass::OnRestore(); - - if ( m_pShakeController ) - { - m_pShakeController->SetEventHandler( &m_shakeCallback ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CEnvShake::ApplyShake( ShakeCommand_t command ) -{ - if ( !HasSpawnFlags( SF_SHAKE_NO_VIEW ) || !HasSpawnFlags( SF_SHAKE_NO_RUMBLE ) ) - { - bool air = (GetSpawnFlags() & SF_SHAKE_INAIR) ? true : false; - UTIL_ScreenShake( GetAbsOrigin(), Amplitude(), Frequency(), Duration(), Radius(), command, air ); - } - - if ( GetSpawnFlags() & SF_SHAKE_ROPES ) - { - CRopeKeyframe::ShakeRopes( GetAbsOrigin(), Radius(false), Frequency() ); - } - - if ( GetSpawnFlags() & SF_SHAKE_PHYSICS ) - { - if ( !m_pShakeController ) - { - m_pShakeController = physenv->CreateMotionController( &m_shakeCallback ); - } - // do physics shake - switch( command ) - { - case SHAKE_START: - case SHAKE_START_NORUMBLE: - case SHAKE_START_RUMBLEONLY: - { - m_stopTime = gpGlobals->curtime + Duration(); - m_nextShake = 0; - m_pShakeController->ClearObjects(); - SetNextThink( gpGlobals->curtime ); - m_currentAmp = Amplitude(); - CBaseEntity *list[1024]; - float radius = Radius(false); - - // probably checked "Shake Everywhere" do a big radius - if ( !radius ) - { - radius = 512; - } - Vector extents = Vector(radius, radius, radius); - extents.z = MAX(extents.z, 100); - Vector mins = GetAbsOrigin() - extents; - Vector maxs = GetAbsOrigin() + extents; - int count = UTIL_EntitiesInBox( list, 1024, mins, maxs, 0 ); - - for ( int i = 0; i < count; i++ ) - { - // - // Only shake physics entities that players can see. This is one frame out of date - // so it's possible that we could miss objects if a player changed PVS this frame. - // - if ( ( list[i]->GetMoveType() == MOVETYPE_VPHYSICS ) ) - { - IPhysicsObject *pPhys = list[i]->VPhysicsGetObject(); - if ( pPhys && pPhys->IsMoveable() ) - { - m_pShakeController->AttachObject( pPhys, false ); - pPhys->Wake(); - } - } - } - } - break; - case SHAKE_STOP: - m_pShakeController->ClearObjects(); - break; - case SHAKE_AMPLITUDE: - m_currentAmp = Amplitude(); - case SHAKE_FREQUENCY: - m_pShakeController->WakeObjects(); - break; - } - } -} - - -//----------------------------------------------------------------------------- -// Purpose: Input handler that starts the screen shake. -//----------------------------------------------------------------------------- -void CEnvShake::InputStartShake( inputdata_t &inputdata ) -{ - if ( HasSpawnFlags( SF_SHAKE_NO_RUMBLE ) ) - { - ApplyShake( SHAKE_START_NORUMBLE ); - } - else if ( HasSpawnFlags( SF_SHAKE_NO_VIEW ) ) - { - ApplyShake( SHAKE_START_RUMBLEONLY ); - } - else - { - ApplyShake( SHAKE_START ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: Input handler that stops the screen shake. -//----------------------------------------------------------------------------- -void CEnvShake::InputStopShake( inputdata_t &inputdata ) -{ - ApplyShake( SHAKE_STOP ); -} - - -//----------------------------------------------------------------------------- -// Purpose: Handles changes to the shake amplitude from an external source. -//----------------------------------------------------------------------------- -void CEnvShake::InputAmplitude( inputdata_t &inputdata ) -{ - SetAmplitude( inputdata.value.Float() ); - ApplyShake( SHAKE_AMPLITUDE ); -} - - -//----------------------------------------------------------------------------- -// Purpose: Handles changes to the shake frequency from an external source. -//----------------------------------------------------------------------------- -void CEnvShake::InputFrequency( inputdata_t &inputdata ) -{ - SetFrequency( inputdata.value.Float() ); - ApplyShake( SHAKE_FREQUENCY ); -} - - -//----------------------------------------------------------------------------- -// Purpose: Calculates the physics shake values -//----------------------------------------------------------------------------- -void CEnvShake::Think( void ) -{ - int i; - - if ( gpGlobals->curtime > m_nextShake ) - { - // Higher frequency means we recalc the extents more often and perturb the display again - m_nextShake = gpGlobals->curtime + (1.0f / Frequency()); - - // Compute random shake extents (the shake will settle down from this) - for (i = 0; i < 2; i++ ) - { - m_maxForce[i] = random->RandomFloat( -1, 1 ); - } - // make the force it point mostly up - m_maxForce.z = 4; - VectorNormalize( m_maxForce ); - m_maxForce *= m_currentAmp * 400; // amplitude is the acceleration of a 100kg object - } - - float fraction = ( m_stopTime - gpGlobals->curtime ) / Duration(); - - if ( fraction < 0 ) - { - m_pShakeController->ClearObjects(); - return; - } - - float freq = 0; - // Ramp up frequency over duration - if ( fraction ) - { - freq = (Frequency() / fraction); - } - - // square fraction to approach zero more quickly - fraction *= fraction; - - // Sine wave that slowly settles to zero - fraction = fraction * sin( gpGlobals->curtime * freq ); - - // Add to view origin - for ( i = 0; i < 3; i++ ) - { - // store the force in the controller callback - m_shakeCallback.m_force[i] = m_maxForce[i] * fraction; - } - - // Drop amplitude a bit, less for higher frequency shakes - m_currentAmp -= m_currentAmp * ( gpGlobals->frametime / (Duration() * Frequency()) ); - SetNextThink( gpGlobals->curtime ); -} - - -//------------------------------------------------------------------------------ -// Purpose: Console command to cause a screen shake. -//------------------------------------------------------------------------------ -void CC_Shake( void ) -{ - CBasePlayer *pPlayer = UTIL_GetCommandClient(); - if (pPlayer) - { - UTIL_ScreenShake( pPlayer->WorldSpaceCenter(), 25.0, 150.0, 1.0, 750, SHAKE_START ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: Draw any debug text overlays -// Returns current text offset from the top -//----------------------------------------------------------------------------- -int CEnvShake::DrawDebugTextOverlays( void ) -{ - int text_offset = BaseClass::DrawDebugTextOverlays(); - - if (m_debugOverlays & OVERLAY_TEXT_BIT) - { - char tempstr[512]; - - // print amplitude - Q_snprintf(tempstr,sizeof(tempstr)," magnitude: %f", m_Amplitude); - EntityText(text_offset,tempstr,0); - text_offset++; - - // print frequency - Q_snprintf(tempstr,sizeof(tempstr)," frequency: %f", m_Frequency); - EntityText(text_offset,tempstr,0); - text_offset++; - - // print duration - Q_snprintf(tempstr,sizeof(tempstr)," duration: %f", m_Duration); - EntityText(text_offset,tempstr,0); - text_offset++; - - // print radius - Q_snprintf(tempstr,sizeof(tempstr)," radius: %f", m_Radius); - EntityText(text_offset,tempstr,0); - text_offset++; - - } - return text_offset; -} - -static ConCommand shake("shake", CC_Shake, "Shake the screen.", FCVAR_CHEAT ); - - +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Implements a screen shake effect that can also shake physics objects. +// +// NOTE: UTIL_ScreenShake() will only shake players who are on the ground +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "shake.h" +#include "physics_saverestore.h" +#include "rope.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +class CPhysicsShake : public IMotionEvent +{ + DECLARE_SIMPLE_DATADESC(); + +public: + virtual simresult_e Simulate( IPhysicsMotionController *pController, IPhysicsObject *pObject, float deltaTime, Vector &linear, AngularImpulse &angular ) + { + Vector contact; + if ( !pObject->GetContactPoint( &contact, NULL ) ) + return SIM_NOTHING; + + // fudge the force a bit to make it more dramatic + pObject->CalculateForceOffset( m_force * (1.0f + pObject->GetMass()*0.4f), contact, &linear, &angular ); + + return SIM_LOCAL_FORCE; + } + + Vector m_force; +}; + +BEGIN_SIMPLE_DATADESC( CPhysicsShake ) + DEFINE_FIELD( m_force, FIELD_VECTOR ), +END_DATADESC() + + +class CEnvShake : public CPointEntity +{ +private: + float m_Amplitude; + float m_Frequency; + float m_Duration; + float m_Radius; // radius of 0 means all players + float m_stopTime; + float m_nextShake; + float m_currentAmp; + + Vector m_maxForce; + + IPhysicsMotionController *m_pShakeController; + CPhysicsShake m_shakeCallback; + + DECLARE_DATADESC(); + +public: + DECLARE_CLASS( CEnvShake, CPointEntity ); + + ~CEnvShake( void ); + virtual void Spawn( void ); + virtual void OnRestore( void ); + + inline float Amplitude( void ) { return m_Amplitude; } + inline float Frequency( void ) { return m_Frequency; } + inline float Duration( void ) { return m_Duration; } + float Radius( bool bPlayers = true ); + inline void SetAmplitude( float amplitude ) { m_Amplitude = amplitude; } + inline void SetFrequency( float frequency ) { m_Frequency = frequency; } + inline void SetDuration( float duration ) { m_Duration = duration; } + inline void SetRadius( float radius ) { m_Radius = radius; } + + int DrawDebugTextOverlays(void); + + // Input handlers + void InputStartShake( inputdata_t &inputdata ); + void InputStopShake( inputdata_t &inputdata ); + void InputAmplitude( inputdata_t &inputdata ); + void InputFrequency( inputdata_t &inputdata ); + + // Causes the camera/physics shakes to happen: + void ApplyShake( ShakeCommand_t command ); + void Think( void ); +}; + +LINK_ENTITY_TO_CLASS( env_shake, CEnvShake ); + +BEGIN_DATADESC( CEnvShake ) + + DEFINE_KEYFIELD( m_Amplitude, FIELD_FLOAT, "amplitude" ), + DEFINE_KEYFIELD( m_Frequency, FIELD_FLOAT, "frequency" ), + DEFINE_KEYFIELD( m_Duration, FIELD_FLOAT, "duration" ), + DEFINE_KEYFIELD( m_Radius, FIELD_FLOAT, "radius" ), + DEFINE_FIELD( m_stopTime, FIELD_TIME ), + DEFINE_FIELD( m_nextShake, FIELD_TIME ), + DEFINE_FIELD( m_currentAmp, FIELD_FLOAT ), + DEFINE_FIELD( m_maxForce, FIELD_VECTOR ), + DEFINE_PHYSPTR( m_pShakeController ), + DEFINE_EMBEDDED( m_shakeCallback ), + + DEFINE_INPUTFUNC( FIELD_VOID, "StartShake", InputStartShake ), + DEFINE_INPUTFUNC( FIELD_VOID, "StopShake", InputStopShake ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "Amplitude", InputAmplitude ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "Frequency", InputFrequency ), + +END_DATADESC() + + + +#define SF_SHAKE_EVERYONE 0x0001 // Don't check radius +#define SF_SHAKE_INAIR 0x0004 // Shake players in air +#define SF_SHAKE_PHYSICS 0x0008 // Shake physically (not just camera) +#define SF_SHAKE_ROPES 0x0010 // Shake ropes too. +#define SF_SHAKE_NO_VIEW 0x0020 // DON'T shake the view (only ropes and/or physics objects) +#define SF_SHAKE_NO_RUMBLE 0x0040 // DON'T Rumble the XBox Controller + + +//----------------------------------------------------------------------------- +// Purpose: Destructor. +//----------------------------------------------------------------------------- +CEnvShake::~CEnvShake( void ) +{ + if ( m_pShakeController ) + { + physenv->DestroyMotionController( m_pShakeController ); + } +} + + +float CEnvShake::Radius(bool bPlayers) +{ + // The radius for players is zero if SF_SHAKE_EVERYONE is set + if ( bPlayers && HasSpawnFlags(SF_SHAKE_EVERYONE)) + return 0; + return m_Radius; +} + + +//----------------------------------------------------------------------------- +// Purpose: Sets default member values when spawning. +//----------------------------------------------------------------------------- +void CEnvShake::Spawn( void ) +{ + SetSolid( SOLID_NONE ); + SetMoveType( MOVETYPE_NONE ); + + if ( GetSpawnFlags() & SF_SHAKE_EVERYONE ) + { + m_Radius = 0; + } + + if ( HasSpawnFlags( SF_SHAKE_NO_VIEW ) && !HasSpawnFlags( SF_SHAKE_PHYSICS ) && !HasSpawnFlags( SF_SHAKE_ROPES ) ) + { + DevWarning( "env_shake %s with \"Don't shake view\" spawnflag set without \"Shake physics\" or \"Shake ropes\" spawnflags set.", GetDebugName() ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Restore the motion controller +//----------------------------------------------------------------------------- +void CEnvShake::OnRestore( void ) +{ + BaseClass::OnRestore(); + + if ( m_pShakeController ) + { + m_pShakeController->SetEventHandler( &m_shakeCallback ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CEnvShake::ApplyShake( ShakeCommand_t command ) +{ + if ( !HasSpawnFlags( SF_SHAKE_NO_VIEW ) || !HasSpawnFlags( SF_SHAKE_NO_RUMBLE ) ) + { + bool air = (GetSpawnFlags() & SF_SHAKE_INAIR) ? true : false; + UTIL_ScreenShake( GetAbsOrigin(), Amplitude(), Frequency(), Duration(), Radius(), command, air ); + } + + if ( GetSpawnFlags() & SF_SHAKE_ROPES ) + { + CRopeKeyframe::ShakeRopes( GetAbsOrigin(), Radius(false), Frequency() ); + } + + if ( GetSpawnFlags() & SF_SHAKE_PHYSICS ) + { + if ( !m_pShakeController ) + { + m_pShakeController = physenv->CreateMotionController( &m_shakeCallback ); + } + // do physics shake + switch( command ) + { + case SHAKE_START: + case SHAKE_START_NORUMBLE: + case SHAKE_START_RUMBLEONLY: + { + m_stopTime = gpGlobals->curtime + Duration(); + m_nextShake = 0; + m_pShakeController->ClearObjects(); + SetNextThink( gpGlobals->curtime ); + m_currentAmp = Amplitude(); + CBaseEntity *list[1024]; + float radius = Radius(false); + + // probably checked "Shake Everywhere" do a big radius + if ( !radius ) + { + radius = 512; + } + Vector extents = Vector(radius, radius, radius); + extents.z = MAX(extents.z, 100); + Vector mins = GetAbsOrigin() - extents; + Vector maxs = GetAbsOrigin() + extents; + int count = UTIL_EntitiesInBox( list, 1024, mins, maxs, 0 ); + + for ( int i = 0; i < count; i++ ) + { + // + // Only shake physics entities that players can see. This is one frame out of date + // so it's possible that we could miss objects if a player changed PVS this frame. + // + if ( ( list[i]->GetMoveType() == MOVETYPE_VPHYSICS ) ) + { + IPhysicsObject *pPhys = list[i]->VPhysicsGetObject(); + if ( pPhys && pPhys->IsMoveable() ) + { + m_pShakeController->AttachObject( pPhys, false ); + pPhys->Wake(); + } + } + } + } + break; + case SHAKE_STOP: + m_pShakeController->ClearObjects(); + break; + case SHAKE_AMPLITUDE: + m_currentAmp = Amplitude(); + case SHAKE_FREQUENCY: + m_pShakeController->WakeObjects(); + break; + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Input handler that starts the screen shake. +//----------------------------------------------------------------------------- +void CEnvShake::InputStartShake( inputdata_t &inputdata ) +{ + if ( HasSpawnFlags( SF_SHAKE_NO_RUMBLE ) ) + { + ApplyShake( SHAKE_START_NORUMBLE ); + } + else if ( HasSpawnFlags( SF_SHAKE_NO_VIEW ) ) + { + ApplyShake( SHAKE_START_RUMBLEONLY ); + } + else + { + ApplyShake( SHAKE_START ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Input handler that stops the screen shake. +//----------------------------------------------------------------------------- +void CEnvShake::InputStopShake( inputdata_t &inputdata ) +{ + ApplyShake( SHAKE_STOP ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Handles changes to the shake amplitude from an external source. +//----------------------------------------------------------------------------- +void CEnvShake::InputAmplitude( inputdata_t &inputdata ) +{ + SetAmplitude( inputdata.value.Float() ); + ApplyShake( SHAKE_AMPLITUDE ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Handles changes to the shake frequency from an external source. +//----------------------------------------------------------------------------- +void CEnvShake::InputFrequency( inputdata_t &inputdata ) +{ + SetFrequency( inputdata.value.Float() ); + ApplyShake( SHAKE_FREQUENCY ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Calculates the physics shake values +//----------------------------------------------------------------------------- +void CEnvShake::Think( void ) +{ + int i; + + if ( gpGlobals->curtime > m_nextShake ) + { + // Higher frequency means we recalc the extents more often and perturb the display again + m_nextShake = gpGlobals->curtime + (1.0f / Frequency()); + + // Compute random shake extents (the shake will settle down from this) + for (i = 0; i < 2; i++ ) + { + m_maxForce[i] = random->RandomFloat( -1, 1 ); + } + // make the force it point mostly up + m_maxForce.z = 4; + VectorNormalize( m_maxForce ); + m_maxForce *= m_currentAmp * 400; // amplitude is the acceleration of a 100kg object + } + + float fraction = ( m_stopTime - gpGlobals->curtime ) / Duration(); + + if ( fraction < 0 ) + { + m_pShakeController->ClearObjects(); + return; + } + + float freq = 0; + // Ramp up frequency over duration + if ( fraction ) + { + freq = (Frequency() / fraction); + } + + // square fraction to approach zero more quickly + fraction *= fraction; + + // Sine wave that slowly settles to zero + fraction = fraction * sin( gpGlobals->curtime * freq ); + + // Add to view origin + for ( i = 0; i < 3; i++ ) + { + // store the force in the controller callback + m_shakeCallback.m_force[i] = m_maxForce[i] * fraction; + } + + // Drop amplitude a bit, less for higher frequency shakes + m_currentAmp -= m_currentAmp * ( gpGlobals->frametime / (Duration() * Frequency()) ); + SetNextThink( gpGlobals->curtime ); +} + + +//------------------------------------------------------------------------------ +// Purpose: Console command to cause a screen shake. +//------------------------------------------------------------------------------ +void CC_Shake( void ) +{ + CBasePlayer *pPlayer = UTIL_GetCommandClient(); + if (pPlayer) + { + UTIL_ScreenShake( pPlayer->WorldSpaceCenter(), 25.0, 150.0, 1.0, 750, SHAKE_START ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Draw any debug text overlays +// Returns current text offset from the top +//----------------------------------------------------------------------------- +int CEnvShake::DrawDebugTextOverlays( void ) +{ + int text_offset = BaseClass::DrawDebugTextOverlays(); + + if (m_debugOverlays & OVERLAY_TEXT_BIT) + { + char tempstr[512]; + + // print amplitude + Q_snprintf(tempstr,sizeof(tempstr)," magnitude: %f", m_Amplitude); + EntityText(text_offset,tempstr,0); + text_offset++; + + // print frequency + Q_snprintf(tempstr,sizeof(tempstr)," frequency: %f", m_Frequency); + EntityText(text_offset,tempstr,0); + text_offset++; + + // print duration + Q_snprintf(tempstr,sizeof(tempstr)," duration: %f", m_Duration); + EntityText(text_offset,tempstr,0); + text_offset++; + + // print radius + Q_snprintf(tempstr,sizeof(tempstr)," radius: %f", m_Radius); + EntityText(text_offset,tempstr,0); + text_offset++; + + } + return text_offset; +} + +static ConCommand shake("shake", CC_Shake, "Shake the screen.", FCVAR_CHEAT ); + + -- cgit v1.2.3