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
![]()
4 years ago
|
//========= 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 );
|