aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/shared/env_meteor_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_meteor_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_meteor_shared.cpp')
-rw-r--r--mp/src/game/shared/env_meteor_shared.cpp798
1 files changed, 399 insertions, 399 deletions
diff --git a/mp/src/game/shared/env_meteor_shared.cpp b/mp/src/game/shared/env_meteor_shared.cpp
index eedab8a1..26bda032 100644
--- a/mp/src/game/shared/env_meteor_shared.cpp
+++ b/mp/src/game/shared/env_meteor_shared.cpp
@@ -1,399 +1,399 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "env_meteor_shared.h"
-#include "mapdata_shared.h"
-#include "sharedInterface.h"
-
-//=============================================================================
-//
-// Meteor Functions.
-//
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-CEnvMeteorShared::CEnvMeteorShared()
-{
- m_nID = 0;
- m_vecStartPosition.Init();
- m_vecDirection.Init();
- m_flSpeed = 0.0f;
- m_flDamageRadius = 0.0f;
- m_flStartTime = METEOR_INVALID_TIME;
- m_flPassiveTime = METEOR_INVALID_TIME;
- m_flWorldEnterTime = METEOR_INVALID_TIME;
- m_flWorldExitTime = METEOR_INVALID_TIME;
- m_nLocation = METEOR_LOCATION_INVALID;
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void CEnvMeteorShared::Init( int nID, float flStartTime, float flPassiveTime,
- const Vector &vecStartPosition,
- const Vector &vecDirection, float flSpeed, float flDamageRadius,
- const Vector &vecTriggerMins, const Vector &vecTriggerMaxs )
-{
- // Setup initial parametric state.
- m_nID = nID;
- VectorCopy( vecStartPosition, m_vecStartPosition );
- VectorCopy( vecStartPosition, m_vecPos );
- VectorCopy( vecDirection, m_vecDirection );
- m_flSpeed = flSpeed;
- m_flDamageRadius = flDamageRadius;
- m_flStartTime = flPassiveTime + flStartTime;
- m_flPassiveTime = flPassiveTime;
- m_flPosTime = m_flStartTime;
-
- // Calculate the enter/exit times.
- CalcEnterAndExitTimes( vecTriggerMins, vecTriggerMaxs );
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void CEnvMeteorShared::GetPositionAtTime( float flTime, Vector &vecPosition )
-{
- float flDeltaTime = flTime - m_flPosTime;
- Vector vecVelocity( m_vecDirection.x * m_flSpeed, m_vecDirection.y * m_flSpeed, m_vecDirection.z * m_flSpeed );
- VectorMA( m_vecPos, flDeltaTime, vecVelocity, vecPosition );
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void CEnvMeteorShared::ConvertFromSkyboxToWorld( void )
-{
- // The new start position is the position at which the meteor enters
- // the skybox.
- Vector vecSkyboxOrigin;
- g_pMapData->Get3DSkyboxOrigin( vecSkyboxOrigin );
- float flSkyboxScale = g_pMapData->Get3DSkyboxScale();
-
- m_vecPos += ( m_flSpeed * m_vecDirection ) * ( m_flWorldEnterTime - m_flStartTime );
- m_vecPos -= vecSkyboxOrigin;
- m_vecPos *= flSkyboxScale;
-
- // Scale the speed.
- m_flSpeed *= flSkyboxScale;
-
- // Reset the start time.
- m_flPosTime = m_flWorldEnterTime;
-
- // Set the location to world.
- m_nLocation = METEOR_LOCATION_WORLD;
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void CEnvMeteorShared::ConvertFromWorldToSkybox( void )
-{
- // Scale the speed.
- float flSkyboxScale = g_pMapData->Get3DSkyboxScale();
- m_flSpeed /= flSkyboxScale;
-
- float flDeltaTime = m_flWorldExitTime - m_flStartTime;
- Vector vecVelocity( m_vecDirection.x * m_flSpeed, m_vecDirection.y * m_flSpeed, m_vecDirection.z * m_flSpeed );
- VectorMA( m_vecStartPosition, flDeltaTime, vecVelocity, m_vecPos );
-
- // Reset the start time.
- m_flPosTime = m_flWorldExitTime;
-
- // Set the location to skybox.
- m_nLocation = METEOR_LOCATION_SKYBOX;
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-bool CEnvMeteorShared::IsInSkybox( float flTime )
-{
- // Check to see if we are always in the skybox!
- if ( m_flWorldEnterTime == METEOR_INVALID_TIME )
- return true;
-
- return ( ( flTime < m_flWorldEnterTime ) || ( flTime > m_flWorldExitTime ) );
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-bool CEnvMeteorShared::IsPassive( float flTime )
-{
- return ( flTime < m_flPassiveTime );
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-bool CEnvMeteorShared::WillTransition( void )
-{
- return ( m_flWorldEnterTime == METEOR_INVALID_TIME );
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-float CEnvMeteorShared::GetDamageRadius( void )
-{
- return m_flDamageRadius;
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void CEnvMeteorShared::CalcEnterAndExitTimes( const Vector &vecTriggerMins,
- const Vector &vecTriggerMaxs )
-{
-#define METEOR_TRIGGER_EPSILON 0.001f
-
- // Initialize the enter/exit fractions.
- float flEnterFrac = 0.0f;
- float flExitFrac = 1.0f;
-
- // Create an arbitrarily large end position.
- Vector vecEndPosition;
- VectorMA( m_vecStartPosition, 32000.0f, m_vecDirection, vecEndPosition );
-
- float flFrac, flDistStart, flDistEnd;
- for( int iAxis = 0; iAxis < 3; iAxis++ )
- {
- // Negative Axis
- flDistStart = -m_vecStartPosition[iAxis] + vecTriggerMins[iAxis];
- flDistEnd = -vecEndPosition[iAxis] + vecTriggerMins[iAxis];
-
- if ( ( flDistStart > 0.0f ) && ( flDistEnd < 0.0f ) )
- {
- flFrac = ( flDistStart - METEOR_TRIGGER_EPSILON ) / ( flDistStart - flDistEnd );
- if ( flFrac > flEnterFrac ) { flEnterFrac = flFrac; }
- }
-
- if ( ( flDistStart < 0.0f ) && ( flDistEnd > 0.0f ) )
- {
- flFrac = ( flDistStart + METEOR_TRIGGER_EPSILON ) / ( flDistStart - flDistEnd );
- if( flFrac < flExitFrac ) { flExitFrac = flFrac; }
- }
-
- if ( ( flDistStart > 0.0f ) && ( flDistEnd > 0.0f ) )
- return;
-
- // Positive Axis
- flDistStart = m_vecStartPosition[iAxis] - vecTriggerMaxs[iAxis];
- flDistEnd = vecEndPosition[iAxis] - vecTriggerMaxs[iAxis];
-
- if ( ( flDistStart > 0.0f ) && ( flDistEnd < 0.0f ) )
- {
- flFrac = ( flDistStart - METEOR_TRIGGER_EPSILON ) / ( flDistStart - flDistEnd );
- if ( flFrac > flEnterFrac ) { flEnterFrac = flFrac; }
- }
-
- if ( ( flDistStart < 0.0f ) && ( flDistEnd > 0.0f ) )
- {
- flFrac = ( flDistStart + METEOR_TRIGGER_EPSILON ) / ( flDistStart - flDistEnd );
- if( flFrac < flExitFrac ) { flExitFrac = flFrac; }
- }
-
- if ( ( flDistStart > 0.0f ) && ( flDistEnd > 0.0f ) )
- return;
- }
-
- // Check for intersection.
- if ( flExitFrac >= flEnterFrac )
- {
- // Check to see if we start in the world or the skybox!
- if ( flEnterFrac == 0.0f )
- {
- m_nLocation = METEOR_LOCATION_WORLD;
- }
- else
- {
- m_nLocation = METEOR_LOCATION_SKYBOX;
- }
-
- // Calculate the enter/exit times.
- Vector vecEnterPoint, vecExitPoint, vecDeltaPosition;
- VectorSubtract( vecEndPosition, m_vecStartPosition, vecDeltaPosition );
- VectorScale( vecDeltaPosition, flEnterFrac, vecEnterPoint );
- VectorScale( vecDeltaPosition, flExitFrac, vecExitPoint );
-
- m_flWorldEnterTime = vecEnterPoint.Length() / m_flSpeed;
- m_flWorldExitTime = vecExitPoint.Length() / m_flSpeed;
- m_flWorldEnterTime += m_flStartTime;
- m_flWorldExitTime += m_flStartTime;
- }
-
-#undef METEOR_TRIGGER_EPSILON
-}
-
-//=============================================================================
-//
-// Meteor Spawner Functions.
-//
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-CEnvMeteorSpawnerShared::CEnvMeteorSpawnerShared()
-{
- m_pFactory = NULL;
- m_nMeteorCount = 0;
-
- m_flStartTime = 0.0f;
- m_nRandomSeed = 0;
-
- m_iMeteorType = -1;
- m_flMeteorDamageRadius = 0.0f;
- m_bSkybox = true;
-
- m_flMinSpawnTime = 0.0f;
- m_flMaxSpawnTime = 0.0f;
- m_nMinSpawnCount = 0;
- m_nMaxSpawnCount = 0;
- m_vecMinBounds.Init();
- m_vecMaxBounds.Init();
- m_flMinSpeed = 0.0f;
- m_flMaxSpeed = 0.0f;
-
- m_flNextSpawnTime = 0.0f;
-
- m_vecTriggerMins.Init();
- m_vecTriggerMaxs.Init();
- m_vecTriggerCenter.Init();
-
- // Debug!
- m_nRandomCallCount = 0;
-
- m_aTargets.Purge();
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void CEnvMeteorSpawnerShared::Init( IMeteorFactory *pFactory, int nRandomSeed, float flTime,
- const Vector &vecMinBounds, const Vector &vecMaxBounds,
- const Vector &vecTriggerMins, const Vector &vecTriggerMaxs )
-{
- // Factory.
- m_pFactory = pFactory;
-
- // Setup the random number stream.
- m_nRandomSeed = nRandomSeed;
- m_NumberStream.SetSeed( nRandomSeed );
-
- // Start time.
- m_flStartTime = flTime;
-
- // Copy the spawner bounds.
- m_vecMinBounds = vecMinBounds;
- m_vecMaxBounds = vecMaxBounds;
-
- // Copy the trigger bounds.
- m_vecTriggerMins = vecTriggerMins;
- m_vecTriggerMaxs = vecTriggerMaxs;
-
- // Get the center of the trigger bounds.
- m_vecTriggerCenter = ( m_vecTriggerMins + m_vecTriggerMaxs ) * 0.5f;
-
- // Setup spawn time.
- m_flNextSpawnTime = m_flStartTime + m_flMaxSpawnTime;
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-int CEnvMeteorSpawnerShared::GetRandomInt( int nMin, int nMax )
-{
- m_nRandomCallCount++;
- return m_NumberStream.RandomInt( nMin, nMax );
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-float CEnvMeteorSpawnerShared::GetRandomFloat( float flMin, float flMax )
-{
- m_nRandomCallCount++;
- return m_NumberStream.RandomFloat( flMin, flMax );
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-float CEnvMeteorSpawnerShared::MeteorThink( float flTime )
-{
- // Check for spawn.
- if ( flTime < m_flNextSpawnTime )
- return m_flNextSpawnTime;
-
- while ( m_flNextSpawnTime < flTime )
- {
- // Get a random number of meteors to spawn and spawn them.
- int nMeteorCount = GetRandomInt( m_nMinSpawnCount, m_nMaxSpawnCount );
- for ( int iMeteor = 0; iMeteor < nMeteorCount; iMeteor++ )
- {
- // Increment the number of meteors created (starting with 1).
- m_nMeteorCount++;
-
- // Get a random meteor position.
- Vector meteorOrigin( GetRandomFloat( m_vecMinBounds.GetX(), m_vecMaxBounds.GetX() ) /* x */,
- GetRandomFloat( m_vecMinBounds.GetY(), m_vecMaxBounds.GetY() ) /* y */,
- GetRandomFloat( m_vecMinBounds.GetZ(), m_vecMaxBounds.GetZ() ) /* z */ );
-
- // Calculate the direction of the meteor based on "targets."
- Vector vecDirection( 0.0f, 0.0f, -1.0f );
- if ( m_aTargets.Count() > 0 )
- {
- float flFreq = 1.0f / m_aTargets.Count();
- float flFreqAccum = flFreq;
-
- int iTarget;
- for( iTarget = 0; iTarget < m_aTargets.Count(); ++iTarget )
- {
- float flRandom = GetRandomFloat( 0.0f, 1.0f );
- if ( flRandom < flFreqAccum )
- break;
-
- flFreqAccum += flFreq;
- }
-
- // Should ever be here!
- if ( iTarget == m_aTargets.Count() )
- {
- iTarget--;
- }
-
- // Just set it to the first target for now!!!
- // NOTE: Will randomly generate from list of targets when more than 1 in
- // the future.
-
- // Move the meteor into the "world."
- Vector vecPositionInWorld;
- Vector vecSkyboxOrigin;
- g_pMapData->Get3DSkyboxOrigin( vecSkyboxOrigin );
- vecPositionInWorld = ( meteorOrigin - vecSkyboxOrigin );
- vecPositionInWorld *= g_pMapData->Get3DSkyboxScale();
-
- Vector vecTargetPos = m_aTargets[iTarget].m_vecPosition;
- vecTargetPos.x += GetRandomFloat( -m_aTargets[iTarget].m_flRadius, m_aTargets[iTarget].m_flRadius );
- vecTargetPos.y += GetRandomFloat( -m_aTargets[iTarget].m_flRadius, m_aTargets[iTarget].m_flRadius );
- vecTargetPos.z += GetRandomFloat( -m_aTargets[iTarget].m_flRadius, m_aTargets[iTarget].m_flRadius );
-
- vecDirection = vecTargetPos - vecPositionInWorld;
- VectorNormalize( vecDirection );
- }
-
- // Pass in the randomized position, randomized speed, and start time.
- m_pFactory->CreateMeteor( m_nMeteorCount, m_iMeteorType, meteorOrigin,
- vecDirection /* direction */,
- GetRandomFloat( m_flMinSpeed, m_flMaxSpeed ) /* speed */,
- m_flNextSpawnTime, m_flMeteorDamageRadius,
- m_vecTriggerMins, m_vecTriggerMaxs );
- }
-
- // Set next spawn time.
- m_flNextSpawnTime += GetRandomFloat( m_flMinSpawnTime, m_flMaxSpawnTime );
- }
-
- // Return the next spawn time.
- return ( m_flNextSpawnTime - gpGlobals->curtime );
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void CEnvMeteorSpawnerShared::AddToTargetList( const Vector &vecPosition, float flRadius )
-{
- int iTarget = m_aTargets.AddToTail();
- m_aTargets[iTarget].m_vecPosition = vecPosition;
- m_aTargets[iTarget].m_flRadius = flRadius;
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "env_meteor_shared.h"
+#include "mapdata_shared.h"
+#include "sharedInterface.h"
+
+//=============================================================================
+//
+// Meteor Functions.
+//
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+CEnvMeteorShared::CEnvMeteorShared()
+{
+ m_nID = 0;
+ m_vecStartPosition.Init();
+ m_vecDirection.Init();
+ m_flSpeed = 0.0f;
+ m_flDamageRadius = 0.0f;
+ m_flStartTime = METEOR_INVALID_TIME;
+ m_flPassiveTime = METEOR_INVALID_TIME;
+ m_flWorldEnterTime = METEOR_INVALID_TIME;
+ m_flWorldExitTime = METEOR_INVALID_TIME;
+ m_nLocation = METEOR_LOCATION_INVALID;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CEnvMeteorShared::Init( int nID, float flStartTime, float flPassiveTime,
+ const Vector &vecStartPosition,
+ const Vector &vecDirection, float flSpeed, float flDamageRadius,
+ const Vector &vecTriggerMins, const Vector &vecTriggerMaxs )
+{
+ // Setup initial parametric state.
+ m_nID = nID;
+ VectorCopy( vecStartPosition, m_vecStartPosition );
+ VectorCopy( vecStartPosition, m_vecPos );
+ VectorCopy( vecDirection, m_vecDirection );
+ m_flSpeed = flSpeed;
+ m_flDamageRadius = flDamageRadius;
+ m_flStartTime = flPassiveTime + flStartTime;
+ m_flPassiveTime = flPassiveTime;
+ m_flPosTime = m_flStartTime;
+
+ // Calculate the enter/exit times.
+ CalcEnterAndExitTimes( vecTriggerMins, vecTriggerMaxs );
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CEnvMeteorShared::GetPositionAtTime( float flTime, Vector &vecPosition )
+{
+ float flDeltaTime = flTime - m_flPosTime;
+ Vector vecVelocity( m_vecDirection.x * m_flSpeed, m_vecDirection.y * m_flSpeed, m_vecDirection.z * m_flSpeed );
+ VectorMA( m_vecPos, flDeltaTime, vecVelocity, vecPosition );
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CEnvMeteorShared::ConvertFromSkyboxToWorld( void )
+{
+ // The new start position is the position at which the meteor enters
+ // the skybox.
+ Vector vecSkyboxOrigin;
+ g_pMapData->Get3DSkyboxOrigin( vecSkyboxOrigin );
+ float flSkyboxScale = g_pMapData->Get3DSkyboxScale();
+
+ m_vecPos += ( m_flSpeed * m_vecDirection ) * ( m_flWorldEnterTime - m_flStartTime );
+ m_vecPos -= vecSkyboxOrigin;
+ m_vecPos *= flSkyboxScale;
+
+ // Scale the speed.
+ m_flSpeed *= flSkyboxScale;
+
+ // Reset the start time.
+ m_flPosTime = m_flWorldEnterTime;
+
+ // Set the location to world.
+ m_nLocation = METEOR_LOCATION_WORLD;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CEnvMeteorShared::ConvertFromWorldToSkybox( void )
+{
+ // Scale the speed.
+ float flSkyboxScale = g_pMapData->Get3DSkyboxScale();
+ m_flSpeed /= flSkyboxScale;
+
+ float flDeltaTime = m_flWorldExitTime - m_flStartTime;
+ Vector vecVelocity( m_vecDirection.x * m_flSpeed, m_vecDirection.y * m_flSpeed, m_vecDirection.z * m_flSpeed );
+ VectorMA( m_vecStartPosition, flDeltaTime, vecVelocity, m_vecPos );
+
+ // Reset the start time.
+ m_flPosTime = m_flWorldExitTime;
+
+ // Set the location to skybox.
+ m_nLocation = METEOR_LOCATION_SKYBOX;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+bool CEnvMeteorShared::IsInSkybox( float flTime )
+{
+ // Check to see if we are always in the skybox!
+ if ( m_flWorldEnterTime == METEOR_INVALID_TIME )
+ return true;
+
+ return ( ( flTime < m_flWorldEnterTime ) || ( flTime > m_flWorldExitTime ) );
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+bool CEnvMeteorShared::IsPassive( float flTime )
+{
+ return ( flTime < m_flPassiveTime );
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+bool CEnvMeteorShared::WillTransition( void )
+{
+ return ( m_flWorldEnterTime == METEOR_INVALID_TIME );
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+float CEnvMeteorShared::GetDamageRadius( void )
+{
+ return m_flDamageRadius;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CEnvMeteorShared::CalcEnterAndExitTimes( const Vector &vecTriggerMins,
+ const Vector &vecTriggerMaxs )
+{
+#define METEOR_TRIGGER_EPSILON 0.001f
+
+ // Initialize the enter/exit fractions.
+ float flEnterFrac = 0.0f;
+ float flExitFrac = 1.0f;
+
+ // Create an arbitrarily large end position.
+ Vector vecEndPosition;
+ VectorMA( m_vecStartPosition, 32000.0f, m_vecDirection, vecEndPosition );
+
+ float flFrac, flDistStart, flDistEnd;
+ for( int iAxis = 0; iAxis < 3; iAxis++ )
+ {
+ // Negative Axis
+ flDistStart = -m_vecStartPosition[iAxis] + vecTriggerMins[iAxis];
+ flDistEnd = -vecEndPosition[iAxis] + vecTriggerMins[iAxis];
+
+ if ( ( flDistStart > 0.0f ) && ( flDistEnd < 0.0f ) )
+ {
+ flFrac = ( flDistStart - METEOR_TRIGGER_EPSILON ) / ( flDistStart - flDistEnd );
+ if ( flFrac > flEnterFrac ) { flEnterFrac = flFrac; }
+ }
+
+ if ( ( flDistStart < 0.0f ) && ( flDistEnd > 0.0f ) )
+ {
+ flFrac = ( flDistStart + METEOR_TRIGGER_EPSILON ) / ( flDistStart - flDistEnd );
+ if( flFrac < flExitFrac ) { flExitFrac = flFrac; }
+ }
+
+ if ( ( flDistStart > 0.0f ) && ( flDistEnd > 0.0f ) )
+ return;
+
+ // Positive Axis
+ flDistStart = m_vecStartPosition[iAxis] - vecTriggerMaxs[iAxis];
+ flDistEnd = vecEndPosition[iAxis] - vecTriggerMaxs[iAxis];
+
+ if ( ( flDistStart > 0.0f ) && ( flDistEnd < 0.0f ) )
+ {
+ flFrac = ( flDistStart - METEOR_TRIGGER_EPSILON ) / ( flDistStart - flDistEnd );
+ if ( flFrac > flEnterFrac ) { flEnterFrac = flFrac; }
+ }
+
+ if ( ( flDistStart < 0.0f ) && ( flDistEnd > 0.0f ) )
+ {
+ flFrac = ( flDistStart + METEOR_TRIGGER_EPSILON ) / ( flDistStart - flDistEnd );
+ if( flFrac < flExitFrac ) { flExitFrac = flFrac; }
+ }
+
+ if ( ( flDistStart > 0.0f ) && ( flDistEnd > 0.0f ) )
+ return;
+ }
+
+ // Check for intersection.
+ if ( flExitFrac >= flEnterFrac )
+ {
+ // Check to see if we start in the world or the skybox!
+ if ( flEnterFrac == 0.0f )
+ {
+ m_nLocation = METEOR_LOCATION_WORLD;
+ }
+ else
+ {
+ m_nLocation = METEOR_LOCATION_SKYBOX;
+ }
+
+ // Calculate the enter/exit times.
+ Vector vecEnterPoint, vecExitPoint, vecDeltaPosition;
+ VectorSubtract( vecEndPosition, m_vecStartPosition, vecDeltaPosition );
+ VectorScale( vecDeltaPosition, flEnterFrac, vecEnterPoint );
+ VectorScale( vecDeltaPosition, flExitFrac, vecExitPoint );
+
+ m_flWorldEnterTime = vecEnterPoint.Length() / m_flSpeed;
+ m_flWorldExitTime = vecExitPoint.Length() / m_flSpeed;
+ m_flWorldEnterTime += m_flStartTime;
+ m_flWorldExitTime += m_flStartTime;
+ }
+
+#undef METEOR_TRIGGER_EPSILON
+}
+
+//=============================================================================
+//
+// Meteor Spawner Functions.
+//
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+CEnvMeteorSpawnerShared::CEnvMeteorSpawnerShared()
+{
+ m_pFactory = NULL;
+ m_nMeteorCount = 0;
+
+ m_flStartTime = 0.0f;
+ m_nRandomSeed = 0;
+
+ m_iMeteorType = -1;
+ m_flMeteorDamageRadius = 0.0f;
+ m_bSkybox = true;
+
+ m_flMinSpawnTime = 0.0f;
+ m_flMaxSpawnTime = 0.0f;
+ m_nMinSpawnCount = 0;
+ m_nMaxSpawnCount = 0;
+ m_vecMinBounds.Init();
+ m_vecMaxBounds.Init();
+ m_flMinSpeed = 0.0f;
+ m_flMaxSpeed = 0.0f;
+
+ m_flNextSpawnTime = 0.0f;
+
+ m_vecTriggerMins.Init();
+ m_vecTriggerMaxs.Init();
+ m_vecTriggerCenter.Init();
+
+ // Debug!
+ m_nRandomCallCount = 0;
+
+ m_aTargets.Purge();
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CEnvMeteorSpawnerShared::Init( IMeteorFactory *pFactory, int nRandomSeed, float flTime,
+ const Vector &vecMinBounds, const Vector &vecMaxBounds,
+ const Vector &vecTriggerMins, const Vector &vecTriggerMaxs )
+{
+ // Factory.
+ m_pFactory = pFactory;
+
+ // Setup the random number stream.
+ m_nRandomSeed = nRandomSeed;
+ m_NumberStream.SetSeed( nRandomSeed );
+
+ // Start time.
+ m_flStartTime = flTime;
+
+ // Copy the spawner bounds.
+ m_vecMinBounds = vecMinBounds;
+ m_vecMaxBounds = vecMaxBounds;
+
+ // Copy the trigger bounds.
+ m_vecTriggerMins = vecTriggerMins;
+ m_vecTriggerMaxs = vecTriggerMaxs;
+
+ // Get the center of the trigger bounds.
+ m_vecTriggerCenter = ( m_vecTriggerMins + m_vecTriggerMaxs ) * 0.5f;
+
+ // Setup spawn time.
+ m_flNextSpawnTime = m_flStartTime + m_flMaxSpawnTime;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+int CEnvMeteorSpawnerShared::GetRandomInt( int nMin, int nMax )
+{
+ m_nRandomCallCount++;
+ return m_NumberStream.RandomInt( nMin, nMax );
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+float CEnvMeteorSpawnerShared::GetRandomFloat( float flMin, float flMax )
+{
+ m_nRandomCallCount++;
+ return m_NumberStream.RandomFloat( flMin, flMax );
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+float CEnvMeteorSpawnerShared::MeteorThink( float flTime )
+{
+ // Check for spawn.
+ if ( flTime < m_flNextSpawnTime )
+ return m_flNextSpawnTime;
+
+ while ( m_flNextSpawnTime < flTime )
+ {
+ // Get a random number of meteors to spawn and spawn them.
+ int nMeteorCount = GetRandomInt( m_nMinSpawnCount, m_nMaxSpawnCount );
+ for ( int iMeteor = 0; iMeteor < nMeteorCount; iMeteor++ )
+ {
+ // Increment the number of meteors created (starting with 1).
+ m_nMeteorCount++;
+
+ // Get a random meteor position.
+ Vector meteorOrigin( GetRandomFloat( m_vecMinBounds.GetX(), m_vecMaxBounds.GetX() ) /* x */,
+ GetRandomFloat( m_vecMinBounds.GetY(), m_vecMaxBounds.GetY() ) /* y */,
+ GetRandomFloat( m_vecMinBounds.GetZ(), m_vecMaxBounds.GetZ() ) /* z */ );
+
+ // Calculate the direction of the meteor based on "targets."
+ Vector vecDirection( 0.0f, 0.0f, -1.0f );
+ if ( m_aTargets.Count() > 0 )
+ {
+ float flFreq = 1.0f / m_aTargets.Count();
+ float flFreqAccum = flFreq;
+
+ int iTarget;
+ for( iTarget = 0; iTarget < m_aTargets.Count(); ++iTarget )
+ {
+ float flRandom = GetRandomFloat( 0.0f, 1.0f );
+ if ( flRandom < flFreqAccum )
+ break;
+
+ flFreqAccum += flFreq;
+ }
+
+ // Should ever be here!
+ if ( iTarget == m_aTargets.Count() )
+ {
+ iTarget--;
+ }
+
+ // Just set it to the first target for now!!!
+ // NOTE: Will randomly generate from list of targets when more than 1 in
+ // the future.
+
+ // Move the meteor into the "world."
+ Vector vecPositionInWorld;
+ Vector vecSkyboxOrigin;
+ g_pMapData->Get3DSkyboxOrigin( vecSkyboxOrigin );
+ vecPositionInWorld = ( meteorOrigin - vecSkyboxOrigin );
+ vecPositionInWorld *= g_pMapData->Get3DSkyboxScale();
+
+ Vector vecTargetPos = m_aTargets[iTarget].m_vecPosition;
+ vecTargetPos.x += GetRandomFloat( -m_aTargets[iTarget].m_flRadius, m_aTargets[iTarget].m_flRadius );
+ vecTargetPos.y += GetRandomFloat( -m_aTargets[iTarget].m_flRadius, m_aTargets[iTarget].m_flRadius );
+ vecTargetPos.z += GetRandomFloat( -m_aTargets[iTarget].m_flRadius, m_aTargets[iTarget].m_flRadius );
+
+ vecDirection = vecTargetPos - vecPositionInWorld;
+ VectorNormalize( vecDirection );
+ }
+
+ // Pass in the randomized position, randomized speed, and start time.
+ m_pFactory->CreateMeteor( m_nMeteorCount, m_iMeteorType, meteorOrigin,
+ vecDirection /* direction */,
+ GetRandomFloat( m_flMinSpeed, m_flMaxSpeed ) /* speed */,
+ m_flNextSpawnTime, m_flMeteorDamageRadius,
+ m_vecTriggerMins, m_vecTriggerMaxs );
+ }
+
+ // Set next spawn time.
+ m_flNextSpawnTime += GetRandomFloat( m_flMinSpawnTime, m_flMaxSpawnTime );
+ }
+
+ // Return the next spawn time.
+ return ( m_flNextSpawnTime - gpGlobals->curtime );
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CEnvMeteorSpawnerShared::AddToTargetList( const Vector &vecPosition, float flRadius )
+{
+ int iTarget = m_aTargets.AddToTail();
+ m_aTargets[iTarget].m_vecPosition = vecPosition;
+ m_aTargets[iTarget].m_flRadius = flRadius;
+}