aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/shared/env_wind_shared.cpp
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /mp/src/game/shared/env_wind_shared.cpp
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/game/shared/env_wind_shared.cpp')
-rw-r--r--mp/src/game/shared/env_wind_shared.cpp586
1 files changed, 293 insertions, 293 deletions
diff --git a/mp/src/game/shared/env_wind_shared.cpp b/mp/src/game/shared/env_wind_shared.cpp
index 9132417b..422e9e99 100644
--- a/mp/src/game/shared/env_wind_shared.cpp
+++ b/mp/src/game/shared/env_wind_shared.cpp
@@ -1,293 +1,293 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-// Information about algorithmic stuff that can occur on both client + server
-//
-// In order to reduce network traffic, it's possible to create a algorithms
-// that will work on both the client and the server and be totally repeatable.
-// All we need do is to send down initial conditions and let the algorithm
-// compute the values at various times. Note that this algorithm will be called
-// at different times with different frequencies on the client and server.
-//
-// The trick here is that in order for it to be repeatable, the algorithm either
-// cannot depend on random numbers, or, if it does, we need to make sure that
-// the random numbers generated are effectively done at the beginning of time,
-// so that differences in frame rate on client and server won't matter. It also
-// is important that the initial state sent across the network is identical
-// bitwise so that we produce the exact same results. Therefore no compression
-// should be used in the datatables.
-//
-// Note also that each algorithm must have its own random number stream so that
-// it cannot possibly interact with other code using random numbers that will
-// be called at various different intervals on the client + server. Use the
-// CUniformRandomStream class for this.
-//
-// There are two types of client-server neutral code: Code that doesn't interact
-// with player prediction, and code that does. The code that doesn't interact
-// with player prediction simply has to be able to produce the result f(time)
-// where time is monotonically increasing. For prediction, we have to produce
-// the result f(time) where time does *not* monotonically increase (time can be
-// anywhere between the "current" time and the prior 10 seconds).
-//
-// Code that is not used by player prediction can maintain state because later
-// calls will always compute the value at some future time. This computation can
-// use random number generation, but with the following restriction: Your code
-// must generate exactly the same number of random numbers regardless of how
-// frequently the code is called.
-//
-// In specific, this means that all random numbers used must either be computed
-// at init time, or must be used in an 'event-based form'. Namely, use random
-// numbers to compute the time at which events occur and the random inputs for
-// those events. When simulating forward, you must simulate all intervening
-// time and generate the same number of random numbers.
-//
-// For functions planned to be used by player prediction, one method is to use
-// some sort of stateless computation (where the only states are the initial
-// state and time). Note that random number generators have state implicit in
-// the number of calls made to that random number generator, and therefore you
-// cannot call a random number generator unless you are able to
-//
-// 1) Use a random number generator that can return the ith random number, namely:
-//
-// float r = random( i ); // i == the ith number in the random sequence
-//
-// 2) Be able to accurately know at any given time t how many random numbers
-// have already been generated (namely, compute the i in part 1 above).
-//
-// There is another alternative for code meant to be used by player prediction:
-// you could just store a history of 'events' from which you could completely
-// determine the value of f(time). That history would need to be at least 10
-// seconds long, which is guaranteed to be longer than the amount of time that
-// prediction would need. I've written a class which I haven't tested yet (but
-// will be using soon) called CTimedEventQueue (currently located in
-// env_wind_shared.h) which I plan to use to solve my problem (getting wind to
-// blow players).
-//
-//=============================================================================//
-#include "cbase.h"
-#include "env_wind_shared.h"
-#include "soundenvelope.h"
-#include "IEffects.h"
-#include "engine/IEngineSound.h"
-#include "sharedInterface.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//-----------------------------------------------------------------------------
-// globals
-//-----------------------------------------------------------------------------
-static Vector s_vecWindVelocity( 0, 0, 0 );
-
-
-CEnvWindShared::CEnvWindShared() : m_WindAveQueue(10), m_WindVariationQueue(10)
-{
- m_pWindSound = NULL;
-}
-
-CEnvWindShared::~CEnvWindShared()
-{
- if (m_pWindSound)
- {
- CSoundEnvelopeController::GetController().Shutdown( m_pWindSound );
- }
-}
-
-void CEnvWindShared::Init( int nEntIndex, int iRandomSeed, float flTime,
- int iInitialWindYaw, float flInitialWindSpeed )
-{
- m_iEntIndex = nEntIndex;
- m_flWindAngleVariation = m_flWindSpeedVariation = 1.0f;
- m_flStartTime = m_flSimTime = m_flSwitchTime = m_flVariationTime = flTime;
- m_iWindSeed = iRandomSeed;
- m_Stream.SetSeed( iRandomSeed );
- m_WindVariationStream.SetSeed( iRandomSeed );
- m_iWindDir = m_iInitialWindDir = iInitialWindYaw;
-
- m_flAveWindSpeed = m_flWindSpeed = m_flInitialWindSpeed = flInitialWindSpeed;
-
- /*
- // Cache in the wind sound...
- if (!g_pEffects->IsServer())
- {
- CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
- m_pWindSound = controller.SoundCreate( -1, CHAN_STATIC,
- "EnvWind.Loop", ATTN_NONE );
- controller.Play( m_pWindSound, 0.0f, 100 );
- }
- */
-
- // Next time a change happens (which will happen immediately), it'll stop gusting
- m_bGusting = true;
-}
-
-
-//-----------------------------------------------------------------------------
-// Computes wind variation
-//-----------------------------------------------------------------------------
-
-#define WIND_VARIATION_UPDATE_TIME 0.1f
-
-void CEnvWindShared::ComputeWindVariation( float flTime )
-{
- // The wind variation is updated every 10th of a second..
- while( flTime >= m_flVariationTime )
- {
- m_flWindAngleVariation = m_WindVariationStream.RandomFloat( -10, 10 );
- m_flWindSpeedVariation = 1.0 + m_WindVariationStream.RandomFloat( -0.2, 0.2 );
- m_flVariationTime += WIND_VARIATION_UPDATE_TIME;
- }
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Updates the wind sound
-//-----------------------------------------------------------------------------
-void CEnvWindShared::UpdateWindSound( float flTotalWindSpeed )
-{
- if (!g_pEffects->IsServer())
- {
- float flDuration = random->RandomFloat( 1.0f, 2.0f );
- CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
-
- // FIXME: Tweak with these numbers
- float flNormalizedWindSpeed = flTotalWindSpeed / 150.0f;
- if (flNormalizedWindSpeed > 1.0f)
- flNormalizedWindSpeed = 1.0f;
- float flPitch = 120 * Bias( flNormalizedWindSpeed, 0.3f ) + 100;
- float flVolume = 0.3f * Bias( flNormalizedWindSpeed, 0.3f ) + 0.7f;
- controller.SoundChangePitch( m_pWindSound, flPitch, flDuration );
- controller.SoundChangeVolume( m_pWindSound, flVolume, flDuration );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Updates the wind speed
-//-----------------------------------------------------------------------------
-
-#define WIND_ACCELERATION 150.0f // wind speed can accelerate this many units per second
-#define WIND_DECELERATION 15.0f // wind speed can decelerate this many units per second
-
-float CEnvWindShared::WindThink( float flTime )
-{
- // NOTE: This algorithm can be client-server neutal because we're using
- // the random number generator to generate *time* at which the wind changes.
- // We therefore need to structure the algorithm so that no matter the
- // frequency of calls to this function we produce the same wind speeds...
-
- ComputeWindVariation( flTime );
-
- while (true)
- {
- // First, simulate up to the next switch time...
- float flTimeToSwitch = m_flSwitchTime - m_flSimTime;
- float flMaxDeltaTime = flTime - m_flSimTime;
-
- bool bGotToSwitchTime = (flMaxDeltaTime > flTimeToSwitch);
-
- float flSimDeltaTime = bGotToSwitchTime ? flTimeToSwitch : flMaxDeltaTime;
-
- // Now that we've chosen
- // either ramp up, or sleep till change
- bool bReachedSteadyState = true;
- if ( m_flAveWindSpeed > m_flWindSpeed )
- {
- m_flWindSpeed += WIND_ACCELERATION * flSimDeltaTime;
- if (m_flWindSpeed > m_flAveWindSpeed)
- m_flWindSpeed = m_flAveWindSpeed;
- else
- bReachedSteadyState = false;
- }
- else if ( m_flAveWindSpeed < m_flWindSpeed )
- {
- m_flWindSpeed -= WIND_DECELERATION * flSimDeltaTime;
- if (m_flWindSpeed < m_flAveWindSpeed)
- m_flWindSpeed = m_flAveWindSpeed;
- else
- bReachedSteadyState = false;
- }
-
- // Update the sim time
-
- // If we didn't get to a switch point, then we're done simulating for now
- if (!bGotToSwitchTime)
- {
- m_flSimTime = flTime;
-
- // We're about to exit, let's set the wind velocity...
- QAngle vecWindAngle( 0, m_iWindDir + m_flWindAngleVariation, 0 );
- AngleVectors( vecWindAngle, &s_vecWindVelocity );
- float flTotalWindSpeed = m_flWindSpeed * m_flWindSpeedVariation;
- s_vecWindVelocity *= flTotalWindSpeed;
-
- // If we reached a steady state, we don't need to be called until the switch time
- // Otherwise, we should be called immediately
-
- // FIXME: If we ever call this from prediction, we'll need
- // to only update the sound if it's a new time
- // Or, we'll need to update the sound elsewhere.
- // Update the sound....
-// UpdateWindSound( flTotalWindSpeed );
-
- // Always immediately call, the wind is forever varying
- return ( flTime + 0.01f );
- }
-
- m_flSimTime = m_flSwitchTime;
-
- // Switch gusting state..
- if( m_bGusting )
- {
- // wind is gusting, so return to normal wind
- m_flAveWindSpeed = m_Stream.RandomInt( m_iMinWind, m_iMaxWind );
-
- // set up for another gust later
- m_bGusting = false;
- m_flSwitchTime += m_flMinGustDelay + m_Stream.RandomFloat( 0, m_flMaxGustDelay );
-
-#ifndef CLIENT_DLL
- m_OnGustEnd.FireOutput( NULL, NULL );
-#endif
- }
- else
- {
- // time for a gust.
- m_flAveWindSpeed = m_Stream.RandomInt( m_iMinGust, m_iMaxGust );
-
- // change wind direction, maybe a lot
- m_iWindDir = anglemod( m_iWindDir + m_Stream.RandomInt(-m_iGustDirChange, m_iGustDirChange) );
-
- // set up to stop the gust in a short while
- m_bGusting = true;
-
-#ifndef CLIENT_DLL
- m_OnGustStart.FireOutput( NULL, NULL );
-#endif
-
- // !!!HACKHACK - gust duration tied to the length of a particular wave file
- m_flSwitchTime += m_flGustDuration;
- }
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Method to reset windspeed..
-//-----------------------------------------------------------------------------
-void ResetWindspeed()
-{
- s_vecWindVelocity.Init( 0, 0, 0 );
-}
-
-
-//-----------------------------------------------------------------------------
-// Method to sample the windspeed at a particular time
-//-----------------------------------------------------------------------------
-void GetWindspeedAtTime( float flTime, Vector &vecVelocity )
-{
- // For now, ignore history and time.. fix later when we use wind to affect
- // client-side prediction
- VectorCopy( s_vecWindVelocity, vecVelocity );
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+// Information about algorithmic stuff that can occur on both client + server
+//
+// In order to reduce network traffic, it's possible to create a algorithms
+// that will work on both the client and the server and be totally repeatable.
+// All we need do is to send down initial conditions and let the algorithm
+// compute the values at various times. Note that this algorithm will be called
+// at different times with different frequencies on the client and server.
+//
+// The trick here is that in order for it to be repeatable, the algorithm either
+// cannot depend on random numbers, or, if it does, we need to make sure that
+// the random numbers generated are effectively done at the beginning of time,
+// so that differences in frame rate on client and server won't matter. It also
+// is important that the initial state sent across the network is identical
+// bitwise so that we produce the exact same results. Therefore no compression
+// should be used in the datatables.
+//
+// Note also that each algorithm must have its own random number stream so that
+// it cannot possibly interact with other code using random numbers that will
+// be called at various different intervals on the client + server. Use the
+// CUniformRandomStream class for this.
+//
+// There are two types of client-server neutral code: Code that doesn't interact
+// with player prediction, and code that does. The code that doesn't interact
+// with player prediction simply has to be able to produce the result f(time)
+// where time is monotonically increasing. For prediction, we have to produce
+// the result f(time) where time does *not* monotonically increase (time can be
+// anywhere between the "current" time and the prior 10 seconds).
+//
+// Code that is not used by player prediction can maintain state because later
+// calls will always compute the value at some future time. This computation can
+// use random number generation, but with the following restriction: Your code
+// must generate exactly the same number of random numbers regardless of how
+// frequently the code is called.
+//
+// In specific, this means that all random numbers used must either be computed
+// at init time, or must be used in an 'event-based form'. Namely, use random
+// numbers to compute the time at which events occur and the random inputs for
+// those events. When simulating forward, you must simulate all intervening
+// time and generate the same number of random numbers.
+//
+// For functions planned to be used by player prediction, one method is to use
+// some sort of stateless computation (where the only states are the initial
+// state and time). Note that random number generators have state implicit in
+// the number of calls made to that random number generator, and therefore you
+// cannot call a random number generator unless you are able to
+//
+// 1) Use a random number generator that can return the ith random number, namely:
+//
+// float r = random( i ); // i == the ith number in the random sequence
+//
+// 2) Be able to accurately know at any given time t how many random numbers
+// have already been generated (namely, compute the i in part 1 above).
+//
+// There is another alternative for code meant to be used by player prediction:
+// you could just store a history of 'events' from which you could completely
+// determine the value of f(time). That history would need to be at least 10
+// seconds long, which is guaranteed to be longer than the amount of time that
+// prediction would need. I've written a class which I haven't tested yet (but
+// will be using soon) called CTimedEventQueue (currently located in
+// env_wind_shared.h) which I plan to use to solve my problem (getting wind to
+// blow players).
+//
+//=============================================================================//
+#include "cbase.h"
+#include "env_wind_shared.h"
+#include "soundenvelope.h"
+#include "IEffects.h"
+#include "engine/IEngineSound.h"
+#include "sharedInterface.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// globals
+//-----------------------------------------------------------------------------
+static Vector s_vecWindVelocity( 0, 0, 0 );
+
+
+CEnvWindShared::CEnvWindShared() : m_WindAveQueue(10), m_WindVariationQueue(10)
+{
+ m_pWindSound = NULL;
+}
+
+CEnvWindShared::~CEnvWindShared()
+{
+ if (m_pWindSound)
+ {
+ CSoundEnvelopeController::GetController().Shutdown( m_pWindSound );
+ }
+}
+
+void CEnvWindShared::Init( int nEntIndex, int iRandomSeed, float flTime,
+ int iInitialWindYaw, float flInitialWindSpeed )
+{
+ m_iEntIndex = nEntIndex;
+ m_flWindAngleVariation = m_flWindSpeedVariation = 1.0f;
+ m_flStartTime = m_flSimTime = m_flSwitchTime = m_flVariationTime = flTime;
+ m_iWindSeed = iRandomSeed;
+ m_Stream.SetSeed( iRandomSeed );
+ m_WindVariationStream.SetSeed( iRandomSeed );
+ m_iWindDir = m_iInitialWindDir = iInitialWindYaw;
+
+ m_flAveWindSpeed = m_flWindSpeed = m_flInitialWindSpeed = flInitialWindSpeed;
+
+ /*
+ // Cache in the wind sound...
+ if (!g_pEffects->IsServer())
+ {
+ CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
+ m_pWindSound = controller.SoundCreate( -1, CHAN_STATIC,
+ "EnvWind.Loop", ATTN_NONE );
+ controller.Play( m_pWindSound, 0.0f, 100 );
+ }
+ */
+
+ // Next time a change happens (which will happen immediately), it'll stop gusting
+ m_bGusting = true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Computes wind variation
+//-----------------------------------------------------------------------------
+
+#define WIND_VARIATION_UPDATE_TIME 0.1f
+
+void CEnvWindShared::ComputeWindVariation( float flTime )
+{
+ // The wind variation is updated every 10th of a second..
+ while( flTime >= m_flVariationTime )
+ {
+ m_flWindAngleVariation = m_WindVariationStream.RandomFloat( -10, 10 );
+ m_flWindSpeedVariation = 1.0 + m_WindVariationStream.RandomFloat( -0.2, 0.2 );
+ m_flVariationTime += WIND_VARIATION_UPDATE_TIME;
+ }
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Updates the wind sound
+//-----------------------------------------------------------------------------
+void CEnvWindShared::UpdateWindSound( float flTotalWindSpeed )
+{
+ if (!g_pEffects->IsServer())
+ {
+ float flDuration = random->RandomFloat( 1.0f, 2.0f );
+ CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
+
+ // FIXME: Tweak with these numbers
+ float flNormalizedWindSpeed = flTotalWindSpeed / 150.0f;
+ if (flNormalizedWindSpeed > 1.0f)
+ flNormalizedWindSpeed = 1.0f;
+ float flPitch = 120 * Bias( flNormalizedWindSpeed, 0.3f ) + 100;
+ float flVolume = 0.3f * Bias( flNormalizedWindSpeed, 0.3f ) + 0.7f;
+ controller.SoundChangePitch( m_pWindSound, flPitch, flDuration );
+ controller.SoundChangeVolume( m_pWindSound, flVolume, flDuration );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Updates the wind speed
+//-----------------------------------------------------------------------------
+
+#define WIND_ACCELERATION 150.0f // wind speed can accelerate this many units per second
+#define WIND_DECELERATION 15.0f // wind speed can decelerate this many units per second
+
+float CEnvWindShared::WindThink( float flTime )
+{
+ // NOTE: This algorithm can be client-server neutal because we're using
+ // the random number generator to generate *time* at which the wind changes.
+ // We therefore need to structure the algorithm so that no matter the
+ // frequency of calls to this function we produce the same wind speeds...
+
+ ComputeWindVariation( flTime );
+
+ while (true)
+ {
+ // First, simulate up to the next switch time...
+ float flTimeToSwitch = m_flSwitchTime - m_flSimTime;
+ float flMaxDeltaTime = flTime - m_flSimTime;
+
+ bool bGotToSwitchTime = (flMaxDeltaTime > flTimeToSwitch);
+
+ float flSimDeltaTime = bGotToSwitchTime ? flTimeToSwitch : flMaxDeltaTime;
+
+ // Now that we've chosen
+ // either ramp up, or sleep till change
+ bool bReachedSteadyState = true;
+ if ( m_flAveWindSpeed > m_flWindSpeed )
+ {
+ m_flWindSpeed += WIND_ACCELERATION * flSimDeltaTime;
+ if (m_flWindSpeed > m_flAveWindSpeed)
+ m_flWindSpeed = m_flAveWindSpeed;
+ else
+ bReachedSteadyState = false;
+ }
+ else if ( m_flAveWindSpeed < m_flWindSpeed )
+ {
+ m_flWindSpeed -= WIND_DECELERATION * flSimDeltaTime;
+ if (m_flWindSpeed < m_flAveWindSpeed)
+ m_flWindSpeed = m_flAveWindSpeed;
+ else
+ bReachedSteadyState = false;
+ }
+
+ // Update the sim time
+
+ // If we didn't get to a switch point, then we're done simulating for now
+ if (!bGotToSwitchTime)
+ {
+ m_flSimTime = flTime;
+
+ // We're about to exit, let's set the wind velocity...
+ QAngle vecWindAngle( 0, m_iWindDir + m_flWindAngleVariation, 0 );
+ AngleVectors( vecWindAngle, &s_vecWindVelocity );
+ float flTotalWindSpeed = m_flWindSpeed * m_flWindSpeedVariation;
+ s_vecWindVelocity *= flTotalWindSpeed;
+
+ // If we reached a steady state, we don't need to be called until the switch time
+ // Otherwise, we should be called immediately
+
+ // FIXME: If we ever call this from prediction, we'll need
+ // to only update the sound if it's a new time
+ // Or, we'll need to update the sound elsewhere.
+ // Update the sound....
+// UpdateWindSound( flTotalWindSpeed );
+
+ // Always immediately call, the wind is forever varying
+ return ( flTime + 0.01f );
+ }
+
+ m_flSimTime = m_flSwitchTime;
+
+ // Switch gusting state..
+ if( m_bGusting )
+ {
+ // wind is gusting, so return to normal wind
+ m_flAveWindSpeed = m_Stream.RandomInt( m_iMinWind, m_iMaxWind );
+
+ // set up for another gust later
+ m_bGusting = false;
+ m_flSwitchTime += m_flMinGustDelay + m_Stream.RandomFloat( 0, m_flMaxGustDelay );
+
+#ifndef CLIENT_DLL
+ m_OnGustEnd.FireOutput( NULL, NULL );
+#endif
+ }
+ else
+ {
+ // time for a gust.
+ m_flAveWindSpeed = m_Stream.RandomInt( m_iMinGust, m_iMaxGust );
+
+ // change wind direction, maybe a lot
+ m_iWindDir = anglemod( m_iWindDir + m_Stream.RandomInt(-m_iGustDirChange, m_iGustDirChange) );
+
+ // set up to stop the gust in a short while
+ m_bGusting = true;
+
+#ifndef CLIENT_DLL
+ m_OnGustStart.FireOutput( NULL, NULL );
+#endif
+
+ // !!!HACKHACK - gust duration tied to the length of a particular wave file
+ m_flSwitchTime += m_flGustDuration;
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Method to reset windspeed..
+//-----------------------------------------------------------------------------
+void ResetWindspeed()
+{
+ s_vecWindVelocity.Init( 0, 0, 0 );
+}
+
+
+//-----------------------------------------------------------------------------
+// Method to sample the windspeed at a particular time
+//-----------------------------------------------------------------------------
+void GetWindspeedAtTime( float flTime, Vector &vecVelocity )
+{
+ // For now, ignore history and time.. fix later when we use wind to affect
+ // client-side prediction
+ VectorCopy( s_vecWindVelocity, vecVelocity );
+}