source-engine/game/client/hl2/c_prop_combine_ball.cpp

340 lines
9.0 KiB
C++
Raw Normal View History

2020-04-22 16:56:21 +00:00
//========= 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 );