diff options
| author | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:31:46 -0800 |
|---|---|---|
| committer | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:46:31 -0800 |
| commit | f56bb35301836e56582a575a75864392a0177875 (patch) | |
| tree | de61ddd39de3e7df52759711950b4c288592f0dc /mp/src/game/shared/env_meteor_shared.cpp | |
| parent | Mark some more files as text. (diff) | |
| download | source-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.cpp | 798 |
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; +} |