initial
This commit is contained in:
54
game/client/AnimateSpecificTextureProxy.cpp
Normal file
54
game/client/AnimateSpecificTextureProxy.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Acts exactly like "AnimatedTexture", but ONLY if the texture
|
||||
// it's working on matches the desired texture to work on.
|
||||
//
|
||||
// This assumes that some other proxy will be switching out the textures.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "materialsystem/imaterialproxy.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/itexture.h"
|
||||
#include "baseanimatedtextureproxy.h"
|
||||
#include "utlstring.h"
|
||||
#include <keyvalues.h>
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class CAnimateSpecificTexture : public CBaseAnimatedTextureProxy
|
||||
{
|
||||
private:
|
||||
CUtlString m_OnlyAnimateOnTexture;
|
||||
public:
|
||||
virtual float GetAnimationStartTime( void* pBaseEntity ) { return 0; }
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( void *pC_BaseEntity );
|
||||
virtual void Release( void ) { delete this; }
|
||||
};
|
||||
|
||||
bool CAnimateSpecificTexture::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
char const* pszAnimateOnTexture = pKeyValues->GetString( "onlyAnimateOnTexture" );
|
||||
if( !pszAnimateOnTexture )
|
||||
return false;
|
||||
|
||||
m_OnlyAnimateOnTexture.Set( pszAnimateOnTexture );
|
||||
|
||||
return CBaseAnimatedTextureProxy::Init( pMaterial, pKeyValues );
|
||||
}
|
||||
|
||||
void CAnimateSpecificTexture::OnBind( void *pC_BaseEntity )
|
||||
{
|
||||
if( FStrEq( m_AnimatedTextureVar->GetTextureValue()->GetName(), m_OnlyAnimateOnTexture ) )
|
||||
{
|
||||
CBaseAnimatedTextureProxy::OnBind( pC_BaseEntity );
|
||||
}
|
||||
//else do nothing
|
||||
}
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CAnimateSpecificTexture, AnimateSpecificTexture );
|
||||
785
game/client/C_MaterialModifyControl.cpp
Normal file
785
game/client/C_MaterialModifyControl.cpp
Normal file
@@ -0,0 +1,785 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Material Modify control entity.
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "proxyentity.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "materialsystem/itexture.h"
|
||||
#include "iviewrender.h"
|
||||
#include "texture_group_names.h"
|
||||
#include "baseanimatedtextureproxy.h"
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define MATERIAL_MODIFY_STRING_SIZE 255
|
||||
#define MATERIAL_MODIFY_ANIMATION_UNSET -1
|
||||
|
||||
// Must match MaterialModifyControl.cpp
|
||||
enum MaterialModifyMode_t
|
||||
{
|
||||
MATERIAL_MODIFY_MODE_NONE = 0,
|
||||
MATERIAL_MODIFY_MODE_SETVAR = 1,
|
||||
MATERIAL_MODIFY_MODE_ANIM_SEQUENCE = 2,
|
||||
MATERIAL_MODIFY_MODE_FLOAT_LERP = 3,
|
||||
};
|
||||
|
||||
ConVar debug_materialmodifycontrol_client( "debug_materialmodifycontrol_client", "0" );
|
||||
|
||||
struct materialanimcommands_t
|
||||
{
|
||||
int iFrameStart;
|
||||
int iFrameEnd;
|
||||
bool bWrap;
|
||||
float flFrameRate;
|
||||
};
|
||||
|
||||
struct materialfloatlerpcommands_t
|
||||
{
|
||||
int flStartValue;
|
||||
int flEndValue;
|
||||
float flTransitionTime;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// FIXME: This really should inherit from something more lightweight
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class C_MaterialModifyControl : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( C_MaterialModifyControl, C_BaseEntity );
|
||||
|
||||
C_MaterialModifyControl();
|
||||
|
||||
void OnPreDataChanged( DataUpdateType_t updateType );
|
||||
void OnDataChanged( DataUpdateType_t updateType );
|
||||
bool ShouldDraw();
|
||||
|
||||
IMaterial *GetMaterial( void ) { return m_pMaterial; }
|
||||
const char *GetMaterialVariableName( void ) { return m_szMaterialVar; }
|
||||
const char *GetMaterialVariableValue( void ) { return m_szMaterialVarValue; }
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
// Animated texture and Float Lerp usage
|
||||
bool HasNewAnimationCommands( void ) { return m_bHasNewAnimationCommands; }
|
||||
void ClearAnimationCommands( void ) { m_bHasNewAnimationCommands = false; }
|
||||
|
||||
// Animated texture usage
|
||||
void GetAnimationCommands( materialanimcommands_t *pCommands );
|
||||
|
||||
// FloatLerp usage
|
||||
void GetFloatLerpCommands( materialfloatlerpcommands_t *pCommands );
|
||||
|
||||
void SetAnimationStartTime( float flTime )
|
||||
{
|
||||
m_flAnimationStartTime = flTime;
|
||||
}
|
||||
float GetAnimationStartTime( void ) const
|
||||
{
|
||||
return m_flAnimationStartTime;
|
||||
}
|
||||
|
||||
MaterialModifyMode_t GetModifyMode( void ) const
|
||||
{
|
||||
return ( MaterialModifyMode_t)m_nModifyMode;
|
||||
}
|
||||
private:
|
||||
|
||||
char m_szMaterialName[MATERIAL_MODIFY_STRING_SIZE];
|
||||
char m_szMaterialVar[MATERIAL_MODIFY_STRING_SIZE];
|
||||
char m_szMaterialVarValue[MATERIAL_MODIFY_STRING_SIZE];
|
||||
IMaterial *m_pMaterial;
|
||||
|
||||
bool m_bHasNewAnimationCommands;
|
||||
|
||||
// Animation commands from the server
|
||||
int m_iFrameStart;
|
||||
int m_iFrameEnd;
|
||||
bool m_bWrap;
|
||||
float m_flFramerate;
|
||||
bool m_bNewAnimCommandsSemaphore;
|
||||
bool m_bOldAnimCommandsSemaphore;
|
||||
|
||||
// Float lerp commands from the server
|
||||
float m_flFloatLerpStartValue;
|
||||
float m_flFloatLerpEndValue;
|
||||
float m_flFloatLerpTransitionTime;
|
||||
bool m_bFloatLerpWrap;
|
||||
float m_flAnimationStartTime;
|
||||
|
||||
int m_nModifyMode;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_MaterialModifyControl, DT_MaterialModifyControl, CMaterialModifyControl)
|
||||
RecvPropString( RECVINFO( m_szMaterialName ) ),
|
||||
RecvPropString( RECVINFO( m_szMaterialVar ) ),
|
||||
RecvPropString( RECVINFO( m_szMaterialVarValue ) ),
|
||||
RecvPropInt( RECVINFO(m_iFrameStart) ),
|
||||
RecvPropInt( RECVINFO(m_iFrameEnd) ),
|
||||
RecvPropInt( RECVINFO(m_bWrap) ),
|
||||
RecvPropFloat( RECVINFO(m_flFramerate) ),
|
||||
RecvPropInt( RECVINFO(m_bNewAnimCommandsSemaphore) ),
|
||||
RecvPropFloat( RECVINFO(m_flFloatLerpStartValue) ),
|
||||
RecvPropFloat( RECVINFO(m_flFloatLerpEndValue) ),
|
||||
RecvPropFloat( RECVINFO(m_flFloatLerpTransitionTime) ),
|
||||
RecvPropInt( RECVINFO(m_bFloatLerpWrap) ),
|
||||
RecvPropInt( RECVINFO(m_nModifyMode) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//------------------------------------------------------------------------------
|
||||
C_MaterialModifyControl::C_MaterialModifyControl()
|
||||
{
|
||||
m_pMaterial = NULL;
|
||||
m_bOldAnimCommandsSemaphore = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_MaterialModifyControl::OnPreDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnPreDataChanged( updateType );
|
||||
|
||||
m_bOldAnimCommandsSemaphore = m_bNewAnimCommandsSemaphore;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//------------------------------------------------------------------------------
|
||||
void C_MaterialModifyControl::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
if( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
m_pMaterial = materials->FindMaterial( m_szMaterialName, TEXTURE_GROUP_OTHER );
|
||||
|
||||
// Clear out our variables
|
||||
m_bHasNewAnimationCommands = true;
|
||||
}
|
||||
|
||||
// Detect changes in the anim commands
|
||||
if ( m_bNewAnimCommandsSemaphore != m_bOldAnimCommandsSemaphore )
|
||||
{
|
||||
m_bHasNewAnimationCommands = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_MaterialModifyControl::GetAnimationCommands( materialanimcommands_t *pCommands )
|
||||
{
|
||||
pCommands->iFrameStart = m_iFrameStart;
|
||||
pCommands->iFrameEnd = m_iFrameEnd;
|
||||
pCommands->bWrap = m_bWrap;
|
||||
pCommands->flFrameRate = m_flFramerate;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_MaterialModifyControl::GetFloatLerpCommands( materialfloatlerpcommands_t *pCommands )
|
||||
{
|
||||
pCommands->flStartValue = m_flFloatLerpStartValue;
|
||||
pCommands->flEndValue = m_flFloatLerpEndValue;
|
||||
pCommands->flTransitionTime = m_flFloatLerpTransitionTime;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: We don't draw.
|
||||
//------------------------------------------------------------------------------
|
||||
bool C_MaterialModifyControl::ShouldDraw()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// THE MATERIALMODIFYPROXY ITSELF
|
||||
//
|
||||
class CMaterialModifyProxy : public CBaseAnimatedTextureProxy
|
||||
{
|
||||
public:
|
||||
CMaterialModifyProxy();
|
||||
virtual ~CMaterialModifyProxy();
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( void *pEntity );
|
||||
virtual IMaterial *GetMaterial();
|
||||
|
||||
private:
|
||||
void OnBindSetVar( C_MaterialModifyControl *pControl );
|
||||
void OnBindAnimatedTexture( C_MaterialModifyControl *pControl );
|
||||
void OnBindFloatLerp( C_MaterialModifyControl *pControl );
|
||||
float GetAnimationStartTime( void* pArg );
|
||||
void AnimationWrapped( void* pArg );
|
||||
|
||||
IMaterial *m_pMaterial;
|
||||
|
||||
// texture animation stuff
|
||||
int m_iFrameStart;
|
||||
int m_iFrameEnd;
|
||||
bool m_bReachedEnd;
|
||||
bool m_bCustomWrap;
|
||||
float m_flCustomFramerate;
|
||||
|
||||
// float lerp stuff
|
||||
IMaterialVar *m_pMaterialVar;
|
||||
int m_flStartValue;
|
||||
int m_flEndValue;
|
||||
float m_flStartTime;
|
||||
float m_flTransitionTime;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CMaterialModifyProxy::CMaterialModifyProxy()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CMaterialModifyProxy::~CMaterialModifyProxy()
|
||||
{
|
||||
}
|
||||
|
||||
bool CMaterialModifyProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
// set var stuff
|
||||
m_pMaterial = pMaterial;
|
||||
|
||||
// float lerp stuff
|
||||
m_flStartValue = MATERIAL_MODIFY_ANIMATION_UNSET;
|
||||
m_flEndValue = MATERIAL_MODIFY_ANIMATION_UNSET;
|
||||
|
||||
// animated stuff
|
||||
// m_pMaterial = pMaterial;
|
||||
// m_iFrameStart = MATERIAL_MODIFY_ANIMATION_UNSET;
|
||||
// m_iFrameEnd = MATERIAL_MODIFY_ANIMATION_UNSET;
|
||||
// m_bReachedEnd = false;
|
||||
// return CBaseAnimatedTextureProxy::Init( pMaterial, pKeyValues );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMaterialModifyProxy::OnBind( void *pEntity )
|
||||
{
|
||||
// Get the modified material vars from the entity input
|
||||
IClientRenderable *pRend = (IClientRenderable *)pEntity;
|
||||
if ( pRend )
|
||||
{
|
||||
C_BaseEntity *pBaseEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
|
||||
if ( pBaseEntity )
|
||||
{
|
||||
if( debug_materialmodifycontrol_client.GetBool() )
|
||||
{
|
||||
// DevMsg( 1, "%s\n", pBaseEntity->GetDebugName() );
|
||||
}
|
||||
int numChildren = 0;
|
||||
bool gotOne = false;
|
||||
for ( C_BaseEntity *pChild = pBaseEntity->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() )
|
||||
{
|
||||
numChildren++;
|
||||
C_MaterialModifyControl *pControl = dynamic_cast<C_MaterialModifyControl*>( pChild );
|
||||
if ( !pControl )
|
||||
continue;
|
||||
|
||||
if( debug_materialmodifycontrol_client.GetBool() )
|
||||
{
|
||||
// DevMsg( 1, "pControl: 0x%p\n", pControl );
|
||||
}
|
||||
|
||||
switch( pControl->GetModifyMode() )
|
||||
{
|
||||
case MATERIAL_MODIFY_MODE_NONE:
|
||||
break;
|
||||
case MATERIAL_MODIFY_MODE_SETVAR:
|
||||
gotOne = true;
|
||||
OnBindSetVar( pControl );
|
||||
break;
|
||||
case MATERIAL_MODIFY_MODE_ANIM_SEQUENCE:
|
||||
OnBindAnimatedTexture( pControl );
|
||||
break;
|
||||
case MATERIAL_MODIFY_MODE_FLOAT_LERP:
|
||||
OnBindFloatLerp( pControl );
|
||||
break;
|
||||
default:
|
||||
Assert( 0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( gotOne )
|
||||
{
|
||||
// DevMsg( 1, "numChildren: %d\n", numChildren );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IMaterial *CMaterialModifyProxy::GetMaterial()
|
||||
{
|
||||
return m_pMaterial;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMaterialModifyProxy::OnBindSetVar( C_MaterialModifyControl *pControl )
|
||||
{
|
||||
IMaterial *pMaterial = pControl->GetMaterial();
|
||||
if( !pMaterial )
|
||||
{
|
||||
Assert( 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pMaterial != m_pMaterial )
|
||||
{
|
||||
// Warning( "\t%s!=%s\n", pMaterial->GetName(), m_pMaterial->GetName() );
|
||||
return;
|
||||
}
|
||||
|
||||
bool bFound;
|
||||
IMaterialVar *pMaterialVar = pMaterial->FindVar( pControl->GetMaterialVariableName(), &bFound, false );
|
||||
if ( !bFound )
|
||||
return;
|
||||
|
||||
if( Q_strcmp( pControl->GetMaterialVariableValue(), "" ) )
|
||||
{
|
||||
// const char *pMaterialName = m_pMaterial->GetName();
|
||||
// const char *pMaterialVarName = pMaterialVar->GetName();
|
||||
// const char *pMaterialVarValue = pControl->GetMaterialVariableValue();
|
||||
// if( debug_materialmodifycontrol_client.GetBool()
|
||||
// && Q_stristr( m_pMaterial->GetName(), "faceandhair" )
|
||||
// && Q_stristr( pMaterialVar->GetName(), "self" )
|
||||
// )
|
||||
// {
|
||||
// static int count = 0;
|
||||
// DevMsg( 1, "CMaterialModifyProxy::OnBindSetVar \"%s\" %s=%s %d pControl=0x%p\n",
|
||||
// m_pMaterial->GetName(), pMaterialVar->GetName(), pControl->GetMaterialVariableValue(), count++, pControl );
|
||||
// }
|
||||
pMaterialVar->SetValueAutodetectType( pControl->GetMaterialVariableValue() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Does the dirty deed
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMaterialModifyProxy::OnBindAnimatedTexture( C_MaterialModifyControl *pControl )
|
||||
{
|
||||
assert ( m_AnimatedTextureVar );
|
||||
if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
|
||||
return;
|
||||
|
||||
ITexture *pTexture;
|
||||
pTexture = m_AnimatedTextureVar->GetTextureValue();
|
||||
|
||||
if ( !pControl )
|
||||
return;
|
||||
|
||||
if ( pControl->HasNewAnimationCommands() )
|
||||
{
|
||||
// Read the data from the modify entity
|
||||
materialanimcommands_t sCommands;
|
||||
pControl->GetAnimationCommands( &sCommands );
|
||||
|
||||
m_iFrameStart = sCommands.iFrameStart;
|
||||
m_iFrameEnd = sCommands.iFrameEnd;
|
||||
m_bCustomWrap = sCommands.bWrap;
|
||||
m_flCustomFramerate = sCommands.flFrameRate;
|
||||
m_bReachedEnd = false;
|
||||
|
||||
m_flStartTime = gpGlobals->curtime;
|
||||
|
||||
pControl->ClearAnimationCommands();
|
||||
}
|
||||
|
||||
// Init all the vars based on whether we're using the base material settings,
|
||||
// or the custom ones from the entity input.
|
||||
int numFrames;
|
||||
bool bWrapAnimation;
|
||||
float flFrameRate;
|
||||
int iLastFrame;
|
||||
|
||||
// Do we have a custom frame section from the server?
|
||||
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||
{
|
||||
if ( m_iFrameEnd == MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||
{
|
||||
m_iFrameEnd = pTexture->GetNumAnimationFrames();
|
||||
}
|
||||
|
||||
numFrames = (m_iFrameEnd - m_iFrameStart) + 1;
|
||||
bWrapAnimation = m_bCustomWrap;
|
||||
flFrameRate = m_flCustomFramerate;
|
||||
iLastFrame = (m_iFrameEnd - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
numFrames = pTexture->GetNumAnimationFrames();
|
||||
bWrapAnimation = m_WrapAnimation;
|
||||
flFrameRate = m_FrameRate;
|
||||
iLastFrame = (numFrames - 1);
|
||||
}
|
||||
|
||||
// Have we already reached the end? If so, stay there.
|
||||
if ( m_bReachedEnd && !bWrapAnimation )
|
||||
{
|
||||
m_AnimatedTextureFrameNumVar->SetIntValue( iLastFrame );
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: Must not use relative time based methods here
|
||||
// because the bind proxy can be called many times per frame.
|
||||
// Prevent multiple Wrap callbacks to be sent for no wrap mode
|
||||
float startTime;
|
||||
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||
{
|
||||
startTime = m_flStartTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
startTime = GetAnimationStartTime(pControl);
|
||||
}
|
||||
float deltaTime = gpGlobals->curtime - startTime;
|
||||
float prevTime = deltaTime - gpGlobals->frametime;
|
||||
|
||||
// Clamp..
|
||||
if (deltaTime < 0.0f)
|
||||
deltaTime = 0.0f;
|
||||
if (prevTime < 0.0f)
|
||||
prevTime = 0.0f;
|
||||
|
||||
float frame = flFrameRate * deltaTime;
|
||||
float prevFrame = flFrameRate * prevTime;
|
||||
|
||||
int intFrame = ((int)frame) % numFrames;
|
||||
int intPrevFrame = ((int)prevFrame) % numFrames;
|
||||
|
||||
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||
{
|
||||
intFrame += m_iFrameStart;
|
||||
intPrevFrame += m_iFrameStart;
|
||||
}
|
||||
|
||||
// Report wrap situation...
|
||||
if (intPrevFrame > intFrame)
|
||||
{
|
||||
m_bReachedEnd = true;
|
||||
|
||||
if (bWrapAnimation)
|
||||
{
|
||||
AnimationWrapped( pControl );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only sent the wrapped message once.
|
||||
// when we're in non-wrapping mode
|
||||
if (prevFrame < numFrames)
|
||||
AnimationWrapped( pControl );
|
||||
intFrame = numFrames - 1;
|
||||
}
|
||||
}
|
||||
|
||||
m_AnimatedTextureFrameNumVar->SetIntValue( intFrame );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
float CMaterialModifyProxy::GetAnimationStartTime( void* pArg )
|
||||
{
|
||||
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||
if (!pRend)
|
||||
return 0.0f;
|
||||
|
||||
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
if (pEntity)
|
||||
{
|
||||
return pEntity->GetTextureAnimationStartTime();
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMaterialModifyProxy::AnimationWrapped( void* pArg )
|
||||
{
|
||||
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||
if (!pRend)
|
||||
return;
|
||||
|
||||
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
if (pEntity)
|
||||
{
|
||||
pEntity->TextureAnimationWrapped();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Does the dirty deed
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMaterialModifyProxy::OnBindFloatLerp( C_MaterialModifyControl *pControl )
|
||||
{
|
||||
if ( !pControl )
|
||||
return;
|
||||
|
||||
if ( pControl->HasNewAnimationCommands() )
|
||||
{
|
||||
pControl->SetAnimationStartTime( gpGlobals->curtime );
|
||||
pControl->ClearAnimationCommands();
|
||||
}
|
||||
|
||||
// Read the data from the modify entity
|
||||
materialfloatlerpcommands_t sCommands;
|
||||
pControl->GetFloatLerpCommands( &sCommands );
|
||||
|
||||
m_flStartValue = sCommands.flStartValue;
|
||||
m_flEndValue = sCommands.flEndValue;
|
||||
m_flTransitionTime = sCommands.flTransitionTime;
|
||||
m_flStartTime = pControl->GetAnimationStartTime();
|
||||
bool bFound;
|
||||
m_pMaterialVar = m_pMaterial->FindVar( pControl->GetMaterialVariableName(), &bFound, false );
|
||||
|
||||
if( bFound )
|
||||
{
|
||||
float currentValue;
|
||||
if( m_flTransitionTime > 0.0f )
|
||||
{
|
||||
currentValue = m_flStartValue + ( m_flEndValue - m_flStartValue ) * clamp( ( ( gpGlobals->curtime - m_flStartTime ) / m_flTransitionTime ), 0.0f, 1.0f );
|
||||
}
|
||||
else
|
||||
{
|
||||
currentValue = m_flEndValue;
|
||||
}
|
||||
|
||||
if( debug_materialmodifycontrol_client.GetBool() && Q_stristr( m_pMaterial->GetName(), "faceandhair" ) && Q_stristr( m_pMaterialVar->GetName(), "warp" ) )
|
||||
{
|
||||
static int count = 0;
|
||||
DevMsg( 1, "CMaterialFloatLerpProxy::OnBind \"%s\" %s=%f %d\n", m_pMaterial->GetName(), m_pMaterialVar->GetName(), currentValue, count++ );
|
||||
}
|
||||
m_pMaterialVar->SetFloatValue( currentValue );
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// MATERIALMODIFYANIMATED PROXY
|
||||
//
|
||||
class CMaterialModifyAnimatedProxy : public CBaseAnimatedTextureProxy
|
||||
{
|
||||
public:
|
||||
CMaterialModifyAnimatedProxy() {};
|
||||
virtual ~CMaterialModifyAnimatedProxy() {};
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( void *pEntity );
|
||||
|
||||
virtual float GetAnimationStartTime( void* pBaseEntity );
|
||||
virtual void AnimationWrapped( void* pC_BaseEntity );
|
||||
|
||||
private:
|
||||
IMaterial *m_pMaterial;
|
||||
int m_iFrameStart;
|
||||
int m_iFrameEnd;
|
||||
bool m_bReachedEnd;
|
||||
float m_flStartTime;
|
||||
bool m_bCustomWrap;
|
||||
float m_flCustomFramerate;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMaterialModifyAnimatedProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
m_pMaterial = pMaterial;
|
||||
m_iFrameStart = MATERIAL_MODIFY_ANIMATION_UNSET;
|
||||
m_iFrameEnd = MATERIAL_MODIFY_ANIMATION_UNSET;
|
||||
m_bReachedEnd = false;
|
||||
return CBaseAnimatedTextureProxy::Init( pMaterial, pKeyValues );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Does the dirty deed
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMaterialModifyAnimatedProxy::OnBind( void *pEntity )
|
||||
{
|
||||
assert ( m_AnimatedTextureVar );
|
||||
if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
|
||||
return;
|
||||
|
||||
ITexture *pTexture;
|
||||
pTexture = m_AnimatedTextureVar->GetTextureValue();
|
||||
|
||||
// Get the modified material vars from the entity input
|
||||
IClientRenderable *pRend = (IClientRenderable *)pEntity;
|
||||
if ( pRend )
|
||||
{
|
||||
C_BaseEntity *pBaseEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
if ( pBaseEntity )
|
||||
{
|
||||
for ( C_BaseEntity *pChild = pBaseEntity->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() )
|
||||
{
|
||||
C_MaterialModifyControl *pControl = dynamic_cast<C_MaterialModifyControl*>( pChild );
|
||||
if ( !pControl )
|
||||
continue;
|
||||
|
||||
if ( !pControl->HasNewAnimationCommands() )
|
||||
continue;
|
||||
|
||||
// Read the data from the modify entity
|
||||
materialanimcommands_t sCommands;
|
||||
pControl->GetAnimationCommands( &sCommands );
|
||||
|
||||
m_iFrameStart = sCommands.iFrameStart;
|
||||
m_iFrameEnd = sCommands.iFrameEnd;
|
||||
m_bCustomWrap = sCommands.bWrap;
|
||||
m_flCustomFramerate = sCommands.flFrameRate;
|
||||
m_bReachedEnd = false;
|
||||
|
||||
m_flStartTime = gpGlobals->curtime;
|
||||
|
||||
pControl->ClearAnimationCommands();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Init all the vars based on whether we're using the base material settings,
|
||||
// or the custom ones from the entity input.
|
||||
int numFrames;
|
||||
bool bWrapAnimation;
|
||||
float flFrameRate;
|
||||
int iLastFrame;
|
||||
|
||||
// Do we have a custom frame section from the server?
|
||||
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||
{
|
||||
if ( m_iFrameEnd == MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||
{
|
||||
m_iFrameEnd = pTexture->GetNumAnimationFrames();
|
||||
}
|
||||
|
||||
numFrames = (m_iFrameEnd - m_iFrameStart) + 1;
|
||||
bWrapAnimation = m_bCustomWrap;
|
||||
flFrameRate = m_flCustomFramerate;
|
||||
iLastFrame = (m_iFrameEnd - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
numFrames = pTexture->GetNumAnimationFrames();
|
||||
bWrapAnimation = m_WrapAnimation;
|
||||
flFrameRate = m_FrameRate;
|
||||
iLastFrame = (numFrames - 1);
|
||||
}
|
||||
|
||||
// Have we already reached the end? If so, stay there.
|
||||
if ( m_bReachedEnd && !bWrapAnimation )
|
||||
{
|
||||
m_AnimatedTextureFrameNumVar->SetIntValue( iLastFrame );
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: Must not use relative time based methods here
|
||||
// because the bind proxy can be called many times per frame.
|
||||
// Prevent multiple Wrap callbacks to be sent for no wrap mode
|
||||
float startTime;
|
||||
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||
{
|
||||
startTime = m_flStartTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
startTime = GetAnimationStartTime(pEntity);
|
||||
}
|
||||
float deltaTime = gpGlobals->curtime - startTime;
|
||||
float prevTime = deltaTime - gpGlobals->frametime;
|
||||
|
||||
// Clamp..
|
||||
if (deltaTime < 0.0f)
|
||||
deltaTime = 0.0f;
|
||||
if (prevTime < 0.0f)
|
||||
prevTime = 0.0f;
|
||||
|
||||
float frame = flFrameRate * deltaTime;
|
||||
float prevFrame = flFrameRate * prevTime;
|
||||
|
||||
int intFrame = ((int)frame) % numFrames;
|
||||
int intPrevFrame = ((int)prevFrame) % numFrames;
|
||||
|
||||
if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
|
||||
{
|
||||
intFrame += m_iFrameStart;
|
||||
intPrevFrame += m_iFrameStart;
|
||||
}
|
||||
|
||||
// Report wrap situation...
|
||||
if (intPrevFrame > intFrame)
|
||||
{
|
||||
m_bReachedEnd = true;
|
||||
|
||||
if (bWrapAnimation)
|
||||
{
|
||||
AnimationWrapped( pEntity );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only sent the wrapped message once.
|
||||
// when we're in non-wrapping mode
|
||||
if (prevFrame < numFrames)
|
||||
AnimationWrapped( pEntity );
|
||||
intFrame = numFrames - 1;
|
||||
}
|
||||
}
|
||||
|
||||
m_AnimatedTextureFrameNumVar->SetIntValue( intFrame );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
float CMaterialModifyAnimatedProxy::GetAnimationStartTime( void* pArg )
|
||||
{
|
||||
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||
if (!pRend)
|
||||
return 0.0f;
|
||||
|
||||
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
if (pEntity)
|
||||
{
|
||||
return pEntity->GetTextureAnimationStartTime();
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMaterialModifyAnimatedProxy::AnimationWrapped( void* pArg )
|
||||
{
|
||||
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||
if (!pRend)
|
||||
return;
|
||||
|
||||
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
if (pEntity)
|
||||
{
|
||||
pEntity->TextureAnimationWrapped();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CMaterialModifyProxy, MaterialModify );
|
||||
EXPOSE_MATERIAL_PROXY( CMaterialModifyAnimatedProxy, MaterialModifyAnimated );
|
||||
60
game/client/C_WaterLODControl.cpp
Normal file
60
game/client/C_WaterLODControl.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Water LOD control entity.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "iviewrender.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// FIXME: This really should inherit from something more lightweight
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose : Water LOD control entity
|
||||
//------------------------------------------------------------------------------
|
||||
class C_WaterLODControl : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_WaterLODControl, C_BaseEntity );
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
void OnDataChanged(DataUpdateType_t updateType);
|
||||
bool ShouldDraw();
|
||||
|
||||
private:
|
||||
float m_flCheapWaterStartDistance;
|
||||
float m_flCheapWaterEndDistance;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_WaterLODControl, DT_WaterLODControl, CWaterLODControl)
|
||||
RecvPropFloat(RECVINFO(m_flCheapWaterStartDistance)),
|
||||
RecvPropFloat(RECVINFO(m_flCheapWaterEndDistance)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
void C_WaterLODControl::OnDataChanged(DataUpdateType_t updateType)
|
||||
{
|
||||
view->SetCheapWaterStartDistance( m_flCheapWaterStartDistance );
|
||||
view->SetCheapWaterEndDistance( m_flCheapWaterEndDistance );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// We don't draw...
|
||||
//------------------------------------------------------------------------------
|
||||
bool C_WaterLODControl::ShouldDraw()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
231
game/client/EffectsClient.cpp
Normal file
231
game/client/EffectsClient.cpp
Normal file
@@ -0,0 +1,231 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Utility code.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "IEffects.h"
|
||||
#include "fx.h"
|
||||
#include "c_te_legacytempents.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Client-server neutral effects interface
|
||||
//-----------------------------------------------------------------------------
|
||||
class CEffectsClient : public IEffects
|
||||
{
|
||||
public:
|
||||
CEffectsClient();
|
||||
virtual ~CEffectsClient();
|
||||
|
||||
// Members of the IEffect interface
|
||||
virtual void Beam( const Vector &Start, const Vector &End, int nModelIndex,
|
||||
int nHaloIndex, unsigned char frameStart, unsigned char frameRate,
|
||||
float flLife, unsigned char width, unsigned char endWidth, unsigned char fadeLength,
|
||||
unsigned char noise, unsigned char red, unsigned char green,
|
||||
unsigned char blue, unsigned char brightness, unsigned char speed);
|
||||
virtual void Smoke( const Vector &origin, int modelIndex, float scale, float framerate );
|
||||
virtual void Sparks( const Vector &position, int nMagnitude = 1, int nTrailLength = 1, const Vector *pvecDir = NULL );
|
||||
virtual void Dust( const Vector &pos, const Vector &dir, float size, float speed );
|
||||
virtual void MuzzleFlash( const Vector &origin, const QAngle &angles, float fScale, int type );
|
||||
virtual void MetalSparks( const Vector &position, const Vector &direction );
|
||||
virtual void EnergySplash( const Vector &position, const Vector &direction, bool bExplosive = false );
|
||||
virtual void Ricochet( const Vector &position, const Vector &direction );
|
||||
|
||||
// FIXME: Should these methods remain in this interface? Or go in some
|
||||
// other client-server neutral interface?
|
||||
virtual float Time();
|
||||
virtual bool IsServer();
|
||||
virtual void SuppressEffectsSounds( bool bSuppress );
|
||||
|
||||
private:
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returning true means don't even call TE func
|
||||
// Input : filter -
|
||||
// *suppress_host -
|
||||
// Output : static bool
|
||||
//-----------------------------------------------------------------------------
|
||||
bool SuppressTE( C_RecipientFilter& filter )
|
||||
{
|
||||
if ( !CanPredict() )
|
||||
return true;
|
||||
|
||||
if ( !filter.GetRecipientCount() )
|
||||
{
|
||||
// Suppress it
|
||||
return true;
|
||||
}
|
||||
|
||||
// There's at least one recipient
|
||||
return false;
|
||||
}
|
||||
|
||||
bool m_bSuppressSound;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Client-server neutral effects interface accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
static CEffectsClient s_EffectClient;
|
||||
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CEffectsClient, IEffects, IEFFECTS_INTERFACE_VERSION, s_EffectClient);
|
||||
IEffects *g_pEffects = &s_EffectClient;
|
||||
|
||||
ConVar r_decals( "r_decals", "2048" );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CEffectsClient::CEffectsClient()
|
||||
{
|
||||
m_bSuppressSound = false;
|
||||
}
|
||||
|
||||
CEffectsClient::~CEffectsClient()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Suppress sound on effects
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEffectsClient::SuppressEffectsSounds( bool bSuppress )
|
||||
{
|
||||
m_bSuppressSound = bSuppress;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Generates a beam
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEffectsClient::Beam( const Vector &vecStartPoint, const Vector &vecEndPoint,
|
||||
int nModelIndex, int nHaloIndex, unsigned char frameStart, unsigned char nFrameRate,
|
||||
float flLife, unsigned char nWidth, unsigned char nEndWidth, unsigned char nFadeLength,
|
||||
unsigned char noise, unsigned char r, unsigned char g,
|
||||
unsigned char b, unsigned char brightness, unsigned char nSpeed)
|
||||
{
|
||||
Assert(0);
|
||||
// CBroadcastRecipientFilter filter;
|
||||
// if ( !SuppressTE( filter ) )
|
||||
// {
|
||||
// beams->CreateBeamPoints( vecStartPoint, vecEndPoint, nModelIndex, nHaloIndex,
|
||||
// m_fHaloScale,
|
||||
// flLife, 0.1 * nWidth, 0.1 * nEndWidth, nFadeLength, 0.01 * nAmplitude, a, 0.1 * nSpeed,
|
||||
// m_nStartFrame, 0.1 * nFrameRate, r, g, b );
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Generates various tempent effects
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEffectsClient::Smoke( const Vector &vecOrigin, int modelIndex, float scale, float framerate )
|
||||
{
|
||||
CPVSFilter filter( vecOrigin );
|
||||
if ( !SuppressTE( filter ) )
|
||||
{
|
||||
int iColor = random->RandomInt(20,35);
|
||||
color32 color;
|
||||
color.r = iColor;
|
||||
color.g = iColor;
|
||||
color.b = iColor;
|
||||
color.a = iColor;
|
||||
QAngle angles;
|
||||
VectorAngles( Vector(0,0,1), angles );
|
||||
FX_Smoke( vecOrigin, angles, scale * 0.1f, 4, (unsigned char *)&color, 255 );
|
||||
}
|
||||
}
|
||||
|
||||
void CEffectsClient::Sparks( const Vector &position, int nMagnitude, int nTrailLength, const Vector *pVecDir )
|
||||
{
|
||||
CPVSFilter filter( position );
|
||||
if ( !SuppressTE( filter ) )
|
||||
{
|
||||
FX_ElectricSpark( position, nMagnitude, nTrailLength, pVecDir );
|
||||
}
|
||||
}
|
||||
|
||||
void CEffectsClient::Dust( const Vector &pos, const Vector &dir, float size, float speed )
|
||||
{
|
||||
CPVSFilter filter( pos );
|
||||
if ( !SuppressTE( filter ) )
|
||||
{
|
||||
FX_Dust( pos, dir, size, speed );
|
||||
}
|
||||
}
|
||||
|
||||
void CEffectsClient::MuzzleFlash( const Vector &vecOrigin, const QAngle &vecAngles, float flScale, int iType )
|
||||
{
|
||||
CPVSFilter filter( vecOrigin );
|
||||
if ( !SuppressTE( filter ) )
|
||||
{
|
||||
switch( iType )
|
||||
{
|
||||
case MUZZLEFLASH_TYPE_DEFAULT:
|
||||
FX_MuzzleEffect( vecOrigin, vecAngles, flScale, INVALID_EHANDLE );
|
||||
break;
|
||||
|
||||
case MUZZLEFLASH_TYPE_GUNSHIP:
|
||||
FX_GunshipMuzzleEffect( vecOrigin, vecAngles, flScale, INVALID_EHANDLE );
|
||||
break;
|
||||
|
||||
case MUZZLEFLASH_TYPE_STRIDER:
|
||||
FX_StriderMuzzleEffect( vecOrigin, vecAngles, flScale, INVALID_EHANDLE );
|
||||
break;
|
||||
|
||||
default:
|
||||
Msg("No case for Muzzleflash type: %d\n", iType );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CEffectsClient::MetalSparks( const Vector &position, const Vector &direction )
|
||||
{
|
||||
CPVSFilter filter( position );
|
||||
if ( !SuppressTE( filter ) )
|
||||
{
|
||||
FX_MetalSpark( position, direction, direction );
|
||||
}
|
||||
}
|
||||
|
||||
void CEffectsClient::EnergySplash( const Vector &position, const Vector &direction, bool bExplosive )
|
||||
{
|
||||
CPVSFilter filter( position );
|
||||
if ( !SuppressTE( filter ) )
|
||||
{
|
||||
FX_EnergySplash( position, direction, bExplosive );
|
||||
}
|
||||
}
|
||||
|
||||
void CEffectsClient::Ricochet( const Vector &position, const Vector &direction )
|
||||
{
|
||||
CPVSFilter filter( position );
|
||||
if ( !SuppressTE( filter ) )
|
||||
{
|
||||
FX_MetalSpark( position, direction, direction );
|
||||
|
||||
if ( !m_bSuppressSound )
|
||||
{
|
||||
FX_RicochetSound( position );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Should these methods remain in this interface? Or go in some
|
||||
// other client-server neutral interface?
|
||||
float CEffectsClient::Time()
|
||||
{
|
||||
return gpGlobals->curtime;
|
||||
}
|
||||
|
||||
|
||||
bool CEffectsClient::IsServer()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
56
game/client/IsNPCProxy.cpp
Normal file
56
game/client/IsNPCProxy.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
//========= Copyright © 1996-2007, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "functionproxy.h"
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the player health (from 0 to 1)
|
||||
//-----------------------------------------------------------------------------
|
||||
class CProxyIsNPC : public CResultProxy
|
||||
{
|
||||
public:
|
||||
bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
void OnBind( void *pC_BaseEntity );
|
||||
|
||||
private:
|
||||
CFloatInput m_Factor;
|
||||
};
|
||||
|
||||
bool CProxyIsNPC::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
if (!CResultProxy::Init( pMaterial, pKeyValues ))
|
||||
return false;
|
||||
|
||||
if (!m_Factor.Init( pMaterial, pKeyValues, "scale", 1 ))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CProxyIsNPC::OnBind( void *pC_BaseEntity )
|
||||
{
|
||||
if ( !pC_BaseEntity )
|
||||
return;
|
||||
|
||||
C_BaseEntity *pEntity = BindArgToEntity( pC_BaseEntity );
|
||||
if ( pEntity && pEntity->IsNPC() )
|
||||
{
|
||||
SetFloatResult( m_Factor.GetFloat() );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFloatResult( 0.0f );
|
||||
}
|
||||
}
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CProxyIsNPC, IsNPC );
|
||||
|
||||
|
||||
65
game/client/MonitorMaterialProxy.cpp
Normal file
65
game/client/MonitorMaterialProxy.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "materialsystem/IMaterialProxy.h"
|
||||
#include "materialsystem/IMaterial.h"
|
||||
#include "materialsystem/IMaterialVar.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
// $monitorTextureVar
|
||||
class CMonitorMaterialProxy : public IMaterialProxy
|
||||
{
|
||||
public:
|
||||
CMonitorMaterialProxy();
|
||||
virtual ~CMonitorMaterialProxy();
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( void *pC_BaseEntity );
|
||||
virtual void Release( void ) { delete this; }
|
||||
private:
|
||||
IMaterialVar *m_pMonitorTextureVar;
|
||||
};
|
||||
|
||||
CMonitorMaterialProxy::CMonitorMaterialProxy()
|
||||
{
|
||||
m_pMonitorTextureVar = NULL;
|
||||
}
|
||||
|
||||
CMonitorMaterialProxy::~CMonitorMaterialProxy()
|
||||
{
|
||||
m_pMonitorTextureVar = NULL;
|
||||
}
|
||||
|
||||
|
||||
bool CMonitorMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
char const* pMonitorTextureVarName = pKeyValues->getString( "$monitorTextureVar" );
|
||||
if( !pMonitorTextureVarName )
|
||||
return false;
|
||||
|
||||
bool foundVar;
|
||||
m_pMonitorTextureVar = pMaterial->FindVar( pMonitorTextureVarName, &foundVar, false );
|
||||
if( !foundVar )
|
||||
{
|
||||
m_pMonitorTextureVar = NULL;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMonitorMaterialProxy::OnBind( void *pC_BaseEntity )
|
||||
{
|
||||
if( !m_pMonitorTextureVar )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CMonitorMaterialProxy, Monitor );
|
||||
101
game/client/NPSClient.h
Normal file
101
game/client/NPSClient.h
Normal file
@@ -0,0 +1,101 @@
|
||||
// *******************************************************************************
|
||||
// *
|
||||
// * Module Name:
|
||||
// * NPSClient.h
|
||||
// *
|
||||
// * Abstract:
|
||||
// * Header for NaturalPoint Simple Game Client API.
|
||||
// *
|
||||
// * Environment:
|
||||
// * Microsoft Windows -- User mode
|
||||
// *
|
||||
// *******************************************************************************
|
||||
|
||||
#ifndef _NPSCLIENT_H_DEFINED_
|
||||
#define _NPSCLIENT_H_DEFINED_
|
||||
|
||||
#pragma pack( push, npsclient_h ) // Save current pack value
|
||||
#pragma pack(1)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
//////////////////
|
||||
/// Typedefs /////////////////////////////////////////////////////////////////////
|
||||
/////////////////
|
||||
|
||||
#ifndef _NPCLIENT_H_DEFINED_
|
||||
|
||||
// NPESULT values are returned from the Game Client API functions.
|
||||
//
|
||||
typedef enum tagNPResult
|
||||
{
|
||||
NP_OK = 0,
|
||||
NP_ERR_DEVICE_NOT_PRESENT,
|
||||
NP_ERR_UNSUPPORTED_OS,
|
||||
NP_ERR_INVALID_ARG,
|
||||
NP_ERR_DLL_NOT_FOUND,
|
||||
NP_ERR_NO_DATA,
|
||||
NP_ERR_INTERNAL_DATA,
|
||||
NP_ERR_ALREADY_REGISTERED, // a window handle or game ID is already registered
|
||||
NP_ERR_UNKNOWN_ID, // unknown game ID registered
|
||||
NP_ERR_READ_ONLY, // parameter is read only
|
||||
|
||||
} NPRESULT;
|
||||
|
||||
typedef struct tagTrackIRData
|
||||
{
|
||||
unsigned short wNPStatus;
|
||||
unsigned short wPFrameSignature;
|
||||
unsigned long dwNPIOData;
|
||||
|
||||
float fNPRoll;
|
||||
float fNPPitch;
|
||||
float fNPYaw;
|
||||
float fNPX;
|
||||
float fNPY;
|
||||
float fNPZ;
|
||||
float fNPRawX;
|
||||
float fNPRawY;
|
||||
float fNPRawZ;
|
||||
float fNPDeltaX;
|
||||
float fNPDeltaY;
|
||||
float fNPDeltaZ;
|
||||
float fNPSmoothX;
|
||||
float fNPSmoothY;
|
||||
float fNPSmoothZ;
|
||||
|
||||
} TRACKIRDATA, *LPTRACKIRDATA;
|
||||
|
||||
#endif
|
||||
|
||||
typedef NPRESULT (__stdcall *PF_NPS_INIT)( HWND );
|
||||
typedef NPRESULT (__stdcall *PF_NPS_SHUTDOWN)( void );
|
||||
typedef NPRESULT (__stdcall *PF_NPS_GETDATA)( LPTRACKIRDATA );
|
||||
|
||||
//// Function Prototypes ///////////////////////////////////////////////
|
||||
//
|
||||
// Functions exported from game client API DLL ( note __stdcall calling convention
|
||||
// is used for ease of interface to clients of differing implementations including
|
||||
// C, C++, Pascal (Delphi) and VB. )
|
||||
//
|
||||
NPRESULT __stdcall NPS_Init( HWND hWnd );
|
||||
NPRESULT __stdcall NPS_Shutdown( void );
|
||||
NPRESULT __stdcall NPS_GetData( LPTRACKIRDATA pTID );
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma pack( pop, npsclient_h ) // Ensure previous pack value is restored
|
||||
|
||||
#endif // #ifdef NPCLIENT_H_DEFINED_
|
||||
|
||||
//
|
||||
// *** End of file: NPSClient.h ***
|
||||
//
|
||||
|
||||
|
||||
245
game/client/NextBot/C_NextBot.cpp
Normal file
245
game/client/NextBot/C_NextBot.cpp
Normal file
@@ -0,0 +1,245 @@
|
||||
// C_NextBot.cpp
|
||||
// Client-side implementation of Next generation bot system
|
||||
// Author: Michael Booth, April 2005
|
||||
// Copyright (c) 2005 Turtle Rock Studios, Inc. - All Rights Reserved
|
||||
|
||||
#include "cbase.h"
|
||||
#include "C_NextBot.h"
|
||||
#include "debugoverlay_shared.h"
|
||||
#include <bitbuf.h>
|
||||
#include "viewrender.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#undef NextBot
|
||||
|
||||
ConVar NextBotShadowDist( "nb_shadow_dist", "400" );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_NextBotCombatCharacter, DT_NextBot, NextBotCombatCharacter )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_NextBotCombatCharacter::C_NextBotCombatCharacter()
|
||||
{
|
||||
// Left4Dead have surfaces too steep for IK to work properly
|
||||
m_EntClientFlags |= ENTCLIENTFLAG_DONTUSEIK;
|
||||
|
||||
m_shadowType = SHADOWS_SIMPLE;
|
||||
m_forcedShadowType = SHADOWS_NONE;
|
||||
m_bForceShadowType = false;
|
||||
|
||||
TheClientNextBots().Register( this );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_NextBotCombatCharacter::~C_NextBotCombatCharacter()
|
||||
{
|
||||
TheClientNextBots().UnRegister( this );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_NextBotCombatCharacter::Spawn( void )
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_NextBotCombatCharacter::UpdateClientSideAnimation()
|
||||
{
|
||||
if (IsDormant())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::UpdateClientSideAnimation();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void C_NextBotCombatCharacter::UpdateShadowLOD( void )
|
||||
{
|
||||
ShadowType_t oldShadowType = m_shadowType;
|
||||
|
||||
if ( m_bForceShadowType )
|
||||
{
|
||||
m_shadowType = m_forcedShadowType;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef NEED_SPLITSCREEN_INTEGRATION
|
||||
FOR_EACH_VALID_SPLITSCREEN_PLAYER( hh )
|
||||
{
|
||||
C_BasePlayer *pl = C_BasePlayer::GetLocalPlayer(hh);
|
||||
if ( pl )
|
||||
{
|
||||
Vector delta = GetAbsOrigin() - C_BasePlayer::GetLocalPlayer(hh)->GetAbsOrigin();
|
||||
#else
|
||||
{
|
||||
if ( C_BasePlayer::GetLocalPlayer() )
|
||||
{
|
||||
Vector delta = GetAbsOrigin() - C_BasePlayer::GetLocalPlayer()->GetAbsOrigin();
|
||||
#endif
|
||||
if ( delta.IsLengthLessThan( NextBotShadowDist.GetFloat() ) )
|
||||
{
|
||||
m_shadowType = SHADOWS_RENDER_TO_TEXTURE_DYNAMIC;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_shadowType = SHADOWS_SIMPLE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_shadowType = SHADOWS_SIMPLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( oldShadowType != m_shadowType )
|
||||
{
|
||||
DestroyShadow();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
ShadowType_t C_NextBotCombatCharacter::ShadowCastType( void )
|
||||
{
|
||||
if ( !IsVisible() )
|
||||
return SHADOWS_NONE;
|
||||
|
||||
if ( m_shadowTimer.IsElapsed() )
|
||||
{
|
||||
m_shadowTimer.Start( 0.15f );
|
||||
UpdateShadowLOD();
|
||||
}
|
||||
|
||||
return m_shadowType;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
bool C_NextBotCombatCharacter::GetForcedShadowCastType( ShadowType_t* pForcedShadowType ) const
|
||||
{
|
||||
if ( pForcedShadowType )
|
||||
{
|
||||
*pForcedShadowType = m_forcedShadowType;
|
||||
}
|
||||
return m_bForceShadowType;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* Singleton accessor.
|
||||
* By returning a reference, we guarantee construction of the
|
||||
* instance before its first use.
|
||||
*/
|
||||
C_NextBotManager &TheClientNextBots( void )
|
||||
{
|
||||
static C_NextBotManager manager;
|
||||
return manager;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
C_NextBotManager::C_NextBotManager( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
C_NextBotManager::~C_NextBotManager()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void C_NextBotManager::Register( C_NextBotCombatCharacter *bot )
|
||||
{
|
||||
m_botList.AddToTail( bot );
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void C_NextBotManager::UnRegister( C_NextBotCombatCharacter *bot )
|
||||
{
|
||||
m_botList.FindAndRemove( bot );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_NextBotManager::SetupInFrustumData( void )
|
||||
{
|
||||
#ifdef ENABLE_AFTER_INTEGRATION
|
||||
// Done already this frame.
|
||||
if ( IsInFrustumDataValid() )
|
||||
return true;
|
||||
|
||||
// Can we use the view data yet?
|
||||
if ( !FrustumCache()->IsValid() )
|
||||
return false;
|
||||
|
||||
// Get the number of active bots.
|
||||
int nBotCount = m_botList.Count();
|
||||
|
||||
// Reset.
|
||||
for ( int iBot = 0; iBot < nBotCount; ++iBot )
|
||||
{
|
||||
// Get the current bot.
|
||||
C_NextBotCombatCharacter *pBot = m_botList[iBot];
|
||||
if ( !pBot )
|
||||
continue;
|
||||
|
||||
pBot->InitFrustumData();
|
||||
}
|
||||
|
||||
FOR_EACH_VALID_SPLITSCREEN_PLAYER( iSlot )
|
||||
{
|
||||
ACTIVE_SPLITSCREEN_PLAYER_GUARD( iSlot );
|
||||
// Get the active local player.
|
||||
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( !pPlayer )
|
||||
continue;
|
||||
|
||||
for ( int iBot = 0; iBot < nBotCount; ++iBot )
|
||||
{
|
||||
// Get the current bot.
|
||||
C_NextBotCombatCharacter *pBot = m_botList[iBot];
|
||||
if ( !pBot )
|
||||
continue;
|
||||
|
||||
// Are we in the view frustum?
|
||||
Vector vecMin, vecMax;
|
||||
pBot->CollisionProp()->WorldSpaceAABB( &vecMin, &vecMax );
|
||||
bool bInFrustum = !FrustumCache()->m_Frustums[iSlot].CullBox( vecMin, vecMax );
|
||||
|
||||
if ( bInFrustum )
|
||||
{
|
||||
Vector vecSegment;
|
||||
VectorSubtract( pBot->GetAbsOrigin(), pPlayer->GetAbsOrigin(), vecSegment );
|
||||
float flDistance = vecSegment.LengthSqr();
|
||||
if ( flDistance < pBot->GetInFrustumDistanceSqr() )
|
||||
{
|
||||
pBot->SetInFrustumDistanceSqr( flDistance );
|
||||
}
|
||||
|
||||
pBot->SetInFrustum( true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mark as setup this frame.
|
||||
m_nInFrustumFrame = gpGlobals->framecount;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
134
game/client/NextBot/C_NextBot.h
Normal file
134
game/client/NextBot/C_NextBot.h
Normal file
@@ -0,0 +1,134 @@
|
||||
// C_NextBot.h
|
||||
// Next generation bot system
|
||||
// Author: Michael Booth, April 2005
|
||||
// Copyright (c) 2005 Turtle Rock Studios, Inc. - All Rights Reserved
|
||||
|
||||
#ifndef _C_NEXT_BOT_H_
|
||||
#define _C_NEXT_BOT_H_
|
||||
|
||||
#include "c_ai_basenpc.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* The interface holding IBody information
|
||||
*/
|
||||
class IBodyClient
|
||||
{
|
||||
public:
|
||||
enum ActivityType
|
||||
{
|
||||
MOTION_CONTROLLED_XY = 0x0001, // XY position and orientation of the bot is driven by the animation.
|
||||
MOTION_CONTROLLED_Z = 0x0002, // Z position of the bot is driven by the animation.
|
||||
ACTIVITY_UNINTERRUPTIBLE= 0x0004, // activity can't be changed until animation finishes
|
||||
ACTIVITY_TRANSITORY = 0x0008, // a short animation that takes over from the underlying animation momentarily, resuming it upon completion
|
||||
ENTINDEX_PLAYBACK_RATE = 0x0010, // played back at different rates based on entindex
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* The client-side implementation of the NextBot
|
||||
*/
|
||||
class C_NextBotCombatCharacter : public C_BaseCombatCharacter
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_NextBotCombatCharacter, C_BaseCombatCharacter );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_NextBotCombatCharacter();
|
||||
virtual ~C_NextBotCombatCharacter();
|
||||
|
||||
public:
|
||||
virtual void Spawn( void );
|
||||
virtual void UpdateClientSideAnimation( void );
|
||||
virtual ShadowType_t ShadowCastType( void );
|
||||
virtual bool IsNextBot() { return true; }
|
||||
void ForceShadowCastType( bool bForce, ShadowType_t forcedShadowType = SHADOWS_NONE ) { m_bForceShadowType = bForce; m_forcedShadowType = forcedShadowType; }
|
||||
bool GetForcedShadowCastType( ShadowType_t* pForcedShadowType ) const;
|
||||
|
||||
// Local In View Data.
|
||||
void InitFrustumData( void ) { m_bInFrustum = false; m_flFrustumDistanceSqr = FLT_MAX; m_nInFrustumFrame = gpGlobals->framecount; }
|
||||
bool IsInFrustumValid( void ) { return ( m_nInFrustumFrame == gpGlobals->framecount ); }
|
||||
void SetInFrustum( bool bInFrustum ) { m_bInFrustum = bInFrustum; }
|
||||
bool IsInFrustum( void ) { return m_bInFrustum; }
|
||||
void SetInFrustumDistanceSqr( float flDistance ) { m_flFrustumDistanceSqr = flDistance; }
|
||||
float GetInFrustumDistanceSqr( void ) { return m_flFrustumDistanceSqr; }
|
||||
|
||||
private:
|
||||
ShadowType_t m_shadowType; // Are we LOD'd to simple shadows?
|
||||
CountdownTimer m_shadowTimer; // Timer to throttle checks for shadow LOD
|
||||
ShadowType_t m_forcedShadowType;
|
||||
bool m_bForceShadowType;
|
||||
void UpdateShadowLOD( void );
|
||||
|
||||
// Local In View Data.
|
||||
int m_nInFrustumFrame;
|
||||
bool m_bInFrustum;
|
||||
float m_flFrustumDistanceSqr;
|
||||
|
||||
private:
|
||||
C_NextBotCombatCharacter( const C_NextBotCombatCharacter & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* The C_NextBotManager manager
|
||||
*/
|
||||
class C_NextBotManager
|
||||
{
|
||||
public:
|
||||
C_NextBotManager( void );
|
||||
~C_NextBotManager();
|
||||
|
||||
/**
|
||||
* Execute functor for each NextBot in the system.
|
||||
* If a functor returns false, stop iteration early
|
||||
* and return false.
|
||||
*/
|
||||
template < typename Functor >
|
||||
bool ForEachCombatCharacter( Functor &func )
|
||||
{
|
||||
for( int i=0; i < m_botList.Count(); ++i )
|
||||
{
|
||||
C_NextBotCombatCharacter *character = m_botList[i];
|
||||
if ( character->IsPlayer() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( character->IsDormant() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !func( character ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int GetActiveCount() { return m_botList.Count(); }
|
||||
|
||||
bool SetupInFrustumData( void );
|
||||
bool IsInFrustumDataValid( void ) { return ( m_nInFrustumFrame == gpGlobals->framecount ); }
|
||||
|
||||
private:
|
||||
friend class C_NextBotCombatCharacter;
|
||||
|
||||
void Register( C_NextBotCombatCharacter *bot );
|
||||
void UnRegister( C_NextBotCombatCharacter *bot );
|
||||
|
||||
CUtlVector< C_NextBotCombatCharacter * > m_botList; ///< list of all active NextBots
|
||||
|
||||
int m_nInFrustumFrame;
|
||||
};
|
||||
|
||||
// singleton accessor
|
||||
extern C_NextBotManager &TheClientNextBots( void );
|
||||
|
||||
|
||||
#endif // _C_NEXT_BOT_H_
|
||||
51
game/client/ProxyHealth.cpp
Normal file
51
game/client/ProxyHealth.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "functionproxy.h"
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the player health (from 0 to 1)
|
||||
//-----------------------------------------------------------------------------
|
||||
class CProxyHealth : public CResultProxy
|
||||
{
|
||||
public:
|
||||
bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
void OnBind( void *pC_BaseEntity );
|
||||
|
||||
private:
|
||||
CFloatInput m_Factor;
|
||||
};
|
||||
|
||||
bool CProxyHealth::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
if (!CResultProxy::Init( pMaterial, pKeyValues ))
|
||||
return false;
|
||||
|
||||
if (!m_Factor.Init( pMaterial, pKeyValues, "scale", 1 ))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CProxyHealth::OnBind( void *pC_BaseEntity )
|
||||
{
|
||||
if (!pC_BaseEntity)
|
||||
return;
|
||||
|
||||
C_BaseEntity *pEntity = BindArgToEntity( pC_BaseEntity );
|
||||
|
||||
Assert( m_pResult );
|
||||
SetFloatResult( pEntity->HealthFraction() * m_Factor.GetFloat() );
|
||||
}
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CProxyHealth, Health );
|
||||
|
||||
|
||||
316
game/client/ScreenSpaceEffects.cpp
Normal file
316
game/client/ScreenSpaceEffects.cpp
Normal file
@@ -0,0 +1,316 @@
|
||||
#include "cbase.h"
|
||||
|
||||
#include "keyvalues.h"
|
||||
#include "cdll_client_int.h"
|
||||
#include "view_scene.h"
|
||||
#include "viewrender.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imaterialsystemhardwareconfig.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
|
||||
#include "ScreenSpaceEffects.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectRegistration code
|
||||
// Used to register and effect with the IScreenSpaceEffectManager
|
||||
//------------------------------------------------------------------------------
|
||||
CScreenSpaceEffectRegistration *CScreenSpaceEffectRegistration::s_pHead = NULL;
|
||||
|
||||
CScreenSpaceEffectRegistration::CScreenSpaceEffectRegistration( const char *pName, IScreenSpaceEffect *pEffect )
|
||||
{
|
||||
m_pEffectName = pName;
|
||||
m_pEffect = pEffect;
|
||||
m_pNext = s_pHead;
|
||||
s_pHead = this;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectManager - Implementation of IScreenSpaceEffectManager
|
||||
//------------------------------------------------------------------------------
|
||||
class CScreenSpaceEffectManager : public IScreenSpaceEffectManager
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void InitScreenSpaceEffects( );
|
||||
virtual void ShutdownScreenSpaceEffects( );
|
||||
|
||||
virtual IScreenSpaceEffect *GetScreenSpaceEffect( const char *pEffectName );
|
||||
|
||||
virtual void SetScreenSpaceEffectParams( const char *pEffectName, KeyValues *params );
|
||||
virtual void SetScreenSpaceEffectParams( IScreenSpaceEffect *pEffect, KeyValues *params );
|
||||
|
||||
virtual void EnableScreenSpaceEffect( const char *pEffectName );
|
||||
virtual void EnableScreenSpaceEffect( IScreenSpaceEffect *pEffect );
|
||||
|
||||
virtual void DisableScreenSpaceEffect( const char *pEffectName );
|
||||
virtual void DisableScreenSpaceEffect( IScreenSpaceEffect *pEffect );
|
||||
|
||||
virtual void DisableAllScreenSpaceEffects( );
|
||||
|
||||
virtual void RenderEffects( int x, int y, int w, int h );
|
||||
};
|
||||
|
||||
CScreenSpaceEffectManager g_ScreenSpaceEffectManager;
|
||||
IScreenSpaceEffectManager *g_pScreenSpaceEffects = &g_ScreenSpaceEffectManager;
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectManager::InitScreenSpaceEffects - Initialise all registered effects
|
||||
//---------------------------------------------------------------------------------------
|
||||
void CScreenSpaceEffectManager::InitScreenSpaceEffects( )
|
||||
{
|
||||
if ( CommandLine()->FindParm( "-filmgrain" ) )
|
||||
{
|
||||
GetScreenSpaceEffect( "filmgrain" )->Enable( true );
|
||||
}
|
||||
|
||||
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
|
||||
{
|
||||
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
|
||||
if( pEffect )
|
||||
{
|
||||
bool bIsEnabled = pEffect->IsEnabled( );
|
||||
pEffect->Init( );
|
||||
pEffect->Enable( bIsEnabled );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectManager::ShutdownScreenSpaceEffects - Shutdown all registered effects
|
||||
//----------------------------------------------------------------------------------------
|
||||
void CScreenSpaceEffectManager::ShutdownScreenSpaceEffects( )
|
||||
{
|
||||
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
|
||||
{
|
||||
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
|
||||
if( pEffect )
|
||||
{
|
||||
pEffect->Shutdown( );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectManager::GetScreenSpaceEffect - Returns a point to the named effect
|
||||
//---------------------------------------------------------------------------------------
|
||||
IScreenSpaceEffect *CScreenSpaceEffectManager::GetScreenSpaceEffect( const char *pEffectName )
|
||||
{
|
||||
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
|
||||
{
|
||||
if( !Q_stricmp( pReg->m_pEffectName, pEffectName ) )
|
||||
{
|
||||
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
|
||||
return pEffect;
|
||||
}
|
||||
}
|
||||
|
||||
Warning( "Could not find screen space effect %s\n", pEffectName );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectManager::SetScreenSpaceEffectParams
|
||||
// - Assign parameters to the specified effect
|
||||
//---------------------------------------------------------------------------------------
|
||||
void CScreenSpaceEffectManager::SetScreenSpaceEffectParams( const char *pEffectName, KeyValues *params )
|
||||
{
|
||||
IScreenSpaceEffect *pEffect = GetScreenSpaceEffect( pEffectName );
|
||||
if( pEffect )
|
||||
SetScreenSpaceEffectParams( pEffect, params );
|
||||
}
|
||||
|
||||
void CScreenSpaceEffectManager::SetScreenSpaceEffectParams( IScreenSpaceEffect *pEffect, KeyValues *params )
|
||||
{
|
||||
if( pEffect )
|
||||
pEffect->SetParameters( params );
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectManager::EnableScreenSpaceEffect
|
||||
// - Enables the specified effect
|
||||
//---------------------------------------------------------------------------------------
|
||||
void CScreenSpaceEffectManager::EnableScreenSpaceEffect( const char *pEffectName )
|
||||
{
|
||||
IScreenSpaceEffect *pEffect = GetScreenSpaceEffect( pEffectName );
|
||||
if( pEffect )
|
||||
EnableScreenSpaceEffect( pEffect );
|
||||
}
|
||||
|
||||
void CScreenSpaceEffectManager::EnableScreenSpaceEffect( IScreenSpaceEffect *pEffect )
|
||||
{
|
||||
if( pEffect )
|
||||
pEffect->Enable( true );
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectManager::DisableScreenSpaceEffect
|
||||
// - Disables the specified effect
|
||||
//---------------------------------------------------------------------------------------
|
||||
void CScreenSpaceEffectManager::DisableScreenSpaceEffect( const char *pEffectName )
|
||||
{
|
||||
IScreenSpaceEffect *pEffect = GetScreenSpaceEffect( pEffectName );
|
||||
if( pEffect )
|
||||
DisableScreenSpaceEffect( pEffect );
|
||||
}
|
||||
|
||||
void CScreenSpaceEffectManager::DisableScreenSpaceEffect( IScreenSpaceEffect *pEffect )
|
||||
{
|
||||
if( pEffect )
|
||||
pEffect->Enable( false );
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectManager::DisableAllScreenSpaceEffects
|
||||
// - Disables all registered screen space effects
|
||||
//---------------------------------------------------------------------------------------
|
||||
void CScreenSpaceEffectManager::DisableAllScreenSpaceEffects( )
|
||||
{
|
||||
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
|
||||
{
|
||||
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
|
||||
if( pEffect )
|
||||
{
|
||||
pEffect->Enable( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// CScreenSpaceEffectManager::RenderEffects
|
||||
// - Renders all registered screen space effects
|
||||
//---------------------------------------------------------------------------------------
|
||||
void CScreenSpaceEffectManager::RenderEffects( int x, int y, int w, int h )
|
||||
{
|
||||
for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
|
||||
{
|
||||
IScreenSpaceEffect *pEffect = pReg->m_pEffect;
|
||||
if( pEffect )
|
||||
{
|
||||
pEffect->Render( x, y, w, h );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Example post-processing effect
|
||||
//------------------------------------------------------------------------------
|
||||
class CExampleEffect : public IScreenSpaceEffect
|
||||
{
|
||||
public:
|
||||
CExampleEffect( );
|
||||
~CExampleEffect( );
|
||||
|
||||
void Init( );
|
||||
void Shutdown( );
|
||||
|
||||
void SetParameters( KeyValues *params );
|
||||
|
||||
void Render( int x, int y, int w, int h );
|
||||
|
||||
void Enable( bool bEnable );
|
||||
bool IsEnabled( );
|
||||
|
||||
private:
|
||||
|
||||
bool m_bEnable;
|
||||
|
||||
CMaterialReference m_Material;
|
||||
};
|
||||
|
||||
ADD_SCREENSPACE_EFFECT( CExampleEffect, exampleeffect );
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CExampleEffect constructor
|
||||
//------------------------------------------------------------------------------
|
||||
CExampleEffect::CExampleEffect( )
|
||||
{
|
||||
m_bEnable = false;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CExampleEffect destructor
|
||||
//------------------------------------------------------------------------------
|
||||
CExampleEffect::~CExampleEffect( )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CExampleEffect init
|
||||
//------------------------------------------------------------------------------
|
||||
void CExampleEffect::Init( )
|
||||
{
|
||||
// This is just example code, init your effect material here
|
||||
//m_Material.Init( "engine/exampleeffect", TEXTURE_GROUP_OTHER );
|
||||
|
||||
m_bEnable = false;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CExampleEffect shutdown
|
||||
//------------------------------------------------------------------------------
|
||||
void CExampleEffect::Shutdown( )
|
||||
{
|
||||
m_Material.Shutdown();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CExampleEffect enable
|
||||
//------------------------------------------------------------------------------
|
||||
void CExampleEffect::Enable( bool bEnable )
|
||||
{
|
||||
// This is just example code, don't enable it
|
||||
// m_bEnable = bEnable;
|
||||
}
|
||||
|
||||
bool CExampleEffect::IsEnabled( )
|
||||
{
|
||||
return m_bEnable;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CExampleEffect SetParameters
|
||||
//------------------------------------------------------------------------------
|
||||
void CExampleEffect::SetParameters( KeyValues *params )
|
||||
{
|
||||
if( params->GetDataType( "example_param" ) == KeyValues::TYPE_STRING )
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CExampleEffect render
|
||||
//------------------------------------------------------------------------------
|
||||
void CExampleEffect::Render( int x, int y, int w, int h )
|
||||
{
|
||||
if ( !IsEnabled() )
|
||||
return;
|
||||
|
||||
// Render Effect
|
||||
Rect_t actualRect;
|
||||
UpdateScreenEffectTexture( 0, x, y, w, h, false, &actualRect );
|
||||
ITexture *pTexture = GetFullFrameFrameBufferTexture( 0 );
|
||||
|
||||
CMatRenderContextPtr pRenderContext( materials );
|
||||
|
||||
pRenderContext->DrawScreenSpaceRectangle( m_Material, x, y, w, h,
|
||||
actualRect.x, actualRect.y, actualRect.x+actualRect.width-1, actualRect.y+actualRect.height-1,
|
||||
pTexture->GetActualWidth(), pTexture->GetActualHeight() );
|
||||
}
|
||||
88
game/client/ScreenSpaceEffects.h
Normal file
88
game/client/ScreenSpaceEffects.h
Normal file
@@ -0,0 +1,88 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=====================================================================================//
|
||||
|
||||
#ifndef SCREENSPACEEFFECTS_H
|
||||
#define SCREENSPACEEFFECTS_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class KeyValues;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Simple base class for screen space post-processing effects
|
||||
//------------------------------------------------------------------------------
|
||||
abstract_class IScreenSpaceEffect
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void Init( ) = 0;
|
||||
virtual void Shutdown( ) = 0;
|
||||
|
||||
virtual void SetParameters( KeyValues *params ) = 0;
|
||||
|
||||
virtual void Render( int x, int y, int w, int h ) = 0;
|
||||
|
||||
virtual void Enable( bool bEnable ) = 0;
|
||||
virtual bool IsEnabled( ) = 0;
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Interface class for managing screen space post-processing effects
|
||||
//------------------------------------------------------------------------------
|
||||
abstract_class IScreenSpaceEffectManager
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void InitScreenSpaceEffects( ) = 0;
|
||||
virtual void ShutdownScreenSpaceEffects( ) = 0;
|
||||
|
||||
virtual IScreenSpaceEffect *GetScreenSpaceEffect( const char *pEffectName ) = 0;
|
||||
|
||||
virtual void SetScreenSpaceEffectParams( const char *pEffectName, KeyValues *params ) = 0;
|
||||
virtual void SetScreenSpaceEffectParams( IScreenSpaceEffect *pEffect, KeyValues *params ) = 0;
|
||||
|
||||
virtual void EnableScreenSpaceEffect( const char *pEffectName ) = 0;
|
||||
virtual void EnableScreenSpaceEffect( IScreenSpaceEffect *pEffect ) = 0;
|
||||
|
||||
virtual void DisableScreenSpaceEffect( const char *pEffectName ) = 0;
|
||||
virtual void DisableScreenSpaceEffect( IScreenSpaceEffect *pEffect ) = 0;
|
||||
|
||||
virtual void DisableAllScreenSpaceEffects( ) = 0;
|
||||
|
||||
virtual void RenderEffects( int x, int y, int w, int h ) = 0;
|
||||
};
|
||||
|
||||
extern IScreenSpaceEffectManager *g_pScreenSpaceEffects;
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Registration class for adding screen space effects to the IScreenSpaceEffectManager
|
||||
//-------------------------------------------------------------------------------------
|
||||
class CScreenSpaceEffectRegistration
|
||||
{
|
||||
public:
|
||||
CScreenSpaceEffectRegistration( const char *pName, IScreenSpaceEffect *pEffect );
|
||||
|
||||
const char *m_pEffectName;
|
||||
IScreenSpaceEffect *m_pEffect;
|
||||
|
||||
CScreenSpaceEffectRegistration *m_pNext;
|
||||
|
||||
static CScreenSpaceEffectRegistration *s_pHead;
|
||||
};
|
||||
|
||||
#define ADD_SCREENSPACE_EFFECT( CEffect, pEffectName ) CEffect pEffectName##_effect; \
|
||||
CScreenSpaceEffectRegistration pEffectName##_reg( #pEffectName, &pEffectName##_effect );
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
172
game/client/TeamBitmapImage.cpp
Normal file
172
game/client/TeamBitmapImage.cpp
Normal file
@@ -0,0 +1,172 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: This is a panel which is rendered image on top of an entity
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "teambitmapimage.h"
|
||||
#include <KeyValues.h>
|
||||
#include "vgui_BitmapImage.h"
|
||||
#include "PanelMetaClassMgr.h"
|
||||
#include "vguimatsurface/IMatSystemSurface.h"
|
||||
#include <vgui_controls/Panel.h>
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A multiplexer bitmap that chooses a bitmap based on team
|
||||
//-----------------------------------------------------------------------------
|
||||
CTeamBitmapImage::CTeamBitmapImage() : m_Alpha(1.0f)
|
||||
{
|
||||
memset( m_ppImage, 0, BITMAP_COUNT * sizeof(BitmapImage*) );
|
||||
m_pEntity = NULL;
|
||||
m_bRelativeTeams = 0;
|
||||
}
|
||||
|
||||
CTeamBitmapImage::~CTeamBitmapImage()
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < BITMAP_COUNT; ++i )
|
||||
{
|
||||
if (m_ppImage[i])
|
||||
delete m_ppImage[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// initialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CTeamBitmapImage::Init( vgui::Panel *pParent, KeyValues* pInitData, C_BaseEntity* pEntity )
|
||||
{
|
||||
static char *pRelativeTeamNames[BITMAP_COUNT] =
|
||||
{
|
||||
"NoTeam",
|
||||
"MyTeam",
|
||||
"EnemyTeam",
|
||||
};
|
||||
|
||||
static char *pAbsoluteTeamNames[BITMAP_COUNT] =
|
||||
{
|
||||
"Team0",
|
||||
"Team1",
|
||||
"Team2",
|
||||
};
|
||||
|
||||
m_pEntity = pEntity;
|
||||
m_bRelativeTeams = (pInitData->GetInt( "relativeteam" ) != 0);
|
||||
|
||||
char **ppTeamNames = m_bRelativeTeams ? pRelativeTeamNames : pAbsoluteTeamNames;
|
||||
|
||||
int i;
|
||||
for ( i = 0 ; i < BITMAP_COUNT; ++i )
|
||||
{
|
||||
// Default to null
|
||||
m_ppImage[i] = NULL;
|
||||
|
||||
// Look for team section
|
||||
KeyValues *pTeamKV = pInitData->FindKey( ppTeamNames[i] );
|
||||
if ( !pTeamKV )
|
||||
continue;
|
||||
|
||||
char const* pClassImage = pTeamKV->GetString( "material" );
|
||||
if ( !pClassImage || !pClassImage[ 0 ] )
|
||||
return false;
|
||||
|
||||
// modulation color
|
||||
Color color;
|
||||
if (!ParseRGBA( pTeamKV, "color", color ))
|
||||
color.SetColor( 255, 255, 255, 255 );
|
||||
|
||||
// hook in the bitmap
|
||||
m_ppImage[i] = new BitmapImage( pParent->GetVPanel(), pClassImage );
|
||||
m_ppImage[i]->SetColor( color );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Alpha modulate...
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTeamBitmapImage::SetAlpha( float alpha )
|
||||
{
|
||||
m_Alpha = clamp( alpha, 0.0f, 1.0f );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// draw
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTeamBitmapImage::Paint( float yaw /*= 0.0f*/ )
|
||||
{
|
||||
if (m_Alpha == 0.0f)
|
||||
return;
|
||||
|
||||
int team = 0;
|
||||
if (m_bRelativeTeams)
|
||||
{
|
||||
if (GetEntity())
|
||||
{
|
||||
if (GetEntity()->GetTeamNumber() != 0)
|
||||
{
|
||||
team = GetEntity()->InLocalTeam() ? 1 : 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetEntity())
|
||||
team = GetEntity()->GetTeamNumber();
|
||||
}
|
||||
|
||||
// Paint the image for the current team
|
||||
if (m_ppImage[team])
|
||||
{
|
||||
// Modulate the color based on the alpha....
|
||||
Color color = m_ppImage[team]->GetColor();
|
||||
int alpha = color[3];
|
||||
color[3] = (alpha * m_Alpha);
|
||||
m_ppImage[team]->SetColor( color );
|
||||
|
||||
if ( yaw != 0.0f )
|
||||
{
|
||||
g_pMatSystemSurface->DisableClipping( true );
|
||||
|
||||
m_ppImage[team]->DoPaint( m_ppImage[team]->GetRenderSizePanel(), yaw );
|
||||
|
||||
g_pMatSystemSurface->DisableClipping( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Paint
|
||||
m_ppImage[team]->Paint();
|
||||
}
|
||||
|
||||
// restore previous color
|
||||
color[3] = alpha;
|
||||
m_ppImage[team]->SetColor( color );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper method to initialize a team image from KeyValues data..
|
||||
//-----------------------------------------------------------------------------
|
||||
bool InitializeTeamImage( KeyValues *pInitData, const char* pSectionName, vgui::Panel *pParent, C_BaseEntity *pEntity, CTeamBitmapImage* pTeamImage )
|
||||
{
|
||||
KeyValues *pTeamImageSection = pInitData;
|
||||
if (pSectionName)
|
||||
{
|
||||
pTeamImageSection = pInitData->FindKey( pSectionName );
|
||||
if ( !pTeamImageSection )
|
||||
return false;
|
||||
}
|
||||
|
||||
return pTeamImage->Init( pParent, pTeamImageSection, pEntity );
|
||||
}
|
||||
|
||||
80
game/client/TeamBitmapImage.h
Normal file
80
game/client/TeamBitmapImage.h
Normal file
@@ -0,0 +1,80 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: This is a panel which is rendered image on top of an entity
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef TEAMBITMAPIMAGE_H
|
||||
#define TEAMBITMAPIMAGE_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//#include "tf_shareddefs.h"
|
||||
|
||||
#include <vgui/vgui.h>
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
class Panel;
|
||||
}
|
||||
|
||||
class BitmapImage;
|
||||
class C_BaseEntity;
|
||||
class KeyValues;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A multiplexer bitmap that chooses a bitmap based on team
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTeamBitmapImage
|
||||
{
|
||||
public:
|
||||
// construction, destruction
|
||||
CTeamBitmapImage();
|
||||
~CTeamBitmapImage();
|
||||
|
||||
// initialization
|
||||
bool Init( vgui::Panel *pParent, KeyValues* pInitData, C_BaseEntity* pEntity );
|
||||
|
||||
// Alpha override...
|
||||
void SetAlpha( float alpha );
|
||||
|
||||
// Paint the sucka. Paint it the size of the parent panel
|
||||
void Paint( float yaw = 0.0f );
|
||||
|
||||
protected:
|
||||
// Wrapper so we can implement this with EHANDLES some day
|
||||
C_BaseEntity *GetEntity() { return m_pEntity; }
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
// NOTE: Was MAX_TF_TEAMS not 4, but I don't like the dependency here.
|
||||
BITMAP_COUNT = 4 + 1
|
||||
};
|
||||
|
||||
BitmapImage *m_ppImage[ BITMAP_COUNT ];
|
||||
C_BaseEntity *m_pEntity;
|
||||
float m_Alpha;
|
||||
bool m_bRelativeTeams;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper method to initialize a team image from KeyValues data..
|
||||
// KeyValues contains the bitmap data. pSectionName, if it exists,
|
||||
// indicates which subsection of pInitData should be looked at to get at the
|
||||
// image data. The final argument is the bitmap image to initialize.
|
||||
// The function returns true if it succeeded.
|
||||
//
|
||||
// NOTE: This function looks for the key values 'material' and 'color'
|
||||
// and uses them to set up the material + modulation color of the image
|
||||
//-----------------------------------------------------------------------------
|
||||
bool InitializeTeamImage( KeyValues *pInitData, const char* pSectionName,
|
||||
vgui::Panel *pParent, C_BaseEntity *pEntity, CTeamBitmapImage* pBitmapImage );
|
||||
|
||||
|
||||
#endif // TEAMBITMAPIMAGE_H
|
||||
83
game/client/ViewConeImage.cpp
Normal file
83
game/client/ViewConeImage.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: This is a panel which is rendered image on top of an entity
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "ViewConeImage.h"
|
||||
#include <keyvalues.h>
|
||||
#include <vgui_controls/Panel.h>
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// initialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CViewConeImage::Init( vgui::Panel *pParent, KeyValues* pInitData )
|
||||
{
|
||||
Assert( pParent );
|
||||
|
||||
// Load viewcone material
|
||||
if (!m_Image.Init( pParent->GetVPanel(), pInitData ))
|
||||
return false;
|
||||
|
||||
// Position the view cone...
|
||||
int viewconesize = pInitData->GetInt( "size", 32 );
|
||||
m_Image.SetRenderSize( viewconesize, viewconesize );
|
||||
|
||||
int cx, cy;
|
||||
pParent->GetSize( cx, cy );
|
||||
m_Image.SetPos( (cx - viewconesize) / 2, (cy - viewconesize) / 2 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Paint the sucka
|
||||
//-----------------------------------------------------------------------------
|
||||
void CViewConeImage::Paint( float yaw )
|
||||
{
|
||||
g_pMatSystemSurface->DisableClipping( true );
|
||||
|
||||
m_Image.DoPaint( NULL, yaw );
|
||||
|
||||
g_pMatSystemSurface->DisableClipping( false );
|
||||
}
|
||||
|
||||
void CViewConeImage::SetColor( int r, int g, int b )
|
||||
{
|
||||
m_Image.SetColor( Color( r, g, b, 255 ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper method to initialize a view cone image from KeyValues data..
|
||||
// KeyValues contains the bitmap data, pSectionName, if it exists,
|
||||
// indicates which subsection of pInitData should be looked at to get at the
|
||||
// image data. The final argument is the bitmap image to initialize.
|
||||
// The function returns true if it succeeded.
|
||||
//
|
||||
// NOTE: This function looks for the key values 'material' and 'color'
|
||||
// and uses them to set up the material + modulation color of the image
|
||||
//-----------------------------------------------------------------------------
|
||||
bool InitializeViewConeImage( KeyValues *pInitData, const char* pSectionName,
|
||||
vgui::Panel *pParent, CViewConeImage* pViewConeImage )
|
||||
{
|
||||
KeyValues *pViewConeImageSection;
|
||||
if (pSectionName)
|
||||
{
|
||||
pViewConeImageSection = pInitData->FindKey( pSectionName );
|
||||
if ( !pViewConeImageSection )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
pViewConeImageSection = pInitData;
|
||||
}
|
||||
|
||||
return pViewConeImage->Init( pParent, pViewConeImageSection );
|
||||
}
|
||||
|
||||
56
game/client/ViewConeImage.h
Normal file
56
game/client/ViewConeImage.h
Normal file
@@ -0,0 +1,56 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: This is a panel which draws a viewcone
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef VIEWCONEIMAGE_H
|
||||
#define VIEWCONEIMAGE_H
|
||||
|
||||
#include "shareddefs.h"
|
||||
#include "vgui_bitmapimage.h"
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
class Panel;
|
||||
}
|
||||
|
||||
class C_BaseEntity;
|
||||
class KeyValues;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A bitmap that renders a view cone based on angles
|
||||
//-----------------------------------------------------------------------------
|
||||
class CViewConeImage
|
||||
{
|
||||
public:
|
||||
// initialization
|
||||
bool Init( vgui::Panel *pParent, KeyValues* pInitData );
|
||||
|
||||
// Paint the sucka
|
||||
void Paint( float yaw );
|
||||
|
||||
void SetColor( int r, int g, int b );
|
||||
|
||||
private:
|
||||
BitmapImage m_Image;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper method to initialize a view cone image from KeyValues data..
|
||||
// KeyValues contains the bitmap data, pSectionName, if it exists,
|
||||
// indicates which subsection of pInitData should be looked at to get at the
|
||||
// image data. The final argument is the bitmap image to initialize.
|
||||
// The function returns true if it succeeded.
|
||||
//
|
||||
// NOTE: This function looks for the key values 'material' and 'color'
|
||||
// and uses them to set up the material + modulation color of the image
|
||||
//-----------------------------------------------------------------------------
|
||||
bool InitializeViewConeImage( KeyValues *pInitData, const char* pSectionName,
|
||||
vgui::Panel *pParent, CViewConeImage* pViewConeImage );
|
||||
|
||||
|
||||
#endif // VIEWCONEIMAGE_H
|
||||
75
game/client/WaterLODMaterialProxy.cpp
Normal file
75
game/client/WaterLODMaterialProxy.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "materialsystem/imaterialproxy.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "iviewrender.h"
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// no inputs, assumes that the results go into $CHEAPWATERSTARTDISTANCE and $CHEAPWATERENDDISTANCE
|
||||
class CWaterLODMaterialProxy : public IMaterialProxy
|
||||
{
|
||||
public:
|
||||
CWaterLODMaterialProxy();
|
||||
virtual ~CWaterLODMaterialProxy();
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( void *pC_BaseEntity );
|
||||
virtual void Release( void ) { delete this; }
|
||||
virtual IMaterial *GetMaterial();
|
||||
|
||||
private:
|
||||
IMaterialVar *m_pCheapWaterStartDistanceVar;
|
||||
IMaterialVar *m_pCheapWaterEndDistanceVar;
|
||||
};
|
||||
|
||||
CWaterLODMaterialProxy::CWaterLODMaterialProxy()
|
||||
{
|
||||
m_pCheapWaterStartDistanceVar = NULL;
|
||||
m_pCheapWaterEndDistanceVar = NULL;
|
||||
}
|
||||
|
||||
CWaterLODMaterialProxy::~CWaterLODMaterialProxy()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool CWaterLODMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
bool foundVar;
|
||||
m_pCheapWaterStartDistanceVar = pMaterial->FindVar( "$CHEAPWATERSTARTDISTANCE", &foundVar, false );
|
||||
if( !foundVar )
|
||||
return false;
|
||||
|
||||
m_pCheapWaterEndDistanceVar = pMaterial->FindVar( "$CHEAPWATERENDDISTANCE", &foundVar, false );
|
||||
if( !foundVar )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CWaterLODMaterialProxy::OnBind( void *pC_BaseEntity )
|
||||
{
|
||||
if( !m_pCheapWaterStartDistanceVar || !m_pCheapWaterEndDistanceVar )
|
||||
{
|
||||
return;
|
||||
}
|
||||
float start, end;
|
||||
view->GetWaterLODParams( start, end );
|
||||
m_pCheapWaterStartDistanceVar->SetFloatValue( start );
|
||||
m_pCheapWaterEndDistanceVar->SetFloatValue( end );
|
||||
}
|
||||
|
||||
IMaterial *CWaterLODMaterialProxy::GetMaterial()
|
||||
{
|
||||
return m_pCheapWaterStartDistanceVar->GetOwningMaterial();
|
||||
}
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CWaterLODMaterialProxy, WaterLOD );
|
||||
70
game/client/WorldDimsProxy.cpp
Normal file
70
game/client/WorldDimsProxy.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "materialsystem/imaterialproxy.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "c_world.h"
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class CWorldDimsProxy : public IMaterialProxy
|
||||
{
|
||||
public:
|
||||
CWorldDimsProxy();
|
||||
virtual ~CWorldDimsProxy();
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( void *pC_BaseEntity );
|
||||
virtual void Release( void ) { delete this; }
|
||||
virtual IMaterial *GetMaterial();
|
||||
|
||||
|
||||
public:
|
||||
IMaterialVar *m_pMinsVar;
|
||||
IMaterialVar *m_pMaxsVar;
|
||||
};
|
||||
|
||||
|
||||
CWorldDimsProxy::CWorldDimsProxy()
|
||||
{
|
||||
m_pMinsVar = m_pMaxsVar = NULL;
|
||||
}
|
||||
|
||||
CWorldDimsProxy::~CWorldDimsProxy()
|
||||
{
|
||||
}
|
||||
|
||||
bool CWorldDimsProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
m_pMinsVar = pMaterial->FindVar( "$world_mins", NULL, false );
|
||||
m_pMaxsVar = pMaterial->FindVar( "$world_maxs", NULL, false );
|
||||
return true;
|
||||
}
|
||||
|
||||
void CWorldDimsProxy::OnBind( void *pC_BaseEntity )
|
||||
{
|
||||
if ( m_pMinsVar && m_pMaxsVar )
|
||||
{
|
||||
C_World *pWorld = GetClientWorldEntity();
|
||||
if ( pWorld )
|
||||
{
|
||||
m_pMinsVar->SetVecValue( (const float*)&pWorld->m_WorldMins, 3 );
|
||||
m_pMaxsVar->SetVecValue( (const float*)&pWorld->m_WorldMaxs, 3 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IMaterial *CWorldDimsProxy::GetMaterial()
|
||||
{
|
||||
return m_pMinsVar->GetOwningMaterial();
|
||||
}
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CWorldDimsProxy, WorldDims );
|
||||
|
||||
|
||||
4109
game/client/_vpc_/manifest_client_csgo/win32/manifest.txt
Normal file
4109
game/client/_vpc_/manifest_client_csgo/win32/manifest.txt
Normal file
File diff suppressed because it is too large
Load Diff
278
game/client/achievement_notification_panel.cpp
Normal file
278
game/client/achievement_notification_panel.cpp
Normal file
@@ -0,0 +1,278 @@
|
||||
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "hud_macros.h"
|
||||
#include "hudelement.h"
|
||||
#include "iclientmode.h"
|
||||
#include "ienginevgui.h"
|
||||
#include <vgui/ILocalize.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include <vgui/IVGUI.h>
|
||||
#include <vgui_controls/EditablePanel.h>
|
||||
#include <vgui_controls/Label.h>
|
||||
#include <vgui_controls/ImagePanel.h>
|
||||
#include "achievement_notification_panel.h"
|
||||
#ifndef NO_STEAM
|
||||
#include "steam/steam_api.h"
|
||||
#endif
|
||||
#include "iachievementmgr.h"
|
||||
#include "fmtstr.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
#define ACHIEVEMENT_NOTIFICATION_DURATION 10.0f
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DECLARE_HUDELEMENT_DEPTH( CAchievementNotificationPanel, 100 );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CAchievementNotificationPanel::CAchievementNotificationPanel( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "AchievementNotificationPanel" )
|
||||
{
|
||||
Panel *pParent = GetClientMode()->GetViewport();
|
||||
SetParent( pParent );
|
||||
|
||||
SetScheme( "basemodui_scheme" );
|
||||
|
||||
m_flHideTime = 0;
|
||||
m_pPanelBackground = new EditablePanel( this, "Notification_Background" );
|
||||
m_pIcon = new ImagePanel( this, "Notification_Icon" );
|
||||
m_pLabelHeading = new Label( this, "HeadingLabel", "" );
|
||||
m_pLabelTitle = new Label( this, "TitleLabel", "" );
|
||||
|
||||
m_pIcon->SetShouldScaleImage( true );
|
||||
|
||||
vgui::ivgui()->AddTickSignal( GetVPanel() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAchievementNotificationPanel::Init()
|
||||
{
|
||||
ListenForGameEvent( "achievement_event" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAchievementNotificationPanel::ApplySchemeSettings( IScheme *pScheme )
|
||||
{
|
||||
// load control settings...
|
||||
LoadControlSettings( "resource/UI/AchievementNotification.res" );
|
||||
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAchievementNotificationPanel::PerformLayout( void )
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
// Set background color of various elements. Need to do this in code, if we do it in res file it gets slammed by the
|
||||
// scheme. (Incl. label background: some products don't have label background colors set in their scheme and helpfully slam it to white.)
|
||||
SetBgColor( Color( 0, 0, 0, 0 ) );
|
||||
m_pLabelHeading->SetBgColor( Color( 0, 0, 0, 0 ) );
|
||||
m_pLabelTitle->SetBgColor( Color( 0, 0, 0, 0 ) );
|
||||
m_pPanelBackground->SetBgColor( Color( 62,70,55, 200 ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAchievementNotificationPanel::FireGameEvent( IGameEvent * event )
|
||||
{
|
||||
const char *name = event->GetName();
|
||||
if ( 0 == Q_strcmp( name, "achievement_event" ) )
|
||||
{
|
||||
const char *pchName = event->GetString( "achievement_name" );
|
||||
int iCur = event->GetInt( "cur_val" );
|
||||
int iMax = event->GetInt( "max_val" );
|
||||
wchar_t szLocalizedName[256]=L"";
|
||||
|
||||
#ifndef NO_STEAM
|
||||
if ( IsPC() )
|
||||
{
|
||||
// shouldn't ever get achievement progress if steam not running and user logged in, but check just in case
|
||||
if ( !steamapicontext->SteamUserStats() )
|
||||
{
|
||||
Msg( "Steam not running, achievement progress notification not displayed\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// use Steam to show achievement progress UI
|
||||
steamapicontext->SteamUserStats()->IndicateAchievementProgress( pchName, iCur, iMax );
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// on X360 we need to show our own achievement progress UI
|
||||
|
||||
const wchar_t *pchLocalizedName = ACHIEVEMENT_LOCALIZED_NAME_FROM_STR( pchName );
|
||||
Assert( pchLocalizedName );
|
||||
if ( !pchLocalizedName || !pchLocalizedName[0] )
|
||||
return;
|
||||
Q_wcsncpy( szLocalizedName, pchLocalizedName, sizeof( szLocalizedName ) );
|
||||
|
||||
// this is achievement progress, compose the message of form: "<name> (<#>/<max>)"
|
||||
wchar_t szFmt[128]=L"";
|
||||
wchar_t szText[512]=L"";
|
||||
wchar_t szNumFound[16]=L"";
|
||||
wchar_t szNumTotal[16]=L"";
|
||||
Q_snwprintf( szNumFound, ARRAYSIZE( szNumFound ), L"%i", iCur );
|
||||
Q_snwprintf( szNumTotal, ARRAYSIZE( szNumTotal ), L"%i", iMax );
|
||||
|
||||
const wchar_t *pchFmt = g_pVGuiLocalize->Find( "#GameUI_Achievement_Progress_Fmt" );
|
||||
if ( !pchFmt || !pchFmt[0] )
|
||||
return;
|
||||
Q_wcsncpy( szFmt, pchFmt, sizeof( szFmt ) );
|
||||
|
||||
g_pVGuiLocalize->ConstructString( szText, sizeof( szText ), szFmt, 3, szLocalizedName, szNumFound, szNumTotal );
|
||||
AddNotification( pchName, g_pVGuiLocalize->FindSafe( "#GameUI_Achievement_Progress" ), szText );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called on each tick
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAchievementNotificationPanel::OnTick( void )
|
||||
{
|
||||
if ( ( m_flHideTime > 0 ) && ( m_flHideTime < gpGlobals->curtime ) )
|
||||
{
|
||||
m_flHideTime = 0;
|
||||
ShowNextNotification();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CAchievementNotificationPanel::ShouldDraw( void )
|
||||
{
|
||||
return ( ( m_flHideTime > 0 ) && ( m_flHideTime > gpGlobals->curtime ) && CHudElement::ShouldDraw() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAchievementNotificationPanel::AddNotification( const char *szIconBaseName, const wchar_t *pHeading, const wchar_t *pTitle )
|
||||
{
|
||||
// put this notification in our queue
|
||||
int iQueueItem = m_queueNotification.AddToTail();
|
||||
Notification_t ¬ification = m_queueNotification[iQueueItem];
|
||||
Q_strncpy( notification.szIconBaseName, szIconBaseName, ARRAYSIZE( notification.szIconBaseName ) );
|
||||
Q_wcsncpy( notification.szHeading, pHeading, sizeof( notification.szHeading ) );
|
||||
Q_wcsncpy( notification.szTitle, pTitle, sizeof( notification.szTitle ) );
|
||||
|
||||
// if we are not currently displaying a notification, go ahead and show this one
|
||||
if ( 0 == m_flHideTime )
|
||||
{
|
||||
ShowNextNotification();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Shows next notification in queue if there is one
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAchievementNotificationPanel::ShowNextNotification()
|
||||
{
|
||||
// see if we have anything to do
|
||||
if ( 0 == m_queueNotification.Count() )
|
||||
{
|
||||
m_flHideTime = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
Notification_t ¬ification = m_queueNotification[ m_queueNotification.Head() ];
|
||||
|
||||
m_flHideTime = gpGlobals->curtime + ACHIEVEMENT_NOTIFICATION_DURATION;
|
||||
|
||||
// set the text and icon in the dialog
|
||||
SetDialogVariable( "heading", notification.szHeading );
|
||||
SetDialogVariable( "title", notification.szTitle );
|
||||
const char *pchIconBaseName = notification.szIconBaseName;
|
||||
if ( pchIconBaseName && pchIconBaseName[0] )
|
||||
{
|
||||
m_pIcon->SetImage( CFmtStr( "achievements/%s.vmt", pchIconBaseName ) );
|
||||
}
|
||||
|
||||
// resize the panel so it always looks good
|
||||
|
||||
// get fonts
|
||||
HFont hFontHeading = m_pLabelHeading->GetFont();
|
||||
HFont hFontTitle = m_pLabelTitle->GetFont();
|
||||
// determine how wide the text strings are
|
||||
int iHeadingWidth = UTIL_ComputeStringWidth( hFontHeading, notification.szHeading );
|
||||
int iTitleWidth = UTIL_ComputeStringWidth( hFontTitle, notification.szTitle );
|
||||
// use the widest string
|
||||
int iTextWidth = MAX( iHeadingWidth, iTitleWidth );
|
||||
// don't let it be insanely wide
|
||||
iTextWidth = MIN( iTextWidth, XRES( 300 ) );
|
||||
int iIconWidth = m_pIcon->GetWide();
|
||||
int iSpacing = XRES( 10 );
|
||||
int iPanelWidth = iSpacing + iIconWidth + iSpacing + iTextWidth + iSpacing;
|
||||
int iPanelX = GetWide() - iPanelWidth;
|
||||
int iIconX = iPanelX + iSpacing;
|
||||
int iTextX = iIconX + iIconWidth + iSpacing;
|
||||
// resize all the elements
|
||||
SetXAndWide( m_pPanelBackground, iPanelX, iPanelWidth );
|
||||
SetXAndWide( m_pIcon, iIconX, iIconWidth );
|
||||
SetXAndWide( m_pLabelHeading, iTextX, iTextWidth );
|
||||
SetXAndWide( m_pLabelTitle, iTextX, iTextWidth );
|
||||
|
||||
m_queueNotification.Remove( m_queueNotification.Head() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAchievementNotificationPanel::SetXAndWide( Panel *pPanel, int x, int wide )
|
||||
{
|
||||
int xCur, yCur;
|
||||
pPanel->GetPos( xCur, yCur );
|
||||
pPanel->SetPos( x, yCur );
|
||||
pPanel->SetWide( wide );
|
||||
}
|
||||
|
||||
CON_COMMAND_F( achievement_notification_test, "Test the hud notification UI", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY )
|
||||
{
|
||||
static int iCount=0;
|
||||
|
||||
CAchievementNotificationPanel *pPanel = GET_HUDELEMENT( CAchievementNotificationPanel );
|
||||
if ( pPanel )
|
||||
{
|
||||
pPanel->AddNotification( "HL2_KILL_ODESSAGUNSHIP", L"Achievement Progress", ( 0 == ( iCount % 2 ) ? L"Test Notification Message A (1/10)" :
|
||||
L"Test Message B" ) );
|
||||
}
|
||||
|
||||
#if 0
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "achievement_event" );
|
||||
if ( event )
|
||||
{
|
||||
const char *szTestStr[] = { "TF_GET_HEADSHOTS", "TF_PLAY_GAME_EVERYMAP", "TF_PLAY_GAME_EVERYCLASS", "TF_GET_HEALPOINTS" };
|
||||
event->SetString( "achievement_name", szTestStr[iCount%ARRAYSIZE(szTestStr)] );
|
||||
event->SetInt( "cur_val", ( iCount%9 ) + 1 );
|
||||
event->SetInt( "max_val", 10 );
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
#endif
|
||||
|
||||
iCount++;
|
||||
}
|
||||
57
game/client/achievement_notification_panel.h
Normal file
57
game/client/achievement_notification_panel.h
Normal file
@@ -0,0 +1,57 @@
|
||||
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef ACHIEVEMENT_NOTIFICATION_PANEL_H
|
||||
#define ACHIEVEMENT_NOTIFICATION_PANEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vgui_controls/EditablePanel.h>
|
||||
#include "hudelement.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
class CAchievementNotificationPanel : public CHudElement, public EditablePanel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CAchievementNotificationPanel, EditablePanel );
|
||||
|
||||
public:
|
||||
explicit CAchievementNotificationPanel( const char *pElementName );
|
||||
|
||||
virtual void Init();
|
||||
virtual void ApplySchemeSettings( IScheme *scheme );
|
||||
virtual bool ShouldDraw( void );
|
||||
virtual void PerformLayout( void );
|
||||
virtual void LevelInit( void ) { m_flHideTime = 0; }
|
||||
virtual void FireGameEvent( IGameEvent * event );
|
||||
virtual void OnTick( void );
|
||||
|
||||
void AddNotification( const char *szIconBaseName, const wchar_t *pHeading, const wchar_t *pTitle );
|
||||
|
||||
private:
|
||||
void ShowNextNotification();
|
||||
void SetXAndWide( Panel *pPanel, int x, int wide );
|
||||
|
||||
float m_flHideTime;
|
||||
|
||||
Label *m_pLabelHeading;
|
||||
Label *m_pLabelTitle;
|
||||
EditablePanel *m_pPanelBackground;
|
||||
ImagePanel *m_pIcon;
|
||||
|
||||
struct Notification_t
|
||||
{
|
||||
char szIconBaseName[255];
|
||||
wchar_t szHeading[255];
|
||||
wchar_t szTitle[255];
|
||||
};
|
||||
|
||||
CUtlLinkedList<Notification_t> m_queueNotification;
|
||||
};
|
||||
|
||||
#endif // ACHIEVEMENT_NOTIFICATION_PANEL_H
|
||||
52
game/client/animatedentitytextureproxy.cpp
Normal file
52
game/client/animatedentitytextureproxy.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "baseanimatedtextureproxy.h"
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class CAnimatedEntityTextureProxy : public CBaseAnimatedTextureProxy
|
||||
{
|
||||
public:
|
||||
CAnimatedEntityTextureProxy() {}
|
||||
virtual ~CAnimatedEntityTextureProxy() {}
|
||||
|
||||
virtual float GetAnimationStartTime( void* pBaseEntity );
|
||||
virtual void AnimationWrapped( void* pC_BaseEntity );
|
||||
|
||||
};
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CAnimatedEntityTextureProxy, AnimatedEntityTexture );
|
||||
|
||||
float CAnimatedEntityTextureProxy::GetAnimationStartTime( void* pArg )
|
||||
{
|
||||
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||
if (!pRend)
|
||||
return 0.0f;
|
||||
|
||||
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
if (pEntity)
|
||||
{
|
||||
return pEntity->GetTextureAnimationStartTime();
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void CAnimatedEntityTextureProxy::AnimationWrapped( void* pArg )
|
||||
{
|
||||
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||
if (!pRend)
|
||||
return;
|
||||
|
||||
C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
if (pEntity)
|
||||
{
|
||||
pEntity->TextureAnimationWrapped();
|
||||
}
|
||||
}
|
||||
57
game/client/animatedoffsettextureproxy.cpp
Normal file
57
game/client/animatedoffsettextureproxy.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "baseanimatedtextureproxy.h"
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class CAnimatedOffsetTextureProxy : public CBaseAnimatedTextureProxy
|
||||
{
|
||||
public:
|
||||
CAnimatedOffsetTextureProxy() : m_flFrameOffset( 0.0f ) {}
|
||||
|
||||
virtual ~CAnimatedOffsetTextureProxy() {}
|
||||
|
||||
virtual float GetAnimationStartTime( void* pBaseEntity );
|
||||
virtual void OnBind( void *pBaseEntity );
|
||||
|
||||
protected:
|
||||
|
||||
float m_flFrameOffset;
|
||||
};
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CAnimatedOffsetTextureProxy, AnimatedOffsetTexture );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : pArg -
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
float CAnimatedOffsetTextureProxy::GetAnimationStartTime( void* pArg )
|
||||
{
|
||||
return m_flFrameOffset;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pBaseEntity -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAnimatedOffsetTextureProxy::OnBind( void *pBaseEntity )
|
||||
{
|
||||
C_BaseEntity* pEntity = (C_BaseEntity*)pBaseEntity;
|
||||
|
||||
if ( pEntity )
|
||||
{
|
||||
m_flFrameOffset = pEntity->GetTextureAnimationStartTime();
|
||||
}
|
||||
|
||||
// Call into the base class
|
||||
CBaseAnimatedTextureProxy::OnBind( pBaseEntity );
|
||||
}
|
||||
|
||||
30
game/client/animatedtextureproxy.cpp
Normal file
30
game/client/animatedtextureproxy.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "baseanimatedtextureproxy.h"
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class CAnimatedTextureProxy : public CBaseAnimatedTextureProxy
|
||||
{
|
||||
public:
|
||||
CAnimatedTextureProxy() {}
|
||||
virtual ~CAnimatedTextureProxy() {}
|
||||
virtual float GetAnimationStartTime( void* pBaseEntity );
|
||||
};
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CAnimatedTextureProxy, AnimatedTexture );
|
||||
|
||||
#pragma warning (disable : 4100)
|
||||
|
||||
float CAnimatedTextureProxy::GetAnimationStartTime( void* pBaseEntity )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
347
game/client/animationlayer.h
Normal file
347
game/client/animationlayer.h
Normal file
@@ -0,0 +1,347 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef ANIMATIONLAYER_H
|
||||
#define ANIMATIONLAYER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "rangecheckedvar.h"
|
||||
#include "tier1/lerp_functions.h"
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
class C_BaseAnimatingOverlay;
|
||||
#endif
|
||||
|
||||
class C_AnimationLayer
|
||||
{
|
||||
public:
|
||||
|
||||
// This allows the datatables to access private members.
|
||||
ALLOW_DATATABLES_PRIVATE_ACCESS();
|
||||
|
||||
C_AnimationLayer();
|
||||
void Reset();
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
void SetOwner( C_BaseAnimatingOverlay *pOverlay );
|
||||
C_BaseAnimatingOverlay *GetOwner() const;
|
||||
#endif
|
||||
|
||||
void SetOrder( int order );
|
||||
bool IsActive( void );
|
||||
float GetFadeout( float flCurTime );
|
||||
|
||||
void SetSequence( int nSequence );
|
||||
void SetCycle( float flCycle );
|
||||
void SetPrevCycle( float flCycle );
|
||||
void SetPlaybackRate( float flPlaybackRate );
|
||||
void SetWeight( float flWeight );
|
||||
void SetWeightDeltaRate( float flDelta );
|
||||
|
||||
int GetOrder() const;
|
||||
int GetSequence( ) const;
|
||||
float GetCycle( ) const;
|
||||
float GetPrevCycle( ) const;
|
||||
float GetPlaybackRate( ) const;
|
||||
float GetWeight( ) const;
|
||||
float GetWeightDeltaRate( ) const;
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
// If the weights, cycle or sequence #s changed due to interpolation then
|
||||
// we'll need to recompute the bbox
|
||||
int GetInvalidatePhysicsBits() const;
|
||||
void SetInvalidatePhysicsBits( int iBit ) { m_nInvalidatePhysicsBits = iBit; }
|
||||
#endif
|
||||
|
||||
public:
|
||||
float m_flLayerAnimtime;
|
||||
float m_flLayerFadeOuttime;
|
||||
|
||||
// dispatch flags
|
||||
CStudioHdr *m_pDispatchedStudioHdr;
|
||||
int m_nDispatchedSrc;
|
||||
int m_nDispatchedDst;
|
||||
|
||||
private:
|
||||
int m_nOrder;
|
||||
CRangeCheckedVar<int, -1, 65535, 0> m_nSequence;
|
||||
CRangeCheckedVar<float, -2, 2, 0> m_flPrevCycle;
|
||||
CRangeCheckedVar<float, -5, 5, 0> m_flWeight;
|
||||
CRangeCheckedVar<float, -5, 5, 0> m_flWeightDeltaRate;
|
||||
|
||||
// used for automatic crossfades between sequence changes
|
||||
CRangeCheckedVar<float, -50, 50, 1> m_flPlaybackRate;
|
||||
CRangeCheckedVar<float, -2, 2, 0> m_flCycle;
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
C_BaseAnimatingOverlay *m_pOwner;
|
||||
int m_nInvalidatePhysicsBits;
|
||||
#endif
|
||||
|
||||
friend class C_BaseAnimatingOverlay;
|
||||
friend C_AnimationLayer LoopingLerp( float flPercent, C_AnimationLayer& from, C_AnimationLayer& to );
|
||||
friend C_AnimationLayer Lerp( float flPercent, const C_AnimationLayer& from, const C_AnimationLayer& to );
|
||||
friend C_AnimationLayer LoopingLerp_Hermite( const C_AnimationLayer& current, float flPercent, C_AnimationLayer& prev, C_AnimationLayer& from, C_AnimationLayer& to );
|
||||
friend C_AnimationLayer Lerp_Hermite( const C_AnimationLayer& current, float flPercent, const C_AnimationLayer& prev, const C_AnimationLayer& from, const C_AnimationLayer& to );
|
||||
friend void Lerp_Clamp( C_AnimationLayer &val );
|
||||
friend int CheckForSequenceBoxChanges( const C_AnimationLayer& newLayer, const C_AnimationLayer& oldLayer );
|
||||
};
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#define CAnimationLayer C_AnimationLayer
|
||||
#endif
|
||||
|
||||
|
||||
inline C_AnimationLayer::C_AnimationLayer()
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
m_pOwner = NULL;
|
||||
m_nInvalidatePhysicsBits = 0;
|
||||
#endif
|
||||
m_pDispatchedStudioHdr = NULL;
|
||||
m_nDispatchedSrc = ACT_INVALID;
|
||||
m_nDispatchedDst = ACT_INVALID;
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
#ifdef GAME_DLL
|
||||
|
||||
inline void C_AnimationLayer::SetSequence( int nSequence )
|
||||
{
|
||||
m_nSequence = nSequence;
|
||||
}
|
||||
|
||||
inline void C_AnimationLayer::SetCycle( float flCycle )
|
||||
{
|
||||
m_flCycle = flCycle;
|
||||
}
|
||||
|
||||
inline void C_AnimationLayer::SetWeight( float flWeight )
|
||||
{
|
||||
m_flWeight = flWeight;
|
||||
}
|
||||
|
||||
#endif // GAME_DLL
|
||||
|
||||
FORCEINLINE void C_AnimationLayer::SetPrevCycle( float flPrevCycle )
|
||||
{
|
||||
m_flPrevCycle = flPrevCycle;
|
||||
}
|
||||
|
||||
FORCEINLINE void C_AnimationLayer::SetPlaybackRate( float flPlaybackRate )
|
||||
{
|
||||
m_flPlaybackRate = flPlaybackRate;
|
||||
}
|
||||
|
||||
FORCEINLINE void C_AnimationLayer::SetWeightDeltaRate( float flDelta )
|
||||
{
|
||||
m_flWeightDeltaRate = flDelta;
|
||||
}
|
||||
|
||||
FORCEINLINE int C_AnimationLayer::GetSequence( ) const
|
||||
{
|
||||
return m_nSequence;
|
||||
}
|
||||
|
||||
FORCEINLINE float C_AnimationLayer::GetCycle( ) const
|
||||
{
|
||||
return m_flCycle;
|
||||
}
|
||||
|
||||
FORCEINLINE float C_AnimationLayer::GetPrevCycle( ) const
|
||||
{
|
||||
return m_flPrevCycle;
|
||||
}
|
||||
|
||||
FORCEINLINE float C_AnimationLayer::GetPlaybackRate( ) const
|
||||
{
|
||||
return m_flPlaybackRate;
|
||||
}
|
||||
|
||||
FORCEINLINE float C_AnimationLayer::GetWeight( ) const
|
||||
{
|
||||
return m_flWeight;
|
||||
}
|
||||
|
||||
FORCEINLINE float C_AnimationLayer::GetWeightDeltaRate( ) const
|
||||
{
|
||||
return m_flWeightDeltaRate;
|
||||
}
|
||||
|
||||
FORCEINLINE int C_AnimationLayer::GetOrder() const
|
||||
{
|
||||
return m_nOrder;
|
||||
}
|
||||
|
||||
inline float C_AnimationLayer::GetFadeout( float flCurTime )
|
||||
{
|
||||
float s;
|
||||
|
||||
if (m_flLayerFadeOuttime <= 0.0f)
|
||||
{
|
||||
s = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// blend in over 0.2 seconds
|
||||
s = 1.0 - (flCurTime - m_flLayerAnimtime) / m_flLayerFadeOuttime;
|
||||
if (s > 0 && s <= 1.0)
|
||||
{
|
||||
// do a nice spline curve
|
||||
s = 3 * s * s - 2 * s * s * s;
|
||||
}
|
||||
else if ( s > 1.0f )
|
||||
{
|
||||
// Shouldn't happen, but maybe curtime is behind animtime?
|
||||
s = 1.0f;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
FORCEINLINE int C_AnimationLayer::GetInvalidatePhysicsBits() const
|
||||
{
|
||||
return m_nInvalidatePhysicsBits;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline C_AnimationLayer LoopingLerp( float flPercent, C_AnimationLayer& from, C_AnimationLayer& to )
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
Assert( from.GetOwner() == to.GetOwner() );
|
||||
#endif
|
||||
|
||||
C_AnimationLayer output;
|
||||
|
||||
output.m_nSequence = to.m_nSequence;
|
||||
output.m_flCycle = LoopingLerp( flPercent, (float)from.m_flCycle, (float)to.m_flCycle );
|
||||
output.m_flPrevCycle = to.m_flPrevCycle;
|
||||
output.m_flWeight = Lerp( flPercent, from.m_flWeight, to.m_flWeight );
|
||||
output.m_nOrder = to.m_nOrder;
|
||||
|
||||
output.m_flLayerAnimtime = to.m_flLayerAnimtime;
|
||||
output.m_flLayerFadeOuttime = to.m_flLayerFadeOuttime;
|
||||
#ifdef CLIENT_DLL
|
||||
output.SetOwner( to.GetOwner() );
|
||||
#endif
|
||||
return output;
|
||||
}
|
||||
|
||||
inline C_AnimationLayer Lerp( float flPercent, const C_AnimationLayer& from, const C_AnimationLayer& to )
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
Assert( from.GetOwner() == to.GetOwner() );
|
||||
#endif
|
||||
|
||||
C_AnimationLayer output;
|
||||
|
||||
output.m_nSequence = to.m_nSequence;
|
||||
output.m_flCycle = Lerp( flPercent, from.m_flCycle, to.m_flCycle );
|
||||
output.m_flPrevCycle = to.m_flPrevCycle;
|
||||
output.m_flWeight = Lerp( flPercent, from.m_flWeight, to.m_flWeight );
|
||||
output.m_nOrder = to.m_nOrder;
|
||||
|
||||
output.m_flLayerAnimtime = to.m_flLayerAnimtime;
|
||||
output.m_flLayerFadeOuttime = to.m_flLayerFadeOuttime;
|
||||
#ifdef CLIENT_DLL
|
||||
output.SetOwner( to.GetOwner() );
|
||||
#endif
|
||||
return output;
|
||||
}
|
||||
|
||||
inline int CheckForSequenceBoxChanges( const C_AnimationLayer& newLayer, const C_AnimationLayer& oldLayer )
|
||||
{
|
||||
int nChangeFlags = 0;
|
||||
|
||||
bool bOldIsZero = ( oldLayer.GetWeight() == 0.0f );
|
||||
bool bNewIsZero = ( newLayer.GetWeight() == 0.0f );
|
||||
|
||||
if ( ( newLayer.GetSequence() != oldLayer.GetSequence() ) ||
|
||||
( bNewIsZero != bOldIsZero ) )
|
||||
{
|
||||
nChangeFlags |= SEQUENCE_CHANGED | BOUNDS_CHANGED;
|
||||
}
|
||||
|
||||
if ( newLayer.GetCycle() != oldLayer.GetCycle() )
|
||||
{
|
||||
nChangeFlags |= ANIMATION_CHANGED;
|
||||
}
|
||||
|
||||
if ( newLayer.GetOrder() != oldLayer.GetOrder() )
|
||||
{
|
||||
nChangeFlags |= BOUNDS_CHANGED;
|
||||
}
|
||||
|
||||
return nChangeFlags;
|
||||
}
|
||||
|
||||
inline C_AnimationLayer LoopingLerp_Hermite( const C_AnimationLayer& current, float flPercent, C_AnimationLayer& prev, C_AnimationLayer& from, C_AnimationLayer& to )
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
Assert( prev.GetOwner() == from.GetOwner() );
|
||||
Assert( from.GetOwner() == to.GetOwner() );
|
||||
#endif
|
||||
|
||||
C_AnimationLayer output;
|
||||
|
||||
output.m_nSequence = to.m_nSequence;
|
||||
output.m_flCycle = LoopingLerp_Hermite( (float)current.m_flCycle, flPercent, (float)prev.m_flCycle, (float)from.m_flCycle, (float)to.m_flCycle );
|
||||
output.m_flPrevCycle = to.m_flPrevCycle;
|
||||
output.m_flWeight = Lerp( flPercent, from.m_flWeight, to.m_flWeight );
|
||||
output.m_nOrder = to.m_nOrder;
|
||||
|
||||
output.m_flLayerAnimtime = to.m_flLayerAnimtime;
|
||||
output.m_flLayerFadeOuttime = to.m_flLayerFadeOuttime;
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
output.SetOwner( to.GetOwner() );
|
||||
output.m_nInvalidatePhysicsBits = CheckForSequenceBoxChanges( output, current );
|
||||
#endif
|
||||
return output;
|
||||
}
|
||||
|
||||
// YWB: Specialization for interpolating euler angles via quaternions...
|
||||
inline C_AnimationLayer Lerp_Hermite( const C_AnimationLayer& current, float flPercent, const C_AnimationLayer& prev, const C_AnimationLayer& from, const C_AnimationLayer& to )
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
Assert( prev.GetOwner() == from.GetOwner() );
|
||||
Assert( from.GetOwner() == to.GetOwner() );
|
||||
#endif
|
||||
|
||||
C_AnimationLayer output;
|
||||
|
||||
output.m_nSequence = to.m_nSequence;
|
||||
output.m_flCycle = Lerp_Hermite( (float)current.m_flCycle, flPercent, (float)prev.m_flCycle, (float)from.m_flCycle, (float)to.m_flCycle );
|
||||
output.m_flPrevCycle = to.m_flPrevCycle;
|
||||
output.m_flWeight = Lerp( flPercent, from.m_flWeight, to.m_flWeight );
|
||||
output.m_nOrder = to.m_nOrder;
|
||||
|
||||
output.m_flLayerAnimtime = to.m_flLayerAnimtime;
|
||||
output.m_flLayerFadeOuttime = to.m_flLayerFadeOuttime;
|
||||
#ifdef CLIENT_DLL
|
||||
output.SetOwner( to.GetOwner() );
|
||||
output.m_nInvalidatePhysicsBits = CheckForSequenceBoxChanges( output, current );
|
||||
#endif
|
||||
return output;
|
||||
}
|
||||
|
||||
inline void Lerp_Clamp( C_AnimationLayer &val )
|
||||
{
|
||||
Lerp_Clamp( val.m_nSequence );
|
||||
Lerp_Clamp( val.m_flCycle );
|
||||
Lerp_Clamp( val.m_flPrevCycle );
|
||||
Lerp_Clamp( val.m_flWeight );
|
||||
Lerp_Clamp( val.m_nOrder );
|
||||
Lerp_Clamp( val.m_flLayerAnimtime );
|
||||
Lerp_Clamp( val.m_flLayerFadeOuttime );
|
||||
}
|
||||
|
||||
#endif // ANIMATIONLAYER_H
|
||||
129
game/client/baseanimatedtextureproxy.cpp
Normal file
129
game/client/baseanimatedtextureproxy.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "baseanimatedtextureproxy.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "materialsystem/itexture.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor, destructor:
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CBaseAnimatedTextureProxy::CBaseAnimatedTextureProxy()
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
CBaseAnimatedTextureProxy::~CBaseAnimatedTextureProxy()
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initialization, shutdown
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBaseAnimatedTextureProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
char const* pAnimatedTextureVarName = pKeyValues->GetString( "animatedTextureVar" );
|
||||
if( !pAnimatedTextureVarName )
|
||||
return false;
|
||||
|
||||
bool foundVar;
|
||||
m_AnimatedTextureVar = pMaterial->FindVar( pAnimatedTextureVarName, &foundVar, false );
|
||||
if( !foundVar )
|
||||
return false;
|
||||
|
||||
char const* pAnimatedTextureFrameNumVarName = pKeyValues->GetString( "animatedTextureFrameNumVar" );
|
||||
if( !pAnimatedTextureFrameNumVarName )
|
||||
return false;
|
||||
|
||||
m_AnimatedTextureFrameNumVar = pMaterial->FindVar( pAnimatedTextureFrameNumVarName, &foundVar, false );
|
||||
if( !foundVar )
|
||||
return false;
|
||||
|
||||
m_FrameRate = pKeyValues->GetFloat( "animatedTextureFrameRate", 15 );
|
||||
m_WrapAnimation = !pKeyValues->GetInt( "animationNoWrap", 0 );
|
||||
return true;
|
||||
}
|
||||
|
||||
void CBaseAnimatedTextureProxy::Cleanup()
|
||||
{
|
||||
m_AnimatedTextureVar = NULL;
|
||||
m_AnimatedTextureFrameNumVar = NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Does the dirty deed
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAnimatedTextureProxy::OnBind( void *pEntity )
|
||||
{
|
||||
Assert ( m_AnimatedTextureVar );
|
||||
|
||||
if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
|
||||
{
|
||||
return;
|
||||
}
|
||||
ITexture *pTexture;
|
||||
pTexture = m_AnimatedTextureVar->GetTextureValue();
|
||||
int numFrames = pTexture->GetNumAnimationFrames();
|
||||
|
||||
if ( numFrames <= 0 )
|
||||
{
|
||||
Assert( !"0 frames in material calling animated texture proxy" );
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: Must not use relative time based methods here
|
||||
// because the bind proxy can be called many times per frame.
|
||||
// Prevent multiple Wrap callbacks to be sent for no wrap mode
|
||||
float startTime = GetAnimationStartTime(pEntity);
|
||||
float deltaTime = gpGlobals->curtime - startTime;
|
||||
float prevTime = deltaTime - gpGlobals->frametime;
|
||||
|
||||
// Clamp..
|
||||
if (deltaTime < 0.0f)
|
||||
deltaTime = 0.0f;
|
||||
if (prevTime < 0.0f)
|
||||
prevTime = 0.0f;
|
||||
|
||||
float frame = m_FrameRate * deltaTime;
|
||||
float prevFrame = m_FrameRate * prevTime;
|
||||
|
||||
int intFrame = ((int)frame) % numFrames;
|
||||
int intPrevFrame = ((int)prevFrame) % numFrames;
|
||||
|
||||
// Report wrap situation...
|
||||
if (intPrevFrame > intFrame)
|
||||
{
|
||||
if (m_WrapAnimation)
|
||||
{
|
||||
AnimationWrapped( pEntity );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only sent the wrapped message once.
|
||||
// when we're in non-wrapping mode
|
||||
if (prevFrame < numFrames)
|
||||
AnimationWrapped( pEntity );
|
||||
intFrame = numFrames - 1;
|
||||
}
|
||||
}
|
||||
|
||||
m_AnimatedTextureFrameNumVar->SetIntValue( intFrame );
|
||||
}
|
||||
|
||||
IMaterial *CBaseAnimatedTextureProxy::GetMaterial()
|
||||
{
|
||||
return m_AnimatedTextureVar->GetOwningMaterial();
|
||||
}
|
||||
47
game/client/baseanimatedtextureproxy.h
Normal file
47
game/client/baseanimatedtextureproxy.h
Normal file
@@ -0,0 +1,47 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef BASEANIMATEDTEXTUREPROXY
|
||||
#define BASEANIMATEDTEXTUREPROXY
|
||||
|
||||
#include "materialsystem/imaterialproxy.h"
|
||||
|
||||
class IMaterial;
|
||||
class IMaterialVar;
|
||||
|
||||
#pragma warning (disable : 4100)
|
||||
|
||||
class CBaseAnimatedTextureProxy : public IMaterialProxy
|
||||
{
|
||||
public:
|
||||
CBaseAnimatedTextureProxy();
|
||||
virtual ~CBaseAnimatedTextureProxy();
|
||||
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( void *pC_BaseEntity );
|
||||
virtual void Release( void ) { delete this; }
|
||||
virtual IMaterial *GetMaterial();
|
||||
|
||||
protected:
|
||||
// derived classes must implement this; it returns the time
|
||||
// that the animation began
|
||||
virtual float GetAnimationStartTime( void* pBaseEntity ) = 0;
|
||||
|
||||
// Derived classes may implement this if they choose;
|
||||
// this method is called whenever the animation wraps...
|
||||
virtual void AnimationWrapped( void* pBaseEntity ) {}
|
||||
|
||||
protected:
|
||||
void Cleanup();
|
||||
|
||||
IMaterialVar *m_AnimatedTextureVar;
|
||||
IMaterialVar *m_AnimatedTextureFrameNumVar;
|
||||
float m_FrameRate;
|
||||
bool m_WrapAnimation;
|
||||
};
|
||||
|
||||
#endif // BASEANIMATEDTEXTUREPROXY
|
||||
175
game/client/baseclientrendertargets.cpp
Normal file
175
game/client/baseclientrendertargets.cpp
Normal file
@@ -0,0 +1,175 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implementation for CBaseClientRenderTargets class.
|
||||
// Provides Init functions for common render textures used by the engine.
|
||||
// Mod makers can inherit from this class, and call the Create functions for
|
||||
// only the render textures the want for their mod.
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "baseclientrendertargets.h" // header
|
||||
#include "materialsystem/imaterialsystemhardwareconfig.h" // Hardware config checks
|
||||
#include "materialsystem/itexture.h" // Hardware config checks
|
||||
#include "tier0/icommandline.h"
|
||||
#ifdef GAMEUI_UISYSTEM2_ENABLED
|
||||
#include "gameui.h"
|
||||
#endif
|
||||
#include "c_env_cascade_light.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
ConVar cl_disable_water_render_targets( "cl_disable_water_render_targets", "0" );
|
||||
|
||||
ITexture* CBaseClientRenderTargets::CreateWaterReflectionTexture( IMaterialSystem* pMaterialSystem, int iSize )
|
||||
{
|
||||
iSize = CommandLine()->ParmValue( "-reflectionTextureSize", iSize );
|
||||
#if defined( PORTAL )
|
||||
return pMaterialSystem->CreateNamedMultiRenderTargetTexture(
|
||||
"_rt_WaterReflection",
|
||||
iSize, iSize, RT_SIZE_NO_CHANGE,
|
||||
pMaterialSystem->GetBackBufferFormat(),
|
||||
|
||||
// Force separate depth buffer for recursive water reflection views, since using the default depth buffer
|
||||
// will clear depth in the upper left hand <512,512> corner of the screen causing translucent renderables to
|
||||
// render on top of closer geometry.
|
||||
MATERIAL_RT_DEPTH_SEPARATE,
|
||||
|
||||
TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT,
|
||||
CREATERENDERTARGETFLAGS_HDR );
|
||||
#else
|
||||
return pMaterialSystem->CreateNamedRenderTargetTextureEx2(
|
||||
"_rt_WaterReflection",
|
||||
iSize, iSize, RT_SIZE_PICMIP,
|
||||
pMaterialSystem->GetBackBufferFormat(),
|
||||
MATERIAL_RT_DEPTH_SHARED,
|
||||
TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT,
|
||||
CREATERENDERTARGETFLAGS_HDR );
|
||||
#endif
|
||||
}
|
||||
|
||||
ITexture* CBaseClientRenderTargets::CreateWaterRefractionTexture( IMaterialSystem* pMaterialSystem, int iSize )
|
||||
{
|
||||
iSize = CommandLine()->ParmValue( "-reflectionTextureSize", iSize );
|
||||
#if defined( PORTAL )
|
||||
return pMaterialSystem->CreateNamedMultiRenderTargetTexture(
|
||||
"_rt_WaterRefraction",
|
||||
iSize, iSize, RT_SIZE_NO_CHANGE,
|
||||
// This is different than reflection because it has to have alpha for fog factor.
|
||||
IMAGE_FORMAT_RGBA8888,
|
||||
|
||||
// Force separate depth buffer for recursive water reflection views, since using the default depth buffer
|
||||
// will clear depth in the upper left hand <512,512> corner of the screen causing translucent renderables to
|
||||
// render on top of closer geometry.
|
||||
//
|
||||
// EDIT: on consoles it doesn't matter for Portal 2 because we never use refraction anyways...we always opt for cheaper translucent water. Save memory instead.
|
||||
// @TODO: get rid of this buffer entirely on consoles
|
||||
IsGameConsole() ? MATERIAL_RT_DEPTH_SHARED : MATERIAL_RT_DEPTH_SEPARATE,
|
||||
|
||||
TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT,
|
||||
CREATERENDERTARGETFLAGS_HDR );
|
||||
#else
|
||||
return pMaterialSystem->CreateNamedRenderTargetTextureEx2(
|
||||
"_rt_WaterRefraction",
|
||||
iSize, iSize, RT_SIZE_PICMIP,
|
||||
// This is different than reflection because it has to have alpha for fog factor.
|
||||
IMAGE_FORMAT_RGBA8888,
|
||||
MATERIAL_RT_DEPTH_SHARED,
|
||||
TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT,
|
||||
CREATERENDERTARGETFLAGS_HDR );
|
||||
#endif
|
||||
}
|
||||
|
||||
ITexture* CBaseClientRenderTargets::CreateCameraTexture( IMaterialSystem* pMaterialSystem, int iSize )
|
||||
{
|
||||
iSize = CommandLine()->ParmValue( "-monitorTextureSize", iSize );
|
||||
return pMaterialSystem->CreateNamedRenderTargetTextureEx2(
|
||||
"_rt_Camera",
|
||||
iSize, iSize, RT_SIZE_DEFAULT,
|
||||
pMaterialSystem->GetBackBufferFormat(),
|
||||
MATERIAL_RT_DEPTH_SHARED,
|
||||
0,
|
||||
CREATERENDERTARGETFLAGS_HDR );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called by the engine in material system init and shutdown.
|
||||
// Clients should override this in their inherited version, but the base
|
||||
// is to init all standard render targets for use.
|
||||
// Input : pMaterialSystem - the engine's material system (our singleton is not yet inited at the time this is called)
|
||||
// pHardwareConfig - the user hardware config, useful for conditional render target setup
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseClientRenderTargets::SetupClientRenderTargets( IMaterialSystem* pMaterialSystem, IMaterialSystemHardwareConfig* pHardwareConfig, int iWaterTextureSize, int iCameraTextureSize )
|
||||
{
|
||||
IMaterialSystem *pSave = materials;
|
||||
|
||||
// Make sure our config is loaded before we try to init rendertargets
|
||||
ConfigureCurrentSystemLevel();
|
||||
|
||||
// Water effects
|
||||
materials = pMaterialSystem; // in case not initted yet for mat system util
|
||||
g_pMaterialSystem = pMaterialSystem;
|
||||
g_pMaterialSystemHardwareConfig = pHardwareConfig;
|
||||
if ( iWaterTextureSize && !cl_disable_water_render_targets.GetBool() )
|
||||
{
|
||||
m_WaterReflectionTexture.Init( CreateWaterReflectionTexture( pMaterialSystem, iWaterTextureSize ) );
|
||||
m_WaterRefractionTexture.Init( CreateWaterRefractionTexture( pMaterialSystem, iWaterTextureSize ) );
|
||||
}
|
||||
|
||||
// mdonofrio - Don't need monitors or flashlight shadows for CS15.
|
||||
// Still need to initrendertargets for shadowmgr (blob/rtt shadows) - it will skip depth textures if convars set appropriately??
|
||||
|
||||
#if !( defined( CSTRIKE15 ) && defined( _PS3 ) )
|
||||
// Monitors
|
||||
if ( iCameraTextureSize )
|
||||
m_CameraTexture.Init( CreateCameraTexture( pMaterialSystem, iCameraTextureSize ) );
|
||||
#endif
|
||||
|
||||
ITexture *pGlintTexture = pMaterialSystem->CreateNamedRenderTargetTextureEx2(
|
||||
"_rt_eyeglint", 32, 32, RT_SIZE_NO_CHANGE, IMAGE_FORMAT_BGRA8888, MATERIAL_RT_DEPTH_NONE );
|
||||
pGlintTexture->IncrementReferenceCount();
|
||||
|
||||
g_CascadeLightManager.InitRenderTargets();
|
||||
|
||||
g_pClientShadowMgr->InitRenderTargets();
|
||||
|
||||
#ifdef GAMEUI_UISYSTEM2_ENABLED
|
||||
g_pGameUIGameSystem->InitRenderTargets();
|
||||
#endif
|
||||
|
||||
m_RenderToRTHelperTexture.Init( pMaterialSystem->CreateNamedRenderTargetTextureEx2( "render_to_rt_helper", 512, 512, RT_SIZE_DEFAULT, IMAGE_FORMAT_RGBA8888, MATERIAL_RT_DEPTH_SHARED, TEXTUREFLAGS_SINGLECOPY ) );
|
||||
|
||||
materials = pSave;
|
||||
}
|
||||
|
||||
void CBaseClientRenderTargets::InitClientRenderTargets( IMaterialSystem* pMaterialSystem, IMaterialSystemHardwareConfig* pHardwareConfig )
|
||||
{
|
||||
SetupClientRenderTargets( pMaterialSystem, pHardwareConfig );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Shut down each CTextureReference we created in InitClientRenderTargets.
|
||||
// Called by the engine in material system shutdown.
|
||||
// Input : -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseClientRenderTargets::ShutdownClientRenderTargets()
|
||||
{
|
||||
// Water effects
|
||||
m_WaterReflectionTexture.Shutdown();
|
||||
m_WaterRefractionTexture.Shutdown();
|
||||
|
||||
// Monitors
|
||||
m_CameraTexture.Shutdown();
|
||||
|
||||
g_pClientShadowMgr->ShutdownRenderTargets();
|
||||
|
||||
g_CascadeLightManager.ShutdownRenderTargets();
|
||||
|
||||
m_RenderToRTHelperTexture.Shutdown();
|
||||
|
||||
}
|
||||
|
||||
static CBaseClientRenderTargets g_BaseClientRenderTargets;
|
||||
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CBaseClientRenderTargets, IClientRenderTargets,
|
||||
CLIENTRENDERTARGETS_INTERFACE_VERSION, g_BaseClientRenderTargets );
|
||||
64
game/client/baseclientrendertargets.h
Normal file
64
game/client/baseclientrendertargets.h
Normal file
@@ -0,0 +1,64 @@
|
||||
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Has init functions for all the standard render targets used by most games.
|
||||
// Mods who wish to make their own render targets can inherit from this class
|
||||
// and in the 'InitClientRenderTargets' interface called by the engine, set up
|
||||
// their own render targets as well as calling the init functions for various
|
||||
// common render targets provided by this class.
|
||||
//
|
||||
// Note: Unless the client defines a singleton interface by inheriting from
|
||||
// this class and exposing the singleton instance, these init and shutdown
|
||||
// functions WILL NOT be called by the engine.
|
||||
//
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
#ifndef CLIENTRENDERTARTETS_H_
|
||||
#define CLIENTRENDERTARTETS_H_
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "game/client/iclientrendertargets.h" // base class with interfaces called by the engine
|
||||
#include "materialsystem/imaterialsystem.h" // for material system classes and interfaces
|
||||
|
||||
|
||||
// Externs
|
||||
class IMaterialSystem;
|
||||
class IMaterialSystemHardwareConfig;
|
||||
|
||||
class CBaseClientRenderTargets : public IClientRenderTargets
|
||||
{
|
||||
// no networked vars
|
||||
DECLARE_CLASS_GAMEROOT( CBaseClientRenderTargets, IClientRenderTargets );
|
||||
public:
|
||||
// Interface called by engine during material system startup.
|
||||
virtual void InitClientRenderTargets ( IMaterialSystem* pMaterialSystem, IMaterialSystemHardwareConfig* pHardwareConfig );
|
||||
// Shutdown all custom render targets here.
|
||||
virtual void ShutdownClientRenderTargets ( void );
|
||||
|
||||
protected:
|
||||
void SetupClientRenderTargets( IMaterialSystem* pMaterialSystem, IMaterialSystemHardwareConfig* pHardwareConfig, int iWaterTextureSize = 1024, int iCameraTextureSize = 256 );
|
||||
|
||||
// Standard render textures used by most mods-- Classes inheriting from
|
||||
// this can choose to init these or not depending on their needs.
|
||||
|
||||
// For reflective and refracting water
|
||||
CTextureReference m_WaterReflectionTexture;
|
||||
CTextureReference m_WaterRefractionTexture;
|
||||
|
||||
// Used for monitors
|
||||
CTextureReference m_CameraTexture;
|
||||
|
||||
CTextureReference m_RenderToRTHelperTexture;
|
||||
|
||||
// Init functions for the common render targets
|
||||
ITexture* CreateWaterReflectionTexture( IMaterialSystem* pMaterialSystem, int iSize = 1024 );
|
||||
ITexture* CreateWaterRefractionTexture( IMaterialSystem* pMaterialSystem, int iSize = 1024 );
|
||||
ITexture* CreateCameraTexture( IMaterialSystem* pMaterialSystem, int iSize = 256 );
|
||||
|
||||
};
|
||||
|
||||
#endif // CLIENTRENDERTARTETS_H_
|
||||
1527
game/client/beamdraw.cpp
Normal file
1527
game/client/beamdraw.cpp
Normal file
File diff suppressed because it is too large
Load Diff
165
game/client/beamdraw.h
Normal file
165
game/client/beamdraw.h
Normal file
@@ -0,0 +1,165 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
#if !defined( BEAMDRAW_H )
|
||||
#define BEAMDRAW_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "mathlib/vector.h"
|
||||
#include "tier2/beamsegdraw.h"
|
||||
#include "c_pixel_visibility.h"
|
||||
|
||||
#define NOISE_DIVISIONS 128
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct model_t;
|
||||
struct BeamTrail_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Beams fill out this data structure
|
||||
// This is also used for rendering
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class Beam_t : public CDefaultClientRenderable
|
||||
{
|
||||
public:
|
||||
Beam_t();
|
||||
|
||||
// Methods of IClientRenderable
|
||||
virtual const Vector& GetRenderOrigin( void );
|
||||
virtual const QAngle& GetRenderAngles( void );
|
||||
virtual const matrix3x4_t &RenderableToWorldTransform();
|
||||
virtual void GetRenderBounds( Vector& mins, Vector& maxs );
|
||||
virtual bool ShouldDraw( void );
|
||||
virtual int DrawModel( int flags, const RenderableInstance_t &instance );
|
||||
|
||||
// Resets the beam state
|
||||
void Reset();
|
||||
|
||||
// Method to computing the bounding box
|
||||
void ComputeBounds();
|
||||
|
||||
// Bounding box...
|
||||
Vector m_Mins;
|
||||
Vector m_Maxs;
|
||||
pixelvis_handle_t *m_queryHandleHalo;
|
||||
float m_haloProxySize;
|
||||
|
||||
// Data is below..
|
||||
|
||||
// Next beam in list
|
||||
Beam_t* next;
|
||||
|
||||
// Type of beam
|
||||
int type;
|
||||
int flags;
|
||||
|
||||
// Control points for the beam
|
||||
int numAttachments;
|
||||
Vector attachment[MAX_BEAM_ENTS];
|
||||
Vector delta;
|
||||
|
||||
// 0 .. 1 over lifetime of beam
|
||||
float t;
|
||||
float freq;
|
||||
|
||||
// Time when beam should die
|
||||
float die;
|
||||
float width;
|
||||
float endWidth;
|
||||
float fadeLength;
|
||||
float amplitude;
|
||||
float life;
|
||||
|
||||
// Color
|
||||
float r, g, b;
|
||||
float brightness;
|
||||
|
||||
// Speed
|
||||
float speed;
|
||||
|
||||
// Animation
|
||||
float frameRate;
|
||||
float frame;
|
||||
int segments;
|
||||
|
||||
// Attachment entities for the beam
|
||||
EHANDLE entity[MAX_BEAM_ENTS];
|
||||
int attachmentIndex[MAX_BEAM_ENTS];
|
||||
|
||||
// Model info
|
||||
int modelIndex;
|
||||
int haloIndex;
|
||||
|
||||
float haloScale;
|
||||
int frameCount;
|
||||
|
||||
float rgNoise[NOISE_DIVISIONS+1];
|
||||
|
||||
// Popcorn trail for beam follows to use
|
||||
BeamTrail_t* trail;
|
||||
|
||||
// for TE_BEAMRINGPOINT
|
||||
float start_radius;
|
||||
float end_radius;
|
||||
|
||||
// for FBEAM_ONLYNOISEONCE
|
||||
bool m_bCalculatedNoise;
|
||||
|
||||
float m_flHDRColorScale;
|
||||
};
|
||||
|
||||
|
||||
int ScreenTransform( const Vector& point, Vector& screen );
|
||||
|
||||
void DrawSegs( int noise_divisions, float *prgNoise, const model_t* spritemodel,
|
||||
float frame, int rendermode, const Vector& source, const Vector& delta,
|
||||
float startWidth, float endWidth, float scale, float freq, float speed, int segments,
|
||||
int flags, float* color, float fadeLength, float flHDRColorScale = 1.0f );
|
||||
void DrawTeslaSegs( int noise_divisions, float *prgNoise, const model_t* spritemodel,
|
||||
float frame, int rendermode, const Vector& source, const Vector& delta,
|
||||
float startWidth, float endWidth, float scale, float freq, float speed, int segments,
|
||||
int flags, float* color, float fadeLength, float flHDRColorScale = 1.0f );
|
||||
void DrawSplineSegs( int noise_divisions, float *prgNoise,
|
||||
const model_t* beammodel, const model_t* halomodel, float flHaloScale,
|
||||
float frame, int rendermode, int numAttachments, Vector* attachment,
|
||||
float startWidth, float endWidth, float scale, float freq, float speed, int segments,
|
||||
int flags, float* color, float fadeLength, float flHDRColorScale = 1.0f );
|
||||
void DrawHalo(IMaterial* pMaterial, const Vector& source, float scale, float const* color, float flHDRColorScale = 1.0f );
|
||||
void BeamDrawHalo( const model_t* spritemodel, float frame, int rendermode, const Vector& source,
|
||||
float scale, float* color, float flHDRColorScale = 1.0f );
|
||||
void DrawDisk( int noise_divisions, float *prgNoise, const model_t* spritemodel,
|
||||
float frame, int rendermode, const Vector& source, const Vector& delta,
|
||||
float width, float scale, float freq, float speed,
|
||||
int segments, float* color, float flHDRColorScale = 1.0f );
|
||||
void DrawCylinder( int noise_divisions, float *prgNoise, const model_t* spritemodel,
|
||||
float frame, int rendermode, const Vector& source,
|
||||
const Vector& delta, float width, float scale, float freq,
|
||||
float speed, int segments, float* color, float flHDRColorScale = 1.0f );
|
||||
void DrawRing( int noise_divisions, float *prgNoise, void (*pfnNoise)( float *noise, int divs, float scale ),
|
||||
const model_t* spritemodel, float frame, int rendermode,
|
||||
const Vector& source, const Vector& delta, float width, float amplitude,
|
||||
float freq, float speed, int segments, float* color, float flHDRColorScale = 1.0f );
|
||||
void DrawBeamFollow( const model_t* spritemodel, BeamTrail_t* pHead, int frame, int rendermode, Vector& delta,
|
||||
Vector& screen, Vector& screenLast, float die, const Vector& source,
|
||||
int flags, float width, float amplitude, float freq, float* color, float flHDRColorScale = 1.0f );
|
||||
|
||||
void DrawBeamQuadratic( const Vector &start, const Vector &control, const Vector &end, float width, const Vector &color, float scrollOffset, float flHDRColorScale = 1.0f );
|
||||
class CEngineSprite *Draw_SetSpriteTexture( const model_t *pSpriteModel, int frame, int rendermode );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Assumes the material has already been bound
|
||||
//-----------------------------------------------------------------------------
|
||||
void DrawSprite( const Vector &vecOrigin, float flWidth, float flHeight, color32 color );
|
||||
|
||||
#endif // BEAMDRAW_H
|
||||
73
game/client/bonetoworldarray.h
Normal file
73
game/client/bonetoworldarray.h
Normal file
@@ -0,0 +1,73 @@
|
||||
//========== Copyright © 2006, Valve Corporation, All rights reserved. ========
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef BONETOWORLDARRAY_H
|
||||
#define BONETOWORLDARRAY_H
|
||||
|
||||
#include "tier0/tslist.h"
|
||||
|
||||
#if defined( _WIN32 )
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier0/memdbgon.h" // for _aligned_malloc usage below
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
template <int NUM_ARRAYS>
|
||||
class CBoneToWorldArrays
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
ALIGNMENT = 128,
|
||||
};
|
||||
|
||||
CBoneToWorldArrays()
|
||||
{
|
||||
const int SIZE_ARRAY = AlignValue( sizeof(matrix3x4_t) * MAXSTUDIOBONES, ALIGNMENT );
|
||||
m_pBase = (matrix3x4_t *)_aligned_malloc( SIZE_ARRAY * NUM_ARRAYS, ALIGNMENT );
|
||||
for ( int i = 0; i < NUM_ARRAYS; i++ )
|
||||
{
|
||||
matrix3x4_t *pArray = (matrix3x4_t *)((byte *)m_pBase + SIZE_ARRAY * i);
|
||||
Assert( (size_t)pArray % ALIGNMENT == 0 );
|
||||
Free( pArray );
|
||||
}
|
||||
}
|
||||
|
||||
~CBoneToWorldArrays()
|
||||
{
|
||||
_aligned_free( m_pBase );
|
||||
}
|
||||
|
||||
int NumArrays()
|
||||
{
|
||||
return NUM_ARRAYS;
|
||||
}
|
||||
|
||||
matrix3x4_t *Alloc( bool bBlock = true )
|
||||
{
|
||||
TSLNodeBase_t *p;
|
||||
while ( ( p = m_Free.Pop() ) == NULL && bBlock )
|
||||
{
|
||||
ThreadPause();
|
||||
}
|
||||
return (matrix3x4_t *)p;
|
||||
}
|
||||
|
||||
void Free( matrix3x4_t *p )
|
||||
{
|
||||
m_Free.Push( (TSLNodeBase_t *) p );
|
||||
}
|
||||
|
||||
private:
|
||||
CTSListBase m_Free;
|
||||
matrix3x4_t *m_pBase;
|
||||
};
|
||||
|
||||
#include "tier0/memdbgoff.h" // for _aligned_malloc usage above
|
||||
|
||||
#endif // BONETOWORLDARRAY_H
|
||||
85
game/client/buildrenderables_PS3.cpp
Normal file
85
game/client/buildrenderables_PS3.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#include "buildrenderables_PS3.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
CPS3BuildRenderablesJob g_BuildRenderablesJob;
|
||||
CPS3BuildRenderablesJob* g_pBuildRenderablesJob = &g_BuildRenderablesJob;
|
||||
|
||||
job_buildrenderables::JobDescriptor_t g_buildRenderablesJobDescriptor ALIGN128;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPS3BuildRenderablesJob::Init( void )
|
||||
{
|
||||
m_bEnabled = false;
|
||||
|
||||
m_buildRenderablesJobData.EnsureCapacity(MAX_CONCURRENT_BUILDVIEWS);
|
||||
|
||||
m_buildRenderablesJobCount = 0;
|
||||
|
||||
// requires a SPURS instance, so register with VJobs
|
||||
if( g_pVJobs )
|
||||
{
|
||||
g_pVJobs->Register( this );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPS3BuildRenderablesJob::Shutdown()
|
||||
{
|
||||
g_pVJobs->Unregister( this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPS3BuildRenderablesJob::OnVjobsInit()
|
||||
{
|
||||
m_bEnabled = true;
|
||||
|
||||
g_buildRenderablesJobDescriptor.header = *m_pRoot->m_pJobBuildRenderables;
|
||||
|
||||
g_buildRenderablesJobDescriptor.header.useInOutBuffer = 1;
|
||||
g_buildRenderablesJobDescriptor.header.sizeStack = (64*1024)/16;
|
||||
g_buildRenderablesJobDescriptor.header.sizeInOrInOut = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPS3BuildRenderablesJob::OnVjobsShutdown()
|
||||
{
|
||||
m_bEnabled = false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
PS3BuildRenderablesJobData *CPS3BuildRenderablesJob::GetJobData( int job )
|
||||
{
|
||||
return &m_buildRenderablesJobData[ job ];
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
188
game/client/buildrenderables_PS3.h
Normal file
188
game/client/buildrenderables_PS3.h
Normal file
@@ -0,0 +1,188 @@
|
||||
//========= Copyright © Valve Corporation, All rights reserved. ============//
|
||||
#ifndef BUILDRENDERABLES_PS3_HDR
|
||||
#define BUILDRENDERABLES_PS3_HDR
|
||||
|
||||
#if defined( _PS3 )
|
||||
|
||||
#if defined(__SPU__)
|
||||
|
||||
#include "ps3/spu_job_shared.h"
|
||||
|
||||
#else
|
||||
|
||||
#include "utlvector.h"
|
||||
#include "vjobs/root.h"
|
||||
#include <vjobs_interface.h>
|
||||
#include <ps3/vjobutils.h>
|
||||
#include <ps3/vjobutils_shared.h>
|
||||
#include "vjobs/jobparams_shared.h"
|
||||
|
||||
#include "ClientLeafSystem.h"
|
||||
|
||||
#endif // __SPU__
|
||||
|
||||
|
||||
// copied from bspfile.h, do we need the rest of that file?
|
||||
#define MAX_MAP_AREAS 256
|
||||
|
||||
// round up to next 16B boundary, then add 16B
|
||||
#define ROUNDUPTONEXT16B( a ) (0x10 + ((a) + (0x10 - ((a)%0x10))))
|
||||
|
||||
|
||||
struct ALIGN128 buildRenderablesJob_SPU
|
||||
{
|
||||
int debugJob; // for dynamic switching of DebuggerBreak
|
||||
uint32 pEA_debugRenderable;
|
||||
|
||||
SetupRenderInfo_t info;
|
||||
void* pEA_worldbrush_leafs; // mleaf_t *
|
||||
|
||||
void* pEA_detailObjects; // CDetailModel *, g_detailObjectSystem->m_DetailObjects.Base()
|
||||
void* pEA_detailObjects_origin; // CDetailModel *, g_detailObjectSystem->m_DetailObjects.Base()
|
||||
// this is ptr to detailmodel.m_origin, so we don't have to fetch the whole thing, stride can this still be sizeof(CDetailModel) to access elements
|
||||
int detailObjects_count; // g_detailObjectSystem->m_DetailObjects.count()
|
||||
Vector viewOrigin; // g_vecCurrentRenderOrigin, CurrentViewOrigin()
|
||||
int strideCDetailModel;
|
||||
|
||||
void* pEA_clientRenderablesList_RenderGroups; // ptr to CEntry m_REnderGroups[RENDER_GROUP_COUNT][MAX_GROUP_ENTITIRES]
|
||||
void* pEA_clientRenderablesList_RenderGroupCounts; // ptr to int m_REnderGroupCounts[RENDER_GROUP_COUNT]
|
||||
|
||||
|
||||
DistanceFadeInfo_t info_mpRenderList_mDetailFade;
|
||||
|
||||
int maxCount;
|
||||
int buildFastReflectionRenderables; // r_fastreflectionfastpath
|
||||
|
||||
//
|
||||
void* pEA_frustums[MAX_MAP_AREAS]; // Frustum_t *
|
||||
int numAreaFrustums;
|
||||
|
||||
// detailobjectsystem info
|
||||
float flFactor;
|
||||
float flDetailFadeStart;
|
||||
float flDetailFadeEnd;
|
||||
|
||||
// translucency
|
||||
float flMinLevelFadeArea;
|
||||
float flMaxLevelFadeArea;
|
||||
float flMinGlobalFadeArea;
|
||||
float flMaxGlobalFadeArea;
|
||||
float flGlobalDistFadeScale;
|
||||
int bComputeScreenFade;
|
||||
ScreenSizeComputeInfo_t screensizecomputeinfo;
|
||||
|
||||
int shouldDrawDetailObjects;
|
||||
|
||||
|
||||
// utl
|
||||
void* pEA_clientleafsystem_mleaf;
|
||||
void* pEA_renderablesLIST; // renderable_LIST_t *
|
||||
void* pEA_renderablesInLeafLIST; // renderableInLeaf_LIST_t *
|
||||
int renderablesHeadIdx;
|
||||
|
||||
// extract
|
||||
int clientleafsystem_alternateSortCount; //
|
||||
int clientleafsystem_drawStaticProps; //
|
||||
int clientleafsystem_disableShadowDepthCount;
|
||||
|
||||
// convar copies
|
||||
int r_drawallrenderables;
|
||||
int r_portaltestents_AND_NOTr_portalsopenall;
|
||||
int r_occlusion;
|
||||
|
||||
// gpGlobals
|
||||
int frameCount;
|
||||
float curTime;
|
||||
|
||||
// CSM View
|
||||
bool bCSMView;
|
||||
bool bDisableCSMCulling;
|
||||
bool bShadowEntities;
|
||||
bool bShadowStaticProps;
|
||||
bool bShadowSprites;
|
||||
bool bIgnoreDisableShadowDepthRendering;
|
||||
int cascadeID;
|
||||
int debugViewID;
|
||||
int debugViewID_DEBUG;
|
||||
|
||||
// OUT
|
||||
void* ppEA_Renderables; // RenderableInfo **
|
||||
void* pEA_RenderablesCount; // int *
|
||||
void* pEA_RLInfo; // BuildRenderListInfo_t *
|
||||
|
||||
void* pEA_DetailRenderables; // DetailRenderableInfo_t *
|
||||
void* pEA_DetailRenderablesCount; // int *
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_GROUP_ENTITIES = 4096,
|
||||
MAX_BONE_SETUP_DEPENDENCY = 64,
|
||||
};
|
||||
|
||||
|
||||
|
||||
} ALIGN128_POST;
|
||||
|
||||
|
||||
#if !defined( __SPU__ )
|
||||
struct ALIGN128 PS3BuildRenderablesJobData
|
||||
{
|
||||
public:
|
||||
|
||||
job_buildrenderables::JobDescriptor_t jobDescriptor ALIGN128;
|
||||
|
||||
// src, SPU in only, going to SPU at start of job
|
||||
buildRenderablesJob_SPU buildRenderablesJobSPU;
|
||||
|
||||
} ALIGN128_POST;
|
||||
|
||||
|
||||
class CPS3BuildRenderablesJob : public VJobInstance
|
||||
{
|
||||
public:
|
||||
CPS3BuildRenderablesJob()
|
||||
{
|
||||
}
|
||||
|
||||
~CPS3BuildRenderablesJob()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
|
||||
void OnVjobsInit( void ); // gets called after m_pRoot was created and assigned
|
||||
void OnVjobsShutdown( void ); // gets called before m_pRoot is about to be destructed and NULL'ed
|
||||
|
||||
void Init( void );
|
||||
void Shutdown( void );
|
||||
|
||||
void ResetBoneJobs( void );
|
||||
|
||||
PS3BuildRenderablesJobData *GetJobData( int job );
|
||||
|
||||
CUtlVector<PS3BuildRenderablesJobData> m_buildRenderablesJobData;
|
||||
|
||||
private:
|
||||
|
||||
int m_buildRenderablesJobCount;
|
||||
int m_buildRenderablesJobNextSPURSPort;
|
||||
|
||||
bool m_bEnabled;
|
||||
};
|
||||
|
||||
|
||||
|
||||
extern IVJobs * g_pVJobs;
|
||||
extern CPS3BuildRenderablesJob* g_pBuildRenderablesJob;
|
||||
extern job_buildrenderables::JobDescriptor_t g_buildRenderablesJobDescriptor ALIGN128;
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // #if !defined(__SPU__)
|
||||
|
||||
|
||||
#endif // if !defined(_PS3)
|
||||
|
||||
|
||||
#endif
|
||||
169
game/client/c_ai_basehumanoid.cpp
Normal file
169
game/client/c_ai_basehumanoid.cpp
Normal file
@@ -0,0 +1,169 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#if 0
|
||||
|
||||
class C_AI_BaseHumanoid : public C_AI_BaseNPC
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_AI_BaseHumanoid, C_AI_BaseNPC );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_AI_BaseHumanoid();
|
||||
|
||||
// model specific
|
||||
virtual bool Interpolate( float currentTime );
|
||||
virtual void StandardBlendingRules( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], float currentTime, int boneMask );
|
||||
|
||||
float m_recanimtime[3];
|
||||
AnimationLayer_t m_Layer[4][3];
|
||||
};
|
||||
|
||||
|
||||
|
||||
C_AI_BaseHumanoid::C_AI_BaseHumanoid()
|
||||
{
|
||||
memset(m_recanimtime, 0, sizeof(m_recanimtime));
|
||||
memset(m_Layer, 0, sizeof(m_Layer));
|
||||
}
|
||||
|
||||
|
||||
BEGIN_RECV_TABLE_NOBASE(AnimationLayer_t, DT_Animationlayer)
|
||||
RecvPropInt(RECVINFO_NAME(nSequence,sequence)),
|
||||
RecvPropFloat(RECVINFO_NAME(flCycle,cycle)),
|
||||
RecvPropFloat(RECVINFO_NAME(flPlaybackrate,playbackrate)),
|
||||
RecvPropFloat(RECVINFO_NAME(flWeight,weight))
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_AI_BaseHumanoid, DT_BaseHumanoid, CAI_BaseHumanoid)
|
||||
/*
|
||||
RecvPropDataTable(RECVINFO_DTNAME(m_Layer[0][2],m_Layer0),0, &REFERENCE_RECV_TABLE(DT_Animationlayer)),
|
||||
RecvPropDataTable(RECVINFO_DTNAME(m_Layer[1][2],m_Layer1),0, &REFERENCE_RECV_TABLE(DT_Animationlayer)),
|
||||
RecvPropDataTable(RECVINFO_DTNAME(m_Layer[2][2],m_Layer2),0, &REFERENCE_RECV_TABLE(DT_Animationlayer)),
|
||||
RecvPropDataTable(RECVINFO_DTNAME(m_Layer[3][2],m_Layer3),0, &REFERENCE_RECV_TABLE(DT_Animationlayer)),
|
||||
*/
|
||||
RecvPropInt(RECVINFO_NAME(m_Layer[0][2].nSequence,sequence0)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[0][2].flCycle,cycle0)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[0][2].flPlaybackrate,playbackrate0)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[0][2].flWeight,weight0)),
|
||||
RecvPropInt(RECVINFO_NAME(m_Layer[1][2].nSequence,sequence1)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[1][2].flCycle,cycle1)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[1][2].flPlaybackrate,playbackrate1)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[1][2].flWeight,weight1)),
|
||||
RecvPropInt(RECVINFO_NAME(m_Layer[2][2].nSequence,sequence2)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[2][2].flCycle,cycle2)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[2][2].flPlaybackrate,playbackrate2)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[2][2].flWeight,weight2)),
|
||||
RecvPropInt(RECVINFO_NAME(m_Layer[3][2].nSequence,sequence3)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[3][2].flCycle,cycle3)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[3][2].flPlaybackrate,playbackrate3)),
|
||||
RecvPropFloat(RECVINFO_NAME(m_Layer[3][2].flWeight,weight3))
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_AI_BaseHumanoid::StandardBlendingRules( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], float currentTime, int boneMask )
|
||||
{
|
||||
VPROF( "C_AI_BaseHumanoid::StandardBlendingRules" );
|
||||
|
||||
BaseClass::StandardBlendingRules( pStudioHdr, pos, q, currentTime, boneMask );
|
||||
|
||||
if ( !hdr )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
float poseparam[MAXSTUDIOPOSEPARAM];
|
||||
|
||||
if ( GetSequence() >= hdr->numseq )
|
||||
{
|
||||
SetSequence( 0 );
|
||||
}
|
||||
|
||||
// interpolate pose parameters
|
||||
for (int i = 0; i < hdr->numposeparameters; i++)
|
||||
{
|
||||
poseparam[ i ] = m_flPoseParameter[i];
|
||||
}
|
||||
|
||||
// build root animation
|
||||
float fCycle = GetCycle();
|
||||
CalcPose( hdr, NULL, pos, q, GetSequence(), fCycle, poseparam );
|
||||
|
||||
// debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), 0, 0, "%30s %6.2f : %6.2f", hdr->pSeqdesc( GetSequence() )->pszLabel( ), fCycle, 1.0 );
|
||||
|
||||
MaintainSequenceTransitions( hdr, fCycle, poseparam, pos, q, boneMask );
|
||||
|
||||
#if 1
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (m_Layer[i][2].nSequence != m_Layer[i][1].nSequence)
|
||||
{
|
||||
if (m_Layer[i][2].flWeight > 0.5) m_Layer[i][1].flWeight = 1.0; else m_Layer[i][1].flWeight = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
Vector pos2[MAXSTUDIOBONES];
|
||||
Quaternion q2[MAXSTUDIOBONES];
|
||||
float fWeight = m_Layer[i][1].flWeight * (1 - dadt) + m_Layer[i][2].flWeight * dadt;
|
||||
|
||||
/*
|
||||
debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), -i - 1, 0,
|
||||
"%2d %6.2f %6.2f : %2d %6.2f %6.2f : %2d %6.2f %6.2f",
|
||||
m_Layer[i][0].nSequence, m_Layer[i][0].flCycle, m_Layer[i][0].flWeight,
|
||||
m_Layer[i][1].nSequence, m_Layer[i][1].flCycle, m_Layer[i][1].flWeight,
|
||||
m_Layer[i][2].nSequence, m_Layer[i][2].flCycle, m_Layer[i][2].flWeight );
|
||||
*/
|
||||
|
||||
if (fWeight > 0)
|
||||
{
|
||||
mstudioseqdesc_t *pseqdesc = hdr->pSeqdesc( m_Layer[i][2].nSequence );
|
||||
|
||||
float fCycle = m_Layer[i][2].flCycle;
|
||||
|
||||
// UNDONE: Do IK here.
|
||||
CalcPose( hdr, NULL, pos2, q2, m_Layer[i][2].nSequence, fCycle, poseparam );
|
||||
|
||||
if (fWeight > 1)
|
||||
fWeight = 1;
|
||||
SlerpBones( hdr, q, pos, pseqdesc, q2, pos2, fWeight );
|
||||
|
||||
engine->Con_NPrintf( 10 + i, "%30s %6.2f : %6.2f", pseqdesc->pszLabel(), fCycle, fWeight );
|
||||
}
|
||||
else
|
||||
{
|
||||
engine->Con_NPrintf( 10 + i, "%30s %6.2f : %6.2f", " ", 0, 0 );
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
CIKContext auto_ik;
|
||||
auto_ik.Init( hdr, GetRenderAngles(), GetRenderOrigin(), gpGlobals->curtime );
|
||||
CalcAutoplaySequences( hdr, &auto_ik, pos, q, poseparam, boneMask, currentTime );
|
||||
|
||||
float controllers[MAXSTUDIOBONECTRLS];
|
||||
GetBoneControllers(controllers);
|
||||
CalcBoneAdj( hdr, pos, q, controllers );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
199
game/client/c_ai_basenpc.cpp
Normal file
199
game/client/c_ai_basenpc.cpp
Normal file
@@ -0,0 +1,199 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_ai_basenpc.h"
|
||||
#include "engine/ivdebugoverlay.h"
|
||||
|
||||
#if defined( HL2_DLL ) || defined( HL2_EPISODIC )
|
||||
#include "c_basehlplayer.h"
|
||||
#endif
|
||||
|
||||
#include "death_pose.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define PING_MAX_TIME 2.0
|
||||
|
||||
//
|
||||
// Global accessors for GLaDOS for lighted mouth proxy
|
||||
//
|
||||
|
||||
CHandle<C_BaseAnimating> g_GLaDOSActor;
|
||||
|
||||
void SetGLaDOSActor( C_BaseAnimating *pActor )
|
||||
{
|
||||
g_GLaDOSActor = pActor;
|
||||
}
|
||||
|
||||
C_BaseAnimating *GetGLaDOSActor( void )
|
||||
{
|
||||
return g_GLaDOSActor;
|
||||
}
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_AI_BaseNPC, DT_AI_BaseNPC, CAI_BaseNPC )
|
||||
RecvPropInt( RECVINFO( m_lifeState ) ),
|
||||
RecvPropBool( RECVINFO( m_bPerformAvoidance ) ),
|
||||
RecvPropBool( RECVINFO( m_bIsMoving ) ),
|
||||
RecvPropBool( RECVINFO( m_bFadeCorpse ) ),
|
||||
RecvPropInt( RECVINFO ( m_iDeathPose) ),
|
||||
RecvPropInt( RECVINFO( m_iDeathFrame) ),
|
||||
RecvPropInt( RECVINFO( m_iSpeedModRadius ) ),
|
||||
RecvPropInt( RECVINFO( m_iSpeedModSpeed ) ),
|
||||
RecvPropInt( RECVINFO( m_bSpeedModActive ) ),
|
||||
RecvPropBool( RECVINFO( m_bImportanRagdoll ) ),
|
||||
RecvPropFloat( RECVINFO( m_flTimePingEffect ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
extern ConVar cl_npc_speedmod_intime;
|
||||
|
||||
bool NPC_IsImportantNPC( C_BaseAnimating *pAnimating )
|
||||
{
|
||||
C_AI_BaseNPC *pBaseNPC = pAnimating->MyNPCPointer();
|
||||
if ( pBaseNPC == NULL )
|
||||
return false;
|
||||
|
||||
return pBaseNPC->ImportantRagdoll();
|
||||
}
|
||||
|
||||
C_AI_BaseNPC::C_AI_BaseNPC()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Makes ragdolls ignore npcclip brushes
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int C_AI_BaseNPC::PhysicsSolidMaskForEntity( void ) const
|
||||
{
|
||||
// This allows ragdolls to move through npcclip brushes
|
||||
if ( !IsRagdoll() )
|
||||
{
|
||||
return MASK_NPCSOLID;
|
||||
}
|
||||
return MASK_SOLID;
|
||||
}
|
||||
|
||||
|
||||
void C_AI_BaseNPC::ClientThink( void )
|
||||
{
|
||||
BaseClass::ClientThink();
|
||||
|
||||
#ifdef HL2_DLL
|
||||
C_BaseHLPlayer *pPlayer = dynamic_cast<C_BaseHLPlayer*>( C_BasePlayer::GetLocalPlayer() );
|
||||
|
||||
if ( ShouldModifyPlayerSpeed() == true )
|
||||
{
|
||||
if ( pPlayer )
|
||||
{
|
||||
float flDist = (GetAbsOrigin() - pPlayer->GetAbsOrigin()).LengthSqr();
|
||||
|
||||
if ( flDist <= GetSpeedModifyRadius() )
|
||||
{
|
||||
if ( pPlayer->m_hClosestNPC )
|
||||
{
|
||||
if ( pPlayer->m_hClosestNPC != this )
|
||||
{
|
||||
float flDistOther = (pPlayer->m_hClosestNPC->GetAbsOrigin() - pPlayer->GetAbsOrigin()).Length();
|
||||
|
||||
//If I'm closer than the other NPC then replace it with myself.
|
||||
if ( flDist < flDistOther )
|
||||
{
|
||||
pPlayer->m_hClosestNPC = this;
|
||||
pPlayer->m_flSpeedModTime = gpGlobals->curtime + cl_npc_speedmod_intime.GetFloat();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pPlayer->m_hClosestNPC = this;
|
||||
pPlayer->m_flSpeedModTime = gpGlobals->curtime + cl_npc_speedmod_intime.GetFloat();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // HL2_DLL
|
||||
|
||||
#ifdef HL2_EPISODIC
|
||||
C_BaseHLPlayer *pPlayer = dynamic_cast<C_BaseHLPlayer*>( C_BasePlayer::GetLocalPlayer() );
|
||||
|
||||
if ( pPlayer && m_flTimePingEffect > gpGlobals->curtime )
|
||||
{
|
||||
float fPingEffectTime = m_flTimePingEffect - gpGlobals->curtime;
|
||||
|
||||
if ( fPingEffectTime > 0.0f )
|
||||
{
|
||||
Vector vRight, vUp;
|
||||
Vector vMins, vMaxs;
|
||||
|
||||
float fFade;
|
||||
|
||||
if( fPingEffectTime <= 1.0f )
|
||||
{
|
||||
fFade = 1.0f - (1.0f - fPingEffectTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
fFade = 1.0f;
|
||||
}
|
||||
|
||||
GetRenderBounds( vMins, vMaxs );
|
||||
AngleVectors (pPlayer->GetAbsAngles(), NULL, &vRight, &vUp );
|
||||
Vector p1 = GetAbsOrigin() + vRight * vMins.x + vUp * vMins.z;
|
||||
Vector p2 = GetAbsOrigin() + vRight * vMaxs.x + vUp * vMins.z;
|
||||
Vector p3 = GetAbsOrigin() + vUp * vMaxs.z;
|
||||
|
||||
int r = 0 * fFade;
|
||||
int g = 255 * fFade;
|
||||
int b = 0 * fFade;
|
||||
|
||||
debugoverlay->AddLineOverlay( p1, p2, r, g, b, true, 0.05f );
|
||||
debugoverlay->AddLineOverlay( p2, p3, r, g, b, true, 0.05f );
|
||||
debugoverlay->AddLineOverlay( p3, p1, r, g, b, true, 0.05f );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void C_AI_BaseNPC::OnDataChanged( DataUpdateType_t type )
|
||||
{
|
||||
BaseClass::OnDataChanged( type );
|
||||
|
||||
// Make sure we're thinking
|
||||
if ( type == DATA_UPDATE_CREATED )
|
||||
{
|
||||
// If this is the GLaDOS actor, then setup a handle to it, globally
|
||||
if ( FStrEq( STRING( GetEntityName() ), "@glados" ) || FStrEq( STRING( GetEntityName() ), "@actor_potatos" ) )
|
||||
{
|
||||
SetGLaDOSActor( this );
|
||||
MouthInfo().ActivateEnvelope();
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( ShouldModifyPlayerSpeed() == true ) || ( m_flTimePingEffect > gpGlobals->curtime ) )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
}
|
||||
|
||||
void C_AI_BaseNPC::GetRagdollInitBoneArrays( matrix3x4a_t *pDeltaBones0, matrix3x4a_t *pDeltaBones1, matrix3x4a_t *pCurrentBones, float boneDt )
|
||||
{
|
||||
ForceSetupBonesAtTime( pDeltaBones0, gpGlobals->curtime - boneDt );
|
||||
GetRagdollCurSequenceWithDeathPose( this, pDeltaBones1, gpGlobals->curtime, m_iDeathPose, m_iDeathFrame );
|
||||
float ragdollCreateTime = PhysGetSyncCreateTime();
|
||||
if ( ragdollCreateTime != gpGlobals->curtime )
|
||||
{
|
||||
// The next simulation frame begins before the end of this frame
|
||||
// so initialize the ragdoll at that time so that it will reach the current
|
||||
// position at curtime. Otherwise the ragdoll will simulate forward from curtime
|
||||
// and pop into the future a bit at this point of transition
|
||||
ForceSetupBonesAtTime( pCurrentBones, ragdollCreateTime );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetupBones( pCurrentBones, MAXSTUDIOBONES, BONE_USED_BY_ANYTHING, gpGlobals->curtime );
|
||||
}
|
||||
}
|
||||
61
game/client/c_ai_basenpc.h
Normal file
61
game/client/c_ai_basenpc.h
Normal file
@@ -0,0 +1,61 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_AI_BASENPC_H
|
||||
#define C_AI_BASENPC_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "c_basecombatcharacter.h"
|
||||
|
||||
// NOTE: MOved all controller code into c_basestudiomodel
|
||||
class C_AI_BaseNPC : public C_BaseCombatCharacter
|
||||
{
|
||||
DECLARE_CLASS( C_AI_BaseNPC, C_BaseCombatCharacter );
|
||||
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_AI_BaseNPC();
|
||||
virtual unsigned int PhysicsSolidMaskForEntity( void ) const;
|
||||
virtual bool IsNPC( void ) { return true; }
|
||||
bool IsMoving( void ){ return m_bIsMoving; }
|
||||
bool ShouldAvoidObstacle( void ){ return m_bPerformAvoidance; }
|
||||
virtual bool AddRagdollToFadeQueue( void ) { return m_bFadeCorpse; }
|
||||
|
||||
virtual void GetRagdollInitBoneArrays( matrix3x4a_t *pDeltaBones0, matrix3x4a_t *pDeltaBones1, matrix3x4a_t *pCurrentBones, float boneDt );
|
||||
|
||||
int GetDeathPose( void ) { return m_iDeathPose; }
|
||||
|
||||
bool ShouldModifyPlayerSpeed( void ) { return m_bSpeedModActive; }
|
||||
int GetSpeedModifyRadius( void ) { return m_iSpeedModRadius; }
|
||||
int GetSpeedModifySpeed( void ) { return m_iSpeedModSpeed; }
|
||||
|
||||
void ClientThink( void );
|
||||
void OnDataChanged( DataUpdateType_t type );
|
||||
bool ImportantRagdoll( void ) { return m_bImportanRagdoll; }
|
||||
|
||||
private:
|
||||
C_AI_BaseNPC( const C_AI_BaseNPC & ); // not defined, not accessible
|
||||
float m_flTimePingEffect;
|
||||
int m_iDeathPose;
|
||||
int m_iDeathFrame;
|
||||
|
||||
int m_iSpeedModRadius;
|
||||
int m_iSpeedModSpeed;
|
||||
|
||||
bool m_bPerformAvoidance;
|
||||
bool m_bIsMoving;
|
||||
bool m_bFadeCorpse;
|
||||
bool m_bSpeedModActive;
|
||||
bool m_bImportanRagdoll;
|
||||
};
|
||||
|
||||
|
||||
#endif // C_AI_BASENPC_H
|
||||
8839
game/client/c_baseanimating.cpp
Normal file
8839
game/client/c_baseanimating.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1021
game/client/c_baseanimating.h
Normal file
1021
game/client/c_baseanimating.h
Normal file
File diff suppressed because it is too large
Load Diff
1149
game/client/c_baseanimatingoverlay.cpp
Normal file
1149
game/client/c_baseanimatingoverlay.cpp
Normal file
File diff suppressed because it is too large
Load Diff
94
game/client/c_baseanimatingoverlay.h
Normal file
94
game/client/c_baseanimatingoverlay.h
Normal file
@@ -0,0 +1,94 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef C_BASEANIMATINGOVERLAY_H
|
||||
#define C_BASEANIMATINGOVERLAY_H
|
||||
#pragma once
|
||||
|
||||
#include "c_baseanimating.h"
|
||||
#include "toolframework/itoolframework.h"
|
||||
|
||||
// For shared code.
|
||||
#define CBaseAnimatingOverlay C_BaseAnimatingOverlay
|
||||
|
||||
|
||||
class C_BaseAnimatingOverlay : public C_BaseAnimating
|
||||
{
|
||||
DECLARE_CLASS( C_BaseAnimatingOverlay, C_BaseAnimating );
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
DECLARE_INTERPOLATION();
|
||||
|
||||
// Inherited from C_BaseAnimating
|
||||
public:
|
||||
virtual C_BaseAnimatingOverlay *GetBaseAnimatingOverlay() { return this; }
|
||||
|
||||
virtual void AccumulateLayers( IBoneSetup &boneSetup, BoneVector pos[], BoneQuaternion q[], float currentTime );
|
||||
virtual void DoAnimationEvents( CStudioHdr *pStudioHdr );
|
||||
virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
|
||||
virtual CStudioHdr *OnNewModel();
|
||||
|
||||
virtual bool Interpolate( float flCurrentTime );
|
||||
|
||||
#if defined( _PS3 )
|
||||
virtual void AccumulateLayers_AddPoseCalls( IBoneSetup_PS3 &boneSetup, BoneVector pos[], BoneQuaternion q[], float currentTime );
|
||||
#endif
|
||||
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
MAX_OVERLAYS = 15,
|
||||
};
|
||||
|
||||
C_BaseAnimatingOverlay();
|
||||
CAnimationLayer* GetAnimOverlay( int i, bool bUseOrder = true );
|
||||
void SetNumAnimOverlays( int num ); // This makes sure there is space for this # of layers.
|
||||
int GetNumAnimOverlays() const;
|
||||
void SetOverlayPrevEventCycle( int nSlot, float flValue );
|
||||
|
||||
void CheckInterpChanges( void );
|
||||
void CheckForLayerPhysicsInvalidate( void );
|
||||
|
||||
virtual bool UpdateDispatchLayer( CAnimationLayer *pLayer, CStudioHdr *pWeaponStudioHdr, int iSequence );
|
||||
void AccumulateDispatchedLayers( C_BaseAnimatingOverlay *pWeapon, CStudioHdr *pWeaponStudioHdr, IBoneSetup &boneSetup, BoneVector pos[], BoneQuaternion q[], float currentTime );
|
||||
void RegenerateDispatchedLayers( IBoneSetup &boneSetup, BoneVector pos[], BoneQuaternion q[], float currentTime );
|
||||
|
||||
void AccumulateInterleavedDispatchedLayers( C_BaseAnimatingOverlay *pWeapon, IBoneSetup &boneSetup, BoneVector pos[], BoneQuaternion q[], float currentTime, bool bSetupInvisibleWeapon = false );
|
||||
|
||||
virtual void NotifyOnLayerChangeSequence( const CAnimationLayer* pLayer, const int nNewSequence ) {};
|
||||
virtual void NotifyOnLayerChangeWeight( const CAnimationLayer* pLayer, const float flNewWeight ) {};
|
||||
virtual void NotifyOnLayerChangeCycle( const CAnimationLayer* pLayer, const float flNewCycle ) {};
|
||||
|
||||
private:
|
||||
void CheckForLayerChanges( CStudioHdr *hdr, float currentTime );
|
||||
|
||||
CUtlVector < CAnimationLayer > m_AnimOverlay;
|
||||
CUtlVector < CInterpolatedVar< CAnimationLayer > > m_iv_AnimOverlay;
|
||||
|
||||
float m_flOverlayPrevEventCycle[ MAX_OVERLAYS ];
|
||||
|
||||
C_BaseAnimatingOverlay( const C_BaseAnimatingOverlay & ); // not defined, not accessible
|
||||
|
||||
friend void ResizeAnimationLayerCallback( void *pStruct, int offsetToUtlVector, int len );
|
||||
};
|
||||
|
||||
|
||||
inline void C_BaseAnimatingOverlay::SetOverlayPrevEventCycle( int nSlot, float flValue )
|
||||
{
|
||||
m_flOverlayPrevEventCycle[nSlot] = flValue;
|
||||
}
|
||||
|
||||
EXTERN_RECV_TABLE(DT_BaseAnimatingOverlay);
|
||||
|
||||
|
||||
#endif // C_BASEANIMATINGOVERLAY_H
|
||||
|
||||
|
||||
|
||||
|
||||
202
game/client/c_basecombatcharacter.cpp
Normal file
202
game/client/c_basecombatcharacter.cpp
Normal file
@@ -0,0 +1,202 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's C_BaseCombatCharacter entity
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_basecombatcharacter.h"
|
||||
#include "c_cs_player.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#if defined( CBaseCombatCharacter )
|
||||
#undef CBaseCombatCharacter
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseCombatCharacter::C_BaseCombatCharacter()
|
||||
{
|
||||
for ( int i=0; i < m_iAmmo.Count(); i++ )
|
||||
m_iAmmo.Set( i, 0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseCombatCharacter::~C_BaseCombatCharacter()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns the amount of ammunition of the specified type the character's carrying
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_BaseCombatCharacter::GetAmmoCount( char *szName ) const
|
||||
{
|
||||
return GetAmmoCount( g_pGameRules->GetAmmoDef()->Index(szName) );
|
||||
}
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Overload our muzzle flash and send it to any actively held weapon
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatCharacter::DoMuzzleFlash()
|
||||
{
|
||||
// Our weapon takes our muzzle flash command
|
||||
C_BaseCombatWeapon *pWeapon = GetActiveWeapon();
|
||||
if ( pWeapon )
|
||||
{
|
||||
pWeapon->DoMuzzleFlash();
|
||||
//NOTENOTE: We do not chain to the base here
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::DoMuzzleFlash();
|
||||
}
|
||||
}
|
||||
|
||||
void C_BaseCombatCharacter::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
// view weapon model cache monitoring
|
||||
// NOTE: expected to be updated ONLY once per frame for the primary player ONLY!
|
||||
// the expectation is that there is ONLY one customer that requires view models
|
||||
// otherwise the lower level code will thrash as it tries to maintain a single player's view model inventory
|
||||
{
|
||||
const char *viewWeapons[MAX_WEAPONS];
|
||||
int nNumViewWeapons = 0;
|
||||
|
||||
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( pLocalPlayer == this && !pLocalPlayer->IsObserver() )
|
||||
{
|
||||
// want to know what this player's weapon inventory is to keep all of these in cache
|
||||
for ( int i = 0; i < MAX_WEAPONS; i++ )
|
||||
{
|
||||
C_BaseCombatWeapon *pWeapon = GetWeapon( i );
|
||||
if ( !pWeapon )
|
||||
continue;
|
||||
|
||||
viewWeapons[nNumViewWeapons] = pWeapon->GetViewModel();
|
||||
nNumViewWeapons++;
|
||||
}
|
||||
}
|
||||
else if ( pLocalPlayer && pLocalPlayer->GetObserverMode() == OBS_MODE_IN_EYE && pLocalPlayer->GetObserverTarget() == this )
|
||||
{
|
||||
// once spectating, PURPOSELY only the active view weapon gets tracked
|
||||
// cycling through spectators is the more common pattern and tracking just the active weapon prevents massive cache thrashing
|
||||
// otherwise maintaining the observer targets inventories would needlessly thrash the cache as the player rapidly cycles
|
||||
C_BaseCombatWeapon *pWeapon = pLocalPlayer->GetActiveWeapon();
|
||||
if ( pWeapon )
|
||||
{
|
||||
viewWeapons[nNumViewWeapons] = pWeapon->GetViewModel();
|
||||
nNumViewWeapons++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( nNumViewWeapons )
|
||||
{
|
||||
// view model weapons are subject to a cache policy that needs to be kept accurate for a SINGLE Player
|
||||
modelinfo->UpdateViewWeaponModelCache( viewWeapons, nNumViewWeapons );
|
||||
}
|
||||
}
|
||||
|
||||
// world weapon model cache monitoring
|
||||
// world weapons have a much looser cache policy and just needs to monitor the important set of world weapons
|
||||
{
|
||||
const char *worldWeapons[MAX_WEAPONS];
|
||||
int nNumWorldWeapons = 0;
|
||||
|
||||
// want to track any world models that are active weapons
|
||||
// the world weapons lying on the ground are the ones that become LRU purge candidates
|
||||
C_BasePlayer *pPlayer = ToBasePlayer( this );
|
||||
if ( pPlayer )
|
||||
{
|
||||
C_BaseCombatWeapon *pWeapon = pPlayer->GetActiveWeapon();
|
||||
if ( pWeapon )
|
||||
{
|
||||
worldWeapons[nNumWorldWeapons] = pWeapon->GetWorldModel();
|
||||
nNumWorldWeapons++;
|
||||
}
|
||||
}
|
||||
|
||||
C_CSPlayer *pCSPlayer = C_CSPlayer::GetLocalCSPlayer();
|
||||
if ( pCSPlayer == this )
|
||||
{
|
||||
int weaponEntIndex = pCSPlayer->GetTargetedWeapon();
|
||||
if ( weaponEntIndex > 0 ) //0 is a valid entity index, but will never be used for a weapon
|
||||
{
|
||||
C_BaseEntity *pEnt = cl_entitylist->GetEnt( weaponEntIndex );
|
||||
C_BaseCombatWeapon *pWeapon = dynamic_cast< C_BaseCombatWeapon * >( pEnt );
|
||||
if ( pWeapon )
|
||||
{
|
||||
worldWeapons[nNumWorldWeapons] = pWeapon->GetWorldModel();
|
||||
nNumWorldWeapons++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( nNumWorldWeapons )
|
||||
{
|
||||
modelinfo->TouchWorldWeaponModelCache( worldWeapons, nNumWorldWeapons );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool C_BaseCombatCharacter::HasEverBeenInjured( void ) const
|
||||
{
|
||||
return ( m_flTimeOfLastInjury != 0.0f );
|
||||
}
|
||||
|
||||
float C_BaseCombatCharacter::GetTimeSinceLastInjury( void ) const
|
||||
{
|
||||
return gpGlobals->curtime - m_flTimeOfLastInjury;
|
||||
}
|
||||
|
||||
IMPLEMENT_CLIENTCLASS(C_BaseCombatCharacter, DT_BaseCombatCharacter, CBaseCombatCharacter);
|
||||
|
||||
// Only send active weapon index to local player
|
||||
BEGIN_RECV_TABLE_NOBASE( C_BaseCombatCharacter, DT_BCCLocalPlayerExclusive )
|
||||
RecvPropTime( RECVINFO( m_flNextAttack ) ),
|
||||
END_RECV_TABLE();
|
||||
|
||||
BEGIN_RECV_TABLE_NOBASE( C_BaseCombatCharacter, DT_BCCNonLocalPlayerExclusive )
|
||||
#if defined( CSTRIKE15 )
|
||||
// In CS:GO send active weapon index to all players except local
|
||||
RecvPropArray3( RECVINFO_ARRAY(m_hMyWeapons), RecvPropEHandle( RECVINFO( m_hMyWeapons[0] ) ) ),
|
||||
#endif
|
||||
END_RECV_TABLE();
|
||||
|
||||
BEGIN_RECV_TABLE(C_BaseCombatCharacter, DT_BaseCombatCharacter)
|
||||
RecvPropDataTable( "bcc_localdata", 0, 0, &REFERENCE_RECV_TABLE(DT_BCCLocalPlayerExclusive) ),
|
||||
RecvPropDataTable( "bcc_nonlocaldata", 0, 0, &REFERENCE_RECV_TABLE(DT_BCCNonLocalPlayerExclusive) ),
|
||||
RecvPropInt( RECVINFO( m_LastHitGroup ) ),
|
||||
RecvPropEHandle( RECVINFO( m_hActiveWeapon ) ),
|
||||
RecvPropTime( RECVINFO( m_flTimeOfLastInjury ) ),
|
||||
RecvPropInt( RECVINFO( m_nRelativeDirectionOfLastInjury ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY(m_hMyWeapons), RecvPropEHandle( RECVINFO( m_hMyWeapons[0] ) ) ),
|
||||
|
||||
#ifdef INVASION_CLIENT_DLL
|
||||
RecvPropInt( RECVINFO( m_iPowerups ) ),
|
||||
#endif
|
||||
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
BEGIN_PREDICTION_DATA( C_BaseCombatCharacter )
|
||||
|
||||
DEFINE_PRED_ARRAY( m_iAmmo, FIELD_INTEGER, MAX_AMMO_TYPES, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_FIELD( m_flNextAttack, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_FIELD( m_hActiveWeapon, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_ARRAY( m_hMyWeapons, FIELD_EHANDLE, MAX_WEAPONS, FTYPEDESC_INSENDTABLE ),
|
||||
|
||||
END_PREDICTION_DATA()
|
||||
181
game/client/c_basecombatcharacter.h
Normal file
181
game/client/c_basecombatcharacter.h
Normal file
@@ -0,0 +1,181 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: Defines the client-side representation of CBaseCombatCharacter.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef C_BASECOMBATCHARACTER_H
|
||||
#define C_BASECOMBATCHARACTER_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "shareddefs.h"
|
||||
#include "c_baseflex.h"
|
||||
|
||||
#define BCC_DEFAULT_LOOK_TOWARDS_TOLERANCE 0.9f
|
||||
|
||||
class C_BaseCombatWeapon;
|
||||
class C_WeaponCombatShield;
|
||||
|
||||
class C_BaseCombatCharacter : public C_BaseFlex
|
||||
{
|
||||
DECLARE_CLASS( C_BaseCombatCharacter, C_BaseFlex );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
C_BaseCombatCharacter( void );
|
||||
virtual ~C_BaseCombatCharacter( void );
|
||||
|
||||
virtual bool IsBaseCombatCharacter( void ) { return true; };
|
||||
virtual C_BaseCombatCharacter *MyCombatCharacterPointer( void ) { return this; }
|
||||
|
||||
virtual void DropPhysicsMag( const char *options ) {}
|
||||
|
||||
// -----------------------
|
||||
// Vision
|
||||
// -----------------------
|
||||
enum FieldOfViewCheckType { USE_FOV, DISREGARD_FOV };
|
||||
bool IsAbleToSee( const CBaseEntity *entity, FieldOfViewCheckType checkFOV ); // Visible starts with line of sight, and adds all the extra game checks like fog, smoke, camo...
|
||||
bool IsAbleToSee( C_BaseCombatCharacter *pBCC, FieldOfViewCheckType checkFOV ); // Visible starts with line of sight, and adds all the extra game checks like fog, smoke, camo...
|
||||
|
||||
virtual bool IsLookingTowards( const CBaseEntity *target, float cosTolerance = BCC_DEFAULT_LOOK_TOWARDS_TOLERANCE ) const; // return true if our view direction is pointing at the given target, within the cosine of the angular tolerance. LINE OF SIGHT IS NOT CHECKED.
|
||||
virtual bool IsLookingTowards( const Vector &target, float cosTolerance = BCC_DEFAULT_LOOK_TOWARDS_TOLERANCE ) const; // return true if our view direction is pointing at the given target, within the cosine of the angular tolerance. LINE OF SIGHT IS NOT CHECKED.
|
||||
|
||||
virtual bool IsInFieldOfView( CBaseEntity *entity ) const; // Calls IsLookingAt with the current field of view.
|
||||
virtual bool IsInFieldOfView( const Vector &pos ) const;
|
||||
|
||||
enum LineOfSightCheckType
|
||||
{
|
||||
IGNORE_NOTHING,
|
||||
IGNORE_ACTORS
|
||||
};
|
||||
virtual bool IsLineOfSightClear( CBaseEntity *entity, LineOfSightCheckType checkType = IGNORE_NOTHING ) const;// strictly LOS check with no other considerations
|
||||
virtual bool IsLineOfSightClear( const Vector &pos, LineOfSightCheckType checkType = IGNORE_NOTHING, CBaseEntity *entityToIgnore = NULL ) const;
|
||||
|
||||
int LastHitGroup() const { return m_LastHitGroup; }
|
||||
|
||||
// -----------------------
|
||||
// Ammo
|
||||
// -----------------------
|
||||
void RemoveAmmo( int iCount, int iAmmoIndex );
|
||||
void RemoveAmmo( int iCount, const char *szName );
|
||||
void RemoveAllAmmo( );
|
||||
int GetAmmoCount( int iAmmoIndex ) const;
|
||||
int GetAmmoCount( char *szName ) const;
|
||||
|
||||
virtual C_BaseCombatWeapon* Weapon_OwnsThisType( const char *pszWeapon, int iSubType = 0 ) const; // True if already owns a weapon of this class
|
||||
virtual C_BaseCombatWeapon *Weapon_GetSlot( int slot ) const;
|
||||
virtual C_BaseCombatWeapon *Weapon_GetPosition( int pos ) const;
|
||||
|
||||
virtual bool Weapon_Switch( C_BaseCombatWeapon *pWeapon, int viewmodelindex = 0 );
|
||||
virtual bool Weapon_CanSwitchTo(C_BaseCombatWeapon *pWeapon);
|
||||
|
||||
// I can't use my current weapon anymore. Switch me to the next best weapon.
|
||||
bool SwitchToNextBestWeapon(C_BaseCombatWeapon *pCurrent);
|
||||
|
||||
virtual C_BaseCombatWeapon *GetActiveWeapon( void ) const;
|
||||
int WeaponCount() const;
|
||||
virtual C_BaseCombatWeapon *GetWeapon( int i ) const;
|
||||
|
||||
// This is a sort of hack back-door only used by physgun!
|
||||
void SetAmmoCount( int iCount, int iAmmoIndex );
|
||||
|
||||
bool HasEverBeenInjured( void ) const;
|
||||
float GetTimeSinceLastInjury( void ) const;
|
||||
RelativeDamagedDirection_t GetLastInjuryRelativeDirection( void ) { return m_nRelativeDirectionOfLastInjury; }
|
||||
|
||||
float GetNextAttack() const { return m_flNextAttack; }
|
||||
void SetNextAttack( float flWait ) { m_flNextAttack = flWait; }
|
||||
|
||||
virtual int BloodColor();
|
||||
|
||||
// Blood color (see BLOOD_COLOR_* macros in baseentity.h)
|
||||
void SetBloodColor( int nBloodColor );
|
||||
|
||||
virtual void DoMuzzleFlash();
|
||||
|
||||
public:
|
||||
|
||||
// BEGIN PREDICTION DATA COMPACTION (these fields are together to allow for faster copying in prediction system)
|
||||
float m_flNextAttack;
|
||||
|
||||
private:
|
||||
bool ComputeLOS( const Vector &vecEyePosition, const Vector &vecTarget ) const;
|
||||
|
||||
public:
|
||||
int m_LastHitGroup;
|
||||
|
||||
private:
|
||||
CNetworkArray( int, m_iAmmo, MAX_AMMO_TYPES );
|
||||
CHandle<C_BaseCombatWeapon> m_hMyWeapons[MAX_WEAPONS];
|
||||
CHandle< C_BaseCombatWeapon > m_hActiveWeapon;
|
||||
float m_flTimeOfLastInjury;
|
||||
RelativeDamagedDirection_t m_nRelativeDirectionOfLastInjury;
|
||||
|
||||
// END PREDICTION DATA COMPACTION
|
||||
|
||||
protected:
|
||||
|
||||
int m_bloodColor; // color of blood particless
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
private:
|
||||
C_BaseCombatCharacter( const C_BaseCombatCharacter & ); // not defined, not accessible
|
||||
|
||||
|
||||
//-----------------------
|
||||
#ifdef INVASION_CLIENT_DLL
|
||||
public:
|
||||
virtual void Release( void );
|
||||
virtual void SetDormant( bool bDormant );
|
||||
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void ClientThink( void );
|
||||
|
||||
// TF2 Powerups
|
||||
virtual bool CanBePoweredUp( void ) { return true; }
|
||||
bool HasPowerup( int iPowerup ) { return ( m_iPowerups & (1 << iPowerup) ) != 0; };
|
||||
virtual void PowerupStart( int iPowerup, bool bInitial );
|
||||
virtual void PowerupEnd( int iPowerup );
|
||||
void RemoveAllPowerups( void );
|
||||
|
||||
// Powerup effects
|
||||
void AddEMPEffect( float flSize );
|
||||
void AddBuffEffect( float flSize );
|
||||
|
||||
C_WeaponCombatShield *GetShield( void );
|
||||
|
||||
public:
|
||||
int m_iPowerups;
|
||||
int m_iPrevPowerups;
|
||||
#endif
|
||||
|
||||
public:
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
};
|
||||
|
||||
inline C_BaseCombatCharacter *ToBaseCombatCharacter( C_BaseEntity *pEntity )
|
||||
{
|
||||
return pEntity ? pEntity->MyCombatCharacterPointer() : NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
inline int C_BaseCombatCharacter::WeaponCount() const
|
||||
{
|
||||
return MAX_WEAPONS;
|
||||
}
|
||||
|
||||
EXTERN_RECV_TABLE(DT_BaseCombatCharacter);
|
||||
|
||||
#endif // C_BASECOMBATCHARACTER_H
|
||||
661
game/client/c_basecombatweapon.cpp
Normal file
661
game/client/c_basecombatweapon.cpp
Normal file
@@ -0,0 +1,661 @@
|
||||
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client side implementation of CBaseCombatWeapon.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "history_resource.h"
|
||||
#include "iclientmode.h"
|
||||
#include "iinput.h"
|
||||
#include "weapon_selection.h"
|
||||
#include "hud_crosshair.h"
|
||||
#include "engine/ivmodelinfo.h"
|
||||
#include "tier0/vprof.h"
|
||||
#include "hltvcamera.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "toolframework/itoolframework.h"
|
||||
#include "toolframework_client.h"
|
||||
#if defined( CSTRIKE15 )
|
||||
#include "c_cs_player.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::SetDormant( bool bDormant )
|
||||
{
|
||||
// If I'm going from active to dormant and I'm carried by another player, holster me.
|
||||
if ( !IsDormant() && bDormant && GetOwner() && !IsCarriedByLocalPlayer() )
|
||||
{
|
||||
Holster( NULL );
|
||||
}
|
||||
|
||||
BaseClass::SetDormant( bDormant );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::NotifyShouldTransmit( ShouldTransmitState_t state )
|
||||
{
|
||||
BaseClass::NotifyShouldTransmit(state);
|
||||
|
||||
if (state == SHOULDTRANSMIT_END)
|
||||
{
|
||||
if (m_iState == WEAPON_IS_ACTIVE)
|
||||
{
|
||||
m_iState = WEAPON_IS_CARRIED_BY_PLAYER;
|
||||
}
|
||||
}
|
||||
else if( state == SHOULDTRANSMIT_START )
|
||||
{
|
||||
// We don't check the value of m_iState because if the weapon is active, we need the state to match reguardless
|
||||
// of what it was.
|
||||
if( GetOwner() && GetOwner()->GetActiveWeapon() == this )
|
||||
{
|
||||
// Restore the Activeness of the weapon if we client-twiddled it off in the first case above.
|
||||
m_iState = WEAPON_IS_ACTIVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: To wrap PORTAL mod specific functionality into one place
|
||||
//-----------------------------------------------------------------------------
|
||||
static inline bool ShouldDrawLocalPlayer( C_BasePlayer *pl )
|
||||
{
|
||||
#if defined( PORTAL )
|
||||
return true;
|
||||
#else
|
||||
Assert( pl );
|
||||
return pl->ShouldDrawLocalPlayer();
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::OnRestore()
|
||||
{
|
||||
BaseClass::OnRestore();
|
||||
|
||||
// if the player is holding this weapon,
|
||||
// mark it as just restored so it won't show as a new pickup
|
||||
if ( C_BasePlayer::IsLocalPlayer( GetOwner() ) )
|
||||
{
|
||||
m_bJustRestored = true;
|
||||
}
|
||||
}
|
||||
|
||||
void C_BaseCombatWeapon::UpdateOnRemove( void )
|
||||
{
|
||||
BaseClass::UpdateOnRemove();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : bnewentity -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
// Must update visibility prior to calling OnDataChanged so that
|
||||
// shadows are dealt with correctly.
|
||||
UpdateVisibility();
|
||||
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
// let the world model know we're updating, in case it wants to as well
|
||||
CBaseWeaponWorldModel *pWeaponWorldModel = GetWeaponWorldModel();
|
||||
if ( pWeaponWorldModel )
|
||||
{
|
||||
pWeaponWorldModel->OnDataChanged( updateType );
|
||||
}
|
||||
|
||||
// If it's being carried by the *local* player, on the first update,
|
||||
// find the registered weapon for this ID
|
||||
|
||||
C_BaseCombatCharacter *pOwner = GetOwner();
|
||||
C_BasePlayer *pPlayer = ToBasePlayer( pOwner );
|
||||
|
||||
#if defined( CSTRIKE15 )
|
||||
C_CSPlayer *pObservedPlayer = GetHudPlayer();
|
||||
// check if weapon was dropped by local player or the player we are observing
|
||||
if ( pObservedPlayer == pPlayer && pObservedPlayer->State_Get() == STATE_ACTIVE )
|
||||
#else
|
||||
// check if weapon is carried by local player
|
||||
bool bIsLocalPlayer = C_BasePlayer::IsLocalPlayer( pPlayer );
|
||||
if ( bIsLocalPlayer )
|
||||
#endif
|
||||
{
|
||||
ACTIVE_SPLITSCREEN_PLAYER_GUARD( C_BasePlayer::GetSplitScreenSlotForPlayer( pPlayer ) );
|
||||
|
||||
// If I was just picked up, or created & immediately carried, add myself to this client's list of weapons
|
||||
if ( m_iState != WEAPON_NOT_CARRIED && m_iOldState == WEAPON_NOT_CARRIED )
|
||||
{
|
||||
// Tell the HUD this weapon's been picked up
|
||||
if ( ShouldDrawPickup() )
|
||||
{
|
||||
CBaseHudWeaponSelection *pHudSelection = GetHudWeaponSelection();
|
||||
if ( pHudSelection )
|
||||
{
|
||||
pHudSelection->OnWeaponPickup( this );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateVisibility();
|
||||
|
||||
m_iOldState = m_iState;
|
||||
|
||||
m_bJustRestored = false;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Is anyone carrying it?
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseCombatWeapon::IsBeingCarried() const
|
||||
{
|
||||
return ( m_hOwner.Get() != NULL );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Is the carrier alive?
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseCombatWeapon::IsCarrierAlive() const
|
||||
{
|
||||
if ( !m_hOwner.Get() )
|
||||
return false;
|
||||
|
||||
return m_hOwner.Get()->GetHealth() > 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Should this object cast shadows?
|
||||
//-----------------------------------------------------------------------------
|
||||
ShadowType_t C_BaseCombatWeapon::ShadowCastType()
|
||||
{
|
||||
if ( IsEffectActive( /*EF_NODRAW |*/ EF_NOSHADOW ) )
|
||||
return SHADOWS_NONE;
|
||||
|
||||
if (!IsBeingCarried())
|
||||
return SHADOWS_RENDER_TO_TEXTURE;
|
||||
|
||||
if (IsCarriedByLocalPlayer())
|
||||
return SHADOWS_NONE;
|
||||
|
||||
return (m_iState != WEAPON_IS_CARRIED_BY_PLAYER) ? SHADOWS_RENDER_TO_TEXTURE : SHADOWS_NONE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This weapon is the active weapon, and it should now draw anything
|
||||
// it wants to. This gets called every frame.
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::Redraw()
|
||||
{
|
||||
if ( GetClientMode()->ShouldDrawCrosshair() )
|
||||
{
|
||||
DrawCrosshair();
|
||||
}
|
||||
|
||||
// ammo drawing has been moved into hud_ammo.cpp
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Draw the weapon's crosshair
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::DrawCrosshair()
|
||||
{
|
||||
#ifndef INFESTED_DLL
|
||||
C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
|
||||
if ( !player )
|
||||
return;
|
||||
|
||||
Color clr = GetHud().m_clrNormal;
|
||||
/*
|
||||
|
||||
// TEST: if the thing under your crosshair is on a different team, light the crosshair with a different color.
|
||||
Vector vShootPos, vShootAngles;
|
||||
GetShootPosition( vShootPos, vShootAngles );
|
||||
|
||||
Vector vForward;
|
||||
AngleVectors( vShootAngles, &vForward );
|
||||
|
||||
|
||||
// Change the color depending on if we're looking at a friend or an enemy.
|
||||
CPartitionFilterListMask filter( PARTITION_ALL_CLIENT_EDICTS );
|
||||
trace_t tr;
|
||||
traceline->TraceLine( vShootPos, vShootPos + vForward * 10000, COLLISION_GROUP_NONE, MASK_SHOT, &tr, true, ~0, &filter );
|
||||
|
||||
if ( tr.index != 0 && tr.index != INVALID_CLIENTENTITY_HANDLE )
|
||||
{
|
||||
C_BaseEntity *pEnt = ClientEntityList().GetBaseEntityFromHandle( tr.index );
|
||||
if ( pEnt )
|
||||
{
|
||||
if ( pEnt->GetTeamNumber() != player->GetTeamNumber() )
|
||||
{
|
||||
g = b = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
CHudCrosshair *crosshair = GET_HUDELEMENT( CHudCrosshair );
|
||||
if ( !crosshair )
|
||||
return;
|
||||
|
||||
// Find out if this weapon's auto-aimed onto a target
|
||||
bool bOnTarget = ( m_iState == WEAPON_IS_ACTIVE ) && player->m_fOnTarget;
|
||||
|
||||
if ( player->GetFOV() >= 90 )
|
||||
{
|
||||
// normal crosshairs
|
||||
if ( bOnTarget && GetWpnData().iconAutoaim )
|
||||
{
|
||||
clr[3] = 255;
|
||||
|
||||
crosshair->SetCrosshair( GetWpnData().iconAutoaim, clr );
|
||||
}
|
||||
else if ( GetWpnData().iconCrosshair )
|
||||
{
|
||||
clr[3] = 255;
|
||||
crosshair->SetCrosshair( GetWpnData().iconCrosshair, clr );
|
||||
}
|
||||
else
|
||||
{
|
||||
crosshair->ResetCrosshair();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Color white( 255, 255, 255, 255 );
|
||||
|
||||
// zoomed crosshairs
|
||||
if (bOnTarget && GetWpnData().iconZoomedAutoaim)
|
||||
crosshair->SetCrosshair(GetWpnData().iconZoomedAutoaim, white);
|
||||
else if ( GetWpnData().iconZoomedCrosshair )
|
||||
crosshair->SetCrosshair( GetWpnData().iconZoomedCrosshair, white );
|
||||
else
|
||||
crosshair->ResetCrosshair();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This weapon is the active weapon, and the viewmodel for it was just drawn.
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::ViewModelDrawn( int nFlags, C_BaseViewModel *pViewModel )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns true if this client's carrying this weapon
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseCombatWeapon::IsCarriedByLocalPlayer( void )
|
||||
{
|
||||
if ( !GetOwner() )
|
||||
return false;
|
||||
|
||||
return ( C_BasePlayer::IsLocalPlayer( GetOwner() ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns true if this weapon is the local client's currently wielded weapon
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseCombatWeapon::IsActiveByLocalPlayer( void )
|
||||
{
|
||||
if ( IsCarriedByLocalPlayer() )
|
||||
{
|
||||
return (m_iState == WEAPON_IS_ACTIVE);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool C_BaseCombatWeapon::GetShootPosition( Vector &vOrigin, QAngle &vAngles )
|
||||
{
|
||||
// Get the entity because the weapon doesn't have the right angles.
|
||||
C_BaseCombatCharacter *pEnt = ToBaseCombatCharacter( GetOwner() );
|
||||
if ( pEnt )
|
||||
{
|
||||
if ( pEnt == C_BasePlayer::GetLocalPlayer() )
|
||||
{
|
||||
vAngles = pEnt->EyeAngles();
|
||||
}
|
||||
else
|
||||
{
|
||||
vAngles = pEnt->GetRenderAngles();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vAngles.Init();
|
||||
}
|
||||
|
||||
C_BasePlayer *player = ToBasePlayer( pEnt );
|
||||
bool bUseViewModel = false;
|
||||
if ( C_BasePlayer::IsLocalPlayer( pEnt ) )
|
||||
{
|
||||
ACTIVE_SPLITSCREEN_PLAYER_GUARD_ENT( pEnt );
|
||||
bUseViewModel = !player->ShouldDrawLocalPlayer();
|
||||
}
|
||||
|
||||
QAngle vDummy;
|
||||
if ( IsActiveByLocalPlayer() && bUseViewModel )
|
||||
{
|
||||
C_BaseViewModel *vm = player ? player->GetViewModel( 0 ) : NULL;
|
||||
if ( vm )
|
||||
{
|
||||
int iAttachment = vm->LookupAttachment( "muzzle" );
|
||||
if ( vm->GetAttachment( iAttachment, vOrigin, vDummy ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Thirdperson
|
||||
int iAttachment = LookupAttachment( "muzzle" );
|
||||
if ( GetAttachment( iAttachment, vOrigin, vDummy ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
vOrigin = GetRenderOrigin();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool C_BaseCombatWeapon::ShouldSuppressForSplitScreenPlayer( int nSlot )
|
||||
{
|
||||
if ( BaseClass::ShouldSuppressForSplitScreenPlayer( nSlot ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
C_BaseCombatCharacter *pOwner = GetOwner();
|
||||
|
||||
// If the owner of this weapon is not allowed to draw in this split screen slot, then don't draw the weapon either.
|
||||
if ( pOwner && pOwner->ShouldSuppressForSplitScreenPlayer( nSlot ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer( nSlot );
|
||||
|
||||
// Carried by local player?
|
||||
// Only draw the weapon if we're in some kind of 3rd person mode because the viewmodel will do that otherwise.
|
||||
if ( pOwner == pLocalPlayer && !pLocalPlayer->ShouldDrawLocalPlayer() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseCombatWeapon::ShouldDraw( void )
|
||||
{
|
||||
|
||||
if ( IsEffectActive( EF_NODRAW ) )
|
||||
return false;
|
||||
|
||||
// weapon has no owner, always draw it
|
||||
if ( !GetOwner() && !IsViewModel() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CBaseWeaponWorldModel *pWeaponWorldModel = GetWeaponWorldModel();
|
||||
if ( pWeaponWorldModel )
|
||||
{
|
||||
return false; // the weapon world model will render in our place if it exists
|
||||
}
|
||||
else
|
||||
{
|
||||
// render only if equipped. The holstered model will render for weapons that aren't equipped
|
||||
return ( GetOwner() && GetOwner()->GetActiveWeapon() == this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return true if a weapon-pickup icon should be displayed when this weapon is received
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseCombatWeapon::ShouldDrawPickup( void )
|
||||
{
|
||||
if ( GetWeaponFlags() & ITEM_FLAG_NOITEMPICKUP )
|
||||
return false;
|
||||
|
||||
if ( m_bJustRestored )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool C_BaseCombatWeapon::IsFirstPersonSpectated( void )
|
||||
{
|
||||
// check if local player chases owner of this weapon in first person
|
||||
C_BasePlayer *localplayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( localplayer && localplayer->IsObserver() && GetOwner() )
|
||||
{
|
||||
// don't draw weapon if chasing this guy as spectator
|
||||
// we don't check that in ShouldDraw() since this may change
|
||||
// without notification
|
||||
if ( localplayer->GetObserverMode() == OBS_MODE_IN_EYE &&
|
||||
localplayer->GetObserverTarget() == GetOwner() &&
|
||||
localplayer->GetObserverInterpState() != C_BasePlayer::OBSERVER_INTERP_TRAVELING )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Hooks into the fast path render system
|
||||
//----------------------------------------------------------------------------
|
||||
IClientModelRenderable* C_BaseCombatWeapon::GetClientModelRenderable()
|
||||
{
|
||||
if ( !m_bReadyToDraw )
|
||||
return 0;
|
||||
|
||||
if( IsFirstPersonSpectated() )
|
||||
return NULL;
|
||||
|
||||
VerifyAndSetContextSensitiveWeaponModel();
|
||||
|
||||
return BaseClass::GetClientModelRenderable();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Render the weapon. Draw the Viewmodel if the weapon's being carried
|
||||
// by this player, otherwise draw the worldmodel.
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_BaseCombatWeapon::DrawModel( int flags, const RenderableInstance_t &instance )
|
||||
{
|
||||
VPROF_BUDGET( "C_BaseCombatWeapon::DrawModel", VPROF_BUDGETGROUP_MODEL_RENDERING );
|
||||
if ( !m_bReadyToDraw )
|
||||
return 0;
|
||||
|
||||
if ( !IsVisible() )
|
||||
return 0;
|
||||
|
||||
if( IsFirstPersonSpectated() )
|
||||
return 0;
|
||||
|
||||
return BaseClass::DrawModel( flags, instance );
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
ConVar stickers_enabled_thirdperson( "stickers_enabled_thirdperson", "1", FCVAR_DEVELOPMENTONLY, "Enable work-in-progress stickers on worldmodels." );
|
||||
|
||||
ConVar stickers_debug_thirdperson_constant( "stickers_debug_thirdperson_constant", "0", FCVAR_DEVELOPMENTONLY, "Continually apply stickers on worldmodels. SLOW" );
|
||||
ConVar stickers_debug_thirdperson_ray( "stickers_debug_thirdperson_ray", "0", FCVAR_DEVELOPMENTONLY, "Show worldmodel sticker projection position and direction." );
|
||||
ConVar stickers_debug_thirdperson_ray_duration( "stickers_debug_thirdperson_ray_duration", "0.1", FCVAR_DEVELOPMENTONLY, "Duration to show sticker projection lines." );
|
||||
ConVar stickers_debug_thirdperson_size( "stickers_debug_thirdperson_size", "0", FCVAR_DEVELOPMENTONLY, "Override worldmodel sticker size." );
|
||||
|
||||
extern ConVar stickers_debug_randomize;
|
||||
#endif
|
||||
|
||||
void C_BaseCombatWeapon::ApplyThirdPersonStickers( C_BaseAnimating *pWeaponModelTargetOverride )
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if (stickers_enabled_thirdperson.GetBool() == 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if ( !IsAbsQueriesValid() )
|
||||
return;
|
||||
|
||||
CEconItemView *pItem = GetEconItemView();
|
||||
if (!pItem)
|
||||
return;
|
||||
|
||||
if ( pItem->GetNumSupportedStickerSlots() == 0 )
|
||||
return;
|
||||
|
||||
C_BaseAnimating *pTargetModel = pWeaponModelTargetOverride ? pWeaponModelTargetOverride : this;
|
||||
|
||||
if ( !pTargetModel->ShouldDraw() )
|
||||
return;
|
||||
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
|
||||
pTargetModel->CreateModelInstance();
|
||||
if ( pTargetModel->GetModelInstance() != MODEL_INSTANCE_INVALID )
|
||||
{
|
||||
if ( modelrender->ModelHasDecals( pTargetModel->GetModelInstance() ) &&
|
||||
#ifdef _DEBUG
|
||||
!stickers_debug_thirdperson_constant.GetBool() &&
|
||||
#endif
|
||||
pItem->ItemHasAnyStickersApplied() )
|
||||
{
|
||||
return; //decals are already applied
|
||||
}
|
||||
modelrender->RemoveAllDecals( pTargetModel->GetModelInstance() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return; //no model instance
|
||||
}
|
||||
|
||||
matrix3x4_t weaponBoneTransform;
|
||||
|
||||
const char* const szStickerBoneLookupTable[] = {
|
||||
"sticker_a",
|
||||
"sticker_b",
|
||||
"sticker_c",
|
||||
"sticker_d",
|
||||
"sticker_e"
|
||||
};
|
||||
|
||||
for (int i=0; i<pItem->GetNumSupportedStickerSlots(); i++ )
|
||||
{
|
||||
IMaterial *pStickerMaterialThirdPerson = pItem->GetStickerIMaterialBySlotIndex(i, true);
|
||||
|
||||
if ( !pStickerMaterialThirdPerson )
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if ( stickers_debug_randomize.GetBool() )
|
||||
{
|
||||
pItem->GenerateStickerMaterials();
|
||||
pStickerMaterialThirdPerson = pItem->GetStickerIMaterialBySlotIndex(i, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
continue; //sticker material is not valid
|
||||
#endif
|
||||
}
|
||||
|
||||
//if the weapon model has world model sticker projection points, use those
|
||||
//otherwise use schema values
|
||||
|
||||
Vector vecWorldRayOrigin, vecWorldRayDirection;
|
||||
|
||||
bool bWeaponProvidedStickerAttachments = false;
|
||||
|
||||
int nStickerAttachmentBoneIndex = pTargetModel->LookupBone( szStickerBoneLookupTable[i] );
|
||||
if ( nStickerAttachmentBoneIndex != -1 )
|
||||
{
|
||||
pTargetModel->GetBoneTransform( nStickerAttachmentBoneIndex, weaponBoneTransform );
|
||||
MatrixPosition( weaponBoneTransform, vecWorldRayOrigin );
|
||||
Vector a,b;
|
||||
MatrixVectors( weaponBoneTransform, &vecWorldRayDirection, &a, &b );
|
||||
bWeaponProvidedStickerAttachments = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
int nBIndex = pTargetModel->LookupBone( pItem->GetStickerWorldModelBoneParentNameBySlotIndex(i) );
|
||||
if ( nBIndex == -1 )
|
||||
continue; //couldn't find the parent bone this sticker slot wanted
|
||||
|
||||
pTargetModel->GetBoneTransform( nBIndex, weaponBoneTransform );
|
||||
|
||||
Ray_t stickerRayLocal;
|
||||
stickerRayLocal.Init( pItem->GetStickerSlotWorldProjectionStartBySlotIndex( i ),
|
||||
pItem->GetStickerSlotWorldProjectionEndBySlotIndex( i ) );
|
||||
|
||||
VectorTransform( stickerRayLocal.m_Start, weaponBoneTransform, vecWorldRayOrigin );
|
||||
VectorRotate( stickerRayLocal.m_Delta, weaponBoneTransform, vecWorldRayDirection );
|
||||
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
if ( stickers_debug_thirdperson_ray.GetBool() )
|
||||
{
|
||||
debugoverlay->AddBoxOverlay( vecWorldRayOrigin, Vector(-0.25,-0.25,-0.25), Vector(0.5,0.5,0.5), QAngle(0,0,0), 255, 0, 0, 180, stickers_debug_thirdperson_ray_duration.GetFloat() );
|
||||
debugoverlay->AddLineOverlay( vecWorldRayOrigin, vecWorldRayOrigin + vecWorldRayDirection, 0,255,0, true, stickers_debug_thirdperson_ray_duration.GetFloat() );
|
||||
}
|
||||
#endif
|
||||
|
||||
Ray_t stickerRayWorld;
|
||||
stickerRayWorld.Init( vecWorldRayOrigin, vecWorldRayOrigin + (3*vecWorldRayDirection) );
|
||||
|
||||
VMatrix vmatrix_weaponBoneTransform( weaponBoneTransform );
|
||||
|
||||
Vector vecStickerUp = vmatrix_weaponBoneTransform.GetLeft();
|
||||
if ( bWeaponProvidedStickerAttachments )
|
||||
{
|
||||
//content defined sticker attachments are z-up
|
||||
vecStickerUp = -vmatrix_weaponBoneTransform.GetUp();
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
float flStickerSize = (stickers_debug_thirdperson_size.GetFloat() == 0) ? stickers_debug_thirdperson_size.GetFloat() : 1.2f;
|
||||
pTargetModel->GetBaseEntity()->AddStudioMaterialDecal( stickerRayWorld, pStickerMaterialThirdPerson, flStickerSize, vecStickerUp );
|
||||
#else
|
||||
pTargetModel->GetBaseEntity()->AddStudioMaterialDecal( stickerRayWorld, pStickerMaterialThirdPerson, 1.2f, vecStickerUp );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//Msg( "Applied stickers to: %s\n", this->GetName() );
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// tool recording
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatWeapon::GetToolRecordingState( KeyValues *msg )
|
||||
{
|
||||
if ( !ToolsEnabled() )
|
||||
return;
|
||||
|
||||
Assert(false);
|
||||
}
|
||||
22
game/client/c_basecombatweapon.h
Normal file
22
game/client/c_basecombatweapon.h
Normal file
@@ -0,0 +1,22 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's CBaseCombatWeapon entity
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef C_BASECOMBATWEAPON_H
|
||||
#define C_BASECOMBATWEAPON_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "basecombatweapon_shared.h"
|
||||
#include "weapons_resource.h"
|
||||
|
||||
class CViewSetup;
|
||||
class C_BaseViewModel;
|
||||
|
||||
#endif // C_BASECOMBATWEAPON
|
||||
28
game/client/c_basedoor.cpp
Normal file
28
game/client/c_basedoor.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_basedoor.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#ifdef CBaseDoor
|
||||
#undef CBaseDoor
|
||||
#endif
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_BaseDoor, DT_BaseDoor, CBaseDoor)
|
||||
RecvPropFloat(RECVINFO(m_flWaveHeight)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
C_BaseDoor::C_BaseDoor( void )
|
||||
{
|
||||
m_flWaveHeight = 0.0f;
|
||||
}
|
||||
|
||||
C_BaseDoor::~C_BaseDoor( void )
|
||||
{
|
||||
}
|
||||
33
game/client/c_basedoor.h
Normal file
33
game/client/c_basedoor.h
Normal file
@@ -0,0 +1,33 @@
|
||||
//========= Copyright Š 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#if !defined( C_BASEDOOR_H )
|
||||
#define C_BASEDOOR_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_baseentity.h"
|
||||
#include "c_basetoggle.h"
|
||||
|
||||
#if defined( CLIENT_DLL )
|
||||
#define CBaseDoor C_BaseDoor
|
||||
#endif
|
||||
|
||||
class C_BaseDoor : public C_BaseToggle
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BaseDoor, C_BaseToggle );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_BaseDoor( void );
|
||||
~C_BaseDoor( void );
|
||||
|
||||
public:
|
||||
float m_flWaveHeight;
|
||||
};
|
||||
|
||||
#endif // C_BASEDOOR_H
|
||||
7223
game/client/c_baseentity.cpp
Normal file
7223
game/client/c_baseentity.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2795
game/client/c_baseentity.h
Normal file
2795
game/client/c_baseentity.h
Normal file
File diff suppressed because it is too large
Load Diff
2200
game/client/c_baseflex.cpp
Normal file
2200
game/client/c_baseflex.cpp
Normal file
File diff suppressed because it is too large
Load Diff
308
game/client/c_baseflex.h
Normal file
308
game/client/c_baseflex.h
Normal file
@@ -0,0 +1,308 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
// Client-side CBasePlayer
|
||||
|
||||
#ifndef C_STUDIOFLEX_H
|
||||
#define C_STUDIOFLEX_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "c_baseanimatingoverlay.h"
|
||||
#include "sceneentity_shared.h"
|
||||
|
||||
#include "utlvector.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Item in list of loaded scene files
|
||||
//-----------------------------------------------------------------------------
|
||||
class CFlexSceneFile
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
MAX_FLEX_FILENAME = 128,
|
||||
};
|
||||
|
||||
char filename[ MAX_FLEX_FILENAME ];
|
||||
void *buffer;
|
||||
};
|
||||
|
||||
// For phoneme emphasis track
|
||||
struct Emphasized_Phoneme;
|
||||
class CSentence;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_BaseFlex : public C_BaseAnimatingOverlay
|
||||
{
|
||||
DECLARE_CLASS( C_BaseFlex, C_BaseAnimatingOverlay );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
DECLARE_INTERPOLATION();
|
||||
|
||||
C_BaseFlex();
|
||||
virtual ~C_BaseFlex();
|
||||
|
||||
virtual void Spawn();
|
||||
|
||||
virtual IClientModelRenderable* GetClientModelRenderable();
|
||||
|
||||
virtual void InitPhonemeMappings();
|
||||
|
||||
void SetupMappings( char const *pchFileRoot );
|
||||
|
||||
virtual CStudioHdr *OnNewModel( void );
|
||||
|
||||
virtual void StandardBlendingRules( CStudioHdr *hdr, BoneVector pos[], BoneQuaternionAligned q[], float currentTime, int boneMask );
|
||||
|
||||
virtual void OnThreadedDrawSetup();
|
||||
|
||||
// model specific
|
||||
virtual void BuildTransformations( CStudioHdr *pStudioHdr, BoneVector *pos, BoneQuaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed );
|
||||
virtual void SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights );
|
||||
virtual bool UsesFlexDelayedWeights();
|
||||
|
||||
virtual bool GetSoundSpatialization( SpatializationInfo_t& info );
|
||||
|
||||
virtual void GetToolRecordingState( KeyValues *msg );
|
||||
|
||||
// Called at the lowest level to actually apply a flex animation
|
||||
void AddFlexAnimation( CSceneEventInfo *info );
|
||||
|
||||
void SetFlexWeight( LocalFlexController_t index, float value );
|
||||
float GetFlexWeight( LocalFlexController_t index );
|
||||
|
||||
// Look up flex controller index by global name
|
||||
LocalFlexController_t FindFlexController( const char *szName );
|
||||
|
||||
public:
|
||||
Vector m_viewtarget;
|
||||
CInterpolatedVar< Vector > m_iv_viewtarget;
|
||||
// indexed by model local flexcontroller
|
||||
float m_flexWeight[MAXSTUDIOFLEXCTRL];
|
||||
CInterpolatedVarArray< float, MAXSTUDIOFLEXCTRL > m_iv_flexWeight;
|
||||
|
||||
int m_blinktoggle;
|
||||
|
||||
static int AddGlobalFlexController( char *szName );
|
||||
static char const *GetGlobalFlexControllerName( int idx );
|
||||
|
||||
// bah, this should be unified with all prev/current stuff.
|
||||
|
||||
public:
|
||||
|
||||
// Keep track of what scenes are being played
|
||||
void StartChoreoScene( CChoreoScene *scene );
|
||||
void RemoveChoreoScene( CChoreoScene *scene );
|
||||
|
||||
// Start the specifics of an scene event
|
||||
virtual bool StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, C_BaseEntity *pTarget );
|
||||
|
||||
virtual bool ProcessSequenceSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event );
|
||||
|
||||
// Remove all playing events
|
||||
void ClearSceneEvents( CChoreoScene *scene, bool canceled );
|
||||
|
||||
// Stop specifics of event
|
||||
virtual bool ClearSceneEvent( CSceneEventInfo *info, bool fastKill, bool canceled );
|
||||
|
||||
// Add the event to the queue for this actor
|
||||
void AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, C_BaseEntity *pTarget = NULL, bool bClientSide = false, C_SceneEntity *pSceneEntity = NULL );
|
||||
|
||||
// Remove the event from the queue for this actor
|
||||
void RemoveSceneEvent( CChoreoScene *scene, CChoreoEvent *event, bool fastKill );
|
||||
|
||||
// Checks to see if the event should be considered "completed"
|
||||
bool CheckSceneEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event );
|
||||
|
||||
// Checks to see if a event should be considered "completed"
|
||||
virtual bool CheckSceneEventCompletion( CSceneEventInfo *info, float currenttime, CChoreoScene *scene, CChoreoEvent *event );
|
||||
|
||||
int FlexControllerLocalToGlobal( const flexsettinghdr_t *pSettinghdr, int key );
|
||||
void EnsureTranslations( const flexsettinghdr_t *pSettinghdr );
|
||||
|
||||
// For handling scene files
|
||||
const void *FindSceneFile( const char *filename );
|
||||
|
||||
static void InvalidateFlexCaches();
|
||||
bool IsFlexCacheValid() const;
|
||||
|
||||
private:
|
||||
Vector SetViewTarget( CStudioHdr *pStudioHdr, const float *pGlobalFlexWeight );
|
||||
void RunFlexRules( CStudioHdr *pStudioHdr, const float *pGlobalFlexWeight, float *dest );
|
||||
|
||||
// Manipulation of events for the object
|
||||
// Should be called by think function to process all scene events
|
||||
// The default implementation resets m_flexWeight array and calls
|
||||
// AddSceneEvents
|
||||
void ProcessSceneEvents( bool bFlexEvents, float *pGlobalFlexWeight );
|
||||
|
||||
// Assumes m_flexWeight array has been set up, this adds the actual currently playing
|
||||
// expressions to the flex weights and adds other scene events as needed
|
||||
bool ProcessSceneEvent( float *pGlobalFlexWeight, bool bFlexEvents, CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event );
|
||||
|
||||
bool RequestStartSequenceSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget );
|
||||
|
||||
bool ProcessFlexAnimationSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event );
|
||||
bool ProcessFlexSettingSceneEvent( float *pGlobalFlexWeight, CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event );
|
||||
void AddFlexSetting( float *pGlobalFlexWeight, const char *expr, float scale,
|
||||
const flexsettinghdr_t *pSettinghdr, bool newexpression );
|
||||
|
||||
// Array of active SceneEvents, in order oldest to newest
|
||||
CUtlVector < CSceneEventInfo > m_SceneEvents;
|
||||
CUtlVector < CChoreoScene * > m_ActiveChoreoScenes;
|
||||
|
||||
bool HasSceneEvents() const;
|
||||
|
||||
private:
|
||||
// Mapping for each loaded scene file used by this actor
|
||||
struct FS_LocalToGlobal_t
|
||||
{
|
||||
explicit FS_LocalToGlobal_t() :
|
||||
m_Key( 0 ),
|
||||
m_nCount( 0 ),
|
||||
m_Mapping( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
explicit FS_LocalToGlobal_t( const flexsettinghdr_t *key ) :
|
||||
m_Key( key ),
|
||||
m_nCount( 0 ),
|
||||
m_Mapping( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
void SetCount( int count )
|
||||
{
|
||||
Assert( !m_Mapping );
|
||||
Assert( count > 0 );
|
||||
m_nCount = count;
|
||||
m_Mapping = new int[ m_nCount ];
|
||||
Q_memset( m_Mapping, 0, m_nCount * sizeof( int ) );
|
||||
}
|
||||
|
||||
FS_LocalToGlobal_t( const FS_LocalToGlobal_t& src )
|
||||
{
|
||||
m_Key = src.m_Key;
|
||||
delete m_Mapping;
|
||||
m_Mapping = new int[ src.m_nCount ];
|
||||
Q_memcpy( m_Mapping, src.m_Mapping, src.m_nCount * sizeof( int ) );
|
||||
|
||||
m_nCount = src.m_nCount;
|
||||
}
|
||||
|
||||
~FS_LocalToGlobal_t()
|
||||
{
|
||||
delete m_Mapping;
|
||||
m_nCount = 0;
|
||||
m_Mapping = 0;
|
||||
}
|
||||
|
||||
const flexsettinghdr_t *m_Key;
|
||||
int m_nCount;
|
||||
int *m_Mapping;
|
||||
};
|
||||
|
||||
static bool FlexSettingLessFunc( const FS_LocalToGlobal_t& lhs, const FS_LocalToGlobal_t& rhs );
|
||||
|
||||
CUtlRBTree< FS_LocalToGlobal_t, unsigned short > m_LocalToGlobal;
|
||||
|
||||
float m_blinktime;
|
||||
int m_prevblinktoggle;
|
||||
|
||||
int m_iBlink;
|
||||
LocalFlexController_t m_iEyeUpdown;
|
||||
LocalFlexController_t m_iEyeRightleft;
|
||||
int m_iMouthAttachment;
|
||||
|
||||
float *m_flFlexDelayedWeight;
|
||||
|
||||
int m_iMostRecentFlexCounter;
|
||||
Vector m_CachedViewTarget;
|
||||
CUtlVector< float > m_CachedFlexWeights;
|
||||
CUtlVector< float > m_CachedDelayedFlexWeights;
|
||||
|
||||
// shared flex controllers
|
||||
static int g_numflexcontrollers;
|
||||
static char *g_flexcontroller[MAXSTUDIOFLEXCTRL*4]; // room for global set of flexcontrollers
|
||||
static float s_pGlobalFlexWeight[MAXSTUDIOFLEXCTRL*4];
|
||||
|
||||
protected:
|
||||
|
||||
enum
|
||||
{
|
||||
PHONEME_CLASS_WEAK = 0,
|
||||
PHONEME_CLASS_NORMAL,
|
||||
PHONEME_CLASS_STRONG,
|
||||
|
||||
NUM_PHONEME_CLASSES
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
struct Emphasized_Phoneme
|
||||
{
|
||||
// Global fields, setup at start
|
||||
char classname[ 64 ];
|
||||
bool required;
|
||||
// Global fields setup first time tracks played
|
||||
bool basechecked;
|
||||
const flexsettinghdr_t *base;
|
||||
const flexsetting_t *exp;
|
||||
|
||||
// Local fields, processed for each sentence
|
||||
bool valid;
|
||||
float amount;
|
||||
};
|
||||
|
||||
Emphasized_Phoneme m_PhonemeClasses[ NUM_PHONEME_CLASSES ];
|
||||
|
||||
private:
|
||||
|
||||
C_BaseFlex( const C_BaseFlex & ); // not defined, not accessible
|
||||
|
||||
const flexsetting_t *FindNamedSetting( const flexsettinghdr_t *pSettinghdr, const char *expr );
|
||||
|
||||
void ProcessVisemes( Emphasized_Phoneme *classes, float *pGlobalFlexWeight );
|
||||
void AddVisemesForSentence( float *pGlobalFlexWeight, Emphasized_Phoneme *classes, float emphasis_intensity, CSentence *sentence, float t, float dt, bool juststarted );
|
||||
void AddViseme( float *pGlobalFlexWeight, Emphasized_Phoneme *classes, float emphasis_intensity, int phoneme, float scale, bool newexpression );
|
||||
bool SetupEmphasisBlend( Emphasized_Phoneme *classes, int phoneme );
|
||||
void ComputeBlendedSetting( Emphasized_Phoneme *classes, float emphasis_intensity );
|
||||
|
||||
#ifdef HL2_CLIENT_DLL
|
||||
public:
|
||||
|
||||
Vector m_vecLean;
|
||||
CInterpolatedVar< Vector > m_iv_vecLean;
|
||||
Vector m_vecShift;
|
||||
CInterpolatedVar< Vector > m_iv_vecShift;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Do we have active expressions?
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool C_BaseFlex::HasSceneEvents() const
|
||||
{
|
||||
return m_SceneEvents.Count() != 0;
|
||||
}
|
||||
|
||||
|
||||
EXTERN_RECV_TABLE(DT_BaseFlex);
|
||||
|
||||
float *GetVisemeWeights( int phoneme );
|
||||
|
||||
#endif // C_STUDIOFLEX_H
|
||||
|
||||
|
||||
|
||||
|
||||
3953
game/client/c_baselesson.cpp
Normal file
3953
game/client/c_baselesson.cpp
Normal file
File diff suppressed because it is too large
Load Diff
462
game/client/c_baselesson.h
Normal file
462
game/client/c_baselesson.h
Normal file
@@ -0,0 +1,462 @@
|
||||
//========= Copyright © 1996-2008, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client handler for instruction players how to play
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef _C_BASELESSON_H_
|
||||
#define _C_BASELESSON_H_
|
||||
|
||||
|
||||
#include "GameEventListener.h"
|
||||
#include "hud_locator_target.h"
|
||||
|
||||
|
||||
#define DECLARE_LESSON( _lessonClassName, _baseLessonClassName ) \
|
||||
typedef _baseLessonClassName BaseClass;\
|
||||
typedef _lessonClassName ThisClass;\
|
||||
_lessonClassName( const char *pchName, bool bIsDefaultHolder, bool bIsOpenOpportunity, int nSplitScreenSlot )\
|
||||
: _baseLessonClassName( pchName, bIsDefaultHolder, bIsOpenOpportunity, nSplitScreenSlot )\
|
||||
{\
|
||||
Init();\
|
||||
}
|
||||
|
||||
|
||||
enum LessonInstanceType
|
||||
{
|
||||
LESSON_INSTANCE_MULTIPLE,
|
||||
LESSON_INSTANCE_SINGLE_OPEN,
|
||||
LESSON_INSTANCE_FIXED_REPLACE,
|
||||
LESSON_INSTANCE_SINGLE_ACTIVE,
|
||||
|
||||
LESSON_INSTANCE_TYPE_TOTAL
|
||||
};
|
||||
|
||||
|
||||
// This is used to solve a problem where bots can take the place of a player, where on or the other don't have valid entities on the client at the same time
|
||||
#define MAX_DELAYED_PLAYER_SWAPS 8
|
||||
|
||||
struct delayed_player_swap_t
|
||||
{
|
||||
CHandle<C_BaseEntity> *phHandleToChange;
|
||||
int iNewUserID;
|
||||
|
||||
delayed_player_swap_t( void )
|
||||
{
|
||||
phHandleToChange = NULL;
|
||||
iNewUserID = -1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
abstract_class CBaseLesson : public CGameEventListener
|
||||
{
|
||||
public:
|
||||
|
||||
CBaseLesson( const char *pchName, bool bIsDefaultHolder, bool bIsOpenOpportunity, int nSplitScreenSlot );
|
||||
virtual ~CBaseLesson( void );
|
||||
|
||||
void AddPrerequisite( const char *pchLessonName );
|
||||
|
||||
const CGameInstructorSymbol& GetNameSymbol( void ) const { return m_stringName; }
|
||||
const char * GetName( void ) const { return m_stringName.String(); }
|
||||
int GetPriority( void ) const { return m_iPriority; }
|
||||
const char * GetCloseReason( void ) const { return m_stringCloseReason.String(); }
|
||||
void SetCloseReason( const char *pchReason ) { m_stringCloseReason = pchReason; }
|
||||
|
||||
CBaseLesson* GetRoot( void ) const { return m_pRoot; }
|
||||
void SetRoot( CBaseLesson *pRoot );
|
||||
const CUtlVector < CBaseLesson * >* GetChildren( void ) const { return &m_OpenOpportunities; }
|
||||
|
||||
float GetInitTime( void ) { return m_fInitTime; }
|
||||
void SetStartTime( void ) { m_fStartTime = gpGlobals->curtime; }
|
||||
void ResetStartTime( void ) { m_fStartTime = 0.0f; m_bHasPlayedSound = false; }
|
||||
|
||||
bool ShouldShowSpew( void );
|
||||
bool NoPriority( void ) const;
|
||||
bool IsDefaultHolder( void ) const { return m_bIsDefaultHolder; }
|
||||
bool IsOpenOpportunity( void ) const { return m_bIsOpenOpportunity; }
|
||||
bool IsLocked( void ) const;
|
||||
bool CanOpenWhenDead( void ) const { return m_bCanOpenWhenDead; }
|
||||
bool CanOpenOnceLearned( void ) const { return !m_bOnceLearnedNeverOpen; }
|
||||
bool IsUsableInMidair( void ) const { return m_bUsableInMidair; }
|
||||
bool IsInstructing( void ) const { return ( m_fStartTime > 0.0f ); }
|
||||
bool IsLearned( void ) const;
|
||||
bool PrerequisitesHaveBeenMet( void ) const;
|
||||
bool IsTimedOut( void );
|
||||
|
||||
int InstanceType( void ) const { return m_iInstanceType; }
|
||||
const CGameInstructorSymbol& GetReplaceKeySymbol( void ) const { return m_stringReplaceKey; }
|
||||
const char* GetReplaceKey( void ) const { return m_stringReplaceKey.String(); }
|
||||
int GetFixedInstancesMax( void ) const { return m_iFixedInstancesMax; }
|
||||
bool ShouldReplaceOnlyWhenStopped( void ) const { return m_bReplaceOnlyWhenStopped; }
|
||||
void SetInstanceActive( bool bInstanceActive ) { m_bInstanceActive = bInstanceActive; }
|
||||
bool IsInstanceActive( void ) const { return m_bInstanceActive; }
|
||||
|
||||
void ResetDisplaysAndSuccesses( void );
|
||||
bool IncDisplayCount( void );
|
||||
bool IncSuccessCount( void );
|
||||
void SetDisplayCount( int iDisplayCount ) { m_iDisplayCount = iDisplayCount; }
|
||||
void SetSuccessCount( int iSuccessCount ) { m_iSuccessCount = iSuccessCount; }
|
||||
int GetDisplayCount( void ) const { return m_iDisplayCount; }
|
||||
int GetSuccessCount( void ) const { return m_iSuccessCount; }
|
||||
int GetDisplayLimit( void ) const { return m_iDisplayLimit; }
|
||||
int GetSuccessLimit( void ) const { return m_iSuccessLimit; }
|
||||
|
||||
void Init( void ); // NOT virtual, each constructor calls their own
|
||||
virtual void InitPrerequisites( void ) {};
|
||||
virtual void Start( void ) = 0;
|
||||
virtual void Stop( void ) = 0;
|
||||
virtual void OnOpen( void ) {};
|
||||
virtual void Update( void ) {};
|
||||
virtual void UpdateInactive( void ) {};
|
||||
|
||||
virtual bool ShouldDisplay( void ) const { return true; }
|
||||
virtual bool IsVisible( void ) const { return true; }
|
||||
virtual bool WasDisplayed( void ) const { return m_bWasDisplayed ? true : false; }
|
||||
virtual void SwapOutPlayers( int iOldUserID, int iNewUserID ) {}
|
||||
virtual void TakePlaceOf( CBaseLesson *pLesson );
|
||||
|
||||
int GetSplitScreenSlot() const { return m_nSplitScreenSlot; }
|
||||
|
||||
const char *GetGroup() { return m_szLessonGroup.String(); }
|
||||
void SetEnabled( bool bEnabled ) { m_bDisabled = !bEnabled; }
|
||||
|
||||
protected:
|
||||
|
||||
void MarkSucceeded( void );
|
||||
void CloseOpportunity( const char *pchReason );
|
||||
bool DoDelayedPlayerSwaps( void ) const;
|
||||
|
||||
private:
|
||||
|
||||
CBaseLesson *m_pRoot;
|
||||
CUtlVector < CBaseLesson * > m_OpenOpportunities;
|
||||
CUtlVector < const CBaseLesson * > m_Prerequisites;
|
||||
|
||||
CGameInstructorSymbol m_stringCloseReason;
|
||||
|
||||
protected:
|
||||
|
||||
CGameInstructorSymbol m_stringName;
|
||||
|
||||
private:
|
||||
|
||||
bool m_bInstanceActive : 1;
|
||||
bool m_bSuccessCounted : 1;
|
||||
bool m_bIsDefaultHolder : 1;
|
||||
bool m_bIsOpenOpportunity : 1;
|
||||
|
||||
protected:
|
||||
|
||||
LessonInstanceType m_iInstanceType;
|
||||
|
||||
int m_iPriority;
|
||||
CGameInstructorSymbol m_stringReplaceKey;
|
||||
int m_iFixedInstancesMax;
|
||||
bool m_bReplaceOnlyWhenStopped;
|
||||
int m_iTeam;
|
||||
bool m_bOnlyKeyboard;
|
||||
bool m_bOnlyGamepad;
|
||||
bool m_bNoSplitscreen;
|
||||
|
||||
int m_iDisplayLimit;
|
||||
int m_iDisplayCount;
|
||||
bool m_bWasDisplayed;
|
||||
int m_iSuccessLimit;
|
||||
int m_iSuccessCount;
|
||||
int m_nSplitScreenSlot;
|
||||
|
||||
float m_fLockDuration;
|
||||
float m_fTimeout;
|
||||
float m_fInitTime;
|
||||
float m_fStartTime;
|
||||
float m_fLockTime;
|
||||
float m_fUpdateInterval;
|
||||
bool m_bHasPlayedSound;
|
||||
|
||||
CGameInstructorSymbol m_szStartSound;
|
||||
CGameInstructorSymbol m_szLessonGroup;
|
||||
|
||||
bool m_bCanOpenWhenDead;
|
||||
bool m_bBumpWithTimeoutWhenLearned;
|
||||
bool m_bOnceLearnedNeverOpen;
|
||||
bool m_bCanTimeoutWhileInactive;
|
||||
bool m_bDisabled;
|
||||
bool m_bUsableInMidair;
|
||||
|
||||
// Right now we can only queue up 4 swaps...
|
||||
// this number can be increased if more entity handle scripted variables are added
|
||||
mutable delayed_player_swap_t m_pDelayedPlayerSwap[ MAX_DELAYED_PLAYER_SWAPS ];
|
||||
mutable int m_iNumDelayedPlayerSwaps;
|
||||
|
||||
public:
|
||||
|
||||
// Colors for console spew in verbose mode
|
||||
static Color m_rgbaVerboseHeader;
|
||||
static Color m_rgbaVerbosePlain;
|
||||
static Color m_rgbaVerboseName;
|
||||
static Color m_rgbaVerboseOpen;
|
||||
static Color m_rgbaVerboseClose;
|
||||
static Color m_rgbaVerboseSuccess;
|
||||
static Color m_rgbaVerboseUpdate;
|
||||
};
|
||||
|
||||
|
||||
class CTextLesson : public CBaseLesson
|
||||
{
|
||||
public:
|
||||
DECLARE_LESSON( CTextLesson, CBaseLesson );
|
||||
|
||||
void Init( void ); // NOT virtual, each constructor calls their own
|
||||
virtual void Start( void );
|
||||
virtual void Stop( void );
|
||||
|
||||
protected:
|
||||
|
||||
CGameInstructorSymbol m_szDisplayText;
|
||||
CGameInstructorSymbol m_szDisplayParamText;
|
||||
CGameInstructorSymbol m_szBinding;
|
||||
CGameInstructorSymbol m_szGamepadBinding;
|
||||
};
|
||||
|
||||
|
||||
class CIconLesson : public CTextLesson
|
||||
{
|
||||
public:
|
||||
DECLARE_LESSON( CIconLesson, CTextLesson );
|
||||
|
||||
void Init( void ); // NOT virtual, each constructor calls their own
|
||||
virtual void Start( void );
|
||||
virtual void Stop( void );
|
||||
virtual void Update( void );
|
||||
virtual void UpdateInactive( void );
|
||||
|
||||
virtual bool ShouldDisplay( void ) const;
|
||||
virtual bool IsVisible( void ) const;
|
||||
virtual void SwapOutPlayers( int iOldUserID, int iNewUserID );
|
||||
virtual void TakePlaceOf( CBaseLesson *pLesson );
|
||||
|
||||
void SetLocatorBinding( CLocatorTarget * pLocatorTarget );
|
||||
|
||||
const char *GetCaptionColorString() { return m_szCaptionColor.String(); }
|
||||
|
||||
bool IsPresentComplete( void );
|
||||
void PresentStart( void );
|
||||
void PresentEnd( void );
|
||||
|
||||
private:
|
||||
virtual void UpdateLocatorTarget( CLocatorTarget *pLocatorTarget, C_BaseEntity *pIconTarget );
|
||||
|
||||
protected:
|
||||
CHandle<C_BaseEntity> m_hIconTarget;
|
||||
CGameInstructorSymbol m_szVguiTargetName;
|
||||
CGameInstructorSymbol m_szVguiTargetLookup;
|
||||
int m_nVguiTargetEdge;
|
||||
float m_flUpOffset;
|
||||
float m_flRelativeUpOffset;
|
||||
float m_fFixedPositionX;
|
||||
float m_fFixedPositionY;
|
||||
|
||||
int m_hLocatorTarget;
|
||||
int m_iFlags;
|
||||
|
||||
float m_fRange;
|
||||
float m_fCurrentDistance;
|
||||
float m_fOnScreenStartTime;
|
||||
float m_fUpdateDistanceTime;
|
||||
|
||||
CGameInstructorSymbol m_szOnscreenIcon;
|
||||
CGameInstructorSymbol m_szOffscreenIcon;
|
||||
CGameInstructorSymbol m_szCaptionColor;
|
||||
|
||||
bool m_bFixedPosition;
|
||||
bool m_bNoIconTarget;
|
||||
bool m_bAllowNodrawTarget;
|
||||
bool m_bVisible;
|
||||
bool m_bShowWhenOccluded;
|
||||
bool m_bNoOffscreen;
|
||||
bool m_bForceCaption;
|
||||
};
|
||||
|
||||
enum LessonAction
|
||||
{
|
||||
LESSON_ACTION_NONE,
|
||||
|
||||
LESSON_ACTION_SCOPE_IN,
|
||||
LESSON_ACTION_SCOPE_OUT,
|
||||
LESSON_ACTION_CLOSE,
|
||||
LESSON_ACTION_SUCCESS,
|
||||
LESSON_ACTION_LOCK,
|
||||
LESSON_ACTION_PRESENT_COMPLETE,
|
||||
LESSON_ACTION_PRESENT_START,
|
||||
LESSON_ACTION_PRESENT_END,
|
||||
|
||||
LESSON_ACTION_REFERENCE_OPEN,
|
||||
|
||||
LESSON_ACTION_IS_MULTIPLAYER,
|
||||
|
||||
LESSON_ACTION_SET,
|
||||
LESSON_ACTION_ADD,
|
||||
LESSON_ACTION_SUBTRACT,
|
||||
LESSON_ACTION_MULTIPLY,
|
||||
LESSON_ACTION_IS,
|
||||
LESSON_ACTION_LESS_THAN,
|
||||
LESSON_ACTION_HAS_PREFIX,
|
||||
LESSON_ACTION_HAS_BIT,
|
||||
LESSON_ACTION_BIT_COUNT_IS,
|
||||
LESSON_ACTION_BIT_COUNT_LESS_THAN,
|
||||
|
||||
LESSON_ACTION_GET_DISTANCE,
|
||||
LESSON_ACTION_GET_ANGULAR_DISTANCE,
|
||||
LESSON_ACTION_GET_PLAYER_DISPLAY_NAME,
|
||||
LESSON_ACTION_CLASSNAME_IS,
|
||||
LESSON_ACTION_MODELNAME_IS,
|
||||
LESSON_ACTION_TEAM_IS,
|
||||
LESSON_ACTION_HEALTH_LESS_THAN,
|
||||
LESSON_ACTION_HEALTH_PERCENTAGE_LESS_THAN,
|
||||
LESSON_ACTION_GET_ACTIVE_WEAPON,
|
||||
LESSON_ACTION_WEAPON_IS,
|
||||
LESSON_ACTION_WEAPON_HAS,
|
||||
LESSON_ACTION_GET_ACTIVE_WEAPON_SLOT,
|
||||
LESSON_ACTION_GET_WEAPON_SLOT,
|
||||
LESSON_ACTION_GET_WEAPON_IN_SLOT,
|
||||
LESSON_ACTION_CLIP_PERCENTAGE_LESS_THAN,
|
||||
LESSON_ACTION_WEAPON_AMMO_LOW,
|
||||
LESSON_ACTION_WEAPON_AMMO_FULL,
|
||||
LESSON_ACTION_WEAPON_AMMO_EMPTY,
|
||||
LESSON_ACTION_WEAPON_CAN_USE,
|
||||
LESSON_ACTION_USE_TARGET_IS,
|
||||
LESSON_ACTION_GET_USE_TARGET,
|
||||
LESSON_ACTION_GET_POTENTIAL_USE_TARGET,
|
||||
|
||||
// Enum continued in Mod_LessonAction
|
||||
LESSON_ACTION_MOD_START,
|
||||
};
|
||||
|
||||
struct LessonElement_t
|
||||
{
|
||||
int iVariable;
|
||||
int iParamVarIndex;
|
||||
int iAction;
|
||||
_fieldtypes paramType;
|
||||
CGameInstructorSymbol szParam;
|
||||
bool bNot : 1;
|
||||
bool bOptionalParam : 1;
|
||||
|
||||
LessonElement_t( int p_iVariable, int p_iAction, bool p_bNot, bool p_bOptionalParam, const char *pchParam, int p_iParamVarIndex, _fieldtypes p_paramType )
|
||||
{
|
||||
iVariable = p_iVariable;
|
||||
iAction = p_iAction;
|
||||
bNot = p_bNot;
|
||||
bOptionalParam = p_bOptionalParam;
|
||||
szParam = pchParam;
|
||||
iParamVarIndex = p_iParamVarIndex;
|
||||
paramType = p_paramType;
|
||||
}
|
||||
|
||||
LessonElement_t( const LessonElement_t &p_LessonElement )
|
||||
{
|
||||
iVariable = p_LessonElement.iVariable;
|
||||
iAction = p_LessonElement.iAction;
|
||||
bNot = p_LessonElement.bNot;
|
||||
bOptionalParam = p_LessonElement.bOptionalParam;
|
||||
szParam = p_LessonElement.szParam;
|
||||
iParamVarIndex = p_LessonElement.iParamVarIndex;
|
||||
paramType = p_LessonElement.paramType;
|
||||
}
|
||||
};
|
||||
|
||||
struct LessonEvent_t
|
||||
{
|
||||
CUtlVector< LessonElement_t > elements;
|
||||
CGameInstructorSymbol szEventName;
|
||||
};
|
||||
|
||||
class CScriptedIconLesson : public CIconLesson
|
||||
{
|
||||
public:
|
||||
DECLARE_LESSON( CScriptedIconLesson, CIconLesson )
|
||||
DECLARE_SIMPLE_DATADESC();
|
||||
|
||||
virtual ~CScriptedIconLesson( void );
|
||||
|
||||
static void PreReadLessonsFromFile( void );
|
||||
static void Mod_PreReadLessonsFromFile( void );
|
||||
|
||||
void Init( void ); // NOT virtual, each constructor calls their own
|
||||
virtual void InitPrerequisites( void );
|
||||
virtual void OnOpen( void );
|
||||
virtual void Update( void );
|
||||
|
||||
virtual void SwapOutPlayers( int iOldUserID, int iNewUserID );
|
||||
|
||||
virtual void FireGameEvent( IGameEvent *event );
|
||||
virtual void ProcessOpenGameEvents( const CScriptedIconLesson *pRootLesson, const char *name, IGameEvent *event );
|
||||
virtual void ProcessCloseGameEvents( const CScriptedIconLesson *pRootLesson, const char *name, IGameEvent *event );
|
||||
virtual void ProcessSuccessGameEvents( const CScriptedIconLesson *pRootLesson, const char *name, IGameEvent *event );
|
||||
|
||||
CUtlVector< LessonEvent_t >& GetOpenEvents( void ) { return m_OpenEvents; }
|
||||
CUtlVector< LessonEvent_t >& GetCloseEvents( void ) { return m_CloseEvents; }
|
||||
CUtlVector< LessonEvent_t >& GetSuccessEvents( void ) { return m_SuccessEvents; }
|
||||
CUtlVector< LessonEvent_t >& GetOnOpenEvents( void ) { return m_OnOpenEvents; }
|
||||
CUtlVector< LessonEvent_t >& GetUpdateEvents( void ) { return m_UpdateEvents; }
|
||||
|
||||
bool ProcessElements( IGameEvent *event, const CUtlVector< LessonElement_t > *pElements );
|
||||
|
||||
private:
|
||||
void InitElementsFromKeys( CUtlVector< LessonElement_t > *pLessonElements, KeyValues *pKey );
|
||||
void InitElementsFromElements( CUtlVector< LessonElement_t > *pLessonElements, const CUtlVector< LessonElement_t > *pLessonElements2 );
|
||||
|
||||
void InitFromKeys( KeyValues *pKey );
|
||||
|
||||
bool ProcessElement( IGameEvent *event, const LessonElement_t *pLessonElement, bool bInFailedScope );
|
||||
|
||||
bool ProcessElementAction( int iAction, bool bNot, const char *pchVarName, float &bVar, const CGameInstructorSymbol *pchParamName, float fParam );
|
||||
bool ProcessElementAction( int iAction, bool bNot, const char *pchVarName, int &bVar, const CGameInstructorSymbol *pchParamName, float fParam );
|
||||
bool ProcessElementAction( int iAction, bool bNot, const char *pchVarName, bool &bVar, const CGameInstructorSymbol *pchParamName, float fParam );
|
||||
bool ProcessElementAction( int iAction, bool bNot, const char *pchVarName, EHANDLE &hVar, const CGameInstructorSymbol *pchParamName, float fParam, C_BaseEntity *pParam, const char *pchParam );
|
||||
bool ProcessElementAction( int iAction, bool bNot, const char *pchVarName, CGameInstructorSymbol *pchVar, const CGameInstructorSymbol *pchParamName, const char *pchParam );
|
||||
|
||||
// Implemented per mod so they can have custom actions
|
||||
bool Mod_ProcessElementAction( int iAction, bool bNot, const char *pchVarName, EHANDLE &hVar, const CGameInstructorSymbol *pchParamName, float fParam, C_BaseEntity *pParam, const char *pchParam, bool &bModHandled );
|
||||
|
||||
LessonEvent_t * AddOpenEvent( void );
|
||||
LessonEvent_t * AddCloseEvent( void );
|
||||
LessonEvent_t * AddSuccessEvent( void );
|
||||
LessonEvent_t * AddOnOpenEvent( void );
|
||||
LessonEvent_t * AddUpdateEvent( void );
|
||||
|
||||
private:
|
||||
static CUtlDict< int, int > LessonActionMap;
|
||||
|
||||
EHANDLE m_hLocalPlayer;
|
||||
float m_fOutput;
|
||||
CHandle<C_BaseEntity> m_hEntity1;
|
||||
CHandle<C_BaseEntity> m_hEntity2;
|
||||
CGameInstructorSymbol m_szString1;
|
||||
CGameInstructorSymbol m_szString2;
|
||||
int m_iInteger1;
|
||||
int m_iInteger2;
|
||||
float m_fFloat1;
|
||||
float m_fFloat2;
|
||||
|
||||
CUtlVector< CGameInstructorSymbol > m_PrerequisiteNames;
|
||||
CUtlVector< LessonEvent_t > m_OpenEvents;
|
||||
CUtlVector< LessonEvent_t > m_CloseEvents;
|
||||
CUtlVector< LessonEvent_t > m_SuccessEvents;
|
||||
CUtlVector< LessonEvent_t > m_OnOpenEvents;
|
||||
CUtlVector< LessonEvent_t > m_UpdateEvents;
|
||||
|
||||
float m_fUpdateEventTime;
|
||||
CScriptedIconLesson *m_pDefaultHolder;
|
||||
|
||||
int m_iScopeDepth;
|
||||
|
||||
// Need this to get offsets to scripted variables
|
||||
friend class LessonVariableInfo;
|
||||
friend int LessonActionFromString( const char *pchName );
|
||||
};
|
||||
|
||||
|
||||
#endif // _C_BASELESSON_H_
|
||||
3809
game/client/c_baseplayer.cpp
Normal file
3809
game/client/c_baseplayer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1017
game/client/c_baseplayer.h
Normal file
1017
game/client/c_baseplayer.h
Normal file
File diff suppressed because it is too large
Load Diff
201
game/client/c_basetempentity.cpp
Normal file
201
game/client/c_basetempentity.cpp
Normal file
@@ -0,0 +1,201 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Core Temp Entity client implementation.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_basetempentity.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
IMPLEMENT_CLIENTCLASS(C_BaseTempEntity, DT_BaseTempEntity, CBaseTempEntity);
|
||||
|
||||
BEGIN_RECV_TABLE_NOBASE(C_BaseTempEntity, DT_BaseTempEntity)
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
// Global list of temp entity classes
|
||||
C_BaseTempEntity *C_BaseTempEntity::s_pTempEntities = NULL;
|
||||
|
||||
// Global list of dynamic temp entities
|
||||
C_BaseTempEntity *C_BaseTempEntity::s_pDynamicEntities = NULL;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns head of list
|
||||
// Output : CBaseTempEntity * -- head of list
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseTempEntity *C_BaseTempEntity::GetDynamicList( void )
|
||||
{
|
||||
return s_pDynamicEntities;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns head of list
|
||||
// Output : CBaseTempEntity * -- head of list
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseTempEntity *C_BaseTempEntity::GetList( void )
|
||||
{
|
||||
return s_pTempEntities;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output :
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseTempEntity::C_BaseTempEntity( void )
|
||||
{
|
||||
// Add to list
|
||||
m_pNext = s_pTempEntities;
|
||||
s_pTempEntities = this;
|
||||
|
||||
m_pNextDynamic = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output :
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseTempEntity::~C_BaseTempEntity( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Get next temp ent in chain
|
||||
// Output : CBaseTempEntity *
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseTempEntity *C_BaseTempEntity::GetNext( void )
|
||||
{
|
||||
return m_pNext;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Get next temp ent in chain
|
||||
// Output : CBaseTempEntity *
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseTempEntity *C_BaseTempEntity::GetNextDynamic( void )
|
||||
{
|
||||
return m_pNextDynamic;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseTempEntity::Precache( void )
|
||||
{
|
||||
// Nothing...
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called at startup to allow temp entities to precache any models/sounds that they need
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseTempEntity::PrecacheTempEnts( void )
|
||||
{
|
||||
C_BaseTempEntity *te = GetList();
|
||||
while ( te )
|
||||
{
|
||||
te->Precache();
|
||||
te = te->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called at startup and level load to clear out leftover temp entities
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseTempEntity::ClearDynamicTempEnts( void )
|
||||
{
|
||||
C_BaseTempEntity *next;
|
||||
C_BaseTempEntity *te = s_pDynamicEntities;
|
||||
while ( te )
|
||||
{
|
||||
next = te->GetNextDynamic();
|
||||
delete te;
|
||||
te = next;
|
||||
}
|
||||
|
||||
s_pDynamicEntities = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called at startup and level load to clear out leftover temp entities
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseTempEntity::CheckDynamicTempEnts( void )
|
||||
{
|
||||
C_BaseTempEntity *next, *newlist = NULL;
|
||||
C_BaseTempEntity *te = s_pDynamicEntities;
|
||||
while ( te )
|
||||
{
|
||||
next = te->GetNextDynamic();
|
||||
if ( te->ShouldDestroy() )
|
||||
{
|
||||
delete te;
|
||||
}
|
||||
else
|
||||
{
|
||||
te->m_pNextDynamic = newlist;
|
||||
newlist = te;
|
||||
}
|
||||
te = next;
|
||||
}
|
||||
|
||||
s_pDynamicEntities = newlist;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Dynamic/non-singleton temp entities are initialized by
|
||||
// calling into here. They should be added to a list of C_BaseTempEntities so
|
||||
// that their memory can be deallocated appropriately.
|
||||
// Input : *pEnt -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseTempEntity::Init( int entnum, int iSerialNum )
|
||||
{
|
||||
if ( entnum != -1 )
|
||||
{
|
||||
Assert( 0 );
|
||||
}
|
||||
|
||||
// Link into dynamic entity list
|
||||
m_pNextDynamic = s_pDynamicEntities;
|
||||
s_pDynamicEntities = this;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void C_BaseTempEntity::Release()
|
||||
{
|
||||
Assert( !"C_BaseTempEntity::Release should never be called" );
|
||||
}
|
||||
|
||||
|
||||
void C_BaseTempEntity::NotifyShouldTransmit( ShouldTransmitState_t state )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : bool -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseTempEntity::PreDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
// TE's may or may not implement this
|
||||
}
|
||||
|
||||
|
||||
int C_BaseTempEntity::entindex( void ) const { Assert( 0 ); return 0; }
|
||||
void C_BaseTempEntity::PostDataUpdate( DataUpdateType_t updateType ) { Assert( 0 ); }
|
||||
void C_BaseTempEntity::OnPreDataChanged( DataUpdateType_t updateType ) { Assert( 0 ); }
|
||||
void C_BaseTempEntity::OnDataChanged( DataUpdateType_t updateType ) { Assert( 0 ); }
|
||||
void C_BaseTempEntity::SetDormant( bool bDormant ) { Assert( 0 ); }
|
||||
bool C_BaseTempEntity::IsDormant( void ) const { Assert( 0 ); return false; };
|
||||
void C_BaseTempEntity::ReceiveMessage( int classID, bf_read &msg ) { Assert( 0 ); }
|
||||
void C_BaseTempEntity::SetDestroyedOnRecreateEntities( void ) { Assert(0); }
|
||||
|
||||
void* C_BaseTempEntity::GetDataTableBasePtr()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
123
game/client/c_basetempentity.h
Normal file
123
game/client/c_basetempentity.h
Normal file
@@ -0,0 +1,123 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef C_BASETEMPENTITY_H
|
||||
#define C_BASETEMPENTITY_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "client_class.h"
|
||||
#include "iclientnetworkable.h"
|
||||
#include "c_recipientfilter.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Base class for TEs. All TEs should derive from this and at
|
||||
// least implement OnDataChanged to be notified when the TE has been received
|
||||
// from the server
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_BaseTempEntity : public IClientUnknown, public IClientNetworkable
|
||||
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS_NOBASE( C_BaseTempEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_BaseTempEntity( void );
|
||||
virtual ~C_BaseTempEntity( void );
|
||||
|
||||
|
||||
// IClientUnknown implementation.
|
||||
public:
|
||||
|
||||
virtual void SetRefEHandle( const CBaseHandle &handle ) { Assert( false ); }
|
||||
virtual const CBaseHandle& GetRefEHandle() const { Assert( false ); return *( ( CBaseHandle* )0 ); }
|
||||
|
||||
virtual IClientUnknown* GetIClientUnknown() { return this; }
|
||||
virtual ICollideable* GetCollideable() { return 0; }
|
||||
virtual IClientNetworkable* GetClientNetworkable() { return this; }
|
||||
virtual IClientRenderable* GetClientRenderable() { return 0; }
|
||||
virtual IClientEntity* GetIClientEntity() { return 0; }
|
||||
virtual C_BaseEntity* GetBaseEntity() { return 0; }
|
||||
virtual IClientThinkable* GetClientThinkable() { return 0; }
|
||||
virtual IClientModelRenderable* GetClientModelRenderable() { return 0; }
|
||||
virtual IClientAlphaProperty* GetClientAlphaProperty() { return 0; }
|
||||
|
||||
// IClientNetworkable overrides.
|
||||
public:
|
||||
|
||||
virtual void Release();
|
||||
virtual void NotifyShouldTransmit( ShouldTransmitState_t state );
|
||||
virtual void PreDataUpdate( DataUpdateType_t updateType );
|
||||
virtual void PostDataUpdate( DataUpdateType_t updateType );
|
||||
virtual void OnDataUnchangedInPVS( void ) { }
|
||||
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void SetDormant( bool bDormant );
|
||||
virtual bool IsDormant( void ) const;
|
||||
virtual int entindex( void ) const;
|
||||
virtual void ReceiveMessage( int classID, bf_read &msg );
|
||||
virtual void* GetDataTableBasePtr();
|
||||
virtual void SetDestroyedOnRecreateEntities( void );
|
||||
|
||||
public:
|
||||
|
||||
// Dummy for CNetworkVars.
|
||||
void NetworkStateChanged() {}
|
||||
void NetworkStateChanged( void *pVar ) {}
|
||||
|
||||
virtual bool Init(int entnum, int iSerialNum);
|
||||
|
||||
virtual void Precache( void );
|
||||
|
||||
// For dynamic entities, return true to allow destruction
|
||||
virtual bool ShouldDestroy( void ) { return false; };
|
||||
|
||||
C_BaseTempEntity *GetNext( void );
|
||||
|
||||
// Get list of tempentities
|
||||
static C_BaseTempEntity *GetList( void );
|
||||
|
||||
C_BaseTempEntity *GetNextDynamic( void );
|
||||
|
||||
// Determine the color modulation amount
|
||||
void GetColorModulation( float* color )
|
||||
{
|
||||
assert(color);
|
||||
color[0] = color[1] = color[2] = 1.0f;
|
||||
}
|
||||
|
||||
// Should this object be able to have shadows cast onto it?
|
||||
virtual bool ShouldReceiveProjectedTextures( int flags ) { return false; }
|
||||
|
||||
// Static members
|
||||
public:
|
||||
// List of dynamically allocated temp entis
|
||||
static C_BaseTempEntity *GetDynamicList();
|
||||
|
||||
// Called at startup to allow temp entities to precache any models/sounds that they need
|
||||
static void PrecacheTempEnts( void );
|
||||
|
||||
static void ClearDynamicTempEnts( void );
|
||||
|
||||
static void CheckDynamicTempEnts( void );
|
||||
|
||||
private:
|
||||
|
||||
// Next in chain
|
||||
C_BaseTempEntity *m_pNext;
|
||||
C_BaseTempEntity *m_pNextDynamic;
|
||||
|
||||
// TEs add themselves to this list for the executable.
|
||||
static C_BaseTempEntity *s_pTempEntities;
|
||||
static C_BaseTempEntity *s_pDynamicEntities;
|
||||
};
|
||||
|
||||
|
||||
#endif // C_BASETEMPENTITY_H
|
||||
120
game/client/c_basetoggle.cpp
Normal file
120
game/client/c_basetoggle.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// Copyright (c) 2007 Turtle Rock Studios, Inc.
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_basetoggle.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_BaseToggle, DT_BaseToggle, CBaseToggle )
|
||||
RecvPropVector( RECVINFO( m_vecFinalDest ) ),
|
||||
RecvPropInt( RECVINFO( m_movementType ) ),
|
||||
RecvPropFloat( RECVINFO( m_flMoveTargetTime ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
BEGIN_PREDICTION_DATA( C_BaseToggle )
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
|
||||
ConVar cl_predict_basetoggles("cl_predict_basetoggles", "1" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// Returns the velocity imparted to players standing on us.
|
||||
void C_BaseToggle::GetGroundVelocityToApply( Vector &vecGroundVel )
|
||||
{
|
||||
vecGroundVel = GetLocalVelocity();
|
||||
if( !GetPredictable() )
|
||||
{
|
||||
vecGroundVel.z = 0.0f; // don't give upward velocity, or it could predict players into the air.
|
||||
}
|
||||
}
|
||||
|
||||
bool C_BaseToggle::ShouldPredict( void )
|
||||
{
|
||||
return cl_predict_basetoggles.GetBool() && (m_movementType == MOVE_TOGGLE_LINEAR);
|
||||
}
|
||||
|
||||
C_BasePlayer *C_BaseToggle::GetPredictionOwner( void )
|
||||
{
|
||||
C_BasePlayer *pPlayer = (C_BasePlayer *)m_hPredictionOwner.Get();
|
||||
|
||||
if( pPlayer && pPlayer->IsLocalPlayer() )
|
||||
return pPlayer;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool C_BaseToggle::PredictionIsPhysicallySimulated( void )
|
||||
{
|
||||
return (m_movementType == MOVE_TOGGLE_LINEAR);
|
||||
}
|
||||
|
||||
void C_BaseToggle::PostDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::PostDataUpdate( updateType );
|
||||
|
||||
m_vLastNetworked = GetNetworkOrigin();
|
||||
m_fLastNetworkedTime = gpGlobals->curtime;
|
||||
|
||||
if( GetPredictionEligible() && m_bWasPredictingMotion && (m_movementType == MOVE_TOGGLE_NONE) )
|
||||
{
|
||||
SetPredictionEligible( false );
|
||||
ResetLatched();
|
||||
}
|
||||
m_bWasPredictingMotion = (m_movementType != MOVE_TOGGLE_NONE);
|
||||
}
|
||||
|
||||
void C_BaseToggle::PhysicsSimulate( void )
|
||||
{
|
||||
BaseClass::PhysicsSimulate();
|
||||
|
||||
if( GetPredictable() )
|
||||
{
|
||||
Vector vOrigin = PredictPosition( GetPredictionOwner()->PredictedServerTime() );
|
||||
|
||||
if( vOrigin == m_vecFinalDest )
|
||||
{
|
||||
SetLocalVelocity( vec3_origin );
|
||||
}
|
||||
SetLocalOrigin( vOrigin );
|
||||
SetNetworkOrigin( vOrigin );
|
||||
}
|
||||
}
|
||||
|
||||
Vector C_BaseToggle::PredictPosition( float fCurTime )
|
||||
{
|
||||
if( (m_movementType != MOVE_TOGGLE_LINEAR) || m_flMoveTargetTime <= 0.0f )
|
||||
return GetNetworkOrigin();
|
||||
|
||||
if( m_flMoveTargetTime > fCurTime )
|
||||
{
|
||||
float fTargetTime = m_flMoveTargetTime;
|
||||
float fTimeRemaining = fTargetTime - fCurTime;
|
||||
float fTotalTime = fTargetTime - m_fLastNetworkedTime;
|
||||
|
||||
if( fTotalTime <= 0.0f )
|
||||
return m_vecFinalDest;
|
||||
|
||||
float fInterp = fTimeRemaining / fTotalTime;
|
||||
|
||||
return (m_vLastNetworked * fInterp) + (m_vecFinalDest * (1.0f - fInterp));
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_vecFinalDest;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_BaseButton, DT_BaseButton, CBaseButton )
|
||||
RecvPropBool( RECVINFO( m_usable ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
bool C_BaseButton::IsPotentiallyUsable( void )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
99
game/client/c_basetoggle.h
Normal file
99
game/client/c_basetoggle.h
Normal file
@@ -0,0 +1,99 @@
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// Copyright (c) 2007 Turtle Rock Studios, Inc.
|
||||
|
||||
#if !defined( C_BASETOGGLE_H )
|
||||
#define C_BASETOGGLE_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_baseentity.h"
|
||||
|
||||
|
||||
//copy/paste from server subs.cpp
|
||||
enum togglemovetypes_t
|
||||
{
|
||||
MOVE_TOGGLE_NONE = 0,
|
||||
MOVE_TOGGLE_LINEAR = 1,
|
||||
MOVE_TOGGLE_ANGULAR = 2,
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
class C_BaseToggle: public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BaseToggle, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE(); //elevators
|
||||
|
||||
virtual void GetGroundVelocityToApply( Vector &vecGroundVel );
|
||||
virtual bool ShouldPredict( void );
|
||||
virtual C_BasePlayer *GetPredictionOwner( void );
|
||||
virtual void PhysicsSimulate( void );
|
||||
virtual bool PredictionErrorShouldResetLatchedForAllPredictables( void ) { return false; }
|
||||
virtual bool PredictionIsPhysicallySimulated( void );
|
||||
virtual void PostDataUpdate( DataUpdateType_t updateType );
|
||||
|
||||
Vector PredictPosition( float fCurTime );
|
||||
|
||||
EHANDLE m_hPredictionOwner;
|
||||
Vector m_vLastNetworked;
|
||||
float m_fLastNetworkedTime;
|
||||
|
||||
Vector m_vecFinalDest;
|
||||
int m_movementType;
|
||||
float m_flMoveTargetTime;
|
||||
bool m_bWasPredictingMotion;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
class C_BaseButton: public C_BaseToggle
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BaseButton, C_BaseToggle );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_BaseButton()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool IsPotentiallyUsable( void );
|
||||
|
||||
private:
|
||||
bool m_usable;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// CButtonTimed - func_button_timed
|
||||
//
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
class C_ButtonTimed: public C_BaseButton
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BaseButton, C_BaseButton );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ButtonTimed();
|
||||
|
||||
const char * GetUseString( void ) const
|
||||
{
|
||||
return m_sUseString;
|
||||
}
|
||||
|
||||
const char * GetUseSubString( void ) const
|
||||
{
|
||||
return m_sUseSubString;
|
||||
}
|
||||
|
||||
private:
|
||||
char m_sUseString[64];
|
||||
char m_sUseSubString[64];
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // C_BASETOGGLE_H
|
||||
1269
game/client/c_baseviewmodel.cpp
Normal file
1269
game/client/c_baseviewmodel.cpp
Normal file
File diff suppressed because it is too large
Load Diff
19
game/client/c_baseviewmodel.h
Normal file
19
game/client/c_baseviewmodel.h
Normal file
@@ -0,0 +1,19 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client side view model implementation. Responsible for drawing
|
||||
// the view model.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_BASEVIEWMODEL_H
|
||||
#define C_BASEVIEWMODEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_baseanimating.h"
|
||||
#include "utlvector.h"
|
||||
#include "baseviewmodel_shared.h"
|
||||
|
||||
#endif // C_BASEVIEWMODEL_H
|
||||
355
game/client/c_beamspotlight.cpp
Normal file
355
game/client/c_beamspotlight.cpp
Normal file
@@ -0,0 +1,355 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "dlight.h"
|
||||
#include "iefx.h"
|
||||
|
||||
#include "beam_shared.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSpotlightTraceCacheEntry
|
||||
{
|
||||
public:
|
||||
CSpotlightTraceCacheEntry()
|
||||
{
|
||||
m_origin.Init();
|
||||
m_radius = -1.0f;
|
||||
}
|
||||
bool IsValidFor( const Vector &origin )
|
||||
{
|
||||
if ( m_radius > 0 && m_origin.DistToSqr(origin) < 1.0f )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
void Cache( const Vector &origin, const trace_t &tr )
|
||||
{
|
||||
m_radius = (tr.endpos - origin).Length();
|
||||
m_origin = origin;
|
||||
}
|
||||
|
||||
Vector m_origin;
|
||||
float m_radius;
|
||||
};
|
||||
|
||||
static const int NUM_CACHE_ENTRIES = 64;
|
||||
|
||||
class C_BeamSpotLight : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BeamSpotLight, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_BeamSpotLight();
|
||||
~C_BeamSpotLight();
|
||||
|
||||
bool ShouldDraw();
|
||||
void ClientThink( void );
|
||||
void OnDataChanged( DataUpdateType_t updateType );
|
||||
void Release( void );
|
||||
|
||||
private:
|
||||
|
||||
Vector SpotlightCurrentPos(void);
|
||||
void SpotlightCreate(void);
|
||||
void SpotlightDestroy(void);
|
||||
|
||||
// Computes render info for a spotlight
|
||||
void ComputeRenderInfo();
|
||||
|
||||
private:
|
||||
|
||||
int m_nHaloIndex;
|
||||
int m_nRotationAxis;
|
||||
float m_flRotationSpeed;
|
||||
|
||||
|
||||
bool m_bSpotlightOn;
|
||||
bool m_bHasDynamicLight;
|
||||
|
||||
float m_flSpotlightMaxLength;
|
||||
float m_flSpotlightGoalWidth;
|
||||
float m_flHDRColorScale;
|
||||
|
||||
Vector m_vSpotlightTargetPos;
|
||||
Vector m_vSpotlightCurrentPos;
|
||||
Vector m_vSpotlightDir;
|
||||
|
||||
CHandle<C_Beam> m_hSpotlight;
|
||||
|
||||
float m_flSpotlightCurLength;
|
||||
|
||||
float m_flLightScale;
|
||||
|
||||
dlight_t* m_pDynamicLight;
|
||||
|
||||
float m_lastTime;
|
||||
CSpotlightTraceCacheEntry *m_pCache;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_BeamSpotLight, DT_BeamSpotlight, CBeamSpotlight )
|
||||
RecvPropInt( RECVINFO(m_nHaloIndex) ),
|
||||
RecvPropBool( RECVINFO(m_bSpotlightOn) ),
|
||||
RecvPropBool( RECVINFO(m_bHasDynamicLight) ),
|
||||
RecvPropFloat( RECVINFO(m_flSpotlightMaxLength) ),
|
||||
RecvPropFloat( RECVINFO(m_flSpotlightGoalWidth) ),
|
||||
RecvPropFloat( RECVINFO(m_flHDRColorScale) ),
|
||||
RecvPropInt( RECVINFO(m_nRotationAxis) ),
|
||||
RecvPropFloat( RECVINFO(m_flRotationSpeed) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
LINK_ENTITY_TO_CLASS( beam_spotlight, C_BeamSpotLight );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BeamSpotLight::C_BeamSpotLight()
|
||||
: m_vSpotlightTargetPos( vec3_origin )
|
||||
, m_vSpotlightCurrentPos( vec3_origin )
|
||||
, m_vSpotlightDir( vec3_origin )
|
||||
, m_flSpotlightCurLength( 0.0f )
|
||||
, m_flLightScale( 100.0f )
|
||||
, m_pDynamicLight( NULL )
|
||||
, m_lastTime( 0.0f )
|
||||
, m_pCache(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
C_BeamSpotLight::~C_BeamSpotLight()
|
||||
{
|
||||
delete[] m_pCache;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BeamSpotLight::ShouldDraw()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BeamSpotLight::ClientThink( void )
|
||||
{
|
||||
float dt = gpGlobals->curtime - m_lastTime;
|
||||
if ( !m_lastTime )
|
||||
{
|
||||
dt = 0.0f;
|
||||
}
|
||||
m_lastTime = gpGlobals->curtime;
|
||||
|
||||
// ---------------------------------------------------
|
||||
// If I don't have a spotlight attempt to create one
|
||||
// ---------------------------------------------------
|
||||
if ( !m_hSpotlight )
|
||||
{
|
||||
if ( m_bSpotlightOn )
|
||||
{
|
||||
// Make the spotlight
|
||||
SpotlightCreate();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_NEVER );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ( !m_bSpotlightOn )
|
||||
{
|
||||
SpotlightDestroy();
|
||||
SetNextClientThink( CLIENT_THINK_NEVER );
|
||||
return;
|
||||
}
|
||||
|
||||
// update rotation
|
||||
if ( m_flRotationSpeed != 0.0f )
|
||||
{
|
||||
QAngle angles = GetAbsAngles();
|
||||
angles[m_nRotationAxis] += m_flRotationSpeed * dt;
|
||||
angles[m_nRotationAxis] = anglemod(angles[m_nRotationAxis]);
|
||||
if ( !m_pCache )
|
||||
{
|
||||
m_pCache = new CSpotlightTraceCacheEntry[NUM_CACHE_ENTRIES];
|
||||
}
|
||||
|
||||
SetAbsAngles( angles );
|
||||
}
|
||||
m_vSpotlightCurrentPos = SpotlightCurrentPos();
|
||||
|
||||
Assert( m_hSpotlight );
|
||||
|
||||
m_hSpotlight->SetStartPos( GetAbsOrigin() );
|
||||
m_hSpotlight->SetEndPos( m_vSpotlightCurrentPos );
|
||||
|
||||
// Avoid sudden change in where beam fades out when cross disconinuities
|
||||
Vector dir = m_vSpotlightCurrentPos - GetAbsOrigin();
|
||||
float flBeamLength = VectorNormalize( dir );
|
||||
m_flSpotlightCurLength = (0.60*m_flSpotlightCurLength) + (0.4*flBeamLength);
|
||||
|
||||
ComputeRenderInfo();
|
||||
|
||||
m_hSpotlight->RelinkBeam();
|
||||
|
||||
//NDebugOverlay::Cross3D(GetAbsOrigin(),Vector(-5,-5,-5),Vector(5,5,5),0,255,0,true,0.1);
|
||||
//NDebugOverlay::Cross3D(m_vSpotlightCurrentPos,Vector(-5,-5,-5),Vector(5,5,5),0,255,0,true,0.1);
|
||||
//NDebugOverlay::Cross3D(m_vSpotlightTargetPos,Vector(-5,-5,-5),Vector(5,5,5),255,0,0,true,0.1);
|
||||
|
||||
// Do we need to keep updating?
|
||||
if ( !GetMoveParent() && m_flRotationSpeed == 0 )
|
||||
{
|
||||
// No reason to think again, we're not going to move unless there's a data change
|
||||
SetNextClientThink( CLIENT_THINK_NEVER );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BeamSpotLight::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
m_flSpotlightCurLength = m_flSpotlightMaxLength;
|
||||
}
|
||||
|
||||
// On a data change always think again
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void C_BeamSpotLight::Release()
|
||||
{
|
||||
SpotlightDestroy();
|
||||
BaseClass::Release();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void C_BeamSpotLight::SpotlightCreate(void)
|
||||
{
|
||||
m_vSpotlightTargetPos = SpotlightCurrentPos();
|
||||
|
||||
{
|
||||
//C_Beam *beam = CBeam::BeamCreate( "sprites/spotlight.vmt", m_flSpotlightGoalWidth );
|
||||
C_Beam *beam = C_Beam::BeamCreate( "sprites/glow_test02.vmt", m_flSpotlightGoalWidth );
|
||||
// Beam only exists client side
|
||||
ClientEntityList().AddNonNetworkableEntity( beam );
|
||||
m_hSpotlight = beam;
|
||||
}
|
||||
|
||||
// Set the temporary spawnflag on the beam so it doesn't save (we'll recreate it on restore)
|
||||
m_hSpotlight->SetHDRColorScale( m_flHDRColorScale );
|
||||
const color24 c = GetRenderColor();
|
||||
m_hSpotlight->SetColor( c.r, c.g, c.b );
|
||||
m_hSpotlight->SetHaloTexture(m_nHaloIndex);
|
||||
m_hSpotlight->SetHaloScale(60);
|
||||
m_hSpotlight->SetEndWidth(m_flSpotlightGoalWidth);
|
||||
m_hSpotlight->SetBeamFlags( (FBEAM_SHADEOUT|FBEAM_NOTILE) );
|
||||
m_hSpotlight->SetBrightness( 64 );
|
||||
m_hSpotlight->SetNoise( 0 );
|
||||
|
||||
m_hSpotlight->PointsInit( GetAbsOrigin(), m_vSpotlightTargetPos );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void C_BeamSpotLight::SpotlightDestroy(void)
|
||||
{
|
||||
if ( m_hSpotlight )
|
||||
{
|
||||
UTIL_Remove( m_hSpotlight );
|
||||
m_hSpotlight.Term();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Vector C_BeamSpotLight::SpotlightCurrentPos(void)
|
||||
{
|
||||
QAngle angles = GetAbsAngles();
|
||||
GetVectors( &m_vSpotlightDir, NULL, NULL );
|
||||
Vector position = GetAbsOrigin();
|
||||
int cacheIndex = -1;
|
||||
if ( m_pCache )
|
||||
{
|
||||
cacheIndex = int( angles[m_nRotationAxis] * float(NUM_CACHE_ENTRIES) * (1.0f / 360.0f)) & (NUM_CACHE_ENTRIES - 1);
|
||||
if ( m_pCache[cacheIndex].IsValidFor(GetAbsOrigin()) )
|
||||
{
|
||||
return position + m_vSpotlightDir * m_pCache[cacheIndex].m_radius;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get beam end point. Only collide with solid objects, not npcs
|
||||
trace_t tr;
|
||||
UTIL_TraceLine( position, position + (m_vSpotlightDir * 2 * m_flSpotlightMaxLength), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr );
|
||||
if ( cacheIndex >= 0 )
|
||||
{
|
||||
m_pCache[cacheIndex].Cache(position, tr);
|
||||
}
|
||||
|
||||
return tr.endpos;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Computes render info for a spotlight
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BeamSpotLight::ComputeRenderInfo()
|
||||
{
|
||||
// Fade out spotlight end if past max length.
|
||||
if ( m_flSpotlightCurLength > 2*m_flSpotlightMaxLength )
|
||||
{
|
||||
SetRenderAlpha( 0 );
|
||||
m_hSpotlight->SetFadeLength( m_flSpotlightMaxLength );
|
||||
}
|
||||
else if ( m_flSpotlightCurLength > m_flSpotlightMaxLength )
|
||||
{
|
||||
SetRenderAlpha( (1-((m_flSpotlightCurLength-m_flSpotlightMaxLength)/m_flSpotlightMaxLength)) );
|
||||
m_hSpotlight->SetFadeLength( m_flSpotlightMaxLength );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRenderAlpha( 1.0 );
|
||||
m_hSpotlight->SetFadeLength( m_flSpotlightCurLength );
|
||||
}
|
||||
|
||||
// Adjust end width to keep beam width constant
|
||||
float flNewWidth = m_flSpotlightGoalWidth * (m_flSpotlightCurLength / m_flSpotlightMaxLength);
|
||||
flNewWidth = clamp(flNewWidth, 0, MAX_BEAM_WIDTH );
|
||||
m_hSpotlight->SetEndWidth(flNewWidth);
|
||||
|
||||
if ( m_bHasDynamicLight )
|
||||
{
|
||||
// <<TODO>> - magic number 1.8 depends on sprite size
|
||||
m_flLightScale = 1.8*flNewWidth;
|
||||
|
||||
if ( m_flLightScale > 0 )
|
||||
{
|
||||
const color24 c = GetRenderColor();
|
||||
float a = GetRenderAlpha() / 255.0f;
|
||||
ColorRGBExp32 color;
|
||||
color.r = c.r * a;
|
||||
color.g = c.g * a;
|
||||
color.b = c.b * a;
|
||||
color.exponent = 0;
|
||||
if ( color.r == 0 && color.g == 0 && color.b == 0 )
|
||||
return;
|
||||
|
||||
// Deal with the environment light
|
||||
if ( !m_pDynamicLight || (m_pDynamicLight->key != index) )
|
||||
{
|
||||
m_pDynamicLight = effects->CL_AllocDlight( index );
|
||||
assert (m_pDynamicLight);
|
||||
}
|
||||
|
||||
//m_pDynamicLight->flags = DLIGHT_NO_MODEL_ILLUMINATION;
|
||||
m_pDynamicLight->radius = m_flLightScale*3.0f;
|
||||
m_pDynamicLight->origin = GetAbsOrigin() + Vector(0,0,5);
|
||||
m_pDynamicLight->die = gpGlobals->curtime + 0.05f;
|
||||
m_pDynamicLight->color = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
92
game/client/c_breakableprop.cpp
Normal file
92
game/client/c_breakableprop.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "model_types.h"
|
||||
#include "vcollide.h"
|
||||
#include "vcollide_parse.h"
|
||||
#include "solidsetdefaults.h"
|
||||
#include "bone_setup.h"
|
||||
#include "engine/ivmodelinfo.h"
|
||||
#include "physics.h"
|
||||
#include "c_breakableprop.h"
|
||||
#include "view.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
void RecvProxy_UnmodifiedQAngles( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
const float *v = pData->m_Value.m_Vector;
|
||||
|
||||
((float*)pOut)[0] = v[0];
|
||||
((float*)pOut)[1] = v[1];
|
||||
((float*)pOut)[2] = v[2];
|
||||
}
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_BreakableProp, DT_BreakableProp, CBreakableProp)
|
||||
RecvPropQAngles( RECVINFO( m_qPreferredPlayerCarryAngles ), 0, RecvProxy_UnmodifiedQAngles ),
|
||||
RecvPropBool( RECVINFO( m_bClientPhysics ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BreakableProp::C_BreakableProp( void )
|
||||
{
|
||||
m_takedamage = DAMAGE_YES;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copy fade from another breakable prop
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BreakableProp::CopyFadeFrom( C_BreakableProp *pSource )
|
||||
{
|
||||
SetGlobalFadeScale( pSource->GetGlobalFadeScale() );
|
||||
SetDistanceFade( pSource->GetMinFadeDist(), pSource->GetMaxFadeDist() );
|
||||
}
|
||||
|
||||
void C_BreakableProp::OnDataChanged( DataUpdateType_t type )
|
||||
{
|
||||
BaseClass::OnDataChanged( type );
|
||||
if ( m_bClientPhysics )
|
||||
{
|
||||
bool bCreate = (type == DATA_UPDATE_CREATED) ? true : false;
|
||||
VPhysicsShadowDataChanged(bCreate, this);
|
||||
}
|
||||
}
|
||||
|
||||
//IPlayerPickupVPhysics
|
||||
bool C_BreakableProp::HasPreferredCarryAnglesForPlayer( CBasePlayer *pPlayer )
|
||||
{
|
||||
return (m_qPreferredPlayerCarryAngles.x < FLT_MAX);
|
||||
}
|
||||
|
||||
QAngle C_BreakableProp::PreferredCarryAngles( void )
|
||||
{
|
||||
return (m_qPreferredPlayerCarryAngles.x < FLT_MAX) ? m_qPreferredPlayerCarryAngles : vec3_angle;
|
||||
}
|
||||
|
||||
|
||||
bool C_BreakableProp::ShouldPredict( void )
|
||||
{
|
||||
#ifdef PORTAL
|
||||
C_BasePlayer *pPredOwner = GetPlayerHoldingEntity( this );
|
||||
return (pPredOwner && pPredOwner->IsLocalPlayer()) ? true : BaseClass::ShouldPredict();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
C_BasePlayer *C_BreakableProp::GetPredictionOwner( void )
|
||||
{
|
||||
#ifdef PORTAL
|
||||
return GetPlayerHoldingEntity( this );
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
52
game/client/c_breakableprop.h
Normal file
52
game/client/c_breakableprop.h
Normal file
@@ -0,0 +1,52 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_BREAKABLEPROP_H
|
||||
#define C_BREAKABLEPROP_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "player_pickup.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_BreakableProp : public C_BaseAnimating, public CDefaultPlayerPickupVPhysics
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BreakableProp, C_BaseAnimating );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_BreakableProp();
|
||||
|
||||
virtual bool IsProp( void ) const
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
//IPlayerPickupVPhysics
|
||||
virtual bool HasPreferredCarryAnglesForPlayer( CBasePlayer *pPlayer );
|
||||
virtual QAngle PreferredCarryAngles( void );
|
||||
|
||||
virtual bool ShouldPredict( void );
|
||||
virtual C_BasePlayer *GetPredictionOwner( void );
|
||||
virtual bool PredictionErrorShouldResetLatchedForAllPredictables( void ) { return false; }
|
||||
|
||||
// Copy fade from another breakable prop
|
||||
void CopyFadeFrom( C_BreakableProp *pSource );
|
||||
virtual void OnDataChanged( DataUpdateType_t type );
|
||||
|
||||
const QAngle &GetNetworkedPreferredPlayerCarryAngles( void ) { return m_qPreferredPlayerCarryAngles; }
|
||||
|
||||
protected:
|
||||
QAngle m_qPreferredPlayerCarryAngles;
|
||||
|
||||
private:
|
||||
bool m_bClientPhysics;
|
||||
};
|
||||
|
||||
#endif // C_BREAKABLEPROP_H
|
||||
251
game/client/c_colorcorrection.cpp
Normal file
251
game/client/c_colorcorrection.cpp
Normal file
@@ -0,0 +1,251 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: Color correction entity with simple radial falloff
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
#include "cbase.h"
|
||||
|
||||
#include "c_colorcorrection.h"
|
||||
#include "filesystem.h"
|
||||
#include "cdll_client_int.h"
|
||||
#include "colorcorrectionmgr.h"
|
||||
#include "materialsystem/MaterialSystemUtil.h"
|
||||
#include "iclientmode.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
static ConVar mat_colcorrection_disableentities( "mat_colcorrection_disableentities", "0", FCVAR_NONE, "Disable map color-correction entities" );
|
||||
|
||||
static ConVar mat_colcorrection_forceentitiesclientside( "mat_colcorrection_forceentitiesclientside", "0", FCVAR_CHEAT, "Forces color correction entities to be updated on the client" );
|
||||
|
||||
#ifdef CColorCorrection
|
||||
#undef CColorCorrection
|
||||
#endif
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ColorCorrection, DT_ColorCorrection, CColorCorrection)
|
||||
RecvPropVector( RECVINFO(m_vecOrigin) ),
|
||||
RecvPropFloat( RECVINFO(m_minFalloff) ),
|
||||
RecvPropFloat( RECVINFO(m_maxFalloff) ),
|
||||
RecvPropFloat( RECVINFO(m_flCurWeight) ),
|
||||
RecvPropFloat( RECVINFO(m_flMaxWeight) ),
|
||||
RecvPropFloat( RECVINFO(m_flFadeInDuration) ),
|
||||
RecvPropFloat( RECVINFO(m_flFadeOutDuration) ),
|
||||
RecvPropString( RECVINFO(m_netLookupFilename) ),
|
||||
RecvPropBool( RECVINFO(m_bEnabled) ),
|
||||
RecvPropBool( RECVINFO(m_bMaster) ),
|
||||
RecvPropBool( RECVINFO(m_bClientSide) ),
|
||||
RecvPropBool( RECVINFO(m_bExclusive) )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//------------------------------------------------------------------------------
|
||||
C_ColorCorrection::C_ColorCorrection()
|
||||
{
|
||||
m_minFalloff = -1.0f;
|
||||
m_maxFalloff = -1.0f;
|
||||
m_flFadeInDuration = 0.0f;
|
||||
m_flFadeOutDuration = 0.0f;
|
||||
m_flCurWeight = 0.0f;
|
||||
m_flMaxWeight = 1.0f;
|
||||
m_netLookupFilename[0] = '\0';
|
||||
m_bEnabled = false;
|
||||
m_bMaster = false;
|
||||
m_bExclusive = false;
|
||||
m_CCHandle = INVALID_CLIENT_CCHANDLE;
|
||||
|
||||
for ( int i = 0; i < MAX_SPLITSCREEN_PLAYERS; i++ )
|
||||
{
|
||||
m_bEnabledOnClient[i] = false;
|
||||
m_flCurWeightOnClient[i] = 0.0f;
|
||||
m_bFadingIn[i] = false;
|
||||
m_flFadeStartWeight[i] = 0.0f;
|
||||
m_flFadeStartTime[i] = 0.0f;
|
||||
m_flFadeDuration[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
C_ColorCorrection::~C_ColorCorrection()
|
||||
{
|
||||
g_pColorCorrectionMgr->RemoveColorCorrectionEntity( this, m_CCHandle );
|
||||
}
|
||||
|
||||
bool C_ColorCorrection::IsClientSide() const
|
||||
{
|
||||
return m_bClientSide || mat_colcorrection_forceentitiesclientside.GetBool();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
void C_ColorCorrection::OnDataChanged(DataUpdateType_t updateType)
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
if ( m_CCHandle == INVALID_CLIENT_CCHANDLE )
|
||||
{
|
||||
// forming a unique name without extension
|
||||
char cleanName[MAX_PATH];
|
||||
V_StripExtension( m_netLookupFilename, cleanName, sizeof( cleanName ) );
|
||||
char name[MAX_PATH];
|
||||
Q_snprintf( name, MAX_PATH, "%s_%d", cleanName, entindex() );
|
||||
|
||||
m_CCHandle = g_pColorCorrectionMgr->AddColorCorrectionEntity( this, name, m_netLookupFilename );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// We don't draw...
|
||||
//------------------------------------------------------------------------------
|
||||
bool C_ColorCorrection::ShouldDraw()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void C_ColorCorrection::Update( C_BasePlayer *pPlayer, float ccScale )
|
||||
{
|
||||
Assert( m_CCHandle != INVALID_CLIENT_CCHANDLE );
|
||||
|
||||
if ( mat_colcorrection_disableentities.GetInt() )
|
||||
{
|
||||
// Allow the colorcorrectionui panel (or user) to turn off color-correction entities
|
||||
g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, 0.0f, m_bExclusive );
|
||||
return;
|
||||
}
|
||||
|
||||
int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT();
|
||||
bool bEnabled = IsClientSide() ? m_bEnabledOnClient[nSlot] : m_bEnabled;
|
||||
|
||||
// fade weight on client
|
||||
if ( IsClientSide() )
|
||||
{
|
||||
m_flCurWeightOnClient[nSlot] = Lerp( GetFadeRatio( nSlot ), m_flFadeStartWeight[nSlot], m_bFadingIn[nSlot] ? m_flMaxWeight : 0.0f );
|
||||
}
|
||||
|
||||
float flCurWeight = IsClientSide() ? m_flCurWeightOnClient[nSlot] : m_flCurWeight;
|
||||
|
||||
if( !bEnabled && flCurWeight == 0.0f )
|
||||
{
|
||||
g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, 0.0f, m_bExclusive );
|
||||
return;
|
||||
}
|
||||
|
||||
Vector playerOrigin = pPlayer->GetAbsOrigin();
|
||||
|
||||
float weight = 0;
|
||||
if ( ( m_minFalloff != -1 ) && ( m_maxFalloff != -1 ) && m_minFalloff != m_maxFalloff )
|
||||
{
|
||||
float dist = (playerOrigin - m_vecOrigin).Length();
|
||||
weight = (dist-m_minFalloff) / (m_maxFalloff-m_minFalloff);
|
||||
if ( weight<0.0f ) weight = 0.0f;
|
||||
if ( weight>1.0f ) weight = 1.0f;
|
||||
}
|
||||
|
||||
g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, flCurWeight * ( 1.0 - weight ) * ccScale, m_bExclusive );
|
||||
}
|
||||
|
||||
void C_ColorCorrection::EnableOnClient( bool bEnable, bool bSkipFade )
|
||||
{
|
||||
if ( !IsClientSide() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT();
|
||||
|
||||
if( m_bEnabledOnClient[nSlot] == bEnable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_bFadingIn[nSlot] = bEnable;
|
||||
m_bEnabledOnClient[nSlot] = bEnable;
|
||||
|
||||
// initialize countdown timer
|
||||
m_flFadeStartWeight[nSlot] = m_flCurWeightOnClient[nSlot];
|
||||
float flFadeTimeScale = 1.0f;
|
||||
if ( m_flMaxWeight != 0.0f )
|
||||
{
|
||||
flFadeTimeScale = m_flCurWeightOnClient[nSlot] / m_flMaxWeight;
|
||||
}
|
||||
|
||||
if ( m_bFadingIn[nSlot] )
|
||||
{
|
||||
flFadeTimeScale = 1.0f - flFadeTimeScale;
|
||||
}
|
||||
|
||||
if ( bSkipFade )
|
||||
{
|
||||
flFadeTimeScale = 0.0f;
|
||||
}
|
||||
|
||||
StartFade( nSlot, flFadeTimeScale * ( m_bFadingIn[nSlot] ? m_flFadeInDuration : m_flFadeOutDuration ) );
|
||||
|
||||
// update the clientside weight once here, in case the fade duration is 0
|
||||
m_flCurWeightOnClient[nSlot] = Lerp( GetFadeRatio( nSlot ), m_flFadeStartWeight[nSlot], m_bFadingIn[nSlot] ? m_flMaxWeight : 0.0f );
|
||||
}
|
||||
|
||||
Vector C_ColorCorrection::GetOrigin()
|
||||
{
|
||||
return m_vecOrigin;
|
||||
}
|
||||
|
||||
float C_ColorCorrection::GetMinFalloff()
|
||||
{
|
||||
return m_minFalloff;
|
||||
}
|
||||
|
||||
float C_ColorCorrection::GetMaxFalloff()
|
||||
{
|
||||
return m_maxFalloff;
|
||||
}
|
||||
|
||||
void C_ColorCorrection::SetWeight( float fWeight )
|
||||
{
|
||||
g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, fWeight, false );
|
||||
}
|
||||
|
||||
void C_ColorCorrection::StartFade( int nSplitScreenSlot, float flDuration )
|
||||
{
|
||||
m_flFadeStartTime[nSplitScreenSlot] = gpGlobals->curtime;
|
||||
m_flFadeDuration[nSplitScreenSlot] = MAX( flDuration, 0.0f );
|
||||
}
|
||||
|
||||
float C_ColorCorrection::GetFadeRatio( int nSplitScreenSlot ) const
|
||||
{
|
||||
float flRatio = 1.0f;
|
||||
|
||||
if ( m_flFadeDuration[nSplitScreenSlot] != 0.0f )
|
||||
{
|
||||
flRatio = ( gpGlobals->curtime - m_flFadeStartTime[nSplitScreenSlot] ) / m_flFadeDuration[nSplitScreenSlot];
|
||||
flRatio = clamp( flRatio, 0.0f, 1.0f );
|
||||
}
|
||||
return flRatio;
|
||||
}
|
||||
|
||||
bool C_ColorCorrection::IsFadeTimeElapsed( int nSplitScreenSlot ) const
|
||||
{
|
||||
return ( ( gpGlobals->curtime - m_flFadeStartTime[nSplitScreenSlot] ) > m_flFadeDuration[nSplitScreenSlot] ) ||
|
||||
( ( gpGlobals->curtime - m_flFadeStartTime[nSplitScreenSlot] ) < 0.0f );
|
||||
}
|
||||
|
||||
#ifndef DOTA_DLL
|
||||
|
||||
void UpdateColorCorrectionEntities( C_BasePlayer *pPlayer, float ccScale, C_ColorCorrection **pList, int listCount )
|
||||
{
|
||||
for ( int i = 0; i < listCount; i++ )
|
||||
{
|
||||
pList[i]->Update(pPlayer, ccScale);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
76
game/client/c_colorcorrection.h
Normal file
76
game/client/c_colorcorrection.h
Normal file
@@ -0,0 +1,76 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: Color correction entity with simple radial falloff
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef C_COLORCORRECTION_H
|
||||
#define C_COLORCORRECTION_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "colorcorrectionmgr.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose : Color correction entity with radial falloff
|
||||
//------------------------------------------------------------------------------
|
||||
class C_ColorCorrection : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_ColorCorrection, C_BaseEntity );
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ColorCorrection();
|
||||
virtual ~C_ColorCorrection();
|
||||
|
||||
void OnDataChanged(DataUpdateType_t updateType);
|
||||
bool ShouldDraw();
|
||||
|
||||
virtual void Update(C_BasePlayer *pPlayer, float ccScale);
|
||||
|
||||
bool IsMaster() const { return m_bMaster; }
|
||||
bool IsClientSide() const;
|
||||
bool IsExclusive() const { return m_bExclusive; }
|
||||
|
||||
void EnableOnClient( bool bEnable, bool bSkipFade = false );
|
||||
|
||||
Vector GetOrigin();
|
||||
float GetMinFalloff();
|
||||
float GetMaxFalloff();
|
||||
|
||||
void SetWeight( float fWeight );
|
||||
|
||||
protected:
|
||||
void StartFade( int nSplitScreenSlot, float flDuration );
|
||||
float GetFadeRatio( int nSplitScreenSlot ) const;
|
||||
bool IsFadeTimeElapsed( int nSplitScreenSlot ) const;
|
||||
|
||||
Vector m_vecOrigin;
|
||||
|
||||
float m_minFalloff;
|
||||
float m_maxFalloff;
|
||||
float m_flFadeInDuration;
|
||||
float m_flFadeOutDuration;
|
||||
float m_flMaxWeight;
|
||||
float m_flCurWeight; // networked from server
|
||||
char m_netLookupFilename[MAX_PATH];
|
||||
|
||||
bool m_bEnabled; // networked from server
|
||||
bool m_bMaster;
|
||||
bool m_bClientSide;
|
||||
bool m_bExclusive;
|
||||
|
||||
bool m_bEnabledOnClient[MAX_SPLITSCREEN_PLAYERS];
|
||||
float m_flCurWeightOnClient[MAX_SPLITSCREEN_PLAYERS];
|
||||
bool m_bFadingIn[MAX_SPLITSCREEN_PLAYERS];
|
||||
float m_flFadeStartWeight[MAX_SPLITSCREEN_PLAYERS];
|
||||
float m_flFadeStartTime[MAX_SPLITSCREEN_PLAYERS];
|
||||
float m_flFadeDuration[MAX_SPLITSCREEN_PLAYERS];
|
||||
|
||||
ClientCCHandle_t m_CCHandle;
|
||||
};
|
||||
|
||||
#endif
|
||||
204
game/client/c_colorcorrectionvolume.cpp
Normal file
204
game/client/c_colorcorrectionvolume.cpp
Normal file
@@ -0,0 +1,204 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: Color correction entity.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
#include "cbase.h"
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "cdll_client_int.h"
|
||||
#include "materialsystem/MaterialSystemUtil.h"
|
||||
#include "colorcorrectionmgr.h"
|
||||
#include "c_triggers.h"
|
||||
|
||||
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// FIXME: This really should inherit from something more lightweight
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose : Shadow control entity
|
||||
//------------------------------------------------------------------------------
|
||||
class C_ColorCorrectionVolume : public C_BaseTrigger
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_ColorCorrectionVolume, C_BaseTrigger );
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
C_ColorCorrectionVolume();
|
||||
virtual ~C_ColorCorrectionVolume();
|
||||
|
||||
void OnDataChanged(DataUpdateType_t updateType);
|
||||
bool ShouldDraw();
|
||||
|
||||
void Update( C_BasePlayer *pPlayer, float ccScale );
|
||||
|
||||
void StartTouch( C_BaseEntity *pOther );
|
||||
void EndTouch( C_BaseEntity *pOther );
|
||||
|
||||
private:
|
||||
float m_LastEnterWeight;
|
||||
float m_LastEnterTime;
|
||||
|
||||
float m_LastExitWeight;
|
||||
float m_LastExitTime;
|
||||
bool m_bEnabled;
|
||||
float m_MaxWeight;
|
||||
float m_FadeDuration;
|
||||
float m_Weight;
|
||||
char m_lookupFilename[MAX_PATH];
|
||||
|
||||
ClientCCHandle_t m_CCHandle;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ColorCorrectionVolume, DT_ColorCorrectionVolume, CColorCorrectionVolume)
|
||||
RecvPropBool( RECVINFO(m_bEnabled) ),
|
||||
RecvPropFloat( RECVINFO(m_MaxWeight) ),
|
||||
RecvPropFloat( RECVINFO(m_FadeDuration) ),
|
||||
RecvPropFloat( RECVINFO(m_Weight) ),
|
||||
RecvPropString( RECVINFO(m_lookupFilename) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
BEGIN_PREDICTION_DATA( C_ColorCorrectionVolume )
|
||||
DEFINE_PRED_FIELD( m_Weight, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//------------------------------------------------------------------------------
|
||||
C_ColorCorrectionVolume::C_ColorCorrectionVolume()
|
||||
{
|
||||
m_CCHandle = INVALID_CLIENT_CCHANDLE;
|
||||
}
|
||||
|
||||
C_ColorCorrectionVolume::~C_ColorCorrectionVolume()
|
||||
{
|
||||
g_pColorCorrectionMgr->RemoveColorCorrectionVolume( this, m_CCHandle );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
void C_ColorCorrectionVolume::OnDataChanged(DataUpdateType_t updateType)
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
if ( m_CCHandle == INVALID_CLIENT_CCHANDLE )
|
||||
{
|
||||
// forming a unique name without extension
|
||||
char cleanName[MAX_PATH];
|
||||
V_StripExtension( m_lookupFilename, cleanName, sizeof( cleanName ) );
|
||||
char name[MAX_PATH];
|
||||
Q_snprintf( name, MAX_PATH, "%s_%d", cleanName, entindex() );
|
||||
|
||||
m_CCHandle = g_pColorCorrectionMgr->AddColorCorrectionVolume( this, name, m_lookupFilename );
|
||||
|
||||
SetSolid( SOLID_BSP );
|
||||
SetSolidFlags( FSOLID_TRIGGER | FSOLID_NOT_SOLID );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// We don't draw...
|
||||
//------------------------------------------------------------------------------
|
||||
bool C_ColorCorrectionVolume::ShouldDraw()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void C_ColorCorrectionVolume::StartTouch( CBaseEntity *pEntity )
|
||||
{
|
||||
m_LastEnterTime = gpGlobals->curtime;
|
||||
m_LastEnterWeight = m_Weight;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void C_ColorCorrectionVolume::EndTouch( CBaseEntity *pEntity )
|
||||
{
|
||||
m_LastExitTime = gpGlobals->curtime;
|
||||
m_LastExitWeight = m_Weight;
|
||||
}
|
||||
|
||||
|
||||
void C_ColorCorrectionVolume::Update( C_BasePlayer *pPlayer, float ccScale )
|
||||
{
|
||||
if ( pPlayer )
|
||||
{
|
||||
bool isTouching = CollisionProp()->IsPointInBounds( pPlayer->EyePosition() );
|
||||
bool wasTouching = m_LastEnterTime > m_LastExitTime;
|
||||
|
||||
if ( isTouching && !wasTouching )
|
||||
{
|
||||
StartTouch( pPlayer );
|
||||
}
|
||||
else if ( !isTouching && wasTouching )
|
||||
{
|
||||
EndTouch( pPlayer );
|
||||
}
|
||||
}
|
||||
|
||||
if( !m_bEnabled )
|
||||
{
|
||||
m_Weight = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_LastEnterTime > m_LastExitTime )
|
||||
{
|
||||
// we most recently entered the volume
|
||||
|
||||
if( m_Weight < 1.0f )
|
||||
{
|
||||
float dt = gpGlobals->curtime - m_LastEnterTime;
|
||||
float weight = m_LastEnterWeight + dt / ((1.0f-m_LastEnterWeight)*m_FadeDuration);
|
||||
if( weight>1.0f )
|
||||
weight = 1.0f;
|
||||
|
||||
m_Weight = weight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we most recently exitted the volume
|
||||
|
||||
if( m_Weight > 0.0f )
|
||||
{
|
||||
float dt = gpGlobals->curtime - m_LastExitTime;
|
||||
float weight = (1.0f-m_LastExitWeight) + dt / (m_LastExitWeight*m_FadeDuration);
|
||||
if( weight>1.0f )
|
||||
weight = 1.0f;
|
||||
|
||||
m_Weight = 1.0f - weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Vector entityPosition = GetAbsOrigin();
|
||||
g_pColorCorrectionMgr->SetColorCorrectionWeight( m_CCHandle, m_Weight * ccScale );
|
||||
}
|
||||
|
||||
|
||||
void UpdateColorCorrectionVolumes( C_BasePlayer *pPlayer, float ccScale, C_ColorCorrectionVolume **pList, int listCount )
|
||||
{
|
||||
for ( int i = 0; i < listCount; i++ )
|
||||
{
|
||||
pList[i]->Update(pPlayer, ccScale);
|
||||
}
|
||||
}
|
||||
239
game/client/c_dynamiclight.cpp
Normal file
239
game/client/c_dynamiclight.cpp
Normal file
@@ -0,0 +1,239 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Dynamic light
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "dlight.h"
|
||||
#include "iefx.h"
|
||||
#include "iviewrender.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
#if HL2_EPISODIC
|
||||
// In Episodic we unify the NO_WORLD_ILLUMINATION lights to use
|
||||
// the more efficient elight structure instead. This should theoretically
|
||||
// be extended to other projects but may have unintended consequences
|
||||
// and bears more thorough testing.
|
||||
//
|
||||
// For an earlier iteration on this technique see changelist 214433,
|
||||
// which had a specific flag for use of elights.
|
||||
#define DLIGHT_NO_WORLD_USES_ELIGHT 1
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A dynamic light, with the goofy hack needed for spotlights
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_DynamicLight : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_DynamicLight, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_DynamicLight();
|
||||
|
||||
public:
|
||||
void OnDataChanged(DataUpdateType_t updateType);
|
||||
bool ShouldDraw();
|
||||
void ClientThink( void );
|
||||
void Release( void );
|
||||
|
||||
unsigned char m_Flags;
|
||||
unsigned char m_LightStyle;
|
||||
|
||||
float m_Radius;
|
||||
int m_Exponent;
|
||||
float m_InnerAngle;
|
||||
float m_OuterAngle;
|
||||
float m_SpotRadius;
|
||||
|
||||
private:
|
||||
dlight_t* m_pDynamicLight;
|
||||
dlight_t* m_pSpotlightEnd;
|
||||
|
||||
|
||||
inline bool ShouldBeElight() { return (m_Flags & DLIGHT_NO_WORLD_ILLUMINATION); }
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_DynamicLight, DT_DynamicLight, CDynamicLight)
|
||||
RecvPropInt (RECVINFO(m_Flags)),
|
||||
RecvPropInt (RECVINFO(m_LightStyle)),
|
||||
RecvPropFloat (RECVINFO(m_Radius)),
|
||||
RecvPropInt (RECVINFO(m_Exponent)),
|
||||
RecvPropFloat (RECVINFO(m_InnerAngle)),
|
||||
RecvPropFloat (RECVINFO(m_OuterAngle)),
|
||||
RecvPropFloat (RECVINFO(m_SpotRadius)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//------------------------------------------------------------------------------
|
||||
C_DynamicLight::C_DynamicLight(void) : m_pSpotlightEnd(0), m_pDynamicLight(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//------------------------------------------------------------------------------
|
||||
void C_DynamicLight::OnDataChanged(DataUpdateType_t updateType)
|
||||
{
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink(gpGlobals->curtime + 0.05);
|
||||
}
|
||||
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//------------------------------------------------------------------------------
|
||||
bool C_DynamicLight::ShouldDraw()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose : Disable drawing of this light when entity perishes
|
||||
//------------------------------------------------------------------------------
|
||||
void C_DynamicLight::Release()
|
||||
{
|
||||
if (m_pDynamicLight)
|
||||
{
|
||||
m_pDynamicLight->die = gpGlobals->curtime;
|
||||
m_pDynamicLight = 0;
|
||||
}
|
||||
|
||||
if (m_pSpotlightEnd)
|
||||
{
|
||||
m_pSpotlightEnd->die = gpGlobals->curtime;
|
||||
m_pSpotlightEnd = 0;
|
||||
}
|
||||
|
||||
BaseClass::Release();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//------------------------------------------------------------------------------
|
||||
void C_DynamicLight::ClientThink(void)
|
||||
{
|
||||
Vector forward;
|
||||
AngleVectors( GetAbsAngles(), &forward );
|
||||
|
||||
if ( (m_Flags & DLIGHT_NO_MODEL_ILLUMINATION) == 0 )
|
||||
{
|
||||
// Deal with the model light
|
||||
if ( !m_pDynamicLight || (m_pDynamicLight->key != index) )
|
||||
{
|
||||
#if DLIGHT_NO_WORLD_USES_ELIGHT
|
||||
m_pDynamicLight = ShouldBeElight() != 0
|
||||
? effects->CL_AllocElight( index )
|
||||
: effects->CL_AllocDlight( index );
|
||||
#else
|
||||
m_pDynamicLight = effects->CL_AllocDlight( index );
|
||||
#endif
|
||||
Assert (m_pDynamicLight);
|
||||
m_pDynamicLight->minlight = 0;
|
||||
}
|
||||
|
||||
m_pDynamicLight->style = m_LightStyle;
|
||||
m_pDynamicLight->radius = m_Radius;
|
||||
m_pDynamicLight->flags = m_Flags;
|
||||
if ( m_OuterAngle > 0 )
|
||||
m_pDynamicLight->flags |= DLIGHT_NO_WORLD_ILLUMINATION;
|
||||
color24 c = GetRenderColor();
|
||||
m_pDynamicLight->color.r = c.r;
|
||||
m_pDynamicLight->color.g = c.g;
|
||||
m_pDynamicLight->color.b = c.b;
|
||||
m_pDynamicLight->color.exponent = m_Exponent; // this makes it match the world
|
||||
m_pDynamicLight->origin = GetAbsOrigin();
|
||||
m_pDynamicLight->m_InnerAngle = m_InnerAngle;
|
||||
m_pDynamicLight->m_OuterAngle = m_OuterAngle;
|
||||
m_pDynamicLight->die = gpGlobals->curtime + 1e6;
|
||||
m_pDynamicLight->m_Direction = forward;
|
||||
}
|
||||
else
|
||||
{
|
||||
// In this case, the m_Flags could have changed; which is how we turn the light off
|
||||
if (m_pDynamicLight)
|
||||
{
|
||||
m_pDynamicLight->die = gpGlobals->curtime;
|
||||
m_pDynamicLight = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if DLIGHT_NO_WORLD_USES_ELIGHT
|
||||
if (( m_OuterAngle > 0 ) && !ShouldBeElight())
|
||||
#else
|
||||
if (( m_OuterAngle > 0 ) && ((m_Flags & DLIGHT_NO_WORLD_ILLUMINATION) == 0))
|
||||
#endif
|
||||
{
|
||||
// Raycast to where the endpoint goes
|
||||
// Deal with the environment light
|
||||
if ( !m_pSpotlightEnd || (m_pSpotlightEnd->key != -index) )
|
||||
{
|
||||
m_pSpotlightEnd = effects->CL_AllocDlight( -index );
|
||||
Assert (m_pSpotlightEnd);
|
||||
}
|
||||
|
||||
// Trace a line outward, don't use hitboxes (too slow)
|
||||
Vector end;
|
||||
VectorMA( GetAbsOrigin(), m_Radius, forward, end );
|
||||
|
||||
trace_t pm;
|
||||
C_BaseEntity::PushEnableAbsRecomputations( false ); // HACK don't recompute positions while doing RayTrace
|
||||
UTIL_TraceLine( GetAbsOrigin(), end, MASK_NPCWORLDSTATIC, NULL, COLLISION_GROUP_NONE, &pm );
|
||||
C_BaseEntity::PopEnableAbsRecomputations();
|
||||
VectorCopy( pm.endpos, m_pSpotlightEnd->origin );
|
||||
|
||||
if (pm.fraction == 1.0f)
|
||||
{
|
||||
m_pSpotlightEnd->die = gpGlobals->curtime;
|
||||
m_pSpotlightEnd = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
float falloff = 1.0 - pm.fraction;
|
||||
falloff *= falloff;
|
||||
|
||||
m_pSpotlightEnd->style = m_LightStyle;
|
||||
m_pSpotlightEnd->flags = DLIGHT_NO_MODEL_ILLUMINATION | (m_Flags & DLIGHT_DISPLACEMENT_MASK);
|
||||
m_pSpotlightEnd->radius = m_SpotRadius; // * falloff;
|
||||
m_pSpotlightEnd->die = gpGlobals->curtime + 1e6;
|
||||
color24 c = GetRenderColor();
|
||||
m_pSpotlightEnd->color.r = c.r * falloff;
|
||||
m_pSpotlightEnd->color.g = c.g * falloff;
|
||||
m_pSpotlightEnd->color.b = c.b * falloff;
|
||||
m_pSpotlightEnd->color.exponent = m_Exponent;
|
||||
|
||||
// For bumped lighting
|
||||
m_pSpotlightEnd->m_Direction = forward;
|
||||
|
||||
// Update list of surfaces we influence
|
||||
render->TouchLight( m_pSpotlightEnd );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// In this case, the m_Flags could have changed; which is how we turn the light off
|
||||
if (m_pSpotlightEnd)
|
||||
{
|
||||
m_pSpotlightEnd->die = gpGlobals->curtime;
|
||||
m_pSpotlightEnd = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SetNextClientThink(gpGlobals->curtime + 0.001);
|
||||
}
|
||||
|
||||
2670
game/client/c_effects.cpp
Normal file
2670
game/client/c_effects.cpp
Normal file
File diff suppressed because it is too large
Load Diff
210
game/client/c_effects.h
Normal file
210
game/client/c_effects.h
Normal file
@@ -0,0 +1,210 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_EFFECTS_H
|
||||
#define C_EFFECTS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "cbase.h"
|
||||
#include "precipitation_shared.h"
|
||||
|
||||
// Draw rain effects.
|
||||
void DrawPrecipitation();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Precipitation particle type
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class CPrecipitationParticle
|
||||
{
|
||||
public:
|
||||
Vector m_Pos;
|
||||
Vector m_Velocity;
|
||||
float m_SpawnTime; // Note: Tweak with this to change lifetime
|
||||
float m_Mass;
|
||||
float m_Ramp;
|
||||
|
||||
float m_flMaxLifetime;
|
||||
int m_nSplitScreenPlayerSlot;
|
||||
};
|
||||
|
||||
class CClient_Precipitation;
|
||||
static CUtlVector<CClient_Precipitation*> g_Precipitations;
|
||||
|
||||
//===========
|
||||
// Snow fall
|
||||
//===========
|
||||
class CSnowFallManager;
|
||||
static CSnowFallManager *s_pSnowFallMgr[ MAX_SPLITSCREEN_PLAYERS ];
|
||||
bool SnowFallManagerCreate( CClient_Precipitation *pSnowEntity );
|
||||
void SnowFallManagerDestroy( void );
|
||||
|
||||
class AshDebrisEffect : public CSimpleEmitter
|
||||
{
|
||||
public:
|
||||
explicit AshDebrisEffect( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
|
||||
|
||||
static AshDebrisEffect* Create( const char *pDebugName );
|
||||
|
||||
virtual float UpdateAlpha( const SimpleParticle *pParticle );
|
||||
virtual float UpdateRoll( SimpleParticle *pParticle, float timeDelta );
|
||||
|
||||
private:
|
||||
AshDebrisEffect( const AshDebrisEffect & );
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Precipitation blocker entity
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_PrecipitationBlocker : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_PrecipitationBlocker, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_PrecipitationBlocker();
|
||||
virtual ~C_PrecipitationBlocker();
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Precipitation base entity
|
||||
//-----------------------------------------------------------------------------
|
||||
class CClient_Precipitation : public C_BaseEntity
|
||||
{
|
||||
class CPrecipitationEffect;
|
||||
friend class CClient_Precipitation::CPrecipitationEffect;
|
||||
|
||||
public:
|
||||
DECLARE_CLASS( CClient_Precipitation, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
CClient_Precipitation();
|
||||
virtual ~CClient_Precipitation();
|
||||
|
||||
// Inherited from C_BaseEntity
|
||||
virtual void Precache( );
|
||||
virtual RenderableTranslucencyType_t ComputeTranslucencyType() { return RENDERABLE_IS_TRANSLUCENT; }
|
||||
|
||||
void Render();
|
||||
|
||||
// Computes where we're gonna emit
|
||||
bool ComputeEmissionArea( Vector& origin, Vector2D& size, C_BaseCombatCharacter *pCharacter );
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Creates a single particle
|
||||
CPrecipitationParticle* CreateParticle();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void ClientThink();
|
||||
|
||||
void Simulate( float dt );
|
||||
|
||||
// Renders the particle
|
||||
void RenderParticle( CPrecipitationParticle* pParticle, CMeshBuilder &mb );
|
||||
|
||||
void CreateWaterSplashes();
|
||||
|
||||
// Emits the actual particles
|
||||
void EmitParticles( float fTimeDelta );
|
||||
|
||||
// Gets the tracer width and speed
|
||||
float GetWidth() const;
|
||||
float GetLength() const;
|
||||
float GetSpeed() const;
|
||||
|
||||
// Gets the remaining lifetime of the particle
|
||||
float GetRemainingLifetime( CPrecipitationParticle* pParticle ) const;
|
||||
|
||||
// Computes the wind vector
|
||||
static void ComputeWindVector( );
|
||||
|
||||
// simulation methods
|
||||
bool SimulateRain( CPrecipitationParticle* pParticle, float dt );
|
||||
bool SimulateSnow( CPrecipitationParticle* pParticle, float dt );
|
||||
|
||||
void CreateParticlePrecip( void );
|
||||
void InitializeParticlePrecip( void );
|
||||
void DispatchOuterParticlePrecip( int nSlot, C_BasePlayer *pPlayer, Vector vForward );
|
||||
void DispatchInnerParticlePrecip( int nSlot, C_BasePlayer *pPlayer, Vector vForward );
|
||||
void DestroyOuterParticlePrecip( int nSlot );
|
||||
void DestroyInnerParticlePrecip( int nSlot );
|
||||
|
||||
void UpdateParticlePrecip( C_BasePlayer *pPlayer, int nSlot );
|
||||
float GetDensity() { return m_flDensity; }
|
||||
|
||||
private:
|
||||
void CreateAshParticle( void );
|
||||
void CreateRainOrSnowParticle( const Vector &vSpawnPosition, const Vector &vEndPosition, const Vector &vVelocity ); // TERROR: adding end pos for lifetime calcs
|
||||
|
||||
// Information helpful in creating and rendering particles
|
||||
IMaterial *m_MatHandle; // material used
|
||||
|
||||
float m_Color[4]; // precip color
|
||||
float m_Lifetime; // Precip lifetime
|
||||
float m_InitialRamp; // Initial ramp value
|
||||
float m_Speed; // Precip speed
|
||||
float m_Width; // Tracer width
|
||||
float m_Remainder; // particles we should render next time
|
||||
PrecipitationType_t m_nPrecipType; // Precip type
|
||||
float m_flHalfScreenWidth; // Precalculated each frame.
|
||||
|
||||
float m_flDensity;
|
||||
|
||||
#ifdef INFESTED_DLL
|
||||
int m_nSnowDustAmount;
|
||||
#endif
|
||||
|
||||
// Some state used in rendering and simulation
|
||||
// Used to modify the rain density and wind from the console
|
||||
static ConVar s_raindensity;
|
||||
static ConVar s_rainwidth;
|
||||
static ConVar s_rainlength;
|
||||
static ConVar s_rainspeed;
|
||||
|
||||
static Vector s_WindVector; // Stores the wind speed vector
|
||||
|
||||
CUtlLinkedList<CPrecipitationParticle> m_Particles;
|
||||
CUtlVector<Vector> m_Splashes;
|
||||
|
||||
struct AshSplit_t
|
||||
{
|
||||
AshSplit_t() : m_bActiveAshEmitter( false ), m_vAshSpawnOrigin( 0, 0, 0 ), m_iAshCount( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
CSmartPtr<AshDebrisEffect> m_pAshEmitter;
|
||||
TimedEvent m_tAshParticleTimer;
|
||||
TimedEvent m_tAshParticleTraceTimer;
|
||||
bool m_bActiveAshEmitter;
|
||||
Vector m_vAshSpawnOrigin;
|
||||
|
||||
int m_iAshCount;
|
||||
};
|
||||
|
||||
protected:
|
||||
AshSplit_t m_Ash[ MAX_SPLITSCREEN_PLAYERS ];
|
||||
|
||||
float m_flParticleInnerDist; //The distance at which to start drawing the inner system
|
||||
char *m_pParticleInnerNearDef; //Name of the first inner system
|
||||
char *m_pParticleInnerFarDef; //Name of the second inner system
|
||||
char *m_pParticleOuterDef; //Name of the outer system
|
||||
HPARTICLEFFECT m_pParticlePrecipInnerNear[ MAX_SPLITSCREEN_PLAYERS ];
|
||||
HPARTICLEFFECT m_pParticlePrecipInnerFar[ MAX_SPLITSCREEN_PLAYERS ];
|
||||
HPARTICLEFFECT m_pParticlePrecipOuter[ MAX_SPLITSCREEN_PLAYERS ];
|
||||
TimedEvent m_tParticlePrecipTraceTimer[ MAX_SPLITSCREEN_PLAYERS ];
|
||||
bool m_bActiveParticlePrecipEmitter[ MAX_SPLITSCREEN_PLAYERS ];
|
||||
bool m_bParticlePrecipInitialized;
|
||||
|
||||
private:
|
||||
CClient_Precipitation( const CClient_Precipitation & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
|
||||
#endif // C_EFFECTS_H
|
||||
788
game/client/c_entitydissolve.cpp
Normal file
788
game/client/c_entitydissolve.cpp
Normal file
@@ -0,0 +1,788 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
#include "iviewrender.h"
|
||||
#include "view.h"
|
||||
#include "studio.h"
|
||||
#include "bone_setup.h"
|
||||
#include "model_types.h"
|
||||
#include "beamdraw.h"
|
||||
#include "engine/ivdebugoverlay.h"
|
||||
#include "iviewrender_beams.h"
|
||||
#include "fx.h"
|
||||
#include "IEffects.h"
|
||||
#include "c_entitydissolve.h"
|
||||
#include "movevars_shared.h"
|
||||
#include "precache_register.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
ConVar cl_portal_use_new_dissolve( "cl_portal_use_new_dissolve", "1", FCVAR_CHEAT, "Use new dissolve effect" );
|
||||
|
||||
PRECACHE_REGISTER_BEGIN( GLOBAL, PrecacheEffectBuild )
|
||||
PRECACHE( MATERIAL,"effects/tesla_glow_noz" )
|
||||
PRECACHE( MATERIAL,"effects/spark" )
|
||||
PRECACHE( MATERIAL,"effects/combinemuzzle2" )
|
||||
PRECACHE( PARTICLE_SYSTEM, "dissolve" )
|
||||
PRECACHE_REGISTER_END()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Networking
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EntityDissolve, DT_EntityDissolve, CEntityDissolve )
|
||||
RecvPropTime(RECVINFO(m_flStartTime)),
|
||||
RecvPropFloat(RECVINFO(m_flFadeOutStart)),
|
||||
RecvPropFloat(RECVINFO(m_flFadeOutLength)),
|
||||
RecvPropFloat(RECVINFO(m_flFadeOutModelStart)),
|
||||
RecvPropFloat(RECVINFO(m_flFadeOutModelLength)),
|
||||
RecvPropFloat(RECVINFO(m_flFadeInStart)),
|
||||
RecvPropFloat(RECVINFO(m_flFadeInLength)),
|
||||
RecvPropInt(RECVINFO(m_nDissolveType)),
|
||||
RecvPropVector( RECVINFO( m_vDissolverOrigin) ),
|
||||
RecvPropInt( RECVINFO( m_nMagnitude ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
extern PMaterialHandle g_Material_Spark;
|
||||
PMaterialHandle g_Material_AR2Glow = NULL;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CEG_NOINLINE C_EntityDissolve::C_EntityDissolve( void )
|
||||
{
|
||||
m_bLinkedToServerEnt = true;
|
||||
CEG_PROTECT_MEMBER_FUNCTION( C_EntityDissolve_C_EntityDissolve );
|
||||
m_pController = NULL;
|
||||
m_bCoreExplode = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityDissolve::GetRenderBounds( Vector& theMins, Vector& theMaxs )
|
||||
{
|
||||
if ( GetMoveParent() )
|
||||
{
|
||||
GetMoveParent()->GetRenderBounds( theMins, theMaxs );
|
||||
}
|
||||
else
|
||||
{
|
||||
theMins = GetAbsOrigin();
|
||||
theMaxs = theMaxs;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// On data changed
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityDissolve::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
m_flNextSparkTime = m_flStartTime;
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
if ( cl_portal_use_new_dissolve.GetBool() )
|
||||
DispatchParticleEffect( "dissolve", PATTACH_ABSORIGIN_FOLLOW, GetMoveParent() );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Cleanup
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityDissolve::UpdateOnRemove( void )
|
||||
{
|
||||
if ( m_pController )
|
||||
{
|
||||
physenv->DestroyMotionController( m_pController );
|
||||
m_pController = NULL;
|
||||
}
|
||||
|
||||
BaseClass::UpdateOnRemove();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Apply the forces to the entity
|
||||
//------------------------------------------------------------------------------
|
||||
IMotionEvent::simresult_e C_EntityDissolve::Simulate( IPhysicsMotionController *pController, IPhysicsObject *pObject, float deltaTime, Vector &linear, AngularImpulse &angular )
|
||||
{
|
||||
linear.Init();
|
||||
angular.Init();
|
||||
|
||||
// Make it zero g
|
||||
linear.z -= -1.02 * sv_gravity.GetFloat();
|
||||
|
||||
Vector vel;
|
||||
AngularImpulse angVel;
|
||||
pObject->GetVelocity( &vel, &angVel );
|
||||
vel += linear * deltaTime; // account for gravity scale
|
||||
|
||||
Vector unitVel = vel;
|
||||
Vector unitAngVel = angVel;
|
||||
|
||||
float speed = VectorNormalize( unitVel );
|
||||
// float angSpeed = VectorNormalize( unitAngVel );
|
||||
|
||||
// float speedScale = 0.0;
|
||||
// float angSpeedScale = 0.0;
|
||||
|
||||
float flLinearLimit = 50;
|
||||
float flLinearLimitDelta = 40;
|
||||
if ( speed > flLinearLimit )
|
||||
{
|
||||
float flDeltaVel = (flLinearLimit - speed) / deltaTime;
|
||||
if ( flLinearLimitDelta != 0.0f )
|
||||
{
|
||||
float flMaxDeltaVel = -flLinearLimitDelta / deltaTime;
|
||||
if ( flDeltaVel < flMaxDeltaVel )
|
||||
{
|
||||
flDeltaVel = flMaxDeltaVel;
|
||||
}
|
||||
}
|
||||
VectorMA( linear, flDeltaVel, unitVel, linear );
|
||||
}
|
||||
|
||||
return SIM_GLOBAL_ACCELERATION;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Tesla effect
|
||||
//-----------------------------------------------------------------------------
|
||||
static void FX_BuildTesla( C_BaseEntity *pEntity, Vector &vecOrigin, Vector &vecEnd )
|
||||
{
|
||||
BeamInfo_t beamInfo;
|
||||
beamInfo.m_pStartEnt = pEntity;
|
||||
beamInfo.m_nStartAttachment = 0;
|
||||
beamInfo.m_pEndEnt = NULL;
|
||||
beamInfo.m_nEndAttachment = 0;
|
||||
beamInfo.m_nType = TE_BEAMTESLA;
|
||||
beamInfo.m_vecStart = vecOrigin;
|
||||
beamInfo.m_vecEnd = vecEnd;
|
||||
beamInfo.m_pszModelName = "sprites/lgtning.vmt";
|
||||
beamInfo.m_flHaloScale = 0.0;
|
||||
beamInfo.m_flLife = random->RandomFloat( 0.25f, 1.0f );
|
||||
beamInfo.m_flWidth = random->RandomFloat( 8.0f, 14.0f );
|
||||
beamInfo.m_flEndWidth = 1.0f;
|
||||
beamInfo.m_flFadeLength = 0.5f;
|
||||
beamInfo.m_flAmplitude = 24;
|
||||
beamInfo.m_flBrightness = 255.0;
|
||||
beamInfo.m_flSpeed = 150.0f;
|
||||
beamInfo.m_nStartFrame = 0.0;
|
||||
beamInfo.m_flFrameRate = 30.0;
|
||||
beamInfo.m_flRed = 255.0;
|
||||
beamInfo.m_flGreen = 255.0;
|
||||
beamInfo.m_flBlue = 255.0;
|
||||
beamInfo.m_nSegments = 18;
|
||||
beamInfo.m_bRenderable = true;
|
||||
beamInfo.m_nFlags = 0; //FBEAM_ONLYNOISEONCE;
|
||||
|
||||
beams->CreateBeamEntPoint( beamInfo );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Tesla effect
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityDissolve::BuildTeslaEffect( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld, bool bRandom, float flYawOffset )
|
||||
{
|
||||
Vector vecOrigin;
|
||||
QAngle vecAngles;
|
||||
MatrixGetColumn( hitboxToWorld, 3, vecOrigin );
|
||||
MatrixAngles( hitboxToWorld, vecAngles.Base() );
|
||||
C_BaseEntity *pEntity = GetMoveParent();
|
||||
|
||||
// Make a couple of tries at it
|
||||
int iTries = -1;
|
||||
Vector vecForward;
|
||||
trace_t tr;
|
||||
do
|
||||
{
|
||||
iTries++;
|
||||
|
||||
// Some beams are deliberatly aimed around the point, the rest are random.
|
||||
if ( !bRandom )
|
||||
{
|
||||
QAngle vecTemp = vecAngles;
|
||||
vecTemp[YAW] += flYawOffset;
|
||||
AngleVectors( vecTemp, &vecForward );
|
||||
|
||||
// Randomly angle it up or down
|
||||
vecForward.z = RandomFloat( -1, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
vecForward = RandomVector( -1, 1 );
|
||||
}
|
||||
|
||||
UTIL_TraceLine( vecOrigin, vecOrigin + (vecForward * 192), MASK_SHOT, pEntity, COLLISION_GROUP_NONE, &tr );
|
||||
} while ( tr.fraction >= 1.0 && iTries < 3 );
|
||||
|
||||
Vector vecEnd = tr.endpos - (vecForward * 8);
|
||||
|
||||
// Only spark & glow if we hit something
|
||||
if ( tr.fraction < 1.0 )
|
||||
{
|
||||
if ( !EffectOccluded( tr.endpos ) )
|
||||
{
|
||||
int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT();
|
||||
|
||||
// Move it towards the camera
|
||||
Vector vecFlash = tr.endpos;
|
||||
Vector vecForward;
|
||||
AngleVectors( MainViewAngles(nSlot), &vecForward );
|
||||
vecFlash -= (vecForward * 8);
|
||||
|
||||
g_pEffects->EnergySplash( vecFlash, -vecForward, false );
|
||||
|
||||
// End glow
|
||||
CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "dust" );
|
||||
pSimple->SetSortOrigin( vecFlash );
|
||||
SimpleParticle *pParticle;
|
||||
pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/tesla_glow_noz" ), vecFlash );
|
||||
if ( pParticle != NULL )
|
||||
{
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = RandomFloat( 0.5, 1 );
|
||||
pParticle->m_vecVelocity = vec3_origin;
|
||||
Vector color( 1,1,1 );
|
||||
float colorRamp = RandomFloat( 0.75f, 1.25f );
|
||||
pParticle->m_uchColor[0] = MIN( 1.0f, color[0] * colorRamp ) * 255.0f;
|
||||
pParticle->m_uchColor[1] = MIN( 1.0f, color[1] * colorRamp ) * 255.0f;
|
||||
pParticle->m_uchColor[2] = MIN( 1.0f, color[2] * colorRamp ) * 255.0f;
|
||||
pParticle->m_uchStartSize = RandomFloat( 6,13 );
|
||||
pParticle->m_uchEndSize = pParticle->m_uchStartSize - 2;
|
||||
pParticle->m_uchStartAlpha = 255;
|
||||
pParticle->m_uchEndAlpha = 10;
|
||||
pParticle->m_flRoll = RandomFloat( 0,360 );
|
||||
pParticle->m_flRollDelta = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build the tesla
|
||||
FX_BuildTesla( pEntity, vecOrigin, tr.endpos );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sorts the components of a vector
|
||||
//-----------------------------------------------------------------------------
|
||||
static inline void SortAbsVectorComponents( const Vector& src, int* pVecIdx )
|
||||
{
|
||||
Vector absVec( fabs(src[0]), fabs(src[1]), fabs(src[2]) );
|
||||
|
||||
int maxIdx = (absVec[0] > absVec[1]) ? 0 : 1;
|
||||
if (absVec[2] > absVec[maxIdx])
|
||||
{
|
||||
maxIdx = 2;
|
||||
}
|
||||
|
||||
// always choose something right-handed....
|
||||
switch( maxIdx )
|
||||
{
|
||||
case 0:
|
||||
pVecIdx[0] = 1;
|
||||
pVecIdx[1] = 2;
|
||||
pVecIdx[2] = 0;
|
||||
break;
|
||||
case 1:
|
||||
pVecIdx[0] = 2;
|
||||
pVecIdx[1] = 0;
|
||||
pVecIdx[2] = 1;
|
||||
break;
|
||||
case 2:
|
||||
pVecIdx[0] = 0;
|
||||
pVecIdx[1] = 1;
|
||||
pVecIdx[2] = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Compute the bounding box's center, size, and basis
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityDissolve::ComputeRenderInfo( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld,
|
||||
Vector *pVecAbsOrigin, Vector *pXVec, Vector *pYVec )
|
||||
{
|
||||
// Compute the center of the hitbox in worldspace
|
||||
Vector vecHitboxCenter;
|
||||
VectorAdd( pHitBox->bbmin, pHitBox->bbmax, vecHitboxCenter );
|
||||
vecHitboxCenter *= 0.5f;
|
||||
VectorTransform( vecHitboxCenter, hitboxToWorld, *pVecAbsOrigin );
|
||||
|
||||
// Get the object's basis
|
||||
Vector vec[3];
|
||||
MatrixGetColumn( hitboxToWorld, 0, vec[0] );
|
||||
MatrixGetColumn( hitboxToWorld, 1, vec[1] );
|
||||
MatrixGetColumn( hitboxToWorld, 2, vec[2] );
|
||||
// vec[1] *= -1.0f;
|
||||
|
||||
Vector vecViewDir;
|
||||
VectorSubtract( CurrentViewOrigin(), *pVecAbsOrigin, vecViewDir );
|
||||
VectorNormalize( vecViewDir );
|
||||
|
||||
// Project the shadow casting direction into the space of the hitbox
|
||||
Vector localViewDir;
|
||||
localViewDir[0] = DotProduct( vec[0], vecViewDir );
|
||||
localViewDir[1] = DotProduct( vec[1], vecViewDir );
|
||||
localViewDir[2] = DotProduct( vec[2], vecViewDir );
|
||||
|
||||
// Figure out which vector has the largest component perpendicular
|
||||
// to the view direction...
|
||||
// Sort by how perpendicular it is
|
||||
int vecIdx[3];
|
||||
SortAbsVectorComponents( localViewDir, vecIdx );
|
||||
|
||||
// Here's our hitbox basis vectors; namely the ones that are
|
||||
// most perpendicular to the view direction
|
||||
*pXVec = vec[vecIdx[0]];
|
||||
*pYVec = vec[vecIdx[1]];
|
||||
|
||||
// Project them into a plane perpendicular to the view direction
|
||||
*pXVec -= vecViewDir * DotProduct( vecViewDir, *pXVec );
|
||||
*pYVec -= vecViewDir * DotProduct( vecViewDir, *pYVec );
|
||||
VectorNormalize( *pXVec );
|
||||
VectorNormalize( *pYVec );
|
||||
|
||||
// Compute the hitbox size
|
||||
Vector boxSize;
|
||||
VectorSubtract( pHitBox->bbmax, pHitBox->bbmin, boxSize );
|
||||
|
||||
// We project the two longest sides into the vectors perpendicular
|
||||
// to the projection direction, then add in the projection of the perp direction
|
||||
Vector2D size( boxSize[vecIdx[0]], boxSize[vecIdx[1]] );
|
||||
size.x *= fabs( DotProduct( vec[vecIdx[0]], *pXVec ) );
|
||||
size.y *= fabs( DotProduct( vec[vecIdx[1]], *pYVec ) );
|
||||
|
||||
// Add the third component into x and y
|
||||
size.x += boxSize[vecIdx[2]] * fabs( DotProduct( vec[vecIdx[2]], *pXVec ) );
|
||||
size.y += boxSize[vecIdx[2]] * fabs( DotProduct( vec[vecIdx[2]], *pYVec ) );
|
||||
|
||||
// Bloat a bit, since the shadow wants to extend outside the model a bit
|
||||
size *= 2.0f;
|
||||
|
||||
// Clamp the minimum size
|
||||
Vector2DMax( size, Vector2D(10.0f, 10.0f), size );
|
||||
|
||||
// Factor the size into the xvec + yvec
|
||||
(*pXVec) *= size.x * 0.5f;
|
||||
(*pYVec) *= size.y * 0.5f;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sparks!
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityDissolve::DoSparks( mstudiohitboxset_t *set, matrix3x4_t *hitboxbones[MAXSTUDIOBONES] )
|
||||
{
|
||||
if ( m_flNextSparkTime > gpGlobals->curtime )
|
||||
return;
|
||||
|
||||
float dt = m_flStartTime + m_flFadeOutStart - gpGlobals->curtime;
|
||||
dt = clamp( dt, 0.0f, m_flFadeOutStart );
|
||||
|
||||
float flNextTime;
|
||||
if (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL)
|
||||
{
|
||||
flNextTime = SimpleSplineRemapVal( dt, 0.0f, m_flFadeOutStart, 2.0f * TICK_INTERVAL, 0.4f );
|
||||
}
|
||||
else
|
||||
{
|
||||
// m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT);
|
||||
flNextTime = SimpleSplineRemapVal( dt, 0.0f, m_flFadeOutStart, 0.3f, 1.0f );
|
||||
}
|
||||
|
||||
m_flNextSparkTime = gpGlobals->curtime + flNextTime;
|
||||
|
||||
// Send out beams around us
|
||||
int iNumBeamsAround = 2;
|
||||
int iNumRandomBeams = 1;
|
||||
int iTotalBeams = iNumBeamsAround + iNumRandomBeams;
|
||||
float flYawOffset = RandomFloat(0,360);
|
||||
for ( int i = 0; i < iTotalBeams; i++ )
|
||||
{
|
||||
int nHitbox = random->RandomInt( 0, set->numhitboxes - 1 );
|
||||
mstudiobbox_t *pBox = set->pHitbox(nHitbox);
|
||||
|
||||
float flActualYawOffset = 0;
|
||||
bool bRandom = ( i >= iNumBeamsAround );
|
||||
if ( !bRandom )
|
||||
{
|
||||
flActualYawOffset = anglemod( flYawOffset + ((360 / iTotalBeams) * i) );
|
||||
}
|
||||
|
||||
BuildTeslaEffect( pBox, *hitboxbones[pBox->bone], bRandom, flActualYawOffset );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityDissolve::SetupEmitter( void )
|
||||
{
|
||||
if ( !m_pEmitter )
|
||||
{
|
||||
m_pEmitter = CSimpleEmitter::Create( "C_EntityDissolve" );
|
||||
m_pEmitter->SetSortOrigin( GetAbsOrigin() );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
float C_EntityDissolve::GetFadeInPercentage( void )
|
||||
{
|
||||
float dt = gpGlobals->curtime - m_flStartTime;
|
||||
|
||||
if ( dt > m_flFadeOutStart )
|
||||
return 1.0f;
|
||||
|
||||
if ( dt < m_flFadeInStart )
|
||||
return 0.0f;
|
||||
|
||||
if ( (dt > m_flFadeInStart) && (dt < m_flFadeInStart + m_flFadeInLength) )
|
||||
{
|
||||
dt -= m_flFadeInStart;
|
||||
|
||||
return ( dt / m_flFadeInLength );
|
||||
}
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
float C_EntityDissolve::GetFadeOutPercentage( void )
|
||||
{
|
||||
float dt = gpGlobals->curtime - m_flStartTime;
|
||||
|
||||
if ( dt < m_flFadeInStart )
|
||||
return 1.0f;
|
||||
|
||||
if ( dt > m_flFadeOutStart )
|
||||
{
|
||||
dt -= m_flFadeOutStart;
|
||||
|
||||
RANDOM_CEG_TEST_SECRET();
|
||||
|
||||
if ( dt > m_flFadeOutLength )
|
||||
return 0.0f;
|
||||
|
||||
return 1.0f - ( dt / m_flFadeOutLength );
|
||||
}
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
float C_EntityDissolve::GetModelFadeOutPercentage( void )
|
||||
{
|
||||
float dt = gpGlobals->curtime - m_flStartTime;
|
||||
|
||||
if ( dt < m_flFadeOutModelStart )
|
||||
return 1.0f;
|
||||
|
||||
if ( dt > m_flFadeOutModelStart )
|
||||
{
|
||||
dt -= m_flFadeOutModelStart;
|
||||
|
||||
if ( dt > m_flFadeOutModelLength )
|
||||
return 0.0f;
|
||||
|
||||
return 1.0f - ( dt / m_flFadeOutModelLength );
|
||||
}
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityDissolve::ClientThink( void )
|
||||
{
|
||||
C_BaseAnimating *pAnimating = GetMoveParent() ? GetMoveParent()->GetBaseAnimating() : NULL;
|
||||
if (!pAnimating)
|
||||
return;
|
||||
|
||||
// NOTE: IsRagdoll means *client-side* ragdoll. We shouldn't be trying to fight
|
||||
// the server ragdoll (or any server physics) on the client
|
||||
if (( !m_pController ) && ( m_nDissolveType == ENTITY_DISSOLVE_NORMAL ) && pAnimating->IsRagdoll())
|
||||
{
|
||||
IPhysicsObject *ppList[VPHYSICS_MAX_OBJECT_LIST_COUNT];
|
||||
int nCount = pAnimating->VPhysicsGetObjectList( ppList, ARRAYSIZE(ppList) );
|
||||
if ( nCount > 0 )
|
||||
{
|
||||
m_pController = physenv->CreateMotionController( this );
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
m_pController->AttachObject( ppList[i], true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
color32 color;
|
||||
|
||||
color.r = color.g = color.b = ( 1.0f - GetFadeInPercentage() ) * 255.0f;
|
||||
color.a = GetModelFadeOutPercentage() * 255.0f;
|
||||
|
||||
// Setup the entity fade
|
||||
pAnimating->SetRenderMode( kRenderTransColor );
|
||||
pAnimating->SetRenderColor( color.r, color.g, color.b );
|
||||
pAnimating->SetRenderAlpha( color.a );
|
||||
|
||||
if ( GetModelFadeOutPercentage() <= 0.2f )
|
||||
{
|
||||
m_bCoreExplode = true;
|
||||
}
|
||||
|
||||
// If we're dead, fade out
|
||||
if ( GetFadeOutPercentage() <= 0.0f )
|
||||
{
|
||||
// Do NOT remove from the client entity list. It'll confuse the local network backdoor, and the entity will never get destroyed
|
||||
// because when the server says to destroy it, the client won't be able to find it.
|
||||
// ClientEntityList().RemoveEntity( GetClientHandle() );
|
||||
|
||||
::partition->Remove( PARTITION_CLIENT_SOLID_EDICTS | PARTITION_CLIENT_RESPONSIVE_EDICTS | PARTITION_CLIENT_NON_STATIC_EDICTS, CollisionProp()->GetPartitionHandle() );
|
||||
|
||||
RemoveFromLeafSystem();
|
||||
|
||||
//FIXME: Ick!
|
||||
//Adrian: I'll assume we don't need the ragdoll either so I'll remove that too.
|
||||
if ( m_bLinkedToServerEnt == false )
|
||||
{
|
||||
Release();
|
||||
|
||||
C_ClientRagdoll *pRagdoll = dynamic_cast <C_ClientRagdoll *> ( pAnimating );
|
||||
|
||||
if ( pRagdoll )
|
||||
{
|
||||
pRagdoll->ReleaseRagdoll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flags -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_EntityDissolve::DrawModel( int flags, const RenderableInstance_t &instance )
|
||||
{
|
||||
if ( !cl_portal_use_new_dissolve.GetBool() )
|
||||
{
|
||||
// See if we should draw
|
||||
if ( gpGlobals->frametime == 0 || m_bReadyToDraw == false )
|
||||
return 0;
|
||||
|
||||
C_BaseAnimating *pAnimating = GetMoveParent() ? GetMoveParent()->GetBaseAnimating() : NULL;
|
||||
if ( pAnimating == NULL )
|
||||
return 0;
|
||||
|
||||
matrix3x4_t *hitboxbones[MAXSTUDIOBONES];
|
||||
if ( pAnimating->HitboxToWorldTransforms( hitboxbones ) == false )
|
||||
return 0;
|
||||
|
||||
studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() );
|
||||
if ( pStudioHdr == NULL )
|
||||
return false;
|
||||
|
||||
mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() );
|
||||
if ( set == NULL )
|
||||
return false;
|
||||
|
||||
// Make sure the emitter is setup properly
|
||||
SetupEmitter();
|
||||
|
||||
// Get fade percentages for the effect
|
||||
float fadeInPerc = GetFadeInPercentage();
|
||||
float fadeOutPerc = GetFadeOutPercentage();
|
||||
|
||||
float fadePerc = ( fadeInPerc >= 1.0f ) ? fadeOutPerc : fadeInPerc;
|
||||
|
||||
Vector vecSkew = vec3_origin;
|
||||
|
||||
// Do extra effects under certain circumstances
|
||||
if ( ( fadePerc < 0.99f ) && ( (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) || (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT) ) )
|
||||
{
|
||||
DoSparks( set, hitboxbones );
|
||||
}
|
||||
|
||||
// Skew the particles in front or in back of their targets
|
||||
vecSkew = CurrentViewForward() * ( 8.0f - ( ( 1.0f - fadePerc ) * 32.0f ) );
|
||||
|
||||
float spriteScale = ( ( gpGlobals->curtime - m_flStartTime ) / m_flFadeOutLength );
|
||||
spriteScale = clamp( spriteScale, 0.75f, 1.0f );
|
||||
|
||||
// Cache off this material reference
|
||||
if ( g_Material_Spark == NULL )
|
||||
{
|
||||
g_Material_Spark = ParticleMgr()->GetPMaterial( "effects/spark" );
|
||||
}
|
||||
|
||||
if ( g_Material_AR2Glow == NULL )
|
||||
{
|
||||
g_Material_AR2Glow = ParticleMgr()->GetPMaterial( "effects/combinemuzzle2" );
|
||||
}
|
||||
|
||||
SimpleParticle *sParticle;
|
||||
|
||||
for ( int i = 0; i < set->numhitboxes; ++i )
|
||||
{
|
||||
Vector vecAbsOrigin, xvec, yvec;
|
||||
mstudiobbox_t *pBox = set->pHitbox(i);
|
||||
ComputeRenderInfo( pBox, *hitboxbones[pBox->bone], &vecAbsOrigin, &xvec, &yvec );
|
||||
|
||||
Vector offset;
|
||||
Vector xDir, yDir;
|
||||
|
||||
xDir = xvec;
|
||||
float xScale = VectorNormalize( xDir ) * 0.75f;
|
||||
|
||||
yDir = yvec;
|
||||
float yScale = VectorNormalize( yDir ) * 0.75f;
|
||||
|
||||
int numParticles = clamp( 3.0f * fadePerc, 0, 3 );
|
||||
|
||||
int iTempParts = 2;
|
||||
|
||||
if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
|
||||
{
|
||||
if ( m_bCoreExplode == true )
|
||||
{
|
||||
numParticles = 15;
|
||||
iTempParts = 20;
|
||||
}
|
||||
}
|
||||
|
||||
for ( int j = 0; j < iTempParts; j++ )
|
||||
{
|
||||
// Skew the origin
|
||||
offset = xDir * Helper_RandomFloat( -xScale*0.5f, xScale*0.5f ) + yDir * Helper_RandomFloat( -yScale*0.5f, yScale*0.5f );
|
||||
offset += vecSkew;
|
||||
|
||||
if ( random->RandomInt( 0, 2 ) != 0 )
|
||||
continue;
|
||||
|
||||
sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), g_Material_Spark, vecAbsOrigin + offset );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return 1;
|
||||
|
||||
sParticle->m_vecVelocity = Vector( Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( 16.0f, 64.0f ) );
|
||||
|
||||
if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
|
||||
{
|
||||
if ( m_bCoreExplode == true )
|
||||
{
|
||||
Vector vDirection = (vecAbsOrigin + offset) - m_vDissolverOrigin;
|
||||
VectorNormalize( vDirection );
|
||||
sParticle->m_vecVelocity = vDirection * m_nMagnitude;
|
||||
}
|
||||
}
|
||||
|
||||
if ( sParticle->m_vecVelocity.z > 0 )
|
||||
{
|
||||
sParticle->m_uchStartSize = random->RandomFloat( 4, 6 ) * spriteScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
sParticle->m_uchStartSize = 2 * spriteScale;
|
||||
}
|
||||
|
||||
sParticle->m_flDieTime = random->RandomFloat( 0.4f, 0.5f );
|
||||
|
||||
// If we're the last particles, last longer
|
||||
if ( numParticles == 0 )
|
||||
{
|
||||
sParticle->m_flDieTime *= 2.0f;
|
||||
sParticle->m_uchStartSize = 2 * spriteScale;
|
||||
sParticle->m_flRollDelta = Helper_RandomFloat( -4.0f, 4.0f );
|
||||
|
||||
if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
|
||||
{
|
||||
if ( m_bCoreExplode == true )
|
||||
{
|
||||
sParticle->m_flDieTime *= 2.0f;
|
||||
sParticle->m_flRollDelta = Helper_RandomFloat( -1.0f, 1.0f );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sParticle->m_flRollDelta = Helper_RandomFloat( -8.0f, 8.0f );
|
||||
}
|
||||
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
|
||||
float alpha = 255;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
sParticle->m_uchEndSize = 0;
|
||||
}
|
||||
|
||||
for ( int j = 0; j < numParticles; j++ )
|
||||
{
|
||||
offset = xDir * Helper_RandomFloat( -xScale*0.5f, xScale*0.5f ) + yDir * Helper_RandomFloat( -yScale*0.5f, yScale*0.5f );
|
||||
offset += vecSkew;
|
||||
|
||||
sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), g_Material_AR2Glow, vecAbsOrigin + offset );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return 1;
|
||||
|
||||
sParticle->m_vecVelocity = Vector( Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -64.0f, 128.0f ) );
|
||||
sParticle->m_uchStartSize = random->RandomFloat( 8, 12 ) * spriteScale;
|
||||
sParticle->m_flDieTime = 0.1f;
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = Helper_RandomFloat( -2.0f, 2.0f );
|
||||
|
||||
float alpha = 255;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
sParticle->m_uchEndSize = 0;
|
||||
|
||||
if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
|
||||
{
|
||||
if ( m_bCoreExplode == true )
|
||||
{
|
||||
Vector vDirection = (vecAbsOrigin + offset) - m_vDissolverOrigin;
|
||||
|
||||
VectorNormalize( vDirection );
|
||||
|
||||
sParticle->m_vecVelocity = vDirection * m_nMagnitude;
|
||||
|
||||
sParticle->m_flDieTime = 0.5f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
77
game/client/c_entitydissolve.h
Normal file
77
game/client/c_entitydissolve.h
Normal file
@@ -0,0 +1,77 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef C_ENTITY_DISSOLVE_H
|
||||
#define C_ENTITY_DISSOLVE_H
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Entity Dissolve, client-side implementation
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_EntityDissolve : public C_BaseEntity, public IMotionEvent
|
||||
{
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_CLASS( C_EntityDissolve, C_BaseEntity );
|
||||
|
||||
C_EntityDissolve( void );
|
||||
|
||||
// Inherited from C_BaseEntity
|
||||
virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
|
||||
virtual int DrawModel( int flags, const RenderableInstance_t &instance );
|
||||
virtual bool ShouldDraw() { return true; }
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void UpdateOnRemove( void );
|
||||
|
||||
// Inherited from IMotionEvent
|
||||
virtual simresult_e Simulate( IPhysicsMotionController *pController, IPhysicsObject *pObject, float deltaTime, Vector &linear, AngularImpulse &angular );
|
||||
|
||||
void SetupEmitter( void );
|
||||
|
||||
void ClientThink( void );
|
||||
|
||||
void SetServerLinkState( bool state ) { m_bLinkedToServerEnt = state; }
|
||||
|
||||
float m_flStartTime;
|
||||
float m_flFadeOutStart;
|
||||
float m_flFadeOutLength;
|
||||
float m_flFadeOutModelStart;
|
||||
float m_flFadeOutModelLength;
|
||||
float m_flFadeInStart;
|
||||
float m_flFadeInLength;
|
||||
int m_nDissolveType;
|
||||
float m_flNextSparkTime;
|
||||
|
||||
Vector m_vDissolverOrigin;
|
||||
int m_nMagnitude;
|
||||
|
||||
bool m_bCoreExplode;
|
||||
|
||||
protected:
|
||||
|
||||
float GetFadeInPercentage( void ); // Fade in amount (entity fading to black)
|
||||
float GetFadeOutPercentage( void ); // Fade out amount (particles fading away)
|
||||
float GetModelFadeOutPercentage( void );// Mode fade out amount
|
||||
|
||||
// Compute the bounding box's center, size, and basis
|
||||
void ComputeRenderInfo( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld,
|
||||
Vector *pVecAbsOrigin, Vector *pXVec, Vector *pYVec );
|
||||
void BuildTeslaEffect( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld, bool bRandom, float flYawOffset );
|
||||
|
||||
void DoSparks( mstudiohitboxset_t *set, matrix3x4_t *hitboxbones[MAXSTUDIOBONES] );
|
||||
|
||||
private:
|
||||
|
||||
CSmartPtr<CSimpleEmitter> m_pEmitter;
|
||||
|
||||
bool m_bLinkedToServerEnt;
|
||||
IPhysicsMotionController *m_pController;
|
||||
};
|
||||
|
||||
#endif // C_ENTITY_DISSOLVE_H
|
||||
|
||||
156
game/client/c_entityflame.cpp
Normal file
156
game/client/c_entityflame.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_entityflame.h"
|
||||
#include "particle_property.h"
|
||||
#include "iefx.h"
|
||||
#include "dlight.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Datadesc
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EntityFlame, DT_EntityFlame, CEntityFlame )
|
||||
RecvPropEHandle(RECVINFO(m_hEntAttached)),
|
||||
RecvPropBool(RECVINFO(m_bCheapEffect)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EntityFlame::C_EntityFlame( void ) : m_hEffect( NULL )
|
||||
{
|
||||
m_hOldAttached = NULL;
|
||||
AddToEntityList( ENTITY_LIST_SIMULATE );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EntityFlame::~C_EntityFlame( void )
|
||||
{
|
||||
StopEffect();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityFlame::StopEffect( void )
|
||||
{
|
||||
if ( m_hEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_hEffect, true );
|
||||
m_hEffect = NULL;
|
||||
}
|
||||
|
||||
if ( m_hEntAttached )
|
||||
{
|
||||
m_hEntAttached->RemoveFlag( FL_ONFIRE );
|
||||
m_hEntAttached->SetEffectEntity( NULL );
|
||||
m_hEntAttached->StopSound( "General.BurningFlesh" );
|
||||
m_hEntAttached->StopSound( "General.BurningObject" );
|
||||
m_hEntAttached = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityFlame::UpdateOnRemove( void )
|
||||
{
|
||||
StopEffect();
|
||||
BaseClass::UpdateOnRemove();
|
||||
}
|
||||
|
||||
void C_EntityFlame::CreateEffect( void )
|
||||
{
|
||||
if ( m_hEffect )
|
||||
{
|
||||
m_hOldAttached = m_hEntAttached;
|
||||
ParticleProp()->StopEmission( m_hEffect, true );
|
||||
m_hEffect = NULL;
|
||||
}
|
||||
|
||||
C_BaseEntity *pEntity = m_hEntAttached;
|
||||
if ( pEntity && !pEntity->IsAbleToHaveFireEffect() )
|
||||
return;
|
||||
|
||||
m_hEffect = ParticleProp()->Create( m_bCheapEffect ? "burning_gib_01" : "burning_character", PATTACH_ABSORIGIN_FOLLOW );
|
||||
if ( m_hEffect )
|
||||
{
|
||||
m_hOldAttached = m_hEntAttached;
|
||||
|
||||
ParticleProp()->AddControlPoint( m_hEffect, 1, pEntity, PATTACH_ABSORIGIN_FOLLOW );
|
||||
m_hEffect->SetControlPoint( 0, GetAbsOrigin() );
|
||||
m_hEffect->SetControlPoint( 1, GetAbsOrigin() );
|
||||
m_hEffect->SetControlPointEntity( 0, pEntity );
|
||||
m_hEffect->SetControlPointEntity( 1, pEntity );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityFlame::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
CreateEffect();
|
||||
}
|
||||
|
||||
// FIXME: This is a bit of a shady path
|
||||
if ( updateType == DATA_UPDATE_DATATABLE_CHANGED )
|
||||
{
|
||||
// If our owner changed, then recreate the effect
|
||||
if ( m_hEntAttached != m_hOldAttached )
|
||||
{
|
||||
CreateEffect();
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_EntityFlame::Simulate( void )
|
||||
{
|
||||
if ( gpGlobals->frametime <= 0.0f )
|
||||
return true;
|
||||
|
||||
#ifdef HL2_EPISODIC
|
||||
if ( IsEffectActive(EF_BRIGHTLIGHT) || IsEffectActive(EF_DIMLIGHT) )
|
||||
{
|
||||
dlight_t *dl = effects->CL_AllocDlight( index );
|
||||
dl->origin = GetAbsOrigin();
|
||||
dl->origin[2] += 16;
|
||||
dl->color.r = 254;
|
||||
dl->color.g = 174;
|
||||
dl->color.b = 10;
|
||||
dl->radius = random->RandomFloat(400,431);
|
||||
dl->die = gpGlobals->curtime + 0.001;
|
||||
}
|
||||
|
||||
#endif // HL2_EPISODIC
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityFlame::ClientThink( void )
|
||||
{
|
||||
StopEffect();
|
||||
Release();
|
||||
}
|
||||
43
game/client/c_entityflame.h
Normal file
43
game/client/c_entityflame.h
Normal file
@@ -0,0 +1,43 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
#ifndef C_ENTITY_FLAME_H
|
||||
#define C_ENTITY_FLAME_H
|
||||
|
||||
#include "c_baseentity.h"
|
||||
|
||||
//
|
||||
// Entity flame, client-side implementation
|
||||
//
|
||||
|
||||
class C_EntityFlame : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_CLASS( C_EntityFlame, C_BaseEntity );
|
||||
|
||||
C_EntityFlame( void );
|
||||
virtual ~C_EntityFlame( void );
|
||||
|
||||
virtual bool Simulate( void );
|
||||
virtual void UpdateOnRemove( void );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void ClientThink( void );
|
||||
|
||||
EHANDLE m_hEntAttached; // The entity that we are burning (attached to).
|
||||
|
||||
private:
|
||||
void CreateEffect( void );
|
||||
void StopEffect( void );
|
||||
|
||||
CUtlReference<CNewParticleEffect> m_hEffect;
|
||||
EHANDLE m_hOldAttached;
|
||||
bool m_bCheapEffect;
|
||||
};
|
||||
|
||||
|
||||
#endif // C_ENTITY_FLAME_H
|
||||
288
game/client/c_entityfreezing.cpp
Normal file
288
game/client/c_entityfreezing.cpp
Normal file
@@ -0,0 +1,288 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
#include "c_entityfreezing.h"
|
||||
#include "studio.h"
|
||||
#include "bone_setup.h"
|
||||
#include "c_surfacerender.h"
|
||||
#include "engine/ivdebugoverlay.h"
|
||||
#include "dt_utlvector_recv.h"
|
||||
#include "debugoverlay_shared.h"
|
||||
#include "animation.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
ConVar cl_blobulator_freezing_max_metaball_radius( "cl_blobulator_freezing_max_metaball_radius",
|
||||
#ifdef INFESTED_DLL
|
||||
"25.0", // Don't need as much precision in Alien swarm because everything is zoomed out
|
||||
#else
|
||||
"12.0",
|
||||
#endif
|
||||
FCVAR_NONE, "Setting this can create more complex surfaces on large hitboxes at the cost of performance.", true, 12.0f, true, 100.0f );
|
||||
|
||||
|
||||
//PRECACHE_REGISTER_BEGIN( GLOBAL, PrecacheEffectFreezing )
|
||||
// PRECACHE( MATERIAL,"effects/tesla_glow_noz" )
|
||||
// PRECACHE( MATERIAL,"effects/spark" )
|
||||
// PRECACHE( MATERIAL,"effects/combinemuzzle2" )
|
||||
//PRECACHE_REGISTER_END()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Networking
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EntityFreezing, DT_EntityFreezing, CEntityFreezing )
|
||||
RecvPropVector( RECVINFO(m_vFreezingOrigin) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY(m_flFrozenPerHitbox), RecvPropFloat( RECVINFO( m_flFrozenPerHitbox[0] ) ) ),
|
||||
RecvPropFloat( RECVINFO(m_flFrozen) ),
|
||||
RecvPropBool( RECVINFO(m_bFinishFreezing) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityFreezing::GetRenderBounds( Vector& theMins, Vector& theMaxs )
|
||||
{
|
||||
if ( GetMoveParent() )
|
||||
{
|
||||
GetMoveParent()->GetRenderBounds( theMins, theMaxs );
|
||||
}
|
||||
else
|
||||
{
|
||||
theMins = GetAbsOrigin();
|
||||
theMaxs = theMaxs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Yes we bloody are
|
||||
//-----------------------------------------------------------------------------
|
||||
RenderableTranslucencyType_t C_EntityFreezing::ComputeTranslucencyType( )
|
||||
{
|
||||
return RENDERABLE_IS_TRANSLUCENT;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// On data changed
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityFreezing::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityFreezing::ClientThink( void )
|
||||
{
|
||||
#ifdef _PS3
|
||||
__nop();
|
||||
#elif defined(LINUX)
|
||||
#elif defined( __clang__ )
|
||||
asm("nop");
|
||||
#elif defined( _WIN32 ) && !defined( WIN64 )
|
||||
__asm nop;
|
||||
#endif
|
||||
//C_BaseAnimating *pAnimating = GetMoveParent() ? GetMoveParent()->GetBaseAnimating() : NULL;
|
||||
//if (!pAnimating)
|
||||
// return;
|
||||
|
||||
//color32 color = pAnimating->GetRenderColor();
|
||||
|
||||
//color.r = color.g = ( 1.0f - m_flFrozen ) * 255.0f;
|
||||
|
||||
//// Setup the entity fade
|
||||
//pAnimating->SetRenderMode( kRenderTransColor );
|
||||
//pAnimating->SetRenderColor( color.r, color.g, color.b, color.a );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flags -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_EntityFreezing::DrawModel( int flags, const RenderableInstance_t &instance )
|
||||
{
|
||||
#ifdef USE_BLOBULATOR
|
||||
|
||||
// See if we should draw
|
||||
if ( m_bReadyToDraw == false )
|
||||
return 0;
|
||||
|
||||
// The parent needs to be a base animating
|
||||
C_BaseAnimating *pAnimating = GetMoveParent() ? GetMoveParent()->GetBaseAnimating() : NULL;
|
||||
if ( pAnimating == NULL )
|
||||
return 0;
|
||||
|
||||
// Make sure we have hitboxes
|
||||
matrix3x4_t *hitboxbones[MAXSTUDIOBONES];
|
||||
if ( pAnimating->HitboxToWorldTransforms( hitboxbones ) == false )
|
||||
return 0;
|
||||
|
||||
studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() );
|
||||
if ( pStudioHdr == NULL )
|
||||
return 0;
|
||||
|
||||
int nEffectsHitboxSet = FindHitboxSetByName( pAnimating->GetModelPtr(), "effects" );
|
||||
mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( nEffectsHitboxSet != -1 ? nEffectsHitboxSet : pAnimating->GetHitboxSet() );
|
||||
if ( !set )
|
||||
return 0;
|
||||
|
||||
// FIXME: No idea how many particles we'll need, so let's start with 1000
|
||||
g_SurfaceRenderParticles.SetCount( 1000 );
|
||||
|
||||
int iNumParticles = 0;
|
||||
|
||||
for ( int i = 0; i < set->numhitboxes; ++i )
|
||||
{
|
||||
mstudiobbox_t *pBox = set->pHitbox(i);
|
||||
matrix3x4_t matBone = *hitboxbones[ pBox->bone ];
|
||||
|
||||
Vector vecHorizontal = pBox->bbmax - pBox->bbmin;
|
||||
|
||||
// Get the particle radius
|
||||
float flShortestAxis = MIN( MIN( vecHorizontal.x, vecHorizontal.y ), vecHorizontal.z );
|
||||
float flDiameter = clamp( flShortestAxis, 1.0f, cl_blobulator_freezing_max_metaball_radius.GetFloat() );
|
||||
float flRadius = flDiameter * 0.5f;
|
||||
float flVarience = flRadius * 0.25f;
|
||||
float flRadiusIsoSurface = flRadius / 12.0f;
|
||||
|
||||
// Get the hitbox data
|
||||
EntityFreezingHitboxBlobData_t *pHitboxBlobData = NULL;
|
||||
|
||||
if ( m_HitboxBlobData.Count() <= i )
|
||||
{
|
||||
// We don't have data for this hitbox yet, so build need relative point positions that are along its faces
|
||||
int nNewHitboxBlobData = m_HitboxBlobData.AddToTail();
|
||||
pHitboxBlobData = &(m_HitboxBlobData[ nNewHitboxBlobData ]);
|
||||
|
||||
// Start in the min corner
|
||||
Vector vecStartPoint = pBox->bbmin + ReplicateToVector( flRadius * 0.5f );
|
||||
Vector vecEndPoint = pBox->bbmax - ReplicateToVector( flRadius * 0.5f );
|
||||
Vector vecPoint;
|
||||
|
||||
bool bEdgeX = true;
|
||||
vecPoint.x = vecStartPoint.x;
|
||||
|
||||
// Loop across each axis
|
||||
while ( vecPoint.x <= vecEndPoint.x )
|
||||
{
|
||||
bool bEdgeY = true;
|
||||
vecPoint.y = vecStartPoint.y;
|
||||
|
||||
while ( vecPoint.y <= vecEndPoint.y )
|
||||
{
|
||||
bool bEdgeZ = true;
|
||||
vecPoint.z = vecStartPoint.z;
|
||||
|
||||
while ( vecPoint.z <= vecEndPoint.z )
|
||||
{
|
||||
// Only add particles not in the middle of the box
|
||||
if ( bEdgeX || bEdgeY || bEdgeZ )
|
||||
{
|
||||
int nNewPoint = pHitboxBlobData->m_vPoints.AddToTail();
|
||||
pHitboxBlobData->m_vPoints[ nNewPoint ] = vecPoint + RandomVector( -flVarience, flVarience );
|
||||
}
|
||||
|
||||
// Make sure the final particles don't stick out past the edge
|
||||
bEdgeZ = ( vecPoint.z < vecEndPoint.z && ( ( !bEdgeX && !bEdgeY ) || vecPoint.z + flRadius >= vecEndPoint.z ) );
|
||||
if ( bEdgeZ )
|
||||
{
|
||||
vecPoint.z = vecEndPoint.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
vecPoint.z += flRadius;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the final particles don't stick out past the edge
|
||||
bEdgeY = ( vecPoint.y < vecEndPoint.y && vecPoint.y + flRadius >= vecEndPoint.y );
|
||||
if ( bEdgeY )
|
||||
{
|
||||
vecPoint.y = vecEndPoint.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
vecPoint.y += flRadius;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the final particles don't stick out past the edge
|
||||
bEdgeX = ( vecPoint.x < vecEndPoint.x && vecPoint.x + flRadius >= vecEndPoint.x );
|
||||
if ( bEdgeX )
|
||||
{
|
||||
vecPoint.x = vecEndPoint.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
vecPoint.x += flRadius;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pHitboxBlobData = &(m_HitboxBlobData[ i ]);
|
||||
}
|
||||
|
||||
// Decide which of the hitbox points to draw based on how frozen the hitbox is and transform them into worldspace
|
||||
for ( int nPoint = 0; nPoint < pHitboxBlobData->m_vPoints.Count() && iNumParticles < 1000; ++nPoint )
|
||||
{
|
||||
// Fast out if the min Z surrounding this hitbox is above the cut off height
|
||||
Vector vecBoxAbsMins, vecBoxAbsMaxs;
|
||||
TransformAABB( matBone, pBox->bbmin, pBox->bbmax, vecBoxAbsMins, vecBoxAbsMaxs );
|
||||
|
||||
if ( m_bFinishFreezing )
|
||||
{
|
||||
m_flFrozenPerHitbox[ i ] = MIN( 1.0f, m_flFrozenPerHitbox[ i ] + gpGlobals->frametime * 0.75f );
|
||||
}
|
||||
|
||||
if ( m_flFrozenPerHitbox[ i ] <= 0.0f )
|
||||
{
|
||||
// No particles will be below the freezing line, skip this hitbox
|
||||
continue;
|
||||
}
|
||||
|
||||
float fCutOffHeight = vecBoxAbsMins.z + ( vecBoxAbsMaxs.z - vecBoxAbsMins.z ) * m_flFrozenPerHitbox[ i ];
|
||||
|
||||
// Get the point in worldspace
|
||||
Vector vecTransformedPoint;
|
||||
VectorTransform( pHitboxBlobData->m_vPoints[ nPoint ], matBone, vecTransformedPoint );
|
||||
|
||||
// Only add particles below this height and if it's not in the middle of the box
|
||||
if ( vecTransformedPoint.z < fCutOffHeight )
|
||||
{
|
||||
ImpParticleWithOneInterpolant* imp_particle = &(g_SurfaceRenderParticles[ iNumParticles ]);
|
||||
imp_particle->center = vecTransformedPoint;
|
||||
imp_particle->setFieldScale( flRadiusIsoSurface );
|
||||
imp_particle->interpolants1.set( 1.0f, 1.0f, 1.0f );
|
||||
imp_particle->interpolants1[ 3 ] = 0.0f;
|
||||
++iNumParticles;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_SurfaceRenderParticles.SetCountNonDestructively( iNumParticles );
|
||||
|
||||
// Set up lighting
|
||||
modelrender->SetupLighting( GetRenderOrigin() );
|
||||
|
||||
Surface_Draw( GetClientRenderable(), GetRenderOrigin(), materials->FindMaterial( "models/weapons/w_icegun/ice_surface", TEXTURE_GROUP_OTHER, true ), 6.5f );
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
47
game/client/c_entityfreezing.h
Normal file
47
game/client/c_entityfreezing.h
Normal file
@@ -0,0 +1,47 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_ENTITY_FREEZING_H
|
||||
#define C_ENTITY_FREEZING_H
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
|
||||
struct EntityFreezingHitboxBlobData_t
|
||||
{
|
||||
CUtlVector<Vector> m_vPoints;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Entity Dissolve, client-side implementation
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_EntityFreezing : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_CLASS( C_EntityFreezing, C_BaseEntity );
|
||||
|
||||
virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
|
||||
virtual RenderableTranslucencyType_t ComputeTranslucencyType( );
|
||||
virtual int DrawModel( int flags, const RenderableInstance_t &instance );
|
||||
virtual bool ShouldDraw() { return true; }
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
void ClientThink( void );
|
||||
|
||||
private:
|
||||
Vector m_vFreezingOrigin;
|
||||
float m_flFrozenPerHitbox[ 50 ];
|
||||
float m_flFrozen;
|
||||
bool m_bFinishFreezing;
|
||||
|
||||
CUtlVector<EntityFreezingHitboxBlobData_t> m_HitboxBlobData;
|
||||
};
|
||||
|
||||
#endif // C_ENTITY_FREEZING_H
|
||||
|
||||
250
game/client/c_entityparticletrail.cpp
Normal file
250
game/client/c_entityparticletrail.cpp
Normal file
@@ -0,0 +1,250 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "baseparticleentity.h"
|
||||
#include "entityparticletrail_shared.h"
|
||||
#include "particlemgr.h"
|
||||
#include "particle_util.h"
|
||||
#include "particles_simple.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Entity particle trail, client-side implementation
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_EntityParticleTrail : public C_BaseParticleEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_CLASS( C_EntityParticleTrail, C_BaseParticleEntity );
|
||||
|
||||
C_EntityParticleTrail( );
|
||||
~C_EntityParticleTrail( );
|
||||
|
||||
// C_BaseEntity
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
// IParticleEffect
|
||||
void Update( float fTimeDelta );
|
||||
virtual void RenderParticles( CParticleRenderIterator *pIterator );
|
||||
virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
|
||||
|
||||
private:
|
||||
|
||||
C_EntityParticleTrail( const C_EntityParticleTrail & ); // not defined, not accessible
|
||||
|
||||
void Start( );
|
||||
void AddParticle( float flInitialDeltaTime, const Vector &vecMins, const Vector &vecMaxs, const matrix3x4_t &boxToWorld );
|
||||
|
||||
int m_iMaterialName;
|
||||
EntityParticleTrailInfo_t m_Info;
|
||||
EHANDLE m_hConstraintEntity;
|
||||
|
||||
PMaterialHandle m_hMaterial;
|
||||
TimedEvent m_teParticleSpawn;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Networking
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EntityParticleTrail, DT_EntityParticleTrail, CEntityParticleTrail )
|
||||
RecvPropInt(RECVINFO(m_iMaterialName)),
|
||||
RecvPropDataTable( RECVINFO_DT( m_Info ), 0, &REFERENCE_RECV_TABLE(DT_EntityParticleTrailInfo) ),
|
||||
RecvPropEHandle(RECVINFO(m_hConstraintEntity)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EntityParticleTrail::C_EntityParticleTrail( void )
|
||||
{
|
||||
}
|
||||
|
||||
C_EntityParticleTrail::~C_EntityParticleTrail()
|
||||
{
|
||||
ParticleMgr()->RemoveEffect( &m_ParticleEffect );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// On data changed
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityParticleTrail::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
Start( );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pParticleMgr -
|
||||
// *pArgs -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityParticleTrail::Start( )
|
||||
{
|
||||
if( ParticleMgr()->AddEffect( &m_ParticleEffect, this ) == false )
|
||||
return;
|
||||
|
||||
const char *pMaterialName = GetMaterialNameFromIndex( m_iMaterialName );
|
||||
if ( !pMaterialName )
|
||||
return;
|
||||
|
||||
m_hMaterial = ParticleMgr()->GetPMaterial( pMaterialName );
|
||||
m_teParticleSpawn.Init( 150 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityParticleTrail::AddParticle( float flInitialDeltaTime, const Vector &vecMins, const Vector &vecMaxs, const matrix3x4_t &boxToWorld )
|
||||
{
|
||||
// Select a random point somewhere in the hitboxes of the entity.
|
||||
Vector vecLocalPosition, vecWorldPosition;
|
||||
vecLocalPosition.x = Lerp( random->RandomFloat( 0.0f, 1.0f ), vecMins.x, vecMaxs.x );
|
||||
vecLocalPosition.y = Lerp( random->RandomFloat( 0.0f, 1.0f ), vecMins.y, vecMaxs.y );
|
||||
vecLocalPosition.z = Lerp( random->RandomFloat( 0.0f, 1.0f ), vecMins.z, vecMaxs.z );
|
||||
VectorTransform( vecLocalPosition, boxToWorld, vecWorldPosition );
|
||||
|
||||
// Don't emit the particle unless it's inside the model
|
||||
if ( m_hConstraintEntity.Get() )
|
||||
{
|
||||
Ray_t ray;
|
||||
trace_t tr;
|
||||
ray.Init( vecWorldPosition, vecWorldPosition );
|
||||
enginetrace->ClipRayToEntity( ray, MASK_ALL, m_hConstraintEntity, &tr );
|
||||
|
||||
if ( !tr.startsolid )
|
||||
return;
|
||||
}
|
||||
|
||||
// Make a new particle
|
||||
SimpleParticle *pParticle = (SimpleParticle *)m_ParticleEffect.AddParticle( sizeof(SimpleParticle), m_hMaterial );
|
||||
if ( pParticle == NULL )
|
||||
return;
|
||||
|
||||
pParticle->m_Pos = vecWorldPosition;
|
||||
pParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
pParticle->m_flRollDelta = Helper_RandomFloat( -2.0f, 2.0f );
|
||||
|
||||
pParticle->m_flLifetime = flInitialDeltaTime;
|
||||
pParticle->m_flDieTime = m_Info.m_flLifetime;
|
||||
|
||||
pParticle->m_uchColor[0] = 64;
|
||||
pParticle->m_uchColor[1] = 140;
|
||||
pParticle->m_uchColor[2] = 225;
|
||||
pParticle->m_uchStartAlpha = Helper_RandomInt( 64, 64 );
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
|
||||
pParticle->m_uchStartSize = m_Info.m_flStartSize;
|
||||
pParticle->m_uchEndSize = m_Info.m_flEndSize;
|
||||
|
||||
pParticle->m_vecVelocity = vec3_origin;
|
||||
VectorMA( pParticle->m_Pos, flInitialDeltaTime, pParticle->m_vecVelocity, pParticle->m_Pos );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : fTimeDelta -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityParticleTrail::Update( float fTimeDelta )
|
||||
{
|
||||
float tempDelta = fTimeDelta;
|
||||
studiohdr_t *pStudioHdr;
|
||||
mstudiohitboxset_t *set;
|
||||
matrix3x4_t *hitboxbones[MAXSTUDIOBONES];
|
||||
|
||||
C_BaseEntity *pMoveParent = GetMoveParent();
|
||||
if ( !pMoveParent )
|
||||
return;
|
||||
|
||||
C_BaseAnimating *pAnimating = pMoveParent->GetBaseAnimating();
|
||||
if (!pAnimating)
|
||||
goto trailNoHitboxes;
|
||||
|
||||
if ( !pAnimating->HitboxToWorldTransforms( hitboxbones ) )
|
||||
goto trailNoHitboxes;
|
||||
|
||||
pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() );
|
||||
if (!pStudioHdr)
|
||||
goto trailNoHitboxes;
|
||||
|
||||
set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() );
|
||||
if ( !set )
|
||||
goto trailNoHitboxes;
|
||||
|
||||
//Add new particles
|
||||
while ( m_teParticleSpawn.NextEvent( tempDelta ) )
|
||||
{
|
||||
int nHitbox = random->RandomInt( 0, set->numhitboxes - 1 );
|
||||
mstudiobbox_t *pBox = set->pHitbox(nHitbox);
|
||||
|
||||
AddParticle( tempDelta, pBox->bbmin, pBox->bbmax, *hitboxbones[pBox->bone] );
|
||||
}
|
||||
return;
|
||||
|
||||
trailNoHitboxes:
|
||||
while ( m_teParticleSpawn.NextEvent( tempDelta ) )
|
||||
{
|
||||
AddParticle( tempDelta, pMoveParent->CollisionProp()->OBBMins(), pMoveParent->CollisionProp()->OBBMaxs(), pMoveParent->EntityToWorldTransform() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void C_EntityParticleTrail::RenderParticles( CParticleRenderIterator *pIterator )
|
||||
{
|
||||
const SimpleParticle *pParticle = (const SimpleParticle*)pIterator->GetFirst();
|
||||
while ( pParticle )
|
||||
{
|
||||
float t = pParticle->m_flLifetime / pParticle->m_flDieTime;
|
||||
|
||||
// Render
|
||||
Vector tPos;
|
||||
TransformParticle( ParticleMgr()->GetModelView(), pParticle->m_Pos, tPos );
|
||||
float sortKey = tPos.z;
|
||||
|
||||
Vector color = Vector( pParticle->m_uchColor[0] / 255.0f, pParticle->m_uchColor[1] / 255.0f, pParticle->m_uchColor[2] / 255.0f );
|
||||
float alpha = Lerp( t, pParticle->m_uchStartAlpha / 255.0f, pParticle->m_uchEndAlpha / 255.0f );
|
||||
float flSize = Lerp( t, pParticle->m_uchStartSize, pParticle->m_uchEndSize );
|
||||
|
||||
// Render it
|
||||
RenderParticle_ColorSize( pIterator->GetParticleDraw(), tPos, color, alpha, flSize );
|
||||
|
||||
pParticle = (const SimpleParticle*)pIterator->GetNext( sortKey );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void C_EntityParticleTrail::SimulateParticles( CParticleSimulateIterator *pIterator )
|
||||
{
|
||||
SimpleParticle *pParticle = (SimpleParticle*)pIterator->GetFirst();
|
||||
while ( pParticle )
|
||||
{
|
||||
// Update position
|
||||
float flTimeDelta = pIterator->GetTimeDelta();
|
||||
pParticle->m_Pos += pParticle->m_vecVelocity * flTimeDelta;
|
||||
|
||||
// NOTE: I'm overloading "die time" to be the actual start time.
|
||||
pParticle->m_flLifetime += flTimeDelta;
|
||||
|
||||
if ( pParticle->m_flLifetime >= pParticle->m_flDieTime )
|
||||
pIterator->RemoveParticle( pParticle );
|
||||
|
||||
pParticle = (SimpleParticle*)pIterator->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
95
game/client/c_env_ambient_light.cpp
Normal file
95
game/client/c_env_ambient_light.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: Ambient light controller entity with simple radial falloff
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
#include "cbase.h"
|
||||
|
||||
#include "c_spatialentity.h"
|
||||
#include "spatialentitymgr.h"
|
||||
#include "c_env_ambient_light.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
static ConVar cl_ambient_light_disableentities( "cl_ambient_light_disableentities", "0", FCVAR_NONE, "Disable map ambient light entities." );
|
||||
|
||||
|
||||
static CSpatialEntityMgr s_EnvAmbientLightMgr;
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EnvAmbientLight, DT_EnvAmbientLight, CEnvAmbientLight )
|
||||
RecvPropVector( RECVINFO_NAME( m_Value, m_vecColor ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
void C_EnvAmbientLight::ApplyAccumulation( void )
|
||||
{
|
||||
Vector rgbVal = BlendedValue();
|
||||
|
||||
static ConVarRef mat_ambient_light_r( "mat_ambient_light_r" );
|
||||
static ConVarRef mat_ambient_light_g( "mat_ambient_light_g" );
|
||||
static ConVarRef mat_ambient_light_b( "mat_ambient_light_b" );
|
||||
|
||||
if ( mat_ambient_light_r.IsValid() )
|
||||
{
|
||||
mat_ambient_light_r.SetValue( rgbVal.x );
|
||||
}
|
||||
|
||||
if ( mat_ambient_light_g.IsValid() )
|
||||
{
|
||||
mat_ambient_light_g.SetValue( rgbVal.y );
|
||||
}
|
||||
|
||||
if ( mat_ambient_light_b.IsValid() )
|
||||
{
|
||||
mat_ambient_light_b.SetValue( rgbVal.z );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void C_EnvAmbientLight::AddToPersonalSpatialEntityMgr( void )
|
||||
{
|
||||
s_EnvAmbientLightMgr.AddSpatialEntity( this );
|
||||
}
|
||||
|
||||
void C_EnvAmbientLight::RemoveFromPersonalSpatialEntityMgr( void )
|
||||
{
|
||||
s_EnvAmbientLightMgr.RemoveSpatialEntity( this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void C_EnvAmbientLight::SetColor( const Vector &vecColor, float flLerpTime )
|
||||
{
|
||||
if ( flLerpTime <= 0 )
|
||||
{
|
||||
m_Value = vecColor / 255.0f;
|
||||
m_colorTimer.Invalidate();
|
||||
return;
|
||||
}
|
||||
|
||||
m_vecStartColor = m_Value;
|
||||
m_vecTargetColor = vecColor / 255.0f;
|
||||
m_colorTimer.Start( flLerpTime );
|
||||
}
|
||||
|
||||
void C_EnvAmbientLight::ClientThink( void )
|
||||
{
|
||||
BaseClass::ClientThink();
|
||||
|
||||
if ( m_colorTimer.HasStarted() )
|
||||
{
|
||||
if ( m_colorTimer.IsElapsed() )
|
||||
{
|
||||
m_Value = m_vecTargetColor;
|
||||
m_colorTimer.Invalidate();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Value = m_vecTargetColor - ( m_vecTargetColor - m_vecStartColor ) * m_colorTimer.GetRemainingRatio();
|
||||
}
|
||||
}
|
||||
}
|
||||
30
game/client/c_env_ambient_light.h
Normal file
30
game/client/c_env_ambient_light.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef _INCLUDED_C_ENV_AMBIENT_LIGHT_H
|
||||
#define _INCLUDED_C_ENV_AMBIENT_LIGHT_H
|
||||
|
||||
#include "c_spatialentity.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose : Ambient light controller entity with radial falloff
|
||||
//------------------------------------------------------------------------------
|
||||
class C_EnvAmbientLight : public C_SpatialEntityTemplate<Vector>
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_EnvAmbientLight, C_SpatialEntityTemplate<Vector> );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
virtual void ApplyAccumulation( void );
|
||||
virtual void ClientThink( void );
|
||||
|
||||
void SetColor( const Vector &vecColor, float flLerpTime = 0 );
|
||||
Vector GetTargetColor() { return m_vecTargetColor * 255.0f; }
|
||||
|
||||
protected:
|
||||
virtual void AddToPersonalSpatialEntityMgr( void );
|
||||
virtual void RemoveFromPersonalSpatialEntityMgr( void );
|
||||
|
||||
Vector m_vecStartColor;
|
||||
Vector m_vecTargetColor;
|
||||
CountdownTimer m_colorTimer;
|
||||
};
|
||||
|
||||
#endif // _INCLUDED_C_ENV_AMBIENT_LIGHT_H
|
||||
1777
game/client/c_env_cascade_light.cpp
Normal file
1777
game/client/c_env_cascade_light.cpp
Normal file
File diff suppressed because it is too large
Load Diff
208
game/client/c_env_cascade_light.h
Normal file
208
game/client/c_env_cascade_light.h
Normal file
@@ -0,0 +1,208 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Directional lighting with cascaded shadow mapping entity.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef C_ENV_CASCADE_LIGHT_H
|
||||
#define C_ENV_CASCADE_LIGHT_H
|
||||
|
||||
#include "c_baseplayer.h"
|
||||
#include "csm_parallel_split.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: Directional lighting with cascaded shadow mapping entity.
|
||||
//------------------------------------------------------------------------------
|
||||
class C_CascadeLight : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_CascadeLight, C_BaseEntity );
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_CascadeLight();
|
||||
|
||||
virtual ~C_CascadeLight();
|
||||
|
||||
static C_CascadeLight *Get() { return m_pCascadeLight; }
|
||||
|
||||
virtual void Spawn();
|
||||
virtual void Release();
|
||||
virtual bool ShouldDraw();
|
||||
virtual void ClientThink();
|
||||
|
||||
inline const Vector &GetShadowDirection() const { return m_shadowDirection; }
|
||||
inline const Vector &GetEnvLightShadowDirection() const { return m_envLightShadowDirection; }
|
||||
inline bool IsEnabled() const { return m_bEnabled; }
|
||||
inline color32 GetColor() const { return m_LightColor; }
|
||||
inline int GetColorScale() const { return m_LightColorScale; }
|
||||
inline bool UseLightEnvAngles() const { return m_bUseLightEnvAngles; }
|
||||
float GetMaxShadowDist() const { return m_flMaxShadowDist; }
|
||||
|
||||
private:
|
||||
static C_CascadeLight *m_pCascadeLight;
|
||||
|
||||
Vector m_shadowDirection;
|
||||
Vector m_envLightShadowDirection;
|
||||
bool m_bEnabled;
|
||||
bool m_bUseLightEnvAngles;
|
||||
color32 m_LightColor;
|
||||
int m_LightColorScale;
|
||||
float m_flMaxShadowDist;
|
||||
};
|
||||
|
||||
class CDebugPrimRenderer2D
|
||||
{
|
||||
public:
|
||||
CDebugPrimRenderer2D();
|
||||
|
||||
void Clear();
|
||||
|
||||
// Normalized [0,1] coords, where (0,0) is upper left
|
||||
void AddNormalizedLine2D( float sx, float sy, float ex, float ey, uint r, uint g, uint b );
|
||||
|
||||
// Screenspace (pixel) coords
|
||||
void AddScreenspaceLine2D( float sx, float sy, float ex, float ey, uint r, uint g, uint b );
|
||||
void AddScreenspaceRect2D( float sx, float sy, float ex, float ey, uint r, uint g, uint b );
|
||||
void AddScreenspaceLineList2D( uint nCount, const Vector2D *pVerts, const VertexColor_t &color );
|
||||
void AddScreenspaceWireframeFrustum2D( const VMatrix &xform, const VertexColor_t &color, bool bShowAxes );
|
||||
|
||||
void Render2D( );
|
||||
|
||||
void RenderScreenspaceDepthTexture( float sx, float sy, float ex, float ey, float su, float sv, float eu, float ev, CTextureReference &depthTex, float zLo, float zHi );
|
||||
|
||||
private:
|
||||
class CDebugLine
|
||||
{
|
||||
public:
|
||||
inline CDebugLine() { }
|
||||
inline CDebugLine( const Vector2D &start, const Vector2D &end, uint r = 255, uint g = 255, uint b = 255, uint a = 255 ) { Init( start, end, r, g, b, a ); }
|
||||
|
||||
inline void Init( const Vector2D &start, const Vector2D &end, uint r = 255, uint g = 255, uint b = 255, uint a = 255 ) { m_EndPoints[0] = start; m_EndPoints[1] = end; m_nColor[0] = r; m_nColor[1] = g; m_nColor[2] = b; m_nColor[3] = a; }
|
||||
|
||||
Vector2D m_EndPoints[2]; // normalized [0,1] coordinates, (0,0) is top-left
|
||||
uint8 m_nColor[4];
|
||||
};
|
||||
CUtlVector< CDebugLine > m_debugLines;
|
||||
|
||||
void RenderDebugLines2D( uint nNumLines, const CDebugLine *pLines );
|
||||
};
|
||||
|
||||
class CCascadeLightManager : public CAutoGameSystemPerFrame
|
||||
{
|
||||
public:
|
||||
CCascadeLightManager();
|
||||
virtual ~CCascadeLightManager();
|
||||
|
||||
bool InitRenderTargets();
|
||||
void ShutdownRenderTargets();
|
||||
|
||||
void LevelInitPreEntity();
|
||||
void LevelInitPostEntity();
|
||||
void LevelShutdownPreEntity();
|
||||
void LevelShutdownPostEntity();
|
||||
|
||||
void Shutdown();
|
||||
|
||||
bool IsEnabled() const;
|
||||
bool IsEnabledAndActive() const;
|
||||
|
||||
virtual void PreRender ();
|
||||
|
||||
void ComputeShadowDepthTextures( const CViewSetup &viewSetup, bool bSetup = false );
|
||||
void UnlockAllShadowDepthTextures();
|
||||
|
||||
void BeginViewModelRendering();
|
||||
void EndViewModelRendering();
|
||||
|
||||
void BeginReflectionView();
|
||||
void EndReflectionView();
|
||||
|
||||
void Draw3DDebugInfo();
|
||||
void Draw2DDebugInfo();
|
||||
|
||||
void DumpStatus();
|
||||
|
||||
CSMQualityMode_t GetCSMQualityMode();
|
||||
|
||||
public:
|
||||
static void RotXPlusDown( const CCommand &args );
|
||||
static void RotXPlusUp( const CCommand &args );
|
||||
static void RotXNegDown( const CCommand &args );
|
||||
static void RotXNegUp( const CCommand &args );
|
||||
static void RotYPlusDown( const CCommand &args );
|
||||
static void RotYPlusUp( const CCommand &args );
|
||||
static void RotYNegDown( const CCommand &args );
|
||||
static void RotYNegUp( const CCommand &args );
|
||||
|
||||
private:
|
||||
class CFullCSMState
|
||||
{
|
||||
public:
|
||||
CFullCSMState()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
inline void Clear()
|
||||
{
|
||||
V_memset( &m_sceneFrustum, 0, sizeof( m_sceneFrustum ) );
|
||||
m_flSceneAspectRatio = 0.0f;
|
||||
m_sceneWorldToView.Identity();
|
||||
m_sceneViewToProj.Identity();
|
||||
m_sceneWorldToProj.Identity();
|
||||
m_CSMParallelSplit.Clear();
|
||||
m_shadowDir.Init( 0, 0, -1.0f );
|
||||
m_flMaxShadowDist = 0.0f;
|
||||
m_flMaxVisibleDist = 0.0f;
|
||||
m_nMaxCascadeSize = 0;
|
||||
m_bValid = false;
|
||||
}
|
||||
|
||||
void Update( const CViewSetup &viewSetup, const Vector &shadowDir, const color32 lightColor, const int lightColorScale, float flMaxShadowDist, float flMaxVisibleDist, uint nMaxCascadeSize, uint nAtlasFirstCascadeIndex, int nCSMQualityLevel, bool bSetAllCascadesToFirst );
|
||||
|
||||
bool IsValid() const { return m_CSMParallelSplit.IsValid() && m_CSMParallelSplit.GetLightState().m_nShadowCascadeSize; }
|
||||
void Reset() { m_CSMParallelSplit.Reset(); }
|
||||
|
||||
CFrustum m_sceneFrustum;
|
||||
float m_flSceneAspectRatio;
|
||||
VMatrix m_sceneWorldToView, m_sceneViewToProj, m_sceneWorldToProj;
|
||||
Vector m_shadowDir;
|
||||
float m_flMaxShadowDist;
|
||||
float m_flMaxVisibleDist;
|
||||
uint m_nMaxCascadeSize;
|
||||
CCSMParallelSplit m_CSMParallelSplit;
|
||||
|
||||
bool m_bValid;
|
||||
};
|
||||
|
||||
void RenderViews( CFullCSMState &state, bool bIncludeViewModels );
|
||||
|
||||
int m_nDepthTextureResolution;
|
||||
CSMQualityMode_t m_nCurRenderTargetQualityMode;
|
||||
|
||||
CFullCSMState m_curState;
|
||||
CFullCSMState m_curViewModelState;
|
||||
|
||||
CFullCSMState m_capturedState;
|
||||
|
||||
CDebugPrimRenderer2D m_debugPrimRenderer;
|
||||
|
||||
bool m_bRenderTargetsAllocated;
|
||||
CTextureReference m_ShadowDepthTexture;
|
||||
CTextureReference m_DummyColorTexture;
|
||||
|
||||
float m_flRotX[2], m_flRotY[2];
|
||||
|
||||
bool m_bCSMIsActive;
|
||||
bool m_bStateIsValid;
|
||||
|
||||
void DeinitRenderTargets();
|
||||
void DrawTextDebugInfo();
|
||||
Vector GetShadowDirection();
|
||||
inline CFullCSMState &GetActiveState() { return m_capturedState.m_CSMParallelSplit.IsValid() ? m_capturedState : m_curState; }
|
||||
};
|
||||
|
||||
extern CCascadeLightManager g_CascadeLightManager;
|
||||
|
||||
#endif // C_ENV_CASCADE_LIGHT_H
|
||||
100
game/client/c_env_dof_controller.cpp
Normal file
100
game/client/c_env_dof_controller.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
extern bool g_bDOFEnabled;
|
||||
extern float g_flDOFNearBlurDepth;
|
||||
extern float g_flDOFNearFocusDepth;
|
||||
extern float g_flDOFFarFocusDepth;
|
||||
extern float g_flDOFFarBlurDepth;
|
||||
extern float g_flDOFNearBlurRadius;
|
||||
extern float g_flDOFFarBlurRadius;
|
||||
|
||||
EHANDLE g_hDOFControllerInUse = INVALID_EHANDLE;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_EnvDOFController : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_EnvDOFController, C_BaseEntity );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_EnvDOFController();
|
||||
~C_EnvDOFController();
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
private:
|
||||
bool m_bDOFEnabled;
|
||||
float m_flNearBlurDepth;
|
||||
float m_flNearFocusDepth;
|
||||
float m_flFarFocusDepth;
|
||||
float m_flFarBlurDepth;
|
||||
float m_flNearBlurRadius;
|
||||
float m_flFarBlurRadius;
|
||||
|
||||
private:
|
||||
C_EnvDOFController( const C_EnvDOFController & );
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EnvDOFController, DT_EnvDOFController, CEnvDOFController )
|
||||
RecvPropInt( RECVINFO(m_bDOFEnabled) ),
|
||||
RecvPropFloat( RECVINFO(m_flNearBlurDepth) ),
|
||||
RecvPropFloat( RECVINFO(m_flNearFocusDepth) ),
|
||||
RecvPropFloat( RECVINFO(m_flFarFocusDepth) ),
|
||||
RecvPropFloat( RECVINFO(m_flFarBlurDepth) ),
|
||||
RecvPropFloat( RECVINFO(m_flNearBlurRadius) ),
|
||||
RecvPropFloat( RECVINFO(m_flFarBlurRadius) )
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EnvDOFController::C_EnvDOFController( void )
|
||||
: m_bDOFEnabled( true ),
|
||||
m_flNearBlurDepth( 50.0f ),
|
||||
m_flNearFocusDepth( 100.0f ),
|
||||
m_flFarFocusDepth( 250.0f ),
|
||||
m_flFarBlurDepth( 1000.0f ),
|
||||
m_flNearBlurRadius( 0.0f ), // no near blur by default
|
||||
m_flFarBlurRadius( 5.0f )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EnvDOFController::~C_EnvDOFController( void )
|
||||
{
|
||||
if ( g_hDOFControllerInUse == this )
|
||||
{
|
||||
g_bDOFEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvDOFController::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
g_bDOFEnabled = m_bDOFEnabled && ( ( m_flNearBlurRadius > 0.0f ) || ( m_flFarBlurRadius > 0.0f ) );
|
||||
g_flDOFNearBlurDepth = m_flNearBlurDepth;
|
||||
g_flDOFNearFocusDepth = m_flNearFocusDepth;
|
||||
g_flDOFFarFocusDepth = m_flFarFocusDepth;
|
||||
g_flDOFFarBlurDepth = m_flFarBlurDepth;
|
||||
g_flDOFNearBlurRadius = m_flNearBlurRadius;
|
||||
g_flDOFFarBlurRadius = m_flFarBlurRadius;
|
||||
|
||||
g_hDOFControllerInUse = this;
|
||||
}
|
||||
52
game/client/c_env_fog_controller.cpp
Normal file
52
game/client/c_env_fog_controller.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
//========= Copyright © 1996-2007, Valve Corporation, All rights reserved. ====
|
||||
//
|
||||
// An entity that allows level designer control over the fog parameters.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_env_fog_controller.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( FogController, DT_FogController )
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Datatable
|
||||
//-----------------------------------------------------------------------------
|
||||
BEGIN_NETWORK_TABLE_NOBASE( CFogController, DT_FogController )
|
||||
// fog data
|
||||
RecvPropInt( RECVINFO( m_fog.enable ) ),
|
||||
RecvPropInt( RECVINFO( m_fog.blend ) ),
|
||||
RecvPropVector( RECVINFO( m_fog.dirPrimary ) ),
|
||||
RecvPropInt( RECVINFO( m_fog.colorPrimary ), 0, RecvProxy_Int32ToColor32 ),
|
||||
RecvPropInt( RECVINFO( m_fog.colorSecondary ), 0, RecvProxy_Int32ToColor32 ),
|
||||
RecvPropFloat( RECVINFO( m_fog.start ) ),
|
||||
RecvPropFloat( RECVINFO( m_fog.end ) ),
|
||||
RecvPropFloat( RECVINFO( m_fog.farz ) ),
|
||||
RecvPropFloat( RECVINFO( m_fog.maxdensity ) ),
|
||||
|
||||
RecvPropInt( RECVINFO( m_fog.colorPrimaryLerpTo ), 0, RecvProxy_Int32ToColor32 ),
|
||||
RecvPropInt( RECVINFO( m_fog.colorSecondaryLerpTo ), 0, RecvProxy_Int32ToColor32 ),
|
||||
RecvPropFloat( RECVINFO( m_fog.startLerpTo ) ),
|
||||
RecvPropFloat( RECVINFO( m_fog.endLerpTo ) ),
|
||||
RecvPropFloat( RECVINFO( m_fog.maxdensityLerpTo ) ),
|
||||
RecvPropFloat( RECVINFO( m_fog.lerptime ) ),
|
||||
RecvPropFloat( RECVINFO( m_fog.duration ) ),
|
||||
RecvPropFloat( RECVINFO( m_fog.HDRColorScale ) ),
|
||||
|
||||
RecvPropFloat( RECVINFO( m_fog.ZoomFogScale ) ),
|
||||
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_FogController::C_FogController()
|
||||
{
|
||||
// Make sure that old maps without fog fields don't get wacked out fog values.
|
||||
m_fog.enable = false;
|
||||
m_fog.maxdensity = 1.0f;
|
||||
m_fog.HDRColorScale = 1.0f;
|
||||
}
|
||||
33
game/client/c_env_fog_controller.h
Normal file
33
game/client/c_env_fog_controller.h
Normal file
@@ -0,0 +1,33 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_ENV_FOG_CONTROLLER_H
|
||||
#define C_ENV_FOG_CONTROLLER_H
|
||||
|
||||
#define CFogController C_FogController
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Class Fog Controller:
|
||||
// Compares a set of integer inputs to the one main input
|
||||
// Outputs true if they are all equivalant, false otherwise
|
||||
//
|
||||
class C_FogController : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_NETWORKCLASS();
|
||||
DECLARE_CLASS( C_FogController, C_BaseEntity );
|
||||
|
||||
C_FogController();
|
||||
|
||||
public:
|
||||
|
||||
fogparams_t m_fog;
|
||||
};
|
||||
|
||||
|
||||
#endif // C_ENV_FOG_CONTROLLER_H
|
||||
304
game/client/c_env_particlescript.cpp
Normal file
304
game/client/c_env_particlescript.cpp
Normal file
@@ -0,0 +1,304 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_baseanimating.h"
|
||||
#include "particlemgr.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "cl_animevent.h"
|
||||
#include "particle_util.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// An entity which emits other entities at points
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_EnvParticleScript : public C_BaseAnimating, public IParticleEffect
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_EnvParticleScript, C_BaseAnimating );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_EnvParticleScript();
|
||||
|
||||
// IParticleEffect overrides.
|
||||
public:
|
||||
virtual bool ShouldSimulate() const { return m_bSimulate; }
|
||||
virtual void SetShouldSimulate( bool bSim ) { m_bSimulate = bSim; }
|
||||
|
||||
virtual void RenderParticles( CParticleRenderIterator *pIterator );
|
||||
virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
|
||||
|
||||
virtual const Vector &GetSortOrigin();
|
||||
|
||||
// C_BaseAnimating overrides
|
||||
public:
|
||||
// NOTE: Ths enclosed particle effect binding will do all the drawing
|
||||
// But we have to return true, unlike other particle systems, for the animation events to work
|
||||
virtual bool ShouldDraw() { return true; }
|
||||
virtual int DrawModel( int flags, const RenderableInstance_t &instance ) { return 0; }
|
||||
|
||||
virtual void FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options );
|
||||
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
private:
|
||||
|
||||
// Creates, destroys particles attached to an attachment
|
||||
void CreateParticle( const char *pAttachmentName, const char *pSpriteName );
|
||||
void DestroyAllParticles( const char *pAttachmentName );
|
||||
void DestroyAllParticles( );
|
||||
|
||||
private:
|
||||
struct ParticleScriptParticle_t : public Particle
|
||||
{
|
||||
int m_nAttachment;
|
||||
float m_flSize;
|
||||
};
|
||||
|
||||
CParticleEffectBinding m_ParticleEffect;
|
||||
float m_flMaxParticleSize;
|
||||
int m_nOldSequence;
|
||||
float m_flSequenceScale;
|
||||
bool m_bSimulate;
|
||||
};
|
||||
|
||||
REGISTER_EFFECT( C_EnvParticleScript );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Datatable
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EnvParticleScript, DT_EnvParticleScript, CEnvParticleScript )
|
||||
RecvPropFloat( RECVINFO(m_flSequenceScale) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EnvParticleScript::C_EnvParticleScript()
|
||||
{
|
||||
m_flMaxParticleSize = 0.0f;
|
||||
m_bSimulate = true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Check for changed sequence numbers
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvParticleScript::OnPreDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnPreDataChanged( updateType );
|
||||
|
||||
m_nOldSequence = GetSequence();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Starts up the particle system
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvParticleScript::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
ParticleMgr()->AddEffect( &m_ParticleEffect, this );
|
||||
g_pClientLeafSystem->EnableRendering( RenderHandle(), false );
|
||||
}
|
||||
|
||||
if ( m_nOldSequence != GetSequence() )
|
||||
{
|
||||
DestroyAllParticles();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creates, destroys particles attached to an attachment
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvParticleScript::CreateParticle( const char *pAttachmentName, const char *pSpriteName )
|
||||
{
|
||||
// Find the attachment
|
||||
int nAttachment = LookupAttachment( pAttachmentName );
|
||||
if ( nAttachment <= 0 )
|
||||
return;
|
||||
|
||||
// Get the sprite materials
|
||||
PMaterialHandle hMat = m_ParticleEffect.FindOrAddMaterial( pSpriteName );
|
||||
ParticleScriptParticle_t *pParticle =
|
||||
(ParticleScriptParticle_t*)m_ParticleEffect.AddParticle(sizeof(ParticleScriptParticle_t), hMat);
|
||||
|
||||
if ( pParticle == NULL )
|
||||
return;
|
||||
|
||||
// Get the sprite size from the material's materialvars
|
||||
bool bFound = false;
|
||||
IMaterialVar *pMaterialVar = NULL;
|
||||
IMaterial *pMaterial = ParticleMgr()->PMaterialToIMaterial( hMat );
|
||||
if ( pMaterial )
|
||||
{
|
||||
pMaterialVar = pMaterial->FindVar( "$spritesize", &bFound, false );
|
||||
}
|
||||
|
||||
if ( bFound )
|
||||
{
|
||||
pParticle->m_flSize = pMaterialVar->GetFloatValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
pParticle->m_flSize = 100.0f;
|
||||
}
|
||||
|
||||
// Make sure the particle cull size reflects our particles
|
||||
if ( pParticle->m_flSize > m_flMaxParticleSize )
|
||||
{
|
||||
m_flMaxParticleSize = pParticle->m_flSize;
|
||||
m_ParticleEffect.SetParticleCullRadius( m_flMaxParticleSize );
|
||||
}
|
||||
|
||||
// Place the particle on the attachment specified
|
||||
pParticle->m_nAttachment = nAttachment;
|
||||
QAngle vecAngles;
|
||||
GetAttachment( nAttachment, pParticle->m_Pos, vecAngles );
|
||||
|
||||
if ( m_flSequenceScale != 1.0f )
|
||||
{
|
||||
pParticle->m_Pos -= GetAbsOrigin();
|
||||
pParticle->m_Pos *= m_flSequenceScale;
|
||||
pParticle->m_Pos += GetAbsOrigin();
|
||||
}
|
||||
}
|
||||
|
||||
void C_EnvParticleScript::DestroyAllParticles( const char *pAttachmentName )
|
||||
{
|
||||
int nAttachment = LookupAttachment( pAttachmentName );
|
||||
if ( nAttachment <= 0 )
|
||||
return;
|
||||
|
||||
int nCount = m_ParticleEffect.GetNumActiveParticles();
|
||||
Particle** ppParticles = (Particle**)stackalloc( nCount * sizeof(Particle*) );
|
||||
int nActualCount = m_ParticleEffect.GetActiveParticleList( nCount, ppParticles );
|
||||
Assert( nActualCount == nCount );
|
||||
|
||||
for ( int i = 0; i < nActualCount; ++i )
|
||||
{
|
||||
ParticleScriptParticle_t *pParticle = (ParticleScriptParticle_t*)ppParticles[i];
|
||||
if ( pParticle->m_nAttachment == nAttachment )
|
||||
{
|
||||
// Mark for deletion
|
||||
pParticle->m_nAttachment = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void C_EnvParticleScript::DestroyAllParticles( )
|
||||
{
|
||||
int nCount = m_ParticleEffect.GetNumActiveParticles();
|
||||
Particle** ppParticles = (Particle**)stackalloc( nCount * sizeof(Particle*) );
|
||||
int nActualCount = m_ParticleEffect.GetActiveParticleList( nCount, ppParticles );
|
||||
Assert( nActualCount == nCount );
|
||||
|
||||
for ( int i = 0; i < nActualCount; ++i )
|
||||
{
|
||||
ParticleScriptParticle_t *pParticle = (ParticleScriptParticle_t*)ppParticles[i];
|
||||
|
||||
// Mark for deletion
|
||||
pParticle->m_nAttachment = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The animation events will create particles on the attachment points
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvParticleScript::FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options )
|
||||
{
|
||||
// Handle events to create + destroy particles
|
||||
switch( event )
|
||||
{
|
||||
case CL_EVENT_SPRITEGROUP_CREATE:
|
||||
{
|
||||
char pAttachmentName[256];
|
||||
char pSpriteName[256];
|
||||
int nArgs = sscanf( options, "%255s %255s", pAttachmentName, pSpriteName );
|
||||
if ( nArgs == 2 )
|
||||
{
|
||||
CreateParticle( pAttachmentName, pSpriteName );
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
case CL_EVENT_SPRITEGROUP_DESTROY:
|
||||
{
|
||||
char pAttachmentName[256];
|
||||
int nArgs = sscanf( options, "%255s", pAttachmentName );
|
||||
if ( nArgs == 1 )
|
||||
{
|
||||
DestroyAllParticles( pAttachmentName );
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Fall back
|
||||
BaseClass::FireEvent( origin, angles, event, options );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Simulate the particles
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvParticleScript::RenderParticles( CParticleRenderIterator *pIterator )
|
||||
{
|
||||
const ParticleScriptParticle_t* pParticle = (const ParticleScriptParticle_t*)pIterator->GetFirst();
|
||||
while ( pParticle )
|
||||
{
|
||||
Vector vecRenderPos;
|
||||
TransformParticle( ParticleMgr()->GetModelView(), pParticle->m_Pos, vecRenderPos );
|
||||
float sortKey = vecRenderPos.z;
|
||||
|
||||
Vector color( 1, 1, 1 );
|
||||
RenderParticle_ColorSize( pIterator->GetParticleDraw(), vecRenderPos, color, 1.0f, pParticle->m_flSize );
|
||||
|
||||
pParticle = (const ParticleScriptParticle_t*)pIterator->GetNext( sortKey );
|
||||
}
|
||||
}
|
||||
|
||||
void C_EnvParticleScript::SimulateParticles( CParticleSimulateIterator *pIterator )
|
||||
{
|
||||
ParticleScriptParticle_t* pParticle = (ParticleScriptParticle_t*)pIterator->GetFirst();
|
||||
while ( pParticle )
|
||||
{
|
||||
// Here's how we retire particles
|
||||
if ( pParticle->m_nAttachment == -1 )
|
||||
{
|
||||
pIterator->RemoveParticle( pParticle );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Move the particle to the attachment point
|
||||
QAngle vecAngles;
|
||||
GetAttachment( pParticle->m_nAttachment, pParticle->m_Pos, vecAngles );
|
||||
|
||||
if ( m_flSequenceScale != 1.0f )
|
||||
{
|
||||
pParticle->m_Pos -= GetAbsOrigin();
|
||||
pParticle->m_Pos *= m_flSequenceScale;
|
||||
pParticle->m_Pos += GetAbsOrigin();
|
||||
}
|
||||
}
|
||||
|
||||
pParticle = (ParticleScriptParticle_t*)pIterator->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
const Vector &C_EnvParticleScript::GetSortOrigin()
|
||||
{
|
||||
return GetAbsOrigin();
|
||||
}
|
||||
495
game/client/c_env_projectedtexture.cpp
Normal file
495
game/client/c_env_projectedtexture.cpp
Normal file
@@ -0,0 +1,495 @@
|
||||
//====== Copyright © 1996-2003, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
#include "c_env_projectedtexture.h"
|
||||
#include "shareddefs.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "view.h"
|
||||
#include "iviewrender.h"
|
||||
#include "view_shared.h"
|
||||
#include "texture_group_names.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "tier0/platform.h"
|
||||
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
float C_EnvProjectedTexture::m_flVisibleBBoxMinHeight = -FLT_MAX;
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EnvProjectedTexture, DT_EnvProjectedTexture, CEnvProjectedTexture )
|
||||
RecvPropEHandle( RECVINFO( m_hTargetEntity ) ),
|
||||
RecvPropBool( RECVINFO( m_bState ) ),
|
||||
RecvPropBool( RECVINFO( m_bAlwaysUpdate ) ),
|
||||
RecvPropFloat( RECVINFO( m_flLightFOV ) ),
|
||||
RecvPropBool( RECVINFO( m_bEnableShadows ) ),
|
||||
RecvPropBool( RECVINFO( m_bSimpleProjection ) ),
|
||||
RecvPropBool( RECVINFO( m_bLightOnlyTarget ) ),
|
||||
RecvPropBool( RECVINFO( m_bLightWorld ) ),
|
||||
RecvPropBool( RECVINFO( m_bCameraSpace ) ),
|
||||
RecvPropFloat( RECVINFO( m_flBrightnessScale ) ),
|
||||
RecvPropInt( RECVINFO( m_LightColor ), 0, RecvProxy_Int32ToColor32 ),
|
||||
RecvPropFloat( RECVINFO( m_flColorTransitionTime ) ),
|
||||
RecvPropFloat( RECVINFO( m_flAmbient ) ),
|
||||
RecvPropString( RECVINFO( m_SpotlightTextureName ) ),
|
||||
RecvPropInt( RECVINFO( m_nSpotlightTextureFrame ) ),
|
||||
RecvPropFloat( RECVINFO( m_flNearZ ) ),
|
||||
RecvPropFloat( RECVINFO( m_flFarZ ) ),
|
||||
RecvPropInt( RECVINFO( m_nShadowQuality ) ),
|
||||
RecvPropFloat( RECVINFO( m_flProjectionSize ) ),
|
||||
RecvPropFloat( RECVINFO( m_flRotation ) ),
|
||||
RecvPropInt( RECVINFO( m_iStyle ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
C_EnvProjectedTexture *C_EnvProjectedTexture::Create( )
|
||||
{
|
||||
C_EnvProjectedTexture *pEnt = new C_EnvProjectedTexture();
|
||||
|
||||
pEnt->m_flNearZ = 4.0f;
|
||||
pEnt->m_flFarZ = 2000.0f;
|
||||
// strcpy( pEnt->m_SpotlightTextureName, "particle/rj" );
|
||||
pEnt->m_bLightWorld = true;
|
||||
pEnt->m_bLightOnlyTarget = false;
|
||||
pEnt->m_bSimpleProjection = true;
|
||||
pEnt->m_nShadowQuality = 1;
|
||||
pEnt->m_flLightFOV = 10.0f;
|
||||
pEnt->m_LightColor.r = 255;
|
||||
pEnt->m_LightColor.g = 255;
|
||||
pEnt->m_LightColor.b = 255;
|
||||
pEnt->m_LightColor.a = 255;
|
||||
pEnt->m_bEnableShadows = false;
|
||||
pEnt->m_flColorTransitionTime = 1.0f;
|
||||
pEnt->m_bCameraSpace = false;
|
||||
pEnt->SetAbsAngles( QAngle( 90, 0, 0 ) );
|
||||
pEnt->m_bAlwaysUpdate = true;
|
||||
pEnt->m_bState = true;
|
||||
pEnt->m_flProjectionSize = 500.0f;
|
||||
pEnt->m_flRotation = 0.0f;
|
||||
|
||||
return pEnt;
|
||||
}
|
||||
|
||||
C_EnvProjectedTexture::C_EnvProjectedTexture( void )
|
||||
{
|
||||
m_LightHandle = CLIENTSHADOW_INVALID_HANDLE;
|
||||
m_bForceUpdate = true;
|
||||
m_pMaterial = NULL;
|
||||
m_bIsCurrentlyProjected = false;
|
||||
AddToEntityList( ENTITY_LIST_SIMULATE );
|
||||
}
|
||||
|
||||
C_EnvProjectedTexture::~C_EnvProjectedTexture( void )
|
||||
{
|
||||
ShutDownLightHandle();
|
||||
}
|
||||
|
||||
void C_EnvProjectedTexture::ShutDownLightHandle( void )
|
||||
{
|
||||
// Clear out the light
|
||||
if( m_LightHandle != CLIENTSHADOW_INVALID_HANDLE )
|
||||
{
|
||||
if ( m_bSimpleProjection == true )
|
||||
{
|
||||
g_pClientShadowMgr->DestroyProjection( m_LightHandle );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pClientShadowMgr->DestroyFlashlight( m_LightHandle );
|
||||
}
|
||||
m_LightHandle = CLIENTSHADOW_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
m_bIsCurrentlyProjected = false;
|
||||
}
|
||||
|
||||
|
||||
void C_EnvProjectedTexture::SetMaterial( IMaterial *pMaterial )
|
||||
{
|
||||
if ( pMaterial != m_ProjectedMaterial )
|
||||
{
|
||||
m_ProjectedMaterial.Init( pMaterial );
|
||||
pMaterial->AddRef();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void C_EnvProjectedTexture::SetLightColor( byte r, byte g, byte b, byte a )
|
||||
{
|
||||
m_LightColor.r = r;
|
||||
m_LightColor.g = g;
|
||||
m_LightColor.b = b;
|
||||
m_LightColor.a = a;
|
||||
}
|
||||
|
||||
|
||||
void C_EnvProjectedTexture::SetSize( float flSize )
|
||||
{
|
||||
m_flProjectionSize = flSize;
|
||||
}
|
||||
|
||||
|
||||
void C_EnvProjectedTexture::SetRotation( float flRotation )
|
||||
{
|
||||
m_flRotation = flRotation;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : updateType -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvProjectedTexture::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
Assert( m_SpotlightTexture.IsValid() == false );
|
||||
m_SpotlightTexture.Init( m_SpotlightTextureName, TEXTURE_GROUP_OTHER, true );
|
||||
m_ProjectedMaterial.Init( m_SpotlightTextureName, TEXTURE_GROUP_OTHER );
|
||||
}
|
||||
|
||||
|
||||
m_bForceUpdate = true;
|
||||
UpdateLight();
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
}
|
||||
|
||||
static ConVar asw_perf_wtf("asw_perf_wtf", "0", FCVAR_DEVELOPMENTONLY, "Disable updating of projected shadow textures from UpdateLight" );
|
||||
extern ConVar r_flashlightenableculling;
|
||||
|
||||
bool C_EnvProjectedTexture::ShouldUpdate( void )
|
||||
{
|
||||
if ( !IsGameConsole() )
|
||||
{
|
||||
CPULevel_t nCPULevel = GetCPULevel();
|
||||
bool bNoDraw = ( GetMinCPULevel() && GetMinCPULevel()-1 > nCPULevel );
|
||||
bNoDraw = bNoDraw || ( GetMaxCPULevel() && GetMaxCPULevel()-1 < nCPULevel );
|
||||
if ( bNoDraw )
|
||||
return false;
|
||||
|
||||
GPULevel_t nGPULevel = GetGPULevel();
|
||||
bNoDraw = ( GetMinGPULevel() && GetMinGPULevel()-1 > nGPULevel );
|
||||
bNoDraw = bNoDraw || ( GetMaxGPULevel() && GetMaxGPULevel()-1 < nGPULevel );
|
||||
if ( bNoDraw )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void C_EnvProjectedTexture::UpdateLight( void )
|
||||
{
|
||||
if ( !ShouldUpdate() )
|
||||
{
|
||||
if ( m_bIsCurrentlyProjected )
|
||||
{
|
||||
ShutDownLightHandle();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
VPROF("C_EnvProjectedTexture::UpdateLight");
|
||||
bool bVisible = true;
|
||||
|
||||
Vector vLinearFloatLightColor( m_LightColor.r, m_LightColor.g, m_LightColor.b );
|
||||
float flLinearFloatLightAlpha = m_LightColor.a;
|
||||
|
||||
if ( m_bAlwaysUpdate )
|
||||
{
|
||||
m_bForceUpdate = true;
|
||||
}
|
||||
|
||||
if ( m_CurrentLinearFloatLightColor != vLinearFloatLightColor || m_flCurrentLinearFloatLightAlpha != flLinearFloatLightAlpha )
|
||||
{
|
||||
float flColorTransitionSpeed = gpGlobals->frametime * m_flColorTransitionTime * 255.0f;
|
||||
|
||||
m_CurrentLinearFloatLightColor.x = Approach( vLinearFloatLightColor.x, m_CurrentLinearFloatLightColor.x, flColorTransitionSpeed );
|
||||
m_CurrentLinearFloatLightColor.y = Approach( vLinearFloatLightColor.y, m_CurrentLinearFloatLightColor.y, flColorTransitionSpeed );
|
||||
m_CurrentLinearFloatLightColor.z = Approach( vLinearFloatLightColor.z, m_CurrentLinearFloatLightColor.z, flColorTransitionSpeed );
|
||||
m_flCurrentLinearFloatLightAlpha = Approach( flLinearFloatLightAlpha, m_flCurrentLinearFloatLightAlpha, flColorTransitionSpeed );
|
||||
|
||||
m_bForceUpdate = true;
|
||||
}
|
||||
|
||||
if ( !m_bForceUpdate && r_flashlightenableculling.GetBool() )
|
||||
{
|
||||
bVisible = IsBBoxVisible();
|
||||
}
|
||||
|
||||
if ( m_bState == false || !bVisible )
|
||||
{
|
||||
// Spotlight's extents aren't in view
|
||||
ShutDownLightHandle();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_LightHandle == CLIENTSHADOW_INVALID_HANDLE || m_hTargetEntity != NULL || m_bForceUpdate )
|
||||
{
|
||||
Vector vForward, vRight, vUp, vPos = GetAbsOrigin();
|
||||
FlashlightState_t state;
|
||||
|
||||
if ( m_hTargetEntity != NULL )
|
||||
{
|
||||
if ( m_bCameraSpace )
|
||||
{
|
||||
const QAngle &angles = GetLocalAngles();
|
||||
|
||||
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
if( pPlayer )
|
||||
{
|
||||
const QAngle playerAngles = pPlayer->GetAbsAngles();
|
||||
|
||||
Vector vPlayerForward, vPlayerRight, vPlayerUp;
|
||||
AngleVectors( playerAngles, &vPlayerForward, &vPlayerRight, &vPlayerUp );
|
||||
|
||||
matrix3x4_t mRotMatrix;
|
||||
AngleMatrix( angles, mRotMatrix );
|
||||
|
||||
VectorITransform( vPlayerForward, mRotMatrix, vForward );
|
||||
VectorITransform( vPlayerRight, mRotMatrix, vRight );
|
||||
VectorITransform( vPlayerUp, mRotMatrix, vUp );
|
||||
|
||||
float dist = (m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin()).Length();
|
||||
vPos = m_hTargetEntity->GetAbsOrigin() - vForward*dist;
|
||||
|
||||
VectorNormalize( vForward );
|
||||
VectorNormalize( vRight );
|
||||
VectorNormalize( vUp );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vForward = m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin();
|
||||
VectorNormalize( vForward );
|
||||
|
||||
// JasonM - unimplemented
|
||||
Assert (0);
|
||||
|
||||
//Quaternion q = DirectionToOrientation( dir );
|
||||
|
||||
|
||||
//
|
||||
// JasonM - set up vRight, vUp
|
||||
//
|
||||
|
||||
// VectorNormalize( vRight );
|
||||
// VectorNormalize( vUp );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AngleVectors( GetAbsAngles(), &vForward, &vRight, &vUp );
|
||||
}
|
||||
|
||||
state.m_fHorizontalFOVDegrees = m_flLightFOV;
|
||||
state.m_fVerticalFOVDegrees = m_flLightFOV;
|
||||
|
||||
state.m_vecLightOrigin = vPos;
|
||||
BasisToQuaternion( vForward, vRight, vUp, state.m_quatOrientation );
|
||||
state.m_NearZ = m_flNearZ;
|
||||
state.m_FarZ = m_flFarZ;
|
||||
|
||||
if ( r_flashlightenableculling.GetBool() )
|
||||
{
|
||||
// quickly check the proposed light's bbox against the view frustum to determine whether we
|
||||
// should bother to create it, if it doesn't exist, or cull it, if it does.
|
||||
|
||||
#ifndef LINUX
|
||||
#pragma message("OPTIMIZATION: this should be made SIMD")
|
||||
#endif
|
||||
// get the half-widths of the near and far planes,
|
||||
// based on the FOV which is in degrees. Remember that
|
||||
// on planet Valve, x is forward, y left, and z up.
|
||||
const float tanHalfAngle = tan( m_flLightFOV * ( M_PI/180.0f ) * 0.5f );
|
||||
const float halfWidthNear = tanHalfAngle * m_flNearZ;
|
||||
const float halfWidthFar = tanHalfAngle * m_flFarZ;
|
||||
// now we can build coordinates in local space: the near rectangle is eg
|
||||
// (0, -halfWidthNear, -halfWidthNear), (0, halfWidthNear, -halfWidthNear),
|
||||
// (0, halfWidthNear, halfWidthNear), (0, -halfWidthNear, halfWidthNear)
|
||||
|
||||
VectorAligned vNearRect[4] = {
|
||||
VectorAligned( m_flNearZ, -halfWidthNear, -halfWidthNear), VectorAligned( m_flNearZ, halfWidthNear, -halfWidthNear),
|
||||
VectorAligned( m_flNearZ, halfWidthNear, halfWidthNear), VectorAligned( m_flNearZ, -halfWidthNear, halfWidthNear)
|
||||
};
|
||||
|
||||
VectorAligned vFarRect[4] = {
|
||||
VectorAligned( m_flFarZ, -halfWidthFar, -halfWidthFar), VectorAligned( m_flFarZ, halfWidthFar, -halfWidthFar),
|
||||
VectorAligned( m_flFarZ, halfWidthFar, halfWidthFar), VectorAligned( m_flFarZ, -halfWidthFar, halfWidthFar)
|
||||
};
|
||||
|
||||
matrix3x4_t matOrientation( vForward, -vRight, vUp, vPos );
|
||||
|
||||
enum
|
||||
{
|
||||
kNEAR = 0,
|
||||
kFAR = 1,
|
||||
};
|
||||
VectorAligned vOutRects[2][4];
|
||||
|
||||
for ( int i = 0 ; i < 4 ; ++i )
|
||||
{
|
||||
VectorTransform( vNearRect[i].Base(), matOrientation, vOutRects[0][i].Base() );
|
||||
}
|
||||
for ( int i = 0 ; i < 4 ; ++i )
|
||||
{
|
||||
VectorTransform( vFarRect[i].Base(), matOrientation, vOutRects[1][i].Base() );
|
||||
}
|
||||
|
||||
// now take the min and max extents for the bbox, and see if it is visible.
|
||||
Vector mins = **vOutRects;
|
||||
Vector maxs = **vOutRects;
|
||||
for ( int i = 1; i < 8 ; ++i )
|
||||
{
|
||||
VectorMin( mins, *(*vOutRects+i), mins );
|
||||
VectorMax( maxs, *(*vOutRects+i), maxs );
|
||||
}
|
||||
|
||||
#if 0 //for debugging the visibility frustum we just calculated
|
||||
NDebugOverlay::Triangle( vOutRects[0][0], vOutRects[0][1], vOutRects[0][2], 255, 0, 0, 100, true, 0.0f ); //first tri
|
||||
NDebugOverlay::Triangle( vOutRects[0][2], vOutRects[0][1], vOutRects[0][0], 255, 0, 0, 100, true, 0.0f ); //make it double sided
|
||||
NDebugOverlay::Triangle( vOutRects[0][2], vOutRects[0][3], vOutRects[0][0], 255, 0, 0, 100, true, 0.0f ); //second tri
|
||||
NDebugOverlay::Triangle( vOutRects[0][0], vOutRects[0][3], vOutRects[0][2], 255, 0, 0, 100, true, 0.0f ); //make it double sided
|
||||
|
||||
NDebugOverlay::Triangle( vOutRects[1][0], vOutRects[1][1], vOutRects[1][2], 0, 0, 255, 100, true, 0.0f ); //first tri
|
||||
NDebugOverlay::Triangle( vOutRects[1][2], vOutRects[1][1], vOutRects[1][0], 0, 0, 255, 100, true, 0.0f ); //make it double sided
|
||||
NDebugOverlay::Triangle( vOutRects[1][2], vOutRects[1][3], vOutRects[1][0], 0, 0, 255, 100, true, 0.0f ); //second tri
|
||||
NDebugOverlay::Triangle( vOutRects[1][0], vOutRects[1][3], vOutRects[1][2], 0, 0, 255, 100, true, 0.0f ); //make it double sided
|
||||
|
||||
NDebugOverlay::Box( vec3_origin, mins, maxs, 0, 255, 0, 100, 0.0f );
|
||||
#endif
|
||||
|
||||
bool bVisible = IsBBoxVisible( mins, maxs );
|
||||
|
||||
|
||||
if (!bVisible)
|
||||
{
|
||||
// Spotlight's extents aren't in view
|
||||
if ( m_LightHandle != CLIENTSHADOW_INVALID_HANDLE )
|
||||
{
|
||||
ShutDownLightHandle();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
float flAlpha = m_flCurrentLinearFloatLightAlpha * ( 1.0f / 255.0f );
|
||||
|
||||
// Get the current light style value to throttle the brightness by
|
||||
flAlpha *= engine->LightStyleValue( m_iStyle );
|
||||
|
||||
state.m_fQuadraticAtten = 0.0;
|
||||
state.m_fLinearAtten = 100;
|
||||
state.m_fConstantAtten = 0.0f;
|
||||
state.m_FarZAtten = m_flFarZ;
|
||||
state.m_fBrightnessScale = m_flBrightnessScale;
|
||||
state.m_Color[0] = m_CurrentLinearFloatLightColor.x * ( 1.0f / 255.0f ) * flAlpha;
|
||||
state.m_Color[1] = m_CurrentLinearFloatLightColor.y * ( 1.0f / 255.0f ) * flAlpha;
|
||||
state.m_Color[2] = m_CurrentLinearFloatLightColor.z * ( 1.0f / 255.0f ) * flAlpha;
|
||||
state.m_Color[3] = 0.0f; // fixme: need to make ambient work m_flAmbient;
|
||||
state.m_flShadowSlopeScaleDepthBias = g_pMaterialSystemHardwareConfig->GetShadowSlopeScaleDepthBias();
|
||||
state.m_flShadowDepthBias = g_pMaterialSystemHardwareConfig->GetShadowDepthBias();
|
||||
state.m_bEnableShadows = m_bEnableShadows;
|
||||
extern ConVar r_flashlightdepthres;
|
||||
state.m_flShadowMapResolution = r_flashlightdepthres.GetFloat();
|
||||
|
||||
if ( m_bSimpleProjection )
|
||||
{
|
||||
state.m_pSpotlightTexture = NULL;
|
||||
state.m_pProjectedMaterial = m_ProjectedMaterial;
|
||||
}
|
||||
else
|
||||
{
|
||||
state.m_pSpotlightTexture = m_SpotlightTexture;
|
||||
state.m_pProjectedMaterial = NULL;
|
||||
}
|
||||
|
||||
state.m_nSpotlightTextureFrame = m_nSpotlightTextureFrame;
|
||||
state.m_flProjectionSize = m_flProjectionSize;
|
||||
state.m_flProjectionRotation = m_flRotation;
|
||||
|
||||
state.m_nShadowQuality = m_nShadowQuality; // Allow entity to affect shadow quality
|
||||
state.m_bShareBetweenSplitscreenPlayers = true; // projected flashlight entities should always be shared among players, because they live in a map.
|
||||
|
||||
if( m_LightHandle == CLIENTSHADOW_INVALID_HANDLE )
|
||||
{
|
||||
// Hack: env projected textures don't work like normal flashlights; they're not assigned to a given splitscreen slot,
|
||||
// but the flashlight code requires this
|
||||
HACK_GETLOCALPLAYER_GUARD( "Env projected texture" );
|
||||
if ( m_bSimpleProjection == true )
|
||||
{
|
||||
m_LightHandle = g_pClientShadowMgr->CreateProjection( state );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_LightHandle = g_pClientShadowMgr->CreateFlashlight( state );
|
||||
}
|
||||
|
||||
if ( m_LightHandle != CLIENTSHADOW_INVALID_HANDLE )
|
||||
{
|
||||
m_bForceUpdate = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_bSimpleProjection == true )
|
||||
{
|
||||
g_pClientShadowMgr->UpdateProjectionState( m_LightHandle, state );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pClientShadowMgr->UpdateFlashlightState( m_LightHandle, state );
|
||||
}
|
||||
m_bForceUpdate = false;
|
||||
}
|
||||
|
||||
g_pClientShadowMgr->GetFrustumExtents( m_LightHandle, m_vecExtentsMin, m_vecExtentsMax );
|
||||
|
||||
m_vecExtentsMin = m_vecExtentsMin - GetAbsOrigin();
|
||||
m_vecExtentsMax = m_vecExtentsMax - GetAbsOrigin();
|
||||
}
|
||||
|
||||
if( m_bLightOnlyTarget )
|
||||
{
|
||||
g_pClientShadowMgr->SetFlashlightTarget( m_LightHandle, m_hTargetEntity );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pClientShadowMgr->SetFlashlightTarget( m_LightHandle, INVALID_EHANDLE );
|
||||
}
|
||||
|
||||
g_pClientShadowMgr->SetFlashlightLightWorld( m_LightHandle, m_bLightWorld );
|
||||
|
||||
if ( !asw_perf_wtf.GetBool() && !m_bForceUpdate )
|
||||
{
|
||||
g_pClientShadowMgr->UpdateProjectedTexture( m_LightHandle, true );
|
||||
}
|
||||
|
||||
m_bIsCurrentlyProjected = true;
|
||||
}
|
||||
|
||||
bool C_EnvProjectedTexture::Simulate( void )
|
||||
{
|
||||
UpdateLight();
|
||||
|
||||
BaseClass::Simulate();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool C_EnvProjectedTexture::IsBBoxVisible( Vector vecExtentsMin, Vector vecExtentsMax )
|
||||
{
|
||||
// Z position clamped to the min height (but must be less than the max)
|
||||
float flVisibleBBoxMinHeight = MIN( vecExtentsMax.z - 1.0f, m_flVisibleBBoxMinHeight );
|
||||
vecExtentsMin.z = MAX( vecExtentsMin.z, flVisibleBBoxMinHeight );
|
||||
|
||||
// Check if the bbox is in the view
|
||||
return !engine->CullBox( vecExtentsMin, vecExtentsMax );
|
||||
}
|
||||
|
||||
100
game/client/c_env_projectedtexture.h
Normal file
100
game/client/c_env_projectedtexture.h
Normal file
@@ -0,0 +1,100 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_ENVPROJECTED_TEXTURE_H
|
||||
#define C_ENVPROJECTED_TEXTURE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_baseentity.h"
|
||||
#include "basetypes.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_EnvProjectedTexture : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_EnvProjectedTexture, C_BaseEntity );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
void SetMaterial( IMaterial *pMaterial );
|
||||
void SetLightColor( byte r, byte g, byte b, byte a );
|
||||
void SetSize( float flSize );
|
||||
void SetRotation( float flRotation );
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
void ShutDownLightHandle( void );
|
||||
|
||||
virtual bool Simulate();
|
||||
|
||||
bool ShouldUpdate( void );
|
||||
void UpdateLight( void );
|
||||
|
||||
C_EnvProjectedTexture();
|
||||
~C_EnvProjectedTexture();
|
||||
|
||||
static void SetVisibleBBoxMinHeight( float flVisibleBBoxMinHeight ) { m_flVisibleBBoxMinHeight = flVisibleBBoxMinHeight; }
|
||||
static float GetVisibleBBoxMinHeight( void ) { return m_flVisibleBBoxMinHeight; }
|
||||
static C_EnvProjectedTexture *Create( );
|
||||
|
||||
private:
|
||||
|
||||
inline bool IsBBoxVisible( void );
|
||||
bool IsBBoxVisible( Vector vecExtentsMin,
|
||||
Vector vecExtentsMax );
|
||||
|
||||
ClientShadowHandle_t m_LightHandle;
|
||||
bool m_bForceUpdate;
|
||||
|
||||
EHANDLE m_hTargetEntity;
|
||||
|
||||
bool m_bState;
|
||||
bool m_bAlwaysUpdate;
|
||||
float m_flLightFOV;
|
||||
bool m_bEnableShadows;
|
||||
bool m_bSimpleProjection;
|
||||
bool m_bLightOnlyTarget;
|
||||
bool m_bLightWorld;
|
||||
bool m_bCameraSpace;
|
||||
float m_flBrightnessScale;
|
||||
color32 m_LightColor;
|
||||
Vector m_CurrentLinearFloatLightColor;
|
||||
float m_flCurrentLinearFloatLightAlpha;
|
||||
float m_flColorTransitionTime;
|
||||
float m_flAmbient;
|
||||
float m_flNearZ;
|
||||
float m_flFarZ;
|
||||
char m_SpotlightTextureName[ MAX_PATH ];
|
||||
CTextureReference m_SpotlightTexture;
|
||||
CMaterialReference m_ProjectedMaterial;
|
||||
int m_nSpotlightTextureFrame;
|
||||
int m_nShadowQuality;
|
||||
int m_iStyle;
|
||||
bool m_bIsCurrentlyProjected;
|
||||
|
||||
// simple projection
|
||||
IMaterial *m_pMaterial;
|
||||
float m_flProjectionSize;
|
||||
float m_flRotation;
|
||||
|
||||
Vector m_vecExtentsMin;
|
||||
Vector m_vecExtentsMax;
|
||||
|
||||
static float m_flVisibleBBoxMinHeight;
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool C_EnvProjectedTexture::IsBBoxVisible( void )
|
||||
{
|
||||
return IsBBoxVisible( GetAbsOrigin() + m_vecExtentsMin, GetAbsOrigin() + m_vecExtentsMax );
|
||||
}
|
||||
|
||||
#endif // C_ENV_PROJECTED_TEXTURE_H
|
||||
311
game/client/c_env_screenoverlay.cpp
Normal file
311
game/client/c_env_screenoverlay.cpp
Normal file
@@ -0,0 +1,311 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "shareddefs.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "view.h"
|
||||
#include "iviewrender.h"
|
||||
#include "view_shared.h"
|
||||
#include "texture_group_names.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "keyvalues.h"
|
||||
#include "ScreenSpaceEffects.h"
|
||||
#include "materialsystem/imaterialsystemhardwareconfig.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_EnvScreenOverlay : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_EnvScreenOverlay, C_BaseEntity );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
void PreDataUpdate( DataUpdateType_t updateType );
|
||||
void PostDataUpdate( DataUpdateType_t updateType );
|
||||
|
||||
void HandleOverlaySwitch( void );
|
||||
void StartOverlays( void );
|
||||
void StopOverlays( void );
|
||||
void StartCurrentOverlay( void );
|
||||
void ClientThink( void );
|
||||
|
||||
protected:
|
||||
char m_iszOverlayNames[ MAX_SCREEN_OVERLAYS ][255];
|
||||
float m_flOverlayTimes[ MAX_SCREEN_OVERLAYS ];
|
||||
float m_flStartTime;
|
||||
int m_iDesiredOverlay;
|
||||
bool m_bIsActive;
|
||||
bool m_bWasActive;
|
||||
int m_iCachedDesiredOverlay;
|
||||
int m_iCurrentOverlay;
|
||||
float m_flCurrentOverlayTime;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EnvScreenOverlay, DT_EnvScreenOverlay, CEnvScreenOverlay )
|
||||
RecvPropArray( RecvPropString( RECVINFO( m_iszOverlayNames[0]) ), m_iszOverlayNames ),
|
||||
RecvPropArray( RecvPropFloat( RECVINFO( m_flOverlayTimes[0] ) ), m_flOverlayTimes ),
|
||||
RecvPropFloat( RECVINFO( m_flStartTime ) ),
|
||||
RecvPropInt( RECVINFO( m_iDesiredOverlay ) ),
|
||||
RecvPropBool( RECVINFO( m_bIsActive ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : updateType -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvScreenOverlay::PreDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::PreDataUpdate( updateType );
|
||||
|
||||
m_bWasActive = m_bIsActive;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvScreenOverlay::PostDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::PostDataUpdate( updateType );
|
||||
|
||||
// If we have a start time now, start the overlays going
|
||||
if ( m_bIsActive && m_flStartTime > 0 && view->GetScreenOverlayMaterial() == NULL )
|
||||
{
|
||||
StartOverlays();
|
||||
}
|
||||
|
||||
if ( m_flStartTime == -1 )
|
||||
{
|
||||
StopOverlays();
|
||||
}
|
||||
|
||||
HandleOverlaySwitch();
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED &&
|
||||
CommandLine()->FindParm( "-makereslists" ) )
|
||||
{
|
||||
for ( int i = 0; i < MAX_SCREEN_OVERLAYS; ++i )
|
||||
{
|
||||
if ( m_iszOverlayNames[ i ] && m_iszOverlayNames[ i ][ 0 ] )
|
||||
{
|
||||
materials->FindMaterial( m_iszOverlayNames[ i ], TEXTURE_GROUP_CLIENT_EFFECTS, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvScreenOverlay::StopOverlays( void )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_NEVER );
|
||||
|
||||
if ( m_bWasActive && !m_bIsActive )
|
||||
{
|
||||
view->SetScreenOverlayMaterial( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvScreenOverlay::StartOverlays( void )
|
||||
{
|
||||
m_iCurrentOverlay = 0;
|
||||
m_flCurrentOverlayTime = 0;
|
||||
m_iCachedDesiredOverlay = 0;
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
|
||||
StartCurrentOverlay();
|
||||
HandleOverlaySwitch();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvScreenOverlay::HandleOverlaySwitch( void )
|
||||
{
|
||||
if( m_iCachedDesiredOverlay != m_iDesiredOverlay )
|
||||
{
|
||||
m_iCurrentOverlay = m_iDesiredOverlay;
|
||||
m_iCachedDesiredOverlay = m_iDesiredOverlay;
|
||||
StartCurrentOverlay();
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvScreenOverlay::StartCurrentOverlay( void )
|
||||
{
|
||||
if ( m_iCurrentOverlay == MAX_SCREEN_OVERLAYS || !m_iszOverlayNames[m_iCurrentOverlay] || !m_iszOverlayNames[m_iCurrentOverlay][0] )
|
||||
{
|
||||
// Hit the end of our overlays, so stop.
|
||||
m_flStartTime = 0;
|
||||
StopOverlays();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_flOverlayTimes[m_iCurrentOverlay] == -1 )
|
||||
m_flCurrentOverlayTime = -1;
|
||||
else
|
||||
m_flCurrentOverlayTime = gpGlobals->curtime + m_flOverlayTimes[m_iCurrentOverlay];
|
||||
|
||||
// Bring up the current overlay
|
||||
IMaterial *pMaterial = materials->FindMaterial( m_iszOverlayNames[m_iCurrentOverlay], TEXTURE_GROUP_CLIENT_EFFECTS, false );
|
||||
if ( !IsErrorMaterial( pMaterial ) )
|
||||
{
|
||||
view->SetScreenOverlayMaterial( pMaterial );
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning("env_screenoverlay couldn't find overlay %s.\n", m_iszOverlayNames[m_iCurrentOverlay] );
|
||||
StopOverlays();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvScreenOverlay::ClientThink( void )
|
||||
{
|
||||
// If the current overlay's run out, go to the next one
|
||||
if ( m_flCurrentOverlayTime != -1 && m_flCurrentOverlayTime < gpGlobals->curtime )
|
||||
{
|
||||
m_iCurrentOverlay++;
|
||||
StartCurrentOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
// Effect types
|
||||
enum
|
||||
{
|
||||
SCREENEFFECT_EP2_ADVISOR_STUN,
|
||||
SCREENEFFECT_EP1_INTRO,
|
||||
SCREENEFFECT_EP2_GROGGY,
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Screenspace effect
|
||||
// ============================================================================
|
||||
|
||||
class C_EnvScreenEffect : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_EnvScreenEffect, C_BaseEntity );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
virtual void ReceiveMessage( int classID, bf_read &msg );
|
||||
|
||||
private:
|
||||
float m_flDuration;
|
||||
int m_nType;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EnvScreenEffect, DT_EnvScreenEffect, CEnvScreenEffect )
|
||||
RecvPropFloat( RECVINFO( m_flDuration ) ),
|
||||
RecvPropInt( RECVINFO( m_nType ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : classID -
|
||||
// &msg -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvScreenEffect::ReceiveMessage( int classID, bf_read &msg )
|
||||
{
|
||||
// Make sure our IDs match
|
||||
if ( classID != GetClientClass()->m_ClassID )
|
||||
{
|
||||
// Message is for subclass
|
||||
BaseClass::ReceiveMessage( classID, msg );
|
||||
return;
|
||||
}
|
||||
|
||||
int messageType = msg.ReadByte();
|
||||
switch( messageType )
|
||||
{
|
||||
// Effect turning on
|
||||
case 0: // FIXME: Declare
|
||||
{
|
||||
// Create a keyvalue block to set these params
|
||||
KeyValues *pKeys = new KeyValues( "keys" );
|
||||
if ( pKeys == NULL )
|
||||
return;
|
||||
|
||||
if ( m_nType == SCREENEFFECT_EP1_INTRO )
|
||||
{
|
||||
// Set our keys
|
||||
pKeys->SetFloat( "duration", m_flDuration );
|
||||
pKeys->SetInt( "fadeout", 0 );
|
||||
|
||||
g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "episodic_intro", pKeys );
|
||||
g_pScreenSpaceEffects->EnableScreenSpaceEffect( "episodic_intro" );
|
||||
}
|
||||
else if ( m_nType == SCREENEFFECT_EP2_ADVISOR_STUN )
|
||||
{
|
||||
// Set our keys
|
||||
pKeys->SetFloat( "duration", m_flDuration );
|
||||
|
||||
g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "episodic_stun", pKeys );
|
||||
g_pScreenSpaceEffects->EnableScreenSpaceEffect( "episodic_stun" );
|
||||
}
|
||||
else if ( m_nType == SCREENEFFECT_EP2_GROGGY )
|
||||
{
|
||||
// Set our keys
|
||||
pKeys->SetFloat( "duration", m_flDuration );
|
||||
pKeys->SetInt( "fadeout", 0 );
|
||||
|
||||
g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "ep2_groggy", pKeys );
|
||||
g_pScreenSpaceEffects->EnableScreenSpaceEffect( "ep2_groggy" );
|
||||
}
|
||||
|
||||
pKeys->deleteThis();
|
||||
}
|
||||
break;
|
||||
|
||||
// Effect turning off
|
||||
case 1: // FIXME: Declare
|
||||
|
||||
if ( m_nType == SCREENEFFECT_EP1_INTRO )
|
||||
{
|
||||
// Create a keyvalue block to set these params
|
||||
KeyValues *pKeys = new KeyValues( "keys" );
|
||||
if ( pKeys == NULL )
|
||||
return;
|
||||
|
||||
// Set our keys
|
||||
pKeys->SetFloat( "duration", m_flDuration );
|
||||
pKeys->SetInt( "fadeout", 1 );
|
||||
|
||||
g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "episodic_intro", pKeys );
|
||||
}
|
||||
else if ( m_nType == SCREENEFFECT_EP2_ADVISOR_STUN )
|
||||
{
|
||||
g_pScreenSpaceEffects->DisableScreenSpaceEffect( "episodic_stun" );
|
||||
}
|
||||
else if ( m_nType == SCREENEFFECT_EP2_GROGGY )
|
||||
{
|
||||
// Create a keyvalue block to set these params
|
||||
KeyValues *pKeys = new KeyValues( "keys" );
|
||||
if ( pKeys == NULL )
|
||||
return;
|
||||
|
||||
// Set our keys
|
||||
pKeys->SetFloat( "duration", m_flDuration );
|
||||
pKeys->SetInt( "fadeout", 1 );
|
||||
|
||||
g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "ep2_groggy", pKeys );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
132
game/client/c_env_tonemap_controller.cpp
Normal file
132
game/client/c_env_tonemap_controller.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
extern bool g_bUseCustomAutoExposureMin;
|
||||
extern bool g_bUseCustomAutoExposureMax;
|
||||
extern bool g_bUseCustomBloomScale;
|
||||
extern float g_flCustomAutoExposureMin;
|
||||
extern float g_flCustomAutoExposureMax;
|
||||
extern float g_flCustomBloomScale;
|
||||
extern float g_flCustomBloomScaleMinimum;
|
||||
extern float g_flBloomExponent;
|
||||
extern float g_flBloomSaturation;
|
||||
extern float g_flTonemapPercentTarget;
|
||||
extern float g_flTonemapPercentBrightPixels;
|
||||
extern float g_flTonemapMinAvgLum;
|
||||
extern float g_flTonemapRate;
|
||||
|
||||
EHANDLE g_hTonemapControllerInUse = INVALID_EHANDLE;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_EnvTonemapController : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_EnvTonemapController, C_BaseEntity );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_EnvTonemapController();
|
||||
|
||||
//private:
|
||||
bool m_bUseCustomAutoExposureMin;
|
||||
bool m_bUseCustomAutoExposureMax;
|
||||
bool m_bUseCustomBloomScale;
|
||||
float m_flCustomAutoExposureMin;
|
||||
float m_flCustomAutoExposureMax;
|
||||
float m_flCustomBloomScale;
|
||||
float m_flCustomBloomScaleMinimum;
|
||||
float m_flBloomExponent;
|
||||
float m_flBloomSaturation;
|
||||
float m_flTonemapPercentTarget;
|
||||
float m_flTonemapPercentBrightPixels;
|
||||
float m_flTonemapMinAvgLum;
|
||||
float m_flTonemapRate;
|
||||
|
||||
private:
|
||||
C_EnvTonemapController( const C_EnvTonemapController & );
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EnvTonemapController, DT_EnvTonemapController, CEnvTonemapController )
|
||||
RecvPropInt( RECVINFO(m_bUseCustomAutoExposureMin) ),
|
||||
RecvPropInt( RECVINFO(m_bUseCustomAutoExposureMax) ),
|
||||
RecvPropInt( RECVINFO(m_bUseCustomBloomScale) ),
|
||||
RecvPropFloat( RECVINFO(m_flCustomAutoExposureMin) ),
|
||||
RecvPropFloat( RECVINFO(m_flCustomAutoExposureMax) ),
|
||||
RecvPropFloat( RECVINFO(m_flCustomBloomScale) ),
|
||||
RecvPropFloat( RECVINFO(m_flCustomBloomScaleMinimum) ),
|
||||
RecvPropFloat( RECVINFO(m_flBloomExponent) ),
|
||||
RecvPropFloat( RECVINFO(m_flBloomSaturation) ),
|
||||
RecvPropFloat( RECVINFO(m_flTonemapPercentTarget) ),
|
||||
RecvPropFloat( RECVINFO(m_flTonemapPercentBrightPixels) ),
|
||||
RecvPropFloat( RECVINFO(m_flTonemapMinAvgLum) ),
|
||||
RecvPropFloat( RECVINFO(m_flTonemapRate) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EnvTonemapController::C_EnvTonemapController( void )
|
||||
{
|
||||
m_bUseCustomAutoExposureMin = false;
|
||||
m_bUseCustomAutoExposureMax = false;
|
||||
m_bUseCustomBloomScale = false;
|
||||
m_flCustomAutoExposureMin = 0;
|
||||
m_flCustomAutoExposureMax = 0;
|
||||
m_flCustomBloomScale = 0.0f;
|
||||
m_flCustomBloomScaleMinimum = 0.0f;
|
||||
m_flBloomExponent = 2.5f;
|
||||
m_flBloomSaturation = 1.0f;
|
||||
m_flTonemapPercentTarget = 65.0f;
|
||||
m_flTonemapPercentBrightPixels = 2.0f;
|
||||
m_flTonemapMinAvgLum = 3.0f;
|
||||
m_flTonemapRate = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GetTonemapSettingsFromEnvTonemapController( void )
|
||||
{
|
||||
C_BasePlayer *localPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( localPlayer )
|
||||
{
|
||||
C_EnvTonemapController *tonemapController = dynamic_cast< C_EnvTonemapController * >(localPlayer->m_hTonemapController.Get());
|
||||
if ( tonemapController != NULL )
|
||||
{
|
||||
g_bUseCustomAutoExposureMin = tonemapController->m_bUseCustomAutoExposureMin;
|
||||
g_bUseCustomAutoExposureMax = tonemapController->m_bUseCustomAutoExposureMax;
|
||||
g_bUseCustomBloomScale = tonemapController->m_bUseCustomBloomScale;
|
||||
g_flCustomAutoExposureMin = tonemapController->m_flCustomAutoExposureMin;
|
||||
g_flCustomAutoExposureMax = tonemapController->m_flCustomAutoExposureMax;
|
||||
g_flCustomBloomScale = tonemapController->m_flCustomBloomScale;
|
||||
g_flCustomBloomScaleMinimum = tonemapController->m_flCustomBloomScaleMinimum;
|
||||
|
||||
g_flBloomExponent = tonemapController->m_flBloomExponent;
|
||||
g_flBloomSaturation = tonemapController->m_flBloomSaturation;
|
||||
g_flTonemapPercentTarget = tonemapController->m_flTonemapPercentTarget;
|
||||
g_flTonemapPercentBrightPixels = tonemapController->m_flTonemapPercentBrightPixels;
|
||||
g_flTonemapMinAvgLum = tonemapController->m_flTonemapMinAvgLum;
|
||||
g_flTonemapRate = tonemapController->m_flTonemapRate;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_bUseCustomAutoExposureMax = false;
|
||||
g_bUseCustomBloomScale = false;
|
||||
|
||||
g_flBloomExponent = 2.5f;
|
||||
g_flBloomSaturation = 1.0f;
|
||||
g_flTonemapPercentTarget = 65.0f;
|
||||
g_flTonemapPercentBrightPixels = 2.0f;
|
||||
g_flTonemapMinAvgLum = 3.0f;
|
||||
g_flTonemapRate = 1.0f;
|
||||
}
|
||||
264
game/client/c_fire_smoke.cpp
Normal file
264
game/client/c_fire_smoke.cpp
Normal file
@@ -0,0 +1,264 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
#include "cbase.h"
|
||||
#include "iviewrender.h"
|
||||
#include "precache_register.h"
|
||||
#include "studio.h"
|
||||
#include "bone_setup.h"
|
||||
#include "engine/ivmodelinfo.h"
|
||||
#include "c_fire_smoke.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "iefx.h"
|
||||
#include "dlight.h"
|
||||
#include "tier0/icommandline.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
PRECACHE_REGISTER_BEGIN( GLOBAL, SmokeStackMaterials )
|
||||
PRECACHE( MATERIAL, "particle/SmokeStack" )
|
||||
PRECACHE_REGISTER_END()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pRecvProp -
|
||||
// *pStruct -
|
||||
// *pVarData -
|
||||
// *pIn -
|
||||
// objectID -
|
||||
//-----------------------------------------------------------------------------
|
||||
void RecvProxy_Scale( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
C_FireSmoke *pFireSmoke = (C_FireSmoke *) pStruct;
|
||||
float scale = pData->m_Value.m_Float;
|
||||
|
||||
//If changed, update our internal information
|
||||
if ( ( pFireSmoke->m_flScale != scale ) && ( pFireSmoke->m_flScaleEnd != scale ) )
|
||||
{
|
||||
pFireSmoke->m_flScaleStart = pFireSmoke->m_flScaleRegister;
|
||||
pFireSmoke->m_flScaleEnd = scale;
|
||||
}
|
||||
|
||||
pFireSmoke->m_flScale = scale;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pRecvProp -
|
||||
// *pStruct -
|
||||
// *pVarData -
|
||||
// *pIn -
|
||||
// objectID -
|
||||
//-----------------------------------------------------------------------------
|
||||
void RecvProxy_ScaleTime( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
C_FireSmoke *pFireSmoke = (C_FireSmoke *) pStruct;
|
||||
float time = pData->m_Value.m_Float;
|
||||
|
||||
//If changed, update our internal information
|
||||
//if ( pFireSmoke->m_flScaleTime != time )
|
||||
{
|
||||
if ( time == -1.0f )
|
||||
{
|
||||
pFireSmoke->m_flScaleTimeStart = Helper_GetTime()-1.0f;
|
||||
pFireSmoke->m_flScaleTimeEnd = pFireSmoke->m_flScaleTimeStart;
|
||||
}
|
||||
else
|
||||
{
|
||||
pFireSmoke->m_flScaleTimeStart = Helper_GetTime();
|
||||
pFireSmoke->m_flScaleTimeEnd = Helper_GetTime() + time;
|
||||
}
|
||||
}
|
||||
|
||||
pFireSmoke->m_flScaleTime = time;
|
||||
}
|
||||
|
||||
//Receive datatable
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_FireSmoke, DT_FireSmoke, CFireSmoke )
|
||||
RecvPropFloat( RECVINFO( m_flStartScale )),
|
||||
RecvPropFloat( RECVINFO( m_flScale ), 0, RecvProxy_Scale ),
|
||||
RecvPropFloat( RECVINFO( m_flScaleTime ), 0, RecvProxy_ScaleTime ),
|
||||
RecvPropInt( RECVINFO( m_nFlags ) ),
|
||||
RecvPropInt( RECVINFO( m_nFlameModelIndex ) ),
|
||||
RecvPropInt( RECVINFO( m_nFlameFromAboveModelIndex ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//==================================================
|
||||
// C_FireSmoke
|
||||
//==================================================
|
||||
|
||||
C_FireSmoke::C_FireSmoke()
|
||||
{
|
||||
}
|
||||
|
||||
C_FireSmoke::~C_FireSmoke()
|
||||
{
|
||||
|
||||
// Shut down our effect if we have it
|
||||
if ( m_hEffect )
|
||||
{
|
||||
m_hEffect->StopEmission(false, false , true);
|
||||
m_hEffect = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#define FLAME_ALPHA_START 0.9f
|
||||
#define FLAME_ALPHA_END 1.0f
|
||||
|
||||
#define FLAME_TRANS_START 0.75f
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_FireSmoke::AddFlames( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : bnewentity -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_FireSmoke::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
Start();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_FireSmoke::UpdateEffects( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_FireSmoke::ShouldDraw()
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_FireSmoke::Start( void )
|
||||
{
|
||||
const char *lpszEffectName;
|
||||
int nSize = (int) floor( m_flStartScale / 36.0f );
|
||||
|
||||
RANDOM_CEG_TEST_SECRET_PERIOD( 36, 67 );
|
||||
|
||||
switch ( nSize )
|
||||
{
|
||||
case 0:
|
||||
lpszEffectName = ( m_nFlags & bitsFIRESMOKE_SMOKE ) ? "env_fire_tiny_smoke" : "env_fire_tiny";
|
||||
break;
|
||||
|
||||
case 1:
|
||||
lpszEffectName = ( m_nFlags & bitsFIRESMOKE_SMOKE ) ? "env_fire_small_smoke" : "env_fire_small";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
lpszEffectName = ( m_nFlags & bitsFIRESMOKE_SMOKE ) ? "env_fire_medium_smoke" : "env_fire_medium";
|
||||
break;
|
||||
|
||||
case 3:
|
||||
default:
|
||||
lpszEffectName = ( m_nFlags & bitsFIRESMOKE_SMOKE ) ? "env_fire_large_smoke" : "env_fire_large";
|
||||
break;
|
||||
}
|
||||
|
||||
// Create the effect of the correct size
|
||||
m_hEffect = ParticleProp()->Create( lpszEffectName, PATTACH_ABSORIGIN );
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: FIXME: what's the right way to do this?
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_FireSmoke::StartClientOnly( void )
|
||||
{
|
||||
Start();
|
||||
|
||||
ClientEntityList().AddNonNetworkableEntity( this );
|
||||
CollisionProp()->CreatePartitionHandle();
|
||||
AddEffects( EF_NORECEIVESHADOW | EF_NOSHADOW );
|
||||
AddToLeafSystem();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_FireSmoke::RemoveClientOnly(void)
|
||||
{
|
||||
ClientThinkList()->RemoveThinkable( GetClientHandle() );
|
||||
|
||||
// Remove from the client entity list.
|
||||
ClientEntityList().RemoveEntity( GetClientHandle() );
|
||||
|
||||
::partition->Remove( PARTITION_CLIENT_SOLID_EDICTS | PARTITION_CLIENT_RESPONSIVE_EDICTS | PARTITION_CLIENT_NON_STATIC_EDICTS, CollisionProp()->GetPartitionHandle() );
|
||||
|
||||
RemoveFromLeafSystem();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_FireSmoke::UpdateAnimation( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_FireSmoke::UpdateFlames( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_FireSmoke::UpdateScale( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_FireSmoke::Update( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_FireSmoke::FindClipPlane( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Spawn smoke (...duh)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_FireSmoke::SpawnSmoke( void )
|
||||
{
|
||||
}
|
||||
268
game/client/c_fire_smoke.h
Normal file
268
game/client/c_fire_smoke.h
Normal file
@@ -0,0 +1,268 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
#ifndef C_FIRE_SMOKE_H
|
||||
#define C_FIRE_SMOKE_H
|
||||
|
||||
#include "particles_simple.h"
|
||||
#include "tempent.h"
|
||||
#include "glow_overlay.h"
|
||||
#include "view.h"
|
||||
#include "particle_litsmokeemitter.h"
|
||||
#include "tier1/utlobjectreference.h"
|
||||
|
||||
|
||||
class CFireOverlay;
|
||||
|
||||
class C_FireSprite : public C_Sprite
|
||||
{
|
||||
DECLARE_CLASS( C_FireSprite, C_Sprite );
|
||||
|
||||
private:
|
||||
virtual int DrawModel( int flags, const RenderableInstance_t &instance )
|
||||
{
|
||||
if ( m_bFadeFromAbove )
|
||||
{
|
||||
// The sprites become less visible the more you look down or up at them
|
||||
Vector vToPos = GetLocalOrigin() - CurrentViewOrigin();
|
||||
VectorNormalize( vToPos );
|
||||
|
||||
float fUpAmount = vToPos.z;
|
||||
|
||||
int iAlpha = 255;
|
||||
|
||||
if ( fUpAmount < -0.75f )
|
||||
iAlpha = 0;
|
||||
else if ( fUpAmount < -0.65f )
|
||||
iAlpha = 255 - (int)( ( fUpAmount + 0.65f ) * 10.0f * -255.0f );
|
||||
else if ( fUpAmount > 0.85f )
|
||||
iAlpha = 0;
|
||||
else if ( fUpAmount > 0.75f )
|
||||
iAlpha = 255 - (int)( ( fUpAmount - 0.75f ) * 10.0f * 255.0f );
|
||||
|
||||
SetColor( iAlpha, iAlpha, iAlpha );
|
||||
}
|
||||
|
||||
return BaseClass::DrawModel( flags, instance );
|
||||
}
|
||||
|
||||
public:
|
||||
Vector m_vecMoveDir;
|
||||
bool m_bFadeFromAbove;
|
||||
};
|
||||
|
||||
class C_FireFromAboveSprite : public C_Sprite
|
||||
{
|
||||
DECLARE_CLASS( C_FireFromAboveSprite, C_Sprite );
|
||||
|
||||
virtual int DrawModel( int flags, const RenderableInstance_t &instance )
|
||||
{
|
||||
// The sprites become more visible the more you look down or up at them
|
||||
Vector vToPos = GetLocalOrigin() - CurrentViewOrigin();
|
||||
VectorNormalize( vToPos );
|
||||
|
||||
float fUpAmount = vToPos.z;
|
||||
|
||||
int iAlpha = 0;
|
||||
|
||||
if ( fUpAmount < -0.85f )
|
||||
iAlpha = 255;
|
||||
else if ( fUpAmount < -0.65f )
|
||||
iAlpha = (int)( ( fUpAmount + 0.65f ) * 5.0f * -255.0f );
|
||||
else if ( fUpAmount > 0.75f )
|
||||
iAlpha = 255;
|
||||
else if ( fUpAmount > 0.55f )
|
||||
iAlpha = (int)( ( fUpAmount - 0.55f ) * 5.0f * 255.0f );
|
||||
|
||||
SetColor( iAlpha, iAlpha, iAlpha );
|
||||
|
||||
return BaseClass::DrawModel( flags, instance );
|
||||
}
|
||||
};
|
||||
|
||||
#define NUM_CHILD_FLAMES 4
|
||||
|
||||
#define SMOKE_RISE_RATE 92.0f
|
||||
#define SMOKE_LIFETIME 2.0f
|
||||
#define EMBER_LIFETIME 2.0f
|
||||
|
||||
#define FLAME_CHILD_SPREAD 64.0f
|
||||
#define FLAME_SOURCE_HEIGHT 128.0f
|
||||
#define FLAME_FROM_ABOVE_SOURCE_HEIGHT 32.0f
|
||||
|
||||
//==================================================
|
||||
// C_FireSmoke
|
||||
//==================================================
|
||||
|
||||
//NOTENOTE: Mirrored in dlls/fire_smoke.h
|
||||
#define bitsFIRESMOKE_NONE 0x00000000
|
||||
#define bitsFIRESMOKE_ACTIVE 0x00000001
|
||||
#define bitsFIRESMOKE_SMOKE 0x00000002
|
||||
#define bitsFIRESMOKE_SMOKE_COLLISION 0x00000004
|
||||
#define bitsFIRESMOKE_GLOW 0x00000008
|
||||
#define bitsFIRESMOKE_VISIBLE_FROM_ABOVE 0x00000010
|
||||
|
||||
#define OVERLAY_MAX_VISIBLE_RANGE 512.0f
|
||||
|
||||
|
||||
class C_FireSmoke : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_CLASS( C_FireSmoke, C_BaseEntity );
|
||||
|
||||
C_FireSmoke();
|
||||
~C_FireSmoke();
|
||||
|
||||
void Start( void );
|
||||
|
||||
void StartClientOnly( void );
|
||||
void RemoveClientOnly( void );
|
||||
|
||||
protected:
|
||||
void Update( void );
|
||||
void UpdateAnimation( void );
|
||||
void UpdateScale( void );
|
||||
void UpdateFlames( void );
|
||||
void AddFlames( void );
|
||||
void SpawnSmoke( void );
|
||||
void FindClipPlane( void );
|
||||
|
||||
//C_BaseEntity
|
||||
public:
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual bool ShouldDraw();
|
||||
|
||||
float GetScale( void ) const { return m_flScaleRegister; }
|
||||
|
||||
//From the server
|
||||
public:
|
||||
float m_flStartScale;
|
||||
float m_flScale;
|
||||
float m_flScaleTime;
|
||||
int m_nFlags;
|
||||
int m_nFlameModelIndex;
|
||||
int m_nFlameFromAboveModelIndex;
|
||||
|
||||
//Client-side only
|
||||
public:
|
||||
float m_flScaleRegister;
|
||||
float m_flScaleStart;
|
||||
float m_flScaleEnd;
|
||||
float m_flScaleTimeStart;
|
||||
float m_flScaleTimeEnd;
|
||||
float m_flChildFlameSpread;
|
||||
|
||||
VPlane m_planeClip;
|
||||
float m_flClipPerc;
|
||||
bool m_bClipTested;
|
||||
|
||||
bool m_bFadingOut;
|
||||
|
||||
protected:
|
||||
|
||||
void UpdateEffects( void );
|
||||
|
||||
//CSmartPtr<CEmberEffect> m_pEmberEmitter;
|
||||
CSmartPtr<CLitSmokeEmitter> m_pSmokeEmitter;
|
||||
|
||||
C_FireSprite m_entFlames[NUM_CHILD_FLAMES];
|
||||
C_FireFromAboveSprite m_entFlamesFromAbove[NUM_CHILD_FLAMES];
|
||||
float m_entFlameScales[NUM_CHILD_FLAMES];
|
||||
|
||||
TimedEvent m_tParticleSpawn;
|
||||
|
||||
CFireOverlay *m_pFireOverlay;
|
||||
|
||||
// New Particle Fire Effect
|
||||
CUtlReference<CNewParticleEffect> m_hEffect;
|
||||
private:
|
||||
C_FireSmoke( const C_FireSmoke & );
|
||||
};
|
||||
|
||||
//Fire overlay
|
||||
class CFireOverlay : public CGlowOverlay
|
||||
{
|
||||
public:
|
||||
|
||||
//Constructor
|
||||
explicit CFireOverlay( C_FireSmoke *owner )
|
||||
{
|
||||
m_pOwner = owner;
|
||||
m_flScale = 0.0f;
|
||||
m_nGUID = random->RandomInt( -999999, 999999 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Generate a flicker value
|
||||
// Output : scalar value
|
||||
//-----------------------------------------------------------------------------
|
||||
float GetFlickerScale( void )
|
||||
{
|
||||
float result;
|
||||
|
||||
float time = Helper_GetTime() + m_nGUID;
|
||||
|
||||
result = sin( time * 1000.0f );
|
||||
result += 0.5f * sin( time * 2000.0f );
|
||||
result -= 0.5f * cos( time * 8000.0f );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Update the overlay
|
||||
//-----------------------------------------------------------------------------
|
||||
virtual bool Update( void )
|
||||
{
|
||||
if ( m_pOwner == NULL )
|
||||
return false;
|
||||
|
||||
float scale = m_pOwner->GetScale();
|
||||
float dscale = scale - m_flScale;
|
||||
|
||||
m_vPos[2] += dscale * FLAME_SOURCE_HEIGHT;
|
||||
m_flScale = scale;
|
||||
|
||||
scale *= 0.75f;
|
||||
|
||||
float flickerScale = GetFlickerScale();
|
||||
|
||||
float newScale = scale + ( scale * flickerScale * 0.1f );
|
||||
|
||||
m_Sprites[0].m_flHorzSize = ( newScale * 0.2f ) + ( m_Sprites[0].m_flHorzSize * 0.8f );
|
||||
m_Sprites[0].m_flVertSize = m_Sprites[0].m_flHorzSize * 1.5f;
|
||||
|
||||
float cameraDistance = ( CurrentViewOrigin() - (m_pOwner->GetAbsOrigin())).Length();
|
||||
|
||||
C_BasePlayer *local = C_BasePlayer::GetLocalPlayer();
|
||||
if ( local )
|
||||
{
|
||||
cameraDistance *= local->GetFOVDistanceAdjustFactor();
|
||||
}
|
||||
|
||||
if ( cameraDistance > OVERLAY_MAX_VISIBLE_RANGE )
|
||||
cameraDistance = OVERLAY_MAX_VISIBLE_RANGE;
|
||||
|
||||
float alpha = 1.0f - ( cameraDistance / OVERLAY_MAX_VISIBLE_RANGE );
|
||||
|
||||
Vector newColor = m_vBaseColors[0] + ( m_vBaseColors[0] * flickerScale * 0.5f );
|
||||
m_Sprites[0].m_vColor = ( newColor * 0.1f ) + ( m_Sprites[0].m_vColor * 0.9f ) * alpha;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
C_FireSmoke *m_pOwner;
|
||||
Vector m_vBaseColors[MAX_SUN_LAYERS];
|
||||
float m_flScale;
|
||||
int m_nGUID;
|
||||
};
|
||||
|
||||
#endif // C_FIRE_SMOKE_H
|
||||
352
game/client/c_fish.cpp
Normal file
352
game/client/c_fish.cpp
Normal file
@@ -0,0 +1,352 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
// c_fish.cpp
|
||||
// Simple fish client-side logic
|
||||
// Author: Michael S. Booth, April 2005
|
||||
|
||||
#include "cbase.h"
|
||||
#include <bitbuf.h>
|
||||
#include "engine/ivdebugoverlay.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
extern float UTIL_WaterLevel( const Vector &position, float minz, float maxz );
|
||||
|
||||
|
||||
ConVar FishDebug( "fish_debug", "0", FCVAR_CHEAT, "Show debug info for fish" );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* Client-side fish entity
|
||||
*/
|
||||
class C_Fish : public C_BaseAnimating
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_Fish, C_BaseAnimating );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
virtual void Spawn( void );
|
||||
virtual void ClientThink();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t type );
|
||||
|
||||
private:
|
||||
friend void RecvProxy_FishOriginX( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||
friend void RecvProxy_FishOriginY( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||
|
||||
Vector m_pos; ///< local position
|
||||
Vector m_vel; ///< local velocity
|
||||
QAngle m_angles; ///< local angles
|
||||
|
||||
int m_localLifeState; ///< our version of m_lifeState
|
||||
|
||||
float m_deathDepth; ///< water depth when we died
|
||||
float m_deathAngle; ///< angle to float at when dead
|
||||
float m_buoyancy; ///< so each fish floats at a different rate when dead
|
||||
|
||||
CountdownTimer m_wiggleTimer; ///< for simulating swimming motions
|
||||
float m_wigglePhase; ///< where in the wiggle sinusoid we are
|
||||
float m_wiggleRate; ///< the speed of our wiggling
|
||||
|
||||
Vector m_actualPos; ///< position from server
|
||||
QAngle m_actualAngles; ///< angles from server
|
||||
|
||||
Vector m_poolOrigin;
|
||||
float m_waterLevel; ///< Z coordinate of water surface
|
||||
|
||||
bool m_gotUpdate; ///< true after we have received a network update
|
||||
|
||||
enum { MAX_ERROR_HISTORY = 20 };
|
||||
float m_errorHistory[ MAX_ERROR_HISTORY ]; ///< error history samples
|
||||
int m_errorHistoryIndex;
|
||||
int m_errorHistoryCount;
|
||||
float m_averageError;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RecvProxy_FishOriginX( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
C_Fish *fish = (C_Fish *)pStruct;
|
||||
float *out = (float *)pOut;
|
||||
|
||||
*out = pData->m_Value.m_Float + fish->m_poolOrigin.x;
|
||||
}
|
||||
|
||||
void RecvProxy_FishOriginY( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
C_Fish *fish = (C_Fish *)pStruct;
|
||||
float *out = (float *)pOut;
|
||||
|
||||
*out = pData->m_Value.m_Float + fish->m_poolOrigin.y;
|
||||
}
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT_NOBASE( C_Fish, DT_CFish, CFish )
|
||||
|
||||
RecvPropVector( RECVINFO(m_poolOrigin) ),
|
||||
|
||||
RecvPropFloat( RECVINFO_NAME( m_actualPos.x, m_x ), 0, RecvProxy_FishOriginX ),
|
||||
RecvPropFloat( RECVINFO_NAME( m_actualPos.y, m_y ), 0, RecvProxy_FishOriginY ),
|
||||
RecvPropFloat( RECVINFO_NAME( m_actualPos.z, m_z ) ),
|
||||
|
||||
RecvPropFloat( RECVINFO_NAME( m_actualAngles.y, m_angle ) ),
|
||||
|
||||
RecvPropInt( RECVINFO(m_nModelIndex) ),
|
||||
RecvPropInt( RECVINFO(m_lifeState) ),
|
||||
|
||||
RecvPropFloat( RECVINFO(m_waterLevel) ), ///< get this from the server in case we die when slightly out of the water due to error correction
|
||||
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Fish::Spawn( void )
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
|
||||
m_angles = QAngle( 0, 0, 0 );
|
||||
m_actualAngles = m_angles;
|
||||
|
||||
m_vel = Vector( 0, 0, 0 );
|
||||
m_gotUpdate = false;
|
||||
m_localLifeState = LIFE_ALIVE;
|
||||
m_buoyancy = RandomFloat( 0.4f, 1.0f );
|
||||
|
||||
m_errorHistoryIndex = 0;
|
||||
m_errorHistoryCount = 0;
|
||||
m_averageError = 0.0f;
|
||||
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Fish::ClientThink()
|
||||
{
|
||||
if (FishDebug.GetBool())
|
||||
{
|
||||
debugoverlay->AddLineOverlay( m_pos, m_actualPos, 255, 0, 0, true, 0.1f );
|
||||
switch( m_localLifeState )
|
||||
{
|
||||
case LIFE_DYING:
|
||||
debugoverlay->AddTextOverlay( m_pos, 0.1f, "DYING" );
|
||||
break;
|
||||
|
||||
case LIFE_DEAD:
|
||||
debugoverlay->AddTextOverlay( m_pos, 0.1f, "DEAD" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float deltaT = gpGlobals->frametime;
|
||||
|
||||
|
||||
// check if we just died
|
||||
if (m_localLifeState == LIFE_ALIVE && m_lifeState != LIFE_ALIVE)
|
||||
{
|
||||
// we have died
|
||||
m_localLifeState = LIFE_DYING;
|
||||
|
||||
m_deathDepth = m_pos.z;
|
||||
|
||||
// determine surface float angle
|
||||
m_deathAngle = RandomFloat( 87.0f, 93.0f ) * ((RandomInt( 0, 100 ) < 50) ? 1.0f : -1.0f);
|
||||
}
|
||||
|
||||
|
||||
switch( m_localLifeState )
|
||||
{
|
||||
case LIFE_DYING:
|
||||
{
|
||||
// depth parameter
|
||||
float t = (m_pos.z - m_deathDepth) / (m_waterLevel - m_deathDepth);
|
||||
t *= t;
|
||||
|
||||
// roll onto side
|
||||
m_angles.z = m_deathAngle * t;
|
||||
|
||||
// float to surface
|
||||
const float fudge = 2.0f;
|
||||
if (m_pos.z < m_waterLevel - fudge)
|
||||
{
|
||||
m_vel.z += (1.0f - t) * m_buoyancy * deltaT;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_localLifeState = LIFE_DEAD;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LIFE_DEAD:
|
||||
{
|
||||
// depth parameter
|
||||
float t = (m_pos.z - m_deathDepth) / (m_waterLevel - m_deathDepth);
|
||||
t *= t;
|
||||
|
||||
// roll onto side
|
||||
m_angles.z = m_deathAngle * t;
|
||||
|
||||
// keep near water surface
|
||||
const float sub = 0.5f;
|
||||
m_vel.z += 10.0f * (m_waterLevel - m_pos.z - sub) * deltaT;
|
||||
|
||||
// bob on surface
|
||||
const float rollAmp = 5.0f;
|
||||
const float rollFreq = 2.33f;
|
||||
m_angles.z += rollAmp * sin( rollFreq * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT;
|
||||
|
||||
const float rollAmp2 = 7.0f;
|
||||
const float rollFreq2 = 4.0f;
|
||||
m_angles.x += rollAmp2 * sin( rollFreq2 * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT;
|
||||
|
||||
const float bobAmp = 0.75f;
|
||||
const float bobFreq = 4.0f;
|
||||
m_vel.z += bobAmp * sin( bobFreq * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT;
|
||||
|
||||
const float bobAmp2 = 0.75f;
|
||||
const float bobFreq2 = 3.333f;
|
||||
m_vel.z += bobAmp2 * sin( bobFreq2 * (gpGlobals->curtime + 10.0f * entindex()) ) * deltaT;
|
||||
|
||||
// decay movement speed to zero
|
||||
const float drag = 1.0f;
|
||||
m_vel.z -= drag * m_vel.z * deltaT;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LIFE_ALIVE:
|
||||
{
|
||||
// use server-side Z coordinate directly
|
||||
m_pos.z = m_actualPos.z;
|
||||
|
||||
// use server-side angles
|
||||
m_angles = m_actualAngles;
|
||||
|
||||
// fishy wiggle based on movement
|
||||
if (!m_wiggleTimer.IsElapsed())
|
||||
{
|
||||
float swimPower = 1.0f - (m_wiggleTimer.GetElapsedTime() / m_wiggleTimer.GetCountdownDuration());
|
||||
const float amp = 6.0f * swimPower;
|
||||
float wiggle = amp * sin( m_wigglePhase );
|
||||
|
||||
m_wigglePhase += m_wiggleRate * deltaT;
|
||||
|
||||
// wiggle decay
|
||||
const float wiggleDecay = 5.0f;
|
||||
m_wiggleRate -= wiggleDecay * deltaT;
|
||||
|
||||
m_angles.y += wiggle;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// compute error between our local position and actual server position
|
||||
Vector error = m_actualPos - m_pos;
|
||||
error.z = 0.0f;
|
||||
float errorLen = error.Length();
|
||||
|
||||
if (m_localLifeState == LIFE_ALIVE)
|
||||
{
|
||||
// if error is far above average, start swimming
|
||||
const float wiggleThreshold = 2.0f;
|
||||
if (errorLen - m_averageError > wiggleThreshold)
|
||||
{
|
||||
// if error is large, we must have started swimming
|
||||
const float swimTime = 5.0f;
|
||||
m_wiggleTimer.Start( swimTime );
|
||||
|
||||
m_wiggleRate = 2.0f * errorLen;
|
||||
|
||||
const float maxWiggleRate = 30.0f;
|
||||
if (m_wiggleRate > maxWiggleRate)
|
||||
{
|
||||
m_wiggleRate = maxWiggleRate;
|
||||
}
|
||||
}
|
||||
|
||||
// update average error
|
||||
m_errorHistory[ m_errorHistoryIndex++ ] = errorLen;
|
||||
if (m_errorHistoryIndex >= MAX_ERROR_HISTORY)
|
||||
{
|
||||
m_errorHistoryIndex = 0;
|
||||
m_errorHistoryCount = MAX_ERROR_HISTORY;
|
||||
}
|
||||
else if (m_errorHistoryCount < MAX_ERROR_HISTORY)
|
||||
{
|
||||
++m_errorHistoryCount;
|
||||
}
|
||||
|
||||
m_averageError = 0.0f;
|
||||
if (m_errorHistoryCount)
|
||||
{
|
||||
for( int r=0; r<m_errorHistoryCount; ++r )
|
||||
{
|
||||
m_averageError += m_errorHistory[r];
|
||||
}
|
||||
m_averageError /= (float)m_errorHistoryCount;
|
||||
}
|
||||
}
|
||||
|
||||
// keep fish motion smooth by correcting towards actual server position
|
||||
// NOTE: This only tracks XY motion
|
||||
const float maxError = 20.0f;
|
||||
float errorT = errorLen / maxError;
|
||||
if (errorT > 1.0f)
|
||||
{
|
||||
errorT = 1.0f;
|
||||
}
|
||||
|
||||
// we want a nonlinear spring force for tracking
|
||||
errorT *= errorT;
|
||||
|
||||
// as fish move faster, their error increases - use a stiffer spring when fast, and a weak one when slow
|
||||
const float trackRate = 0.0f + errorT * 115.0f;
|
||||
m_vel.x += trackRate * error.x * deltaT;
|
||||
m_vel.y += trackRate * error.y * deltaT;
|
||||
|
||||
const float trackDrag = 2.0f + errorT * 6.0f;
|
||||
m_vel.x -= trackDrag * m_vel.x * deltaT;
|
||||
m_vel.y -= trackDrag * m_vel.y * deltaT;
|
||||
|
||||
|
||||
// euler integration
|
||||
m_pos += m_vel * deltaT;
|
||||
|
||||
SetNetworkOrigin( m_pos );
|
||||
SetAbsOrigin( m_pos );
|
||||
|
||||
SetNetworkAngles( m_angles );
|
||||
SetAbsAngles( m_angles );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Fish::OnDataChanged( DataUpdateType_t type )
|
||||
{
|
||||
//if (!m_gotUpdate)
|
||||
|
||||
if (type == DATA_UPDATE_CREATED)
|
||||
{
|
||||
// initial update
|
||||
m_gotUpdate = true;
|
||||
|
||||
m_pos = m_actualPos;
|
||||
m_vel = Vector( 0, 0, 0 );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
305
game/client/c_forcefeedback.cpp
Normal file
305
game/client/c_forcefeedback.cpp
Normal file
@@ -0,0 +1,305 @@
|
||||
#include "cbase.h"
|
||||
#include "forcefeedback.h"
|
||||
#include "hud_macros.h"
|
||||
#include "input.h"
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
#define FF_CLIENT_FLAG 0x8000
|
||||
|
||||
class FFParams
|
||||
{
|
||||
public:
|
||||
FORCEFEEDBACK_t m_nEffectType;
|
||||
FFBaseParams_t m_BaseParams;
|
||||
};
|
||||
|
||||
struct FFEffectInfo_t
|
||||
{
|
||||
FORCEFEEDBACK_t effectType;
|
||||
char const *name;
|
||||
};
|
||||
|
||||
#define DECLARE_FFEFFECT( name ) { name, #name }
|
||||
|
||||
static FFEffectInfo_t g_EffectTypes[] =
|
||||
{
|
||||
DECLARE_FFEFFECT( FORCE_FEEDBACK_SHOT_SINGLE ),
|
||||
DECLARE_FFEFFECT( FORCE_FEEDBACK_SHOT_DOUBLE ),
|
||||
DECLARE_FFEFFECT( FORCE_FEEDBACK_TAKEDAMAGE ),
|
||||
DECLARE_FFEFFECT( FORCE_FEEDBACK_SCREENSHAKE ),
|
||||
DECLARE_FFEFFECT( FORCE_FEEDBACK_SKIDDING ),
|
||||
DECLARE_FFEFFECT( FORCE_FEEDBACK_BREAKING )
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : effect -
|
||||
// Output : char const
|
||||
//-----------------------------------------------------------------------------
|
||||
char const *NameForForceFeedbackEffect( FORCEFEEDBACK_t effect )
|
||||
{
|
||||
int c = ARRAYSIZE( g_EffectTypes );
|
||||
if ( (int)effect < 0 || (int)effect >= c )
|
||||
return "???";
|
||||
|
||||
const FFEffectInfo_t& info = g_EffectTypes[ (int)effect ];
|
||||
Assert( info.effectType == effect );
|
||||
return info.name;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *name -
|
||||
// Output : FORCEFEEDBACK_t
|
||||
//-----------------------------------------------------------------------------
|
||||
FORCEFEEDBACK_t ForceFeedbackEffectForName( const char *name )
|
||||
{
|
||||
int c = ARRAYSIZE( g_EffectTypes );
|
||||
for ( int i = 0 ; i < c; ++i )
|
||||
{
|
||||
const FFEffectInfo_t& info = g_EffectTypes[ i ];
|
||||
|
||||
if ( !Q_stricmp( info.name, name ) )
|
||||
return info.effectType;
|
||||
}
|
||||
|
||||
return ( FORCEFEEDBACK_t )-1;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CForceFeedback : public IForceFeedback, public CAutoGameSystem
|
||||
{
|
||||
public:
|
||||
virtual bool Init();
|
||||
virtual void Shutdown();
|
||||
|
||||
// API
|
||||
virtual void StopAllEffects( CBasePlayer *player );
|
||||
virtual void StopEffect( CBasePlayer *player, FORCEFEEDBACK_t effect );
|
||||
virtual void StartEffect( CBasePlayer *player, FORCEFEEDBACK_t effect, const FFBaseParams_t& params );
|
||||
|
||||
virtual void PauseAll( CBasePlayer *player );
|
||||
virtual void ResumeAll( CBasePlayer *player );
|
||||
|
||||
void MsgFunc_ForceFeedback( bf_read &msg );
|
||||
|
||||
private:
|
||||
|
||||
void Internal_StopAllEffects();
|
||||
void Internal_StopEffect( FORCEFEEDBACK_t effect );
|
||||
void Internal_StartEffect( FORCEFEEDBACK_t, const FFBaseParams_t& params );
|
||||
void Internal_PauseAll();
|
||||
void Internal_ResumeAll();
|
||||
};
|
||||
|
||||
static CForceFeedback g_ForceFeedbackSingleton;
|
||||
IForceFeedback *forcefeedback = &g_ForceFeedbackSingleton;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &msg -
|
||||
//-----------------------------------------------------------------------------
|
||||
void __MsgFunc_ForceFeedback( bf_read &msg )
|
||||
{
|
||||
g_ForceFeedbackSingleton.MsgFunc_ForceFeedback( msg );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CForceFeedback::Init()
|
||||
{
|
||||
HOOK_MESSAGE( ForceFeedback );
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CForceFeedback::Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *player -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CForceFeedback::StopAllEffects( CBasePlayer *player )
|
||||
{
|
||||
if ( !player )
|
||||
return;
|
||||
|
||||
Internal_StopAllEffects();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *player -
|
||||
// effect -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CForceFeedback::StopEffect( CBasePlayer *player, FORCEFEEDBACK_t effect )
|
||||
{
|
||||
if ( !player )
|
||||
return;
|
||||
|
||||
Internal_StopEffect( effect );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *player -
|
||||
// effect -
|
||||
// params -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CForceFeedback::StartEffect( CBasePlayer *player, FORCEFEEDBACK_t effect, const FFBaseParams_t& params )
|
||||
{
|
||||
if ( !player )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Internal_StartEffect( effect, params );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *player -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CForceFeedback::PauseAll( CBasePlayer *player )
|
||||
{
|
||||
if ( !player )
|
||||
return;
|
||||
|
||||
Internal_PauseAll();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *player -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CForceFeedback::ResumeAll( CBasePlayer *player )
|
||||
{
|
||||
if ( !player )
|
||||
return;
|
||||
|
||||
Internal_ResumeAll();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CForceFeedback::Internal_StopAllEffects()
|
||||
{
|
||||
input->ForceFeedback_StopAll();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : heffect -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CForceFeedback::Internal_StopEffect( FORCEFEEDBACK_t effect )
|
||||
{
|
||||
input->ForceFeedback_Stop( effect );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : effect -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CForceFeedback::Internal_StartEffect( FORCEFEEDBACK_t effect, const FFBaseParams_t& params)
|
||||
{
|
||||
char const *name = NameForForceFeedbackEffect( effect );
|
||||
Msg( "Starting FF effect '%s'\n", name );
|
||||
|
||||
FFParams p;
|
||||
p.m_nEffectType = effect;
|
||||
p.m_BaseParams = params;
|
||||
|
||||
input->ForceFeedback_Start( effect, params );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CForceFeedback::Internal_PauseAll()
|
||||
{
|
||||
input->ForceFeedback_Pause();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CForceFeedback::Internal_ResumeAll()
|
||||
{
|
||||
input->ForceFeedback_Resume();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pszName -
|
||||
// iSize -
|
||||
// *pbuf -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CForceFeedback::MsgFunc_ForceFeedback( bf_read &msg )
|
||||
{
|
||||
byte msgType = msg.ReadByte();
|
||||
|
||||
switch ( msgType )
|
||||
{
|
||||
default:
|
||||
{
|
||||
Warning( "Bad parse in MsgFunc_ForceFeedback!\n" );
|
||||
}
|
||||
break;
|
||||
case FFMSG_STOPALL:
|
||||
{
|
||||
Internal_StopAllEffects();
|
||||
}
|
||||
break;
|
||||
case FFMSG_START:
|
||||
{
|
||||
FORCEFEEDBACK_t effectType = (FORCEFEEDBACK_t)msg.ReadByte();
|
||||
|
||||
FFBaseParams_t params;
|
||||
params.m_flDirection = 360.0f * ( (byte)msg.ReadByte() / 255.0f );
|
||||
params.m_flDuration = (float)msg.ReadLong() / 1000.0f;
|
||||
params.m_flGain = ( (byte)msg.ReadByte() / 255.0f );
|
||||
params.m_nPriority = msg.ReadByte();
|
||||
params.m_bSolo = msg.ReadByte() == 0 ? false : true;
|
||||
|
||||
if ( effectType >= 0 && effectType < NUM_FORCE_FEEDBACK_PRESETS )
|
||||
{
|
||||
Internal_StartEffect( effectType, params );
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "Bad parse in MsgFunc_ForceFeedback, FFMSG_START (%i)!\n", effectType );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FFMSG_STOP:
|
||||
{
|
||||
FORCEFEEDBACK_t effectType = (FORCEFEEDBACK_t)msg.ReadByte();
|
||||
|
||||
Internal_StopEffect( effectType );
|
||||
}
|
||||
break;
|
||||
case FFMSG_PAUSE:
|
||||
{
|
||||
Internal_PauseAll();
|
||||
}
|
||||
break;
|
||||
case FFMSG_RESUME:
|
||||
{
|
||||
Internal_ResumeAll();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
132
game/client/c_func_areaportalwindow.cpp
Normal file
132
game/client/c_func_areaportalwindow.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
#include "cbase.h"
|
||||
#include "view.h"
|
||||
#include "model_types.h"
|
||||
#include "ivrenderview.h"
|
||||
#include "engine/ivmodelinfo.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define VIEWER_PADDING 80.0f
|
||||
|
||||
class C_FuncAreaPortalWindow : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_CLASS( C_FuncAreaPortalWindow, C_BaseEntity );
|
||||
|
||||
|
||||
// Overrides.
|
||||
public:
|
||||
RenderableTranslucencyType_t ComputeTranslucencyType( void );
|
||||
virtual int DrawModel( int flags, const RenderableInstance_t &instance );
|
||||
virtual bool ShouldReceiveProjectedTextures( int flags );
|
||||
|
||||
private:
|
||||
|
||||
float GetDistanceBlend();
|
||||
|
||||
public:
|
||||
float m_flFadeStartDist; // Distance at which it starts fading (when <= this, alpha=m_flTranslucencyLimit).
|
||||
float m_flFadeDist; // Distance at which it becomes solid.
|
||||
|
||||
// 0-1 value - minimum translucency it's allowed to get to.
|
||||
float m_flTranslucencyLimit;
|
||||
|
||||
int m_iBackgroundModelIndex;
|
||||
};
|
||||
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_FuncAreaPortalWindow, DT_FuncAreaPortalWindow, CFuncAreaPortalWindow )
|
||||
RecvPropFloat( RECVINFO( m_flFadeStartDist ) ),
|
||||
RecvPropFloat( RECVINFO( m_flFadeDist ) ),
|
||||
RecvPropFloat( RECVINFO( m_flTranslucencyLimit ) ),
|
||||
RecvPropInt( RECVINFO( m_iBackgroundModelIndex ) )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
RenderableTranslucencyType_t C_FuncAreaPortalWindow::ComputeTranslucencyType( void )
|
||||
{
|
||||
return RENDERABLE_IS_TRANSLUCENT;
|
||||
}
|
||||
|
||||
int C_FuncAreaPortalWindow::DrawModel( int flags, const RenderableInstance_t &instance )
|
||||
{
|
||||
if ( !m_bReadyToDraw )
|
||||
return 0;
|
||||
|
||||
if( !GetModel() )
|
||||
return 0;
|
||||
|
||||
// Make sure we're a brush model.
|
||||
int modelType = modelinfo->GetModelType( GetModel() );
|
||||
if( modelType != mod_brush )
|
||||
return 0;
|
||||
|
||||
// Draw the fading version.
|
||||
float flBlendAlpha = GetDistanceBlend();
|
||||
if ( flBlendAlpha == 0.0f )
|
||||
return 0;
|
||||
|
||||
render->SetBlend( flBlendAlpha );
|
||||
|
||||
DrawBrushModelMode_t mode = DBM_DRAW_ALL;
|
||||
if ( flags & STUDIO_TWOPASS )
|
||||
{
|
||||
mode = ( flags & STUDIO_TRANSPARENCY ) ? DBM_DRAW_TRANSLUCENT_ONLY : DBM_DRAW_OPAQUE_ONLY;
|
||||
}
|
||||
|
||||
render->DrawBrushModelEx(
|
||||
this,
|
||||
(model_t *)GetModel(),
|
||||
GetAbsOrigin(),
|
||||
GetAbsAngles(),
|
||||
mode );
|
||||
|
||||
// Draw the optional foreground model next.
|
||||
// Only use the alpha in the texture from the thing in the front.
|
||||
if (m_iBackgroundModelIndex >= 0)
|
||||
{
|
||||
render->SetBlend( 1 );
|
||||
model_t *pBackground = ( model_t * )modelinfo->GetModel( m_iBackgroundModelIndex );
|
||||
if( pBackground && modelinfo->GetModelType( pBackground ) == mod_brush )
|
||||
{
|
||||
render->DrawBrushModelEx(
|
||||
this,
|
||||
pBackground,
|
||||
GetAbsOrigin(),
|
||||
GetAbsAngles(),
|
||||
mode );
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
float C_FuncAreaPortalWindow::GetDistanceBlend()
|
||||
{
|
||||
// Get the viewer's distance to us.
|
||||
float flDist = CollisionProp()->CalcDistanceFromPoint( CurrentViewOrigin() );
|
||||
C_BasePlayer *local = C_BasePlayer::GetLocalPlayer();
|
||||
if ( local )
|
||||
{
|
||||
flDist *= local->GetFOVDistanceAdjustFactor();
|
||||
}
|
||||
|
||||
return RemapValClamped( flDist, m_flFadeStartDist, m_flFadeDist, m_flTranslucencyLimit, 1 );
|
||||
}
|
||||
|
||||
bool C_FuncAreaPortalWindow::ShouldReceiveProjectedTextures( int flags )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
1168
game/client/c_func_breakablesurf.cpp
Normal file
1168
game/client/c_func_breakablesurf.cpp
Normal file
File diff suppressed because it is too large
Load Diff
184
game/client/c_func_breakablesurf.h
Normal file
184
game/client/c_func_breakablesurf.h
Normal file
@@ -0,0 +1,184 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
#ifndef C_FUNC_BREAKABLESURF_H
|
||||
#define C_FUNC_BREAKABLESURF_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "iviewrender.h"
|
||||
#include "proxyentity.h"
|
||||
|
||||
#define MAX_NUM_PANELS 16
|
||||
|
||||
#define NUM_EDGE_TYPES 4
|
||||
#define NUM_EDGE_STYLES 3
|
||||
|
||||
extern IVDebugOverlay *debugoverlay;
|
||||
|
||||
enum WinSide_t
|
||||
{
|
||||
WIN_SIDE_BOTTOM,
|
||||
WIN_SIDE_RIGHT,
|
||||
WIN_SIDE_TOP,
|
||||
WIN_SIDE_LEFT,
|
||||
};
|
||||
|
||||
enum WinEdge_t
|
||||
{
|
||||
EDGE_NOT = -1, // No edge
|
||||
EDGE_NONE, /* No edge on both sides /##\ */
|
||||
EDGE_FULL, // Edge on both sides |##|
|
||||
EDGE_LEFT, /* Edge is on left only |##\ */
|
||||
EDGE_RIGHT, // Edge is on right only /##|
|
||||
};
|
||||
|
||||
#define STYLE_HIGHLIGHT = -1;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// All the information associated with a particular handle
|
||||
//-----------------------------------------------------------------------------
|
||||
struct Panel_t
|
||||
{
|
||||
char m_nWidth;
|
||||
char m_nHeight;
|
||||
char m_nSide;
|
||||
char m_nEdgeType;
|
||||
char m_nStyle;
|
||||
};
|
||||
|
||||
struct EdgeTexture_t
|
||||
{
|
||||
int m_nRenderIndex;
|
||||
int m_nStyle;
|
||||
CMaterialReference m_pMaterialEdge;
|
||||
CTextureReference m_pMaterialEdgeTexture;
|
||||
};
|
||||
|
||||
class C_BreakableSurface : public C_BaseEntity, public IBrushRenderer
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BreakableSurface, C_BaseEntity );
|
||||
DECLARE_DATADESC();
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
|
||||
int m_nNumWide;
|
||||
int m_nNumHigh;
|
||||
float m_flPanelWidth;
|
||||
float m_flPanelHeight;
|
||||
Vector m_vNormal;
|
||||
Vector m_vCorner;
|
||||
bool m_bIsBroken;
|
||||
int m_nSurfaceType;
|
||||
|
||||
|
||||
// This is the texture we're going to use to multiply by the cracked base texture
|
||||
ITexture* m_pCurrentDetailTexture;
|
||||
|
||||
// Stores linked list of edges to render
|
||||
CUtlLinkedList< Panel_t, unsigned short > m_RenderList;
|
||||
|
||||
|
||||
C_BreakableSurface();
|
||||
~C_BreakableSurface();
|
||||
|
||||
public:
|
||||
void InitMaterial(WinEdge_t nEdgeType, int nEdgeStyle, char const* pMaterialName);
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
RenderableTranslucencyType_t ComputeTranslucencyType( void );
|
||||
bool HavePanel(int nWidth, int nHeight);
|
||||
bool RenderBrushModelSurface( IClientEntity* pBaseEntity, IBrushSurface* pBrushSurface );
|
||||
int DrawModel( int flags, const RenderableInstance_t &instance );
|
||||
void DrawSolidBlocks( IBrushSurface* pBrushSurface );
|
||||
|
||||
virtual void OnRestore();
|
||||
|
||||
virtual bool ShouldReceiveProjectedTextures( int flags );
|
||||
|
||||
private:
|
||||
// One bit per pane
|
||||
CNetworkArray( bool, m_RawPanelBitVec, MAX_NUM_PANELS * MAX_NUM_PANELS );
|
||||
bool m_PrevRawPanelBitVec[ MAX_NUM_PANELS * MAX_NUM_PANELS ];
|
||||
|
||||
// 2 bits of flags and 2 bits of edge type
|
||||
byte m_nPanelBits[MAX_NUM_PANELS][MAX_NUM_PANELS]; //UNDONE: allocate this dynamically?
|
||||
CMaterialReference m_pMaterialBox;
|
||||
EdgeTexture_t m_pSolid;
|
||||
EdgeTexture_t m_pEdge[NUM_EDGE_TYPES][NUM_EDGE_STYLES];
|
||||
|
||||
inline bool InLegalRange(int nWidth, int nHeight);
|
||||
inline bool IsPanelSolid(int nWidth, int nHeight);
|
||||
inline bool IsPanelStale(int nWidth, int nHeight);
|
||||
inline void SetPanelSolid(int nWidth, int nHeight, bool value);
|
||||
inline void SetPanelStale(int nWidth, int nHeight, bool value);
|
||||
|
||||
void DrawOneEdge( IBrushSurface* pBrushSurface, IMesh* pMesh,
|
||||
CMeshBuilder *pMeshBuilder, const Vector &vStartPos,
|
||||
const Vector &vWStep, const Vector &vHstep, WinSide_t nEdge);
|
||||
void DrawOneHighlight( IBrushSurface* pBrushSurface, IMesh* pMesh,
|
||||
CMeshBuilder *pMeshBuilder, const Vector &vStartPos,
|
||||
const Vector &vWStep, const Vector &vHstep, WinSide_t nEdge);
|
||||
void DrawOneBlock(IBrushSurface* pBrushSurface, IMesh* pMesh,
|
||||
CMeshBuilder *pMeshBuilder, const Vector &vPosition,
|
||||
const Vector &vWidth, const Vector &vHeight);
|
||||
|
||||
void DrawRenderList( IBrushSurface* pBrushSurface);
|
||||
void DrawRenderListHighlights( IBrushSurface* pBrushSurface );
|
||||
int FindRenderPanel(int nWidth, int nHeight, WinSide_t nSide);
|
||||
void AddToRenderList(int nWidth, int nHeight, WinSide_t nSide, WinEdge_t nEdgeType, int forceStyle);
|
||||
int FindFirstRenderTexture(WinEdge_t nEdgeType, int nStyle);
|
||||
|
||||
inline void SetStyleType( int w, int h, int type )
|
||||
{
|
||||
Assert( type < NUM_EDGE_STYLES );
|
||||
Assert( type >= 0 );
|
||||
// Clear old value
|
||||
m_nPanelBits[ w ][ h ] &= ( ~0x03 << 2 );
|
||||
// Insert new value
|
||||
m_nPanelBits[ w ][ h ] |= ( type << 2 );
|
||||
}
|
||||
|
||||
inline int GetStyleType( int w, int h )
|
||||
{
|
||||
int value = m_nPanelBits[ w ][ h ];
|
||||
value = ( value >> 2 ) & 0x03;
|
||||
Assert( value < NUM_EDGE_STYLES );
|
||||
return value;
|
||||
}
|
||||
|
||||
// Gets at the cracked version of the material
|
||||
void FindCrackedMaterial();
|
||||
|
||||
CMaterialReference m_pCrackedMaterial;
|
||||
CTextureReference m_pMaterialBoxTexture;
|
||||
|
||||
|
||||
void UpdateEdgeType(int nWidth, int nHeight, int forceStyle = -1 );
|
||||
};
|
||||
|
||||
class CBreakableSurfaceProxy : public CEntityMaterialProxy
|
||||
{
|
||||
public:
|
||||
CBreakableSurfaceProxy();
|
||||
virtual ~CBreakableSurfaceProxy();
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( C_BaseEntity *pC_BaseEntity );
|
||||
virtual IMaterial *GetMaterial();
|
||||
|
||||
private:
|
||||
// get at the material whose texture we're going to steal
|
||||
void AcquireSourceMaterial( C_BaseEntity* pEnt );
|
||||
|
||||
IMaterialVar* m_BaseTextureVar;
|
||||
};
|
||||
|
||||
|
||||
#endif // C_FUNC_BREAKABLESURF_H
|
||||
17
game/client/c_func_brush.cpp
Normal file
17
game/client/c_func_brush.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "cbase.h"
|
||||
#include "c_func_brush.h"
|
||||
#include "toolframework_client.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_FuncBrush, DT_FuncBrush, CFuncBrush )
|
||||
END_RECV_TABLE()
|
||||
|
||||
void C_FuncBrush::OnDataChanged( DataUpdateType_t type )
|
||||
{
|
||||
BaseClass::OnDataChanged( type );
|
||||
|
||||
bool bCreate = (type == DATA_UPDATE_CREATED) ? true : false;
|
||||
VPhysicsShadowDataChanged(bCreate, this);
|
||||
}
|
||||
24
game/client/c_func_brush.h
Normal file
24
game/client/c_func_brush.h
Normal file
@@ -0,0 +1,24 @@
|
||||
//========= Copyright © 1996-2008, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_FUNC_BRUSH_H
|
||||
#define C_FUNC_BRUSH_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class C_FuncBrush : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_FuncBrush, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
void OnDataChanged( DataUpdateType_t type );
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // C_FUNC_BRUSH_H
|
||||
|
||||
150
game/client/c_func_conveyor.cpp
Normal file
150
game/client/c_func_conveyor.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "materialsystem/imaterialproxy.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "functionproxy.h"
|
||||
#include <keyvalues.h>
|
||||
#include "mathlib/vmatrix.h"
|
||||
|
||||
#include "imaterialproxydict.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class C_FuncConveyor : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_FuncConveyor, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_FuncConveyor();
|
||||
|
||||
float GetConveyorSpeed() { return m_flConveyorSpeed; }
|
||||
|
||||
private:
|
||||
float m_flConveyorSpeed;
|
||||
};
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_FuncConveyor, DT_FuncConveyor, CFuncConveyor )
|
||||
RecvPropFloat( RECVINFO( m_flConveyorSpeed ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
C_FuncConveyor::C_FuncConveyor()
|
||||
{
|
||||
m_flConveyorSpeed = 0.0;
|
||||
}
|
||||
|
||||
|
||||
class CConveyorMaterialProxy : public IMaterialProxy
|
||||
{
|
||||
public:
|
||||
CConveyorMaterialProxy();
|
||||
virtual ~CConveyorMaterialProxy();
|
||||
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( void *pC_BaseEntity );
|
||||
virtual void Release( void ) { delete this; }
|
||||
virtual IMaterial *GetMaterial();
|
||||
|
||||
private:
|
||||
C_BaseEntity *BindArgToEntity( void *pArg );
|
||||
|
||||
IMaterialVar *m_pTextureScrollVar;
|
||||
};
|
||||
|
||||
CConveyorMaterialProxy::CConveyorMaterialProxy()
|
||||
{
|
||||
m_pTextureScrollVar = NULL;
|
||||
}
|
||||
|
||||
CConveyorMaterialProxy::~CConveyorMaterialProxy()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool CConveyorMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
char const* pScrollVarName = pKeyValues->GetString( "textureScrollVar" );
|
||||
if( !pScrollVarName )
|
||||
return false;
|
||||
|
||||
bool foundVar;
|
||||
m_pTextureScrollVar = pMaterial->FindVar( pScrollVarName, &foundVar, false );
|
||||
if( !foundVar )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
C_BaseEntity *CConveyorMaterialProxy::BindArgToEntity( void *pArg )
|
||||
{
|
||||
IClientRenderable *pRend = (IClientRenderable *)pArg;
|
||||
return pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
}
|
||||
|
||||
void CConveyorMaterialProxy::OnBind( void *pC_BaseEntity )
|
||||
{
|
||||
if( !pC_BaseEntity )
|
||||
return;
|
||||
|
||||
C_BaseEntity *pEntity = BindArgToEntity( pC_BaseEntity );
|
||||
|
||||
if ( !pEntity )
|
||||
return;
|
||||
|
||||
C_FuncConveyor *pConveyor = dynamic_cast<C_FuncConveyor*>(pEntity);
|
||||
|
||||
if ( !pConveyor )
|
||||
return;
|
||||
|
||||
if ( !m_pTextureScrollVar )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float flConveyorSpeed = pConveyor->GetConveyorSpeed();
|
||||
float flRate = abs( flConveyorSpeed ) / 128.0;
|
||||
float flAngle = (flConveyorSpeed >= 0) ? 180 : 0;
|
||||
|
||||
float sOffset = gpGlobals->curtime * cos( flAngle * ( M_PI / 180.0f ) ) * flRate;
|
||||
float tOffset = gpGlobals->curtime * sin( flAngle * ( M_PI / 180.0f ) ) * flRate;
|
||||
|
||||
// make sure that we are positive
|
||||
if( sOffset < 0.0f )
|
||||
{
|
||||
sOffset += 1.0f + -( int )sOffset;
|
||||
}
|
||||
if( tOffset < 0.0f )
|
||||
{
|
||||
tOffset += 1.0f + -( int )tOffset;
|
||||
}
|
||||
|
||||
// make sure that we are in a [0,1] range
|
||||
sOffset = sOffset - ( int )sOffset;
|
||||
tOffset = tOffset - ( int )tOffset;
|
||||
|
||||
if (m_pTextureScrollVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)
|
||||
{
|
||||
VMatrix mat;
|
||||
MatrixBuildTranslation( mat, sOffset, tOffset, 0.0f );
|
||||
m_pTextureScrollVar->SetMatrixValue( mat );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pTextureScrollVar->SetVecValue( sOffset, tOffset, 0.0f );
|
||||
}
|
||||
}
|
||||
|
||||
IMaterial *CConveyorMaterialProxy::GetMaterial()
|
||||
{
|
||||
return m_pTextureScrollVar ? m_pTextureScrollVar->GetOwningMaterial() : NULL;
|
||||
}
|
||||
|
||||
EXPOSE_MATERIAL_PROXY( CConveyorMaterialProxy, ConveyorScroll );
|
||||
367
game/client/c_func_dust.cpp
Normal file
367
game/client/c_func_dust.cpp
Normal file
@@ -0,0 +1,367 @@
|
||||
//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "fx.h"
|
||||
#include "c_func_dust.h"
|
||||
#include "func_dust_shared.h"
|
||||
#include "c_te_particlesystem.h"
|
||||
#include "env_wind_shared.h"
|
||||
#include "engine/IEngineTrace.h"
|
||||
#include "tier0/vprof.h"
|
||||
#include "particles_ez.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT_NOBASE( C_Func_Dust, DT_Func_Dust, CFunc_Dust )
|
||||
RecvPropInt( RECVINFO(m_Color), 0, RecvProxy_Int32ToColor32 ),
|
||||
RecvPropInt( RECVINFO(m_SpawnRate) ),
|
||||
RecvPropFloat( RECVINFO(m_flSizeMin) ),
|
||||
RecvPropFloat( RECVINFO(m_flSizeMax) ),
|
||||
RecvPropInt( RECVINFO(m_LifetimeMin) ),
|
||||
RecvPropInt( RECVINFO(m_LifetimeMax) ),
|
||||
RecvPropInt( RECVINFO(m_DustFlags) ),
|
||||
RecvPropInt( RECVINFO(m_SpeedMax) ),
|
||||
RecvPropInt( RECVINFO(m_DistMax) ),
|
||||
RecvPropInt( RECVINFO( m_nModelIndex ) ),
|
||||
RecvPropFloat( RECVINFO( m_FallSpeed ) ),
|
||||
RecvPropBool( RECVINFO( m_bAffectedByWind ) ),
|
||||
RecvPropDataTable( RECVINFO_DT( m_Collision ), 0, &REFERENCE_RECV_TABLE(DT_CollisionProperty) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------ //
|
||||
// CDustEffect implementation.
|
||||
// ------------------------------------------------------------------------------------ //
|
||||
#define DUST_ACCEL 50
|
||||
|
||||
|
||||
void CDustEffect::RenderParticles( CParticleRenderIterator *pIterator )
|
||||
{
|
||||
const CFuncDustParticle *pParticle = (const CFuncDustParticle*)pIterator->GetFirst();
|
||||
while ( pParticle )
|
||||
{
|
||||
// Velocity.
|
||||
float flAlpha;
|
||||
if( m_pDust->m_DustFlags & DUSTFLAGS_FROZEN )
|
||||
{
|
||||
flAlpha = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Alpha.
|
||||
float flAngle = (pParticle->m_flLifetime / pParticle->m_flDieTime) * M_PI * 2;
|
||||
flAlpha = sin( flAngle - (M_PI * 0.5f) ) * 0.5f + 0.5f;
|
||||
}
|
||||
|
||||
Vector tPos;
|
||||
TransformParticle( ParticleMgr()->GetModelView(), pParticle->m_Pos, tPos );
|
||||
float sortKey = (int) tPos.z;
|
||||
|
||||
if( -tPos.z <= m_pDust->m_DistMax )
|
||||
{
|
||||
flAlpha *= 1 + (tPos.z / m_pDust->m_DistMax);
|
||||
|
||||
// Draw it.
|
||||
float flSize = pParticle->m_flSize;
|
||||
if( m_pDust->m_DustFlags & DUSTFLAGS_SCALEMOTES )
|
||||
flSize *= -tPos.z;
|
||||
|
||||
RenderParticle_Color255Size(
|
||||
pIterator->GetParticleDraw(),
|
||||
tPos,
|
||||
Vector( m_pDust->m_Color.r, m_pDust->m_Color.g, m_pDust->m_Color.b ),
|
||||
flAlpha * m_pDust->m_Color.a,
|
||||
flSize
|
||||
);
|
||||
}
|
||||
|
||||
pParticle = (const CFuncDustParticle*)pIterator->GetNext( sortKey );
|
||||
}
|
||||
}
|
||||
|
||||
void CDustEffect::SimulateParticles( CParticleSimulateIterator *pIterator )
|
||||
{
|
||||
Vector vecWind;
|
||||
if ( m_pDust->m_bAffectedByWind )
|
||||
GetWindspeedAtTime( gpGlobals->curtime, vecWind );
|
||||
else
|
||||
vecWind = Vector( 0, 0, 0 );
|
||||
|
||||
CFuncDustParticle *pParticle = (CFuncDustParticle*)pIterator->GetFirst();
|
||||
while ( pParticle )
|
||||
{
|
||||
// Velocity.
|
||||
if( !(m_pDust->m_DustFlags & DUSTFLAGS_FROZEN) )
|
||||
{
|
||||
// Kill the particle?
|
||||
pParticle->m_flLifetime += pIterator->GetTimeDelta();
|
||||
if( pParticle->m_flLifetime >= pParticle->m_flDieTime )
|
||||
{
|
||||
pIterator->RemoveParticle( pParticle );
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( int i = 0 ; i < 2 ; i++ )
|
||||
{
|
||||
if ( pParticle->m_vVelocity[i] < vecWind[i] )
|
||||
{
|
||||
pParticle->m_vVelocity[i] += ( gpGlobals->frametime * DUST_ACCEL );
|
||||
|
||||
// clamp
|
||||
if ( pParticle->m_vVelocity[i] > vecWind[i] )
|
||||
pParticle->m_vVelocity[i] = vecWind[i];
|
||||
}
|
||||
else if (pParticle->m_vVelocity[i] > vecWind[i] )
|
||||
{
|
||||
pParticle->m_vVelocity[i] -= ( gpGlobals->frametime * DUST_ACCEL );
|
||||
|
||||
// clamp.
|
||||
if ( pParticle->m_vVelocity[i] < vecWind[i] )
|
||||
pParticle->m_vVelocity[i] = vecWind[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Apply velocity.
|
||||
pParticle->m_Pos.MulAdd( pParticle->m_Pos, pParticle->m_vVelocity, pIterator->GetTimeDelta() );
|
||||
}
|
||||
}
|
||||
|
||||
pParticle = (CFuncDustParticle*)pIterator->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------ //
|
||||
// C_Func_Dust implementation.
|
||||
// ------------------------------------------------------------------------------------ //
|
||||
|
||||
C_Func_Dust::C_Func_Dust() : m_Effect( "C_Func_Dust" )
|
||||
{
|
||||
m_Effect.m_pDust = this;
|
||||
m_Effect.SetDynamicallyAllocated( false ); // So it doesn't try to delete itself.
|
||||
}
|
||||
|
||||
|
||||
C_Func_Dust::~C_Func_Dust()
|
||||
{
|
||||
}
|
||||
|
||||
void C_Func_Dust::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
m_hMaterial = m_Effect.GetPMaterial( "particle/sparkles" );
|
||||
|
||||
m_Effect.SetSortOrigin( WorldSpaceCenter( ) );
|
||||
|
||||
// Let us think each frame.
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
|
||||
// If we're setup to be frozen, just make a bunch of particles initially.
|
||||
if( m_DustFlags & DUSTFLAGS_FROZEN )
|
||||
{
|
||||
for( int i=0; i < m_SpawnRate; i++ )
|
||||
{
|
||||
AttemptSpawnNewParticle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_Spawner.Init( m_SpawnRate ); // N particles per second
|
||||
}
|
||||
|
||||
|
||||
void C_Func_Dust::ClientThink()
|
||||
{
|
||||
// If frozen, don't make new particles.
|
||||
if( m_DustFlags & DUSTFLAGS_FROZEN )
|
||||
return;
|
||||
|
||||
// Spawn particles?
|
||||
if( m_DustFlags & DUSTFLAGS_ON )
|
||||
{
|
||||
float flDelta = MIN( gpGlobals->frametime, 0.1f );
|
||||
while( m_Spawner.NextEvent( flDelta ) )
|
||||
{
|
||||
AttemptSpawnNewParticle();
|
||||
}
|
||||
}
|
||||
|
||||
// Tell the particle manager our bbox.
|
||||
Vector vWorldMins, vWorldMaxs;
|
||||
CollisionProp()->WorldSpaceAABB( &vWorldMins, &vWorldMaxs );
|
||||
vWorldMins -= Vector( m_flSizeMax, m_flSizeMax, m_flSizeMax );
|
||||
vWorldMaxs += Vector( m_flSizeMax, m_flSizeMax, m_flSizeMax );
|
||||
m_Effect.GetBinding().SetBBox( vWorldMins, vWorldMaxs );
|
||||
}
|
||||
|
||||
|
||||
bool C_Func_Dust::ShouldDraw()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void C_Func_Dust::AttemptSpawnNewParticle()
|
||||
{
|
||||
// Find a random spot inside our bmodel.
|
||||
static int nTests=10;
|
||||
|
||||
for( int iTest=0; iTest < nTests; iTest++ )
|
||||
{
|
||||
Vector vPercent = RandomVector( 0, 1 );
|
||||
Vector vTest = WorldAlignMins() + (WorldAlignMaxs() - WorldAlignMins()) * vPercent;
|
||||
|
||||
int contents = enginetrace->GetPointContents_Collideable( GetCollideable(), vTest );
|
||||
if( contents & CONTENTS_SOLID )
|
||||
{
|
||||
CFuncDustParticle *pParticle = (CFuncDustParticle*)m_Effect.AddParticle( 10, m_hMaterial, vTest );
|
||||
if( pParticle )
|
||||
{
|
||||
pParticle->m_vVelocity = RandomVector( -m_SpeedMax, m_SpeedMax );
|
||||
pParticle->m_vVelocity.z -= m_FallSpeed;
|
||||
|
||||
pParticle->m_flLifetime = 0;
|
||||
pParticle->m_flDieTime = RandomFloat( m_LifetimeMin, m_LifetimeMax );
|
||||
|
||||
if( m_DustFlags & DUSTFLAGS_SCALEMOTES )
|
||||
pParticle->m_flSize = RandomFloat( m_flSizeMin/10000.0f, m_flSizeMax/10000.0f );
|
||||
else
|
||||
pParticle->m_flSize = RandomFloat( m_flSizeMin, m_flSizeMax );
|
||||
|
||||
pParticle->m_Color = m_Color;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Dust
|
||||
//
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Spew out dust!
|
||||
//-----------------------------------------------------------------------------
|
||||
void FX_Dust( const Vector &vecOrigin, const Vector &vecDirection, float flSize, float flSpeed )
|
||||
{
|
||||
VPROF_BUDGET( "FX_Dust", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
|
||||
|
||||
int numPuffs = (flSize*0.5f);
|
||||
|
||||
if ( numPuffs < 1 )
|
||||
numPuffs = 1;
|
||||
if ( numPuffs > 32 )
|
||||
numPuffs = 32;
|
||||
|
||||
float speed = flSpeed * 0.1f;
|
||||
|
||||
if ( speed < 0 )
|
||||
speed = 1.0f;
|
||||
if (speed > 48.0f )
|
||||
speed = 48.0f;
|
||||
|
||||
//FIXME: Better sampling area
|
||||
Vector offset = vecOrigin + ( vecDirection * flSize );
|
||||
|
||||
//Find area ambient light color and use it to tint smoke
|
||||
Vector worldLight = WorldGetLightForPoint( offset, true );
|
||||
|
||||
// Throw puffs
|
||||
SimpleParticle particle;
|
||||
for ( int i = 0; i < numPuffs; i++ )
|
||||
{
|
||||
offset.Random( -(flSize*0.25f), flSize*0.25f );
|
||||
offset += vecOrigin + ( vecDirection * flSize );
|
||||
|
||||
particle.m_Pos = offset;
|
||||
particle.m_flLifetime = 0.0f;
|
||||
particle.m_flDieTime = random->RandomFloat( 0.4f, 1.0f );
|
||||
|
||||
particle.m_vecVelocity = vecDirection * random->RandomFloat( speed*0.5f, speed ) * i;
|
||||
particle.m_vecVelocity[2] = 0.0f;
|
||||
|
||||
int color = random->RandomInt( 48, 64 );
|
||||
|
||||
particle.m_uchColor[0] = (color+16) + ( worldLight[0] * (float) color );
|
||||
particle.m_uchColor[1] = (color+8) + ( worldLight[1] * (float) color );
|
||||
particle.m_uchColor[2] = color + ( worldLight[2] * (float) color );
|
||||
|
||||
particle.m_uchStartAlpha= random->RandomInt( 64, 128 );
|
||||
particle.m_uchEndAlpha = 0;
|
||||
particle.m_uchStartSize = random->RandomInt( 2, 8 );
|
||||
particle.m_uchEndSize = random->RandomInt( 24, 48 );
|
||||
particle.m_flRoll = random->RandomInt( 0, 360 );
|
||||
particle.m_flRollDelta = random->RandomFloat( -0.5f, 0.5f );
|
||||
|
||||
AddSimpleParticle( &particle, g_Mat_DustPuff[random->RandomInt(0,1)] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class C_TEDust: public C_TEParticleSystem
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_TEDust, C_TEParticleSystem );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_TEDust();
|
||||
virtual ~C_TEDust();
|
||||
|
||||
public:
|
||||
virtual void PostDataUpdate( DataUpdateType_t updateType );
|
||||
virtual bool ShouldDraw() { return true; }
|
||||
|
||||
public:
|
||||
|
||||
float m_flSize;
|
||||
float m_flSpeed;
|
||||
Vector m_vecDirection;
|
||||
|
||||
protected:
|
||||
void GetDustColor( Vector &color );
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_EVENT_DT( C_TEDust, DT_TEDust, CTEDust )
|
||||
RecvPropFloat(RECVINFO(m_flSize)),
|
||||
RecvPropFloat(RECVINFO(m_flSpeed)),
|
||||
RecvPropVector(RECVINFO(m_vecDirection)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//==================================================
|
||||
// C_TEDust
|
||||
//==================================================
|
||||
|
||||
C_TEDust::C_TEDust()
|
||||
{
|
||||
}
|
||||
|
||||
C_TEDust::~C_TEDust()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : bNewEntity - whether or not to start a new entity
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TEDust::PostDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
FX_Dust( m_vecOrigin, m_vecDirection, m_flSize, m_flSpeed );
|
||||
}
|
||||
|
||||
|
||||
void TE_Dust( IRecipientFilter& filter, float delay,
|
||||
const Vector &pos, const Vector &dir, float size, float speed )
|
||||
{
|
||||
FX_Dust( pos, dir, size, speed );
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user