Modified source engine (2017) developed by valve and leaked in 2020. Not for commercial purporses
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.
 
 
 
 
 
 

272 lines
7.6 KiB

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Alyx's EMP effect
//
//=============================================================================//
#include "cbase.h"
#include "env_alyxemp_shared.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define EMP_BEAM_SPRITE "effects/laser1.vmt"
LINK_ENTITY_TO_CLASS( env_alyxemp, CAlyxEmpEffect );
BEGIN_DATADESC( CAlyxEmpEffect )
DEFINE_KEYFIELD( m_nType, FIELD_INTEGER, "Type" ),
DEFINE_KEYFIELD( m_strTargetName, FIELD_STRING, "EndTargetName" ),
DEFINE_FIELD( m_nState, FIELD_INTEGER ),
DEFINE_FIELD( m_flDuration, FIELD_FLOAT ),
DEFINE_FIELD( m_flStartTime, FIELD_TIME ),
DEFINE_FIELD( m_hTargetEnt, FIELD_EHANDLE ),
DEFINE_FIELD( m_hBeam, FIELD_EHANDLE ),
DEFINE_FIELD( m_iState, FIELD_INTEGER ),
DEFINE_FIELD( m_bAutomated, FIELD_BOOLEAN ),
DEFINE_THINKFUNC( AutomaticThink ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "StartCharge", InputStartCharge ),
DEFINE_INPUTFUNC( FIELD_VOID, "StartDischarge", InputStartDischarge ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "Stop", InputStop ),
DEFINE_INPUTFUNC( FIELD_STRING, "SetTargetEnt", InputSetTargetEnt ),
END_DATADESC()
IMPLEMENT_SERVERCLASS_ST( CAlyxEmpEffect, DT_AlyxEmpEffect )
SendPropInt( SENDINFO(m_nState), 8, SPROP_UNSIGNED),
SendPropFloat( SENDINFO(m_flDuration), 0, SPROP_NOSCALE),
SendPropFloat( SENDINFO(m_flStartTime), 0, SPROP_NOSCALE),
END_SEND_TABLE()
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CAlyxEmpEffect::Spawn( void )
{
Precache();
// No model but we still need to force this!
AddEFlags( EFL_FORCE_CHECK_TRANSMIT );
// No shadows
AddEffects( EF_NOSHADOW | EF_NORECEIVESHADOW );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CAlyxEmpEffect::Activate( void )
{
// Start out with a target entity
SetTargetEntity( STRING(m_strTargetName) );
BaseClass::Activate();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *szEntityName -
//-----------------------------------------------------------------------------
void CAlyxEmpEffect::SetTargetEntity( const char *szEntityName )
{
// Find and store off our target entity
CBaseEntity *pTargetEnt = NULL;
if ( szEntityName && szEntityName[0] )
{
pTargetEnt = gEntList.FindEntityByName( NULL, szEntityName );
if ( pTargetEnt == NULL )
{
Assert(0);
DevMsg( "Unable to find env_alyxemp (%s) target %s!\n", GetEntityName().ToCStr(), szEntityName );
}
}
SetTargetEntity( pTargetEnt );
}
//-----------------------------------------------------------------------------
// Passing NULL is ok!
//-----------------------------------------------------------------------------
void CAlyxEmpEffect::SetTargetEntity( CBaseEntity *pTarget )
{
m_hTargetEnt.Set( pTarget );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CAlyxEmpEffect::ActivateAutomatic( CBaseEntity *pAlyx, CBaseEntity *pTarget )
{
Assert( pAlyx->GetBaseAnimating() != NULL );
SetParent( pAlyx, pAlyx->GetBaseAnimating()->LookupAttachment("LeftHand") );
SetLocalOrigin( vec3_origin );
m_iState = ALYXEMP_STATE_OFF;
SetTargetEntity( pTarget );
SetThink( &CAlyxEmpEffect::AutomaticThink );
SetNextThink( gpGlobals->curtime );
m_bAutomated = true;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CAlyxEmpEffect::AutomaticThink()
{
bool bSetNextThink = true;
switch( m_iState )
{
case ALYXEMP_STATE_OFF:
StartCharge( 0.05f );
break;
case ALYXEMP_STATE_CHARGING:
StartDischarge();
break;
case ALYXEMP_STATE_DISCHARGING:
Stop( 1.0f );
bSetNextThink = false;
break;
}
m_iState++;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CAlyxEmpEffect::Precache( void )
{
PrecacheModel( EMP_BEAM_SPRITE );
PrecacheScriptSound( "AlyxEmp.Charge" );
PrecacheScriptSound( "AlyxEmp.Discharge" );
PrecacheScriptSound( "AlyxEmp.Stop" );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : &inputdata -
//-----------------------------------------------------------------------------
void CAlyxEmpEffect::InputStartCharge( inputdata_t &inputdata )
{
StartCharge( inputdata.value.Float() );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CAlyxEmpEffect::StartCharge( float flDuration )
{
EmitSound( "AlyxEmp.Charge" );
m_nState = (int)ALYXEMP_STATE_CHARGING;
m_flDuration = flDuration;
m_flStartTime = gpGlobals->curtime;
if( m_bAutomated )
{
SetNextThink( gpGlobals->curtime + m_flDuration );
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : &inputdata -
//-----------------------------------------------------------------------------
void CAlyxEmpEffect::InputStartDischarge( inputdata_t &inputdata )
{
StartDischarge();
}
void CAlyxEmpEffect::StartDischarge()
{
EmitSound( "AlyxEmp.Discharge" );
m_nState = (int)ALYXEMP_STATE_DISCHARGING;
m_flStartTime = gpGlobals->curtime;
// Beam effects on the target entity!
if ( !m_hBeam && m_hTargetEnt )
{
// Check to store off our view model index
m_hBeam = CBeam::BeamCreate( EMP_BEAM_SPRITE, 8 );
if ( m_hBeam != NULL )
{
m_hBeam->PointEntInit( m_hTargetEnt->GetAbsOrigin(), this );
m_hBeam->SetStartEntity( m_hTargetEnt );
m_hBeam->SetWidth( 4 );
m_hBeam->SetEndWidth( 8 );
m_hBeam->SetBrightness( 255 );
m_hBeam->SetColor( 255, 255, 255 );
m_hBeam->LiveForTime( 999.0f );
m_hBeam->RelinkBeam();
m_hBeam->SetNoise( 16 );
}
// End hit
Vector shotDir = ( GetAbsOrigin() - m_hTargetEnt->GetAbsOrigin() );
VectorNormalize( shotDir );
CPVSFilter filter( m_hTargetEnt->GetAbsOrigin() );
te->GaussExplosion( filter, 0.0f, m_hTargetEnt->GetAbsOrigin() - ( shotDir * 4.0f ), RandomVector(-1.0f, 1.0f), 0 );
}
if( m_bAutomated )
{
SetNextThink( gpGlobals->curtime + 0.5f );
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : &inputdata -
//-----------------------------------------------------------------------------
void CAlyxEmpEffect::InputStop( inputdata_t &inputdata )
{
float flDuration = inputdata.value.Float();
Stop( flDuration );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CAlyxEmpEffect::Stop( float flDuration )
{
EmitSound( "AlyxEmp.Stop" );
m_nState = (int)ALYXEMP_STATE_OFF;
m_flDuration = flDuration;
m_flStartTime = gpGlobals->curtime;
if ( m_hBeam != NULL )
{
UTIL_Remove( m_hBeam );
m_hBeam = NULL;
}
if( m_bAutomated )
{
SetThink( &CAlyxEmpEffect::SUB_Remove );
SetNextThink( gpGlobals->curtime + flDuration + 1.0f );
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : &inputdata -
//-----------------------------------------------------------------------------
void CAlyxEmpEffect::InputSetTargetEnt( inputdata_t &inputdata )
{
SetTargetEntity( inputdata.value.String() );
}