You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
340 lines
9.0 KiB
340 lines
9.0 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
#include "c_prop_combine_ball.h" |
|
#include "materialsystem/imaterial.h" |
|
#include "model_types.h" |
|
#include "c_physicsprop.h" |
|
#include "c_te_effect_dispatch.h" |
|
#include "fx_quad.h" |
|
#include "fx.h" |
|
#include "clienteffectprecachesystem.h" |
|
#include "view.h" |
|
#include "view_scene.h" |
|
#include "beamdraw.h" |
|
|
|
// Precache our effects |
|
CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectCombineBall ) |
|
CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1" ) |
|
CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1b" ) |
|
CLIENTEFFECT_MATERIAL( "effects/combinemuzzle1_nocull" ) |
|
CLIENTEFFECT_MATERIAL( "effects/combinemuzzle2_nocull" ) |
|
CLIENTEFFECT_MATERIAL( "effects/combinemuzzle1" ) |
|
CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1" ) |
|
CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1b" ) |
|
CLIENTEFFECT_REGISTER_END() |
|
|
|
IMPLEMENT_CLIENTCLASS_DT( C_PropCombineBall, DT_PropCombineBall, CPropCombineBall ) |
|
RecvPropBool( RECVINFO( m_bEmit ) ), |
|
RecvPropFloat( RECVINFO( m_flRadius ) ), |
|
RecvPropBool( RECVINFO( m_bHeld ) ), |
|
RecvPropBool( RECVINFO( m_bLaunched ) ), |
|
END_RECV_TABLE() |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
C_PropCombineBall::C_PropCombineBall( void ) |
|
{ |
|
m_pFlickerMaterial = NULL; |
|
m_pBodyMaterial = NULL; |
|
m_pBlurMaterial = NULL; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : updateType - |
|
//----------------------------------------------------------------------------- |
|
void C_PropCombineBall::OnDataChanged( DataUpdateType_t updateType ) |
|
{ |
|
BaseClass::OnDataChanged( updateType ); |
|
|
|
if ( updateType == DATA_UPDATE_CREATED ) |
|
{ |
|
m_vecLastOrigin = GetAbsOrigin(); |
|
InitMaterials(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Output : RenderGroup_t |
|
//----------------------------------------------------------------------------- |
|
RenderGroup_t C_PropCombineBall::GetRenderGroup( void ) |
|
{ |
|
return RENDER_GROUP_TRANSLUCENT_ENTITY; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Cache the material handles |
|
// Output : Returns true on success, false on failure. |
|
//----------------------------------------------------------------------------- |
|
bool C_PropCombineBall::InitMaterials( void ) |
|
{ |
|
// Motion blur |
|
if ( m_pBlurMaterial == NULL ) |
|
{ |
|
m_pBlurMaterial = materials->FindMaterial( "effects/ar2_altfire1b", NULL, false ); |
|
|
|
if ( m_pBlurMaterial == NULL ) |
|
return false; |
|
} |
|
|
|
// Main body of the ball |
|
if ( m_pBodyMaterial == NULL ) |
|
{ |
|
m_pBodyMaterial = materials->FindMaterial( "effects/ar2_altfire1", NULL, false ); |
|
|
|
if ( m_pBodyMaterial == NULL ) |
|
return false; |
|
} |
|
|
|
// Flicker material |
|
if ( m_pFlickerMaterial == NULL ) |
|
{ |
|
m_pFlickerMaterial = materials->FindMaterial( "effects/combinemuzzle1", NULL, false ); |
|
|
|
if ( m_pFlickerMaterial == NULL ) |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void C_PropCombineBall::DrawMotionBlur( void ) |
|
{ |
|
float color[3]; |
|
|
|
Vector vecDir = GetAbsOrigin() - m_vecLastOrigin; |
|
float speed = VectorNormalize( vecDir ); |
|
|
|
speed = clamp( speed, 0, 32 ); |
|
|
|
float stepSize = MIN( ( speed * 0.5f ), 4.0f ); |
|
|
|
Vector spawnPos = GetAbsOrigin(); |
|
Vector spawnStep = -vecDir * stepSize; |
|
|
|
float base = RemapValClamped( speed, 4, 32, 0.0f, 1.0f ); |
|
|
|
CMatRenderContextPtr pRenderContext( materials ); |
|
pRenderContext->Bind( m_pBlurMaterial ); |
|
|
|
// Draw the motion blurred trail |
|
for ( int i = 0; i < 8; i++ ) |
|
{ |
|
spawnPos += spawnStep; |
|
|
|
color[0] = color[1] = color[2] = base * ( 1.0f - ( (float) i / 12.0f ) ); |
|
|
|
DrawHalo( m_pBlurMaterial, spawnPos, m_flRadius, color ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void C_PropCombineBall::DrawFlicker( void ) |
|
{ |
|
float rand1 = random->RandomFloat( 0.2f, 0.3f ); |
|
float rand2 = random->RandomFloat( 1.5f, 2.5f ); |
|
|
|
if ( gpGlobals->frametime == 0.0f ) |
|
{ |
|
rand1 = 0.2f; |
|
rand2 = 1.5f; |
|
} |
|
|
|
float color[3]; |
|
color[0] = color[1] = color[2] = rand1; |
|
|
|
// Draw the flickering glow |
|
CMatRenderContextPtr pRenderContext( materials ); |
|
pRenderContext->Bind( m_pFlickerMaterial ); |
|
DrawHalo( m_pFlickerMaterial, GetAbsOrigin(), m_flRadius * rand2, color ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : pMaterial - |
|
// source - |
|
// color - |
|
//----------------------------------------------------------------------------- |
|
void DrawHaloOriented( const Vector& source, float scale, float const *color, float roll ) |
|
{ |
|
Vector point, screen; |
|
|
|
CMatRenderContextPtr pRenderContext( materials ); |
|
IMesh* pMesh = pRenderContext->GetDynamicMesh(); |
|
|
|
CMeshBuilder meshBuilder; |
|
meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); |
|
|
|
// Transform source into screen space |
|
ScreenTransform( source, screen ); |
|
|
|
Vector right, up; |
|
float sr, cr; |
|
|
|
SinCos( roll, &sr, &cr ); |
|
|
|
for ( int i = 0; i < 3; i++ ) |
|
{ |
|
right[i] = CurrentViewRight()[i] * cr + CurrentViewUp()[i] * sr; |
|
up[i] = CurrentViewRight()[i] * -sr + CurrentViewUp()[i] * cr; |
|
} |
|
|
|
meshBuilder.Color3fv (color); |
|
meshBuilder.TexCoord2f (0, 0, 1); |
|
VectorMA (source, -scale, up, point); |
|
VectorMA (point, -scale, right, point); |
|
meshBuilder.Position3fv (point.Base()); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.Color3fv (color); |
|
meshBuilder.TexCoord2f (0, 0, 0); |
|
VectorMA (source, scale, up, point); |
|
VectorMA (point, -scale, right, point); |
|
meshBuilder.Position3fv (point.Base()); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.Color3fv (color); |
|
meshBuilder.TexCoord2f (0, 1, 0); |
|
VectorMA (source, scale, up, point); |
|
VectorMA (point, scale, right, point); |
|
meshBuilder.Position3fv (point.Base()); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.Color3fv (color); |
|
meshBuilder.TexCoord2f (0, 1, 1); |
|
VectorMA (source, -scale, up, point); |
|
VectorMA (point, scale, right, point); |
|
meshBuilder.Position3fv (point.Base()); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.End(); |
|
pMesh->Draw(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : flags - |
|
// Output : int |
|
//----------------------------------------------------------------------------- |
|
int C_PropCombineBall::DrawModel( int flags ) |
|
{ |
|
if ( !m_bEmit ) |
|
return 0; |
|
|
|
// Make sure our materials are cached |
|
if ( !InitMaterials() ) |
|
{ |
|
//NOTENOTE: This means that a material was not found for the combine ball, so it may not render! |
|
AssertOnce( 0 ); |
|
return 0; |
|
} |
|
|
|
// Draw the flickering overlay |
|
DrawFlicker(); |
|
|
|
// Draw the motion blur from movement |
|
if ( m_bHeld || m_bLaunched ) |
|
{ |
|
DrawMotionBlur(); |
|
} |
|
|
|
// Draw the model if we're being held |
|
if ( m_bHeld ) |
|
{ |
|
QAngle angles; |
|
VectorAngles( -CurrentViewForward(), angles ); |
|
|
|
// Always orient towards the camera! |
|
SetAbsAngles( angles ); |
|
|
|
BaseClass::DrawModel( flags ); |
|
} |
|
else |
|
{ |
|
float color[3]; |
|
color[0] = color[1] = color[2] = 1.0f; |
|
|
|
float sinOffs = 1.0f * sin( gpGlobals->curtime * 25 ); |
|
|
|
float roll = SpawnTime(); |
|
|
|
// Draw the main ball body |
|
CMatRenderContextPtr pRenderContext( materials ); |
|
pRenderContext->Bind( m_pBodyMaterial, (C_BaseEntity*) this ); |
|
DrawHaloOriented( GetAbsOrigin(), m_flRadius + sinOffs, color, roll ); |
|
} |
|
|
|
m_vecLastOrigin = GetAbsOrigin(); |
|
|
|
return 1; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : &data - |
|
//----------------------------------------------------------------------------- |
|
void CombineBallImpactCallback( const CEffectData &data ) |
|
{ |
|
// Quick flash |
|
FX_AddQuad( data.m_vOrigin, |
|
data.m_vNormal, |
|
data.m_flRadius * 10.0f, |
|
0, |
|
0.75f, |
|
1.0f, |
|
0.0f, |
|
0.4f, |
|
random->RandomInt( 0, 360 ), |
|
0, |
|
Vector( 1.0f, 1.0f, 1.0f ), |
|
0.25f, |
|
"effects/combinemuzzle1_nocull", |
|
(FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) ); |
|
|
|
// Lingering burn |
|
FX_AddQuad( data.m_vOrigin, |
|
data.m_vNormal, |
|
data.m_flRadius * 2.0f, |
|
data.m_flRadius * 4.0f, |
|
0.75f, |
|
1.0f, |
|
0.0f, |
|
0.4f, |
|
random->RandomInt( 0, 360 ), |
|
0, |
|
Vector( 1.0f, 1.0f, 1.0f ), |
|
0.5f, |
|
"effects/combinemuzzle2_nocull", |
|
(FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) ); |
|
|
|
// Throw sparks |
|
FX_ElectricSpark( data.m_vOrigin, 2, 1, &data.m_vNormal ); |
|
} |
|
|
|
DECLARE_CLIENT_EFFECT( "cball_bounce", CombineBallImpactCallback ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : &data - |
|
//----------------------------------------------------------------------------- |
|
void CombineBallExplosionCallback( const CEffectData &data ) |
|
{ |
|
Vector normal(0,0,1); |
|
|
|
// Throw sparks |
|
FX_ElectricSpark( data.m_vOrigin, 4, 1, &normal ); |
|
} |
|
|
|
DECLARE_CLIENT_EFFECT( "cball_explode", CombineBallExplosionCallback ); |