You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
234 lines
6.5 KiB
234 lines
6.5 KiB
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $Workfile: $
|
|
// $Date: $
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
// $Log: $
|
|
//
|
|
// $NoKeywords: $
|
|
//=============================================================================//
|
|
#include "cbase.h"
|
|
#include "clientsideeffects.h"
|
|
#include "tier0/vprof.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
bool g_FXCreationAllowed = false;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : state -
|
|
//-----------------------------------------------------------------------------
|
|
void SetFXCreationAllowed( bool state )
|
|
{
|
|
g_FXCreationAllowed = state;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Output : Returns true on success, false on failure.
|
|
//-----------------------------------------------------------------------------
|
|
bool FXCreationAllowed( void )
|
|
{
|
|
return g_FXCreationAllowed;
|
|
}
|
|
|
|
// TODO: Sort effects and their children back to front from view positon? At least with buckets or something.
|
|
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Construct and activate effect
|
|
// Input : *name -
|
|
//-----------------------------------------------------------------------------
|
|
CClientSideEffect::CClientSideEffect( const char *name )
|
|
{
|
|
m_pszName = name;
|
|
Assert( name );
|
|
|
|
m_bActive = true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Destroy effect
|
|
//-----------------------------------------------------------------------------
|
|
CClientSideEffect::~CClientSideEffect( void )
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Get name of effect
|
|
// Output : const char
|
|
//-----------------------------------------------------------------------------
|
|
const char *CClientSideEffect::GetName( void )
|
|
{
|
|
return m_pszName;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Is effect still active?
|
|
// Output : Returns true on success, false on failure.
|
|
//-----------------------------------------------------------------------------
|
|
bool CClientSideEffect::IsActive( void )
|
|
{
|
|
return m_bActive;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Mark effect for destruction
|
|
//-----------------------------------------------------------------------------
|
|
void CClientSideEffect::Destroy( void )
|
|
{
|
|
m_bActive = false;
|
|
}
|
|
|
|
#define MAX_EFFECTS 256
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Implements effects list interface
|
|
//-----------------------------------------------------------------------------
|
|
class CEffectsList : public IEffectsList
|
|
{
|
|
public:
|
|
CEffectsList( void );
|
|
virtual ~CEffectsList( void );
|
|
|
|
// Add an effect to the effects list
|
|
void AddEffect( CClientSideEffect *effect );
|
|
// Remove the specified effect
|
|
// Draw/update all effects in the current list
|
|
void DrawEffects( double frametime );
|
|
// Flush out all effects from the list
|
|
void Flush( void );
|
|
private:
|
|
void RemoveEffect( int effectIndex );
|
|
// Current number of effects
|
|
int m_nEffects;
|
|
// Pointers to current effects
|
|
CClientSideEffect *m_rgEffects[ MAX_EFFECTS ];
|
|
};
|
|
|
|
// Implements effects list and exposes interface
|
|
static CEffectsList g_EffectsList;
|
|
// Public interface
|
|
IEffectsList *clienteffects = ( IEffectsList * )&g_EffectsList;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
CEffectsList::CEffectsList( void )
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
CEffectsList::~CEffectsList( void )
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Add effect to effects list
|
|
// Input : *effect -
|
|
//-----------------------------------------------------------------------------
|
|
void CEffectsList::AddEffect( CClientSideEffect *effect )
|
|
{
|
|
#if 0
|
|
if ( FXCreationAllowed() == false )
|
|
{
|
|
//NOTENOTE: If you've hit this, you may not add a client effect where you have attempted to.
|
|
// Most often this means that you have added it in an entity's DrawModel function.
|
|
// Move this to the ClientThink function instead!
|
|
|
|
Assert(0);
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
if ( effect == NULL )
|
|
return;
|
|
|
|
if ( m_nEffects >= MAX_EFFECTS )
|
|
{
|
|
DevWarning( 1, "No room for effect %s\n", effect->GetName() );
|
|
return;
|
|
}
|
|
|
|
m_rgEffects[ m_nEffects++ ] = effect;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Remove specified effect by index
|
|
// Input : effectIndex -
|
|
//-----------------------------------------------------------------------------
|
|
void CEffectsList::RemoveEffect( int effectIndex )
|
|
{
|
|
if ( effectIndex >= m_nEffects || effectIndex < 0 )
|
|
return;
|
|
|
|
CClientSideEffect *pEffect = m_rgEffects[effectIndex];
|
|
m_nEffects--;
|
|
|
|
if ( m_nEffects > 0 && effectIndex != m_nEffects )
|
|
{
|
|
// move the last one down to fill the empty slot
|
|
m_rgEffects[effectIndex] = m_rgEffects[m_nEffects];
|
|
}
|
|
|
|
pEffect->Destroy();
|
|
|
|
delete pEffect; //FIXME: Yes, no?
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Iterate through list and simulate/draw stuff
|
|
// Input : frametime -
|
|
//-----------------------------------------------------------------------------
|
|
void CEffectsList::DrawEffects( double frametime )
|
|
{
|
|
VPROF_BUDGET( "CEffectsList::DrawEffects", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
|
|
int i;
|
|
CClientSideEffect *effect;
|
|
|
|
// Go backwards so deleting effects doesn't screw up
|
|
for ( i = m_nEffects - 1 ; i >= 0; i-- )
|
|
{
|
|
effect = m_rgEffects[ i ];
|
|
if ( !effect )
|
|
continue;
|
|
|
|
// Simulate
|
|
effect->Draw( frametime );
|
|
|
|
// Remove it if needed
|
|
if ( !effect->IsActive() )
|
|
{
|
|
RemoveEffect( i );
|
|
}
|
|
}
|
|
}
|
|
|
|
//==================================================
|
|
// Purpose:
|
|
// Input:
|
|
//==================================================
|
|
|
|
void CEffectsList::Flush( void )
|
|
{
|
|
int i;
|
|
CClientSideEffect *effect;
|
|
|
|
// Go backwards so deleting effects doesn't screw up
|
|
for ( i = m_nEffects - 1 ; i >= 0; i-- )
|
|
{
|
|
effect = m_rgEffects[ i ];
|
|
|
|
if ( effect == NULL )
|
|
continue;
|
|
|
|
RemoveEffect( i );
|
|
}
|
|
}
|