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.
359 lines
9.7 KiB
359 lines
9.7 KiB
5 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
// $NoKeywords: $
|
||
|
//=============================================================================//
|
||
|
#include "cbase.h"
|
||
|
#include "iefx.h"
|
||
|
#include "dlight.h"
|
||
|
#include "engine/IEngineSound.h"
|
||
|
#include "view.h"
|
||
|
#include "beamdraw.h"
|
||
|
#include "clienteffectprecachesystem.h"
|
||
|
#include "weapon_combat_usedwithshieldbase.h"
|
||
|
#include "c_weapon__stubs.h"
|
||
|
#include <vgui/ISurface.h>
|
||
|
|
||
|
#define BALL_GROW_TIME 1.5
|
||
|
|
||
|
// Precache the effects
|
||
|
CLIENTEFFECT_REGISTER_BEGIN( PrecacheWeaponCombat_ChargeablePlasma )
|
||
|
CLIENTEFFECT_MATERIAL( "sprites/chargeball_team1" )
|
||
|
CLIENTEFFECT_MATERIAL( "sprites/chargeball_team2" )
|
||
|
CLIENTEFFECT_REGISTER_END()
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
class C_WeaponCombat_ChargeablePlasma : public C_WeaponCombatUsedWithShieldBase
|
||
|
{
|
||
|
DECLARE_CLASS( C_WeaponCombat_ChargeablePlasma, C_WeaponCombatUsedWithShieldBase );
|
||
|
|
||
|
public:
|
||
|
DECLARE_CLIENTCLASS();
|
||
|
DECLARE_PREDICTABLE();
|
||
|
|
||
|
C_WeaponCombat_ChargeablePlasma( void );
|
||
|
~C_WeaponCombat_ChargeablePlasma( void );
|
||
|
|
||
|
virtual void PreDataUpdate( DataUpdateType_t updateType );
|
||
|
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||
|
virtual bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
|
||
|
virtual void DrawCrosshair( void );
|
||
|
virtual void ClientThink( );
|
||
|
virtual int DrawModel( int flags );
|
||
|
virtual void ViewModelDrawn( C_BaseViewModel *pBaseViewModel );
|
||
|
virtual void NotifyShouldTransmit( ShouldTransmitState_t state );
|
||
|
virtual bool IsTransparent( );
|
||
|
|
||
|
private:
|
||
|
void StartCharging();
|
||
|
void StopCharging();
|
||
|
void DrawChargingEffect( float flSize, C_BaseAnimating *pAttachedEnt );
|
||
|
|
||
|
private:
|
||
|
bool m_bCharging;
|
||
|
bool m_bLastCharging;
|
||
|
float m_flPower;
|
||
|
float m_flChargeStartTime;
|
||
|
CMaterialReference m_hMaterial;
|
||
|
|
||
|
private:
|
||
|
C_WeaponCombat_ChargeablePlasma( const C_WeaponCombat_ChargeablePlasma & );
|
||
|
};
|
||
|
|
||
|
STUB_WEAPON_CLASS_IMPLEMENT( weapon_combat_chargeableplasma, C_WeaponCombat_ChargeablePlasma );
|
||
|
|
||
|
IMPLEMENT_CLIENTCLASS_DT( C_WeaponCombat_ChargeablePlasma, DT_WeaponCombat_ChargeablePlasma, CWeaponCombat_ChargeablePlasma )
|
||
|
RecvPropInt( RECVINFO(m_bCharging) ),
|
||
|
END_RECV_TABLE()
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
C_WeaponCombat_ChargeablePlasma::C_WeaponCombat_ChargeablePlasma( void )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
C_WeaponCombat_ChargeablePlasma::~C_WeaponCombat_ChargeablePlasma( void )
|
||
|
{
|
||
|
Holster( NULL );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void C_WeaponCombat_ChargeablePlasma::PreDataUpdate( DataUpdateType_t updateType )
|
||
|
{
|
||
|
BaseClass::PreDataUpdate( updateType );
|
||
|
|
||
|
m_bLastCharging = m_bCharging;
|
||
|
}
|
||
|
|
||
|
|
||
|
void C_WeaponCombat_ChargeablePlasma::NotifyShouldTransmit( ShouldTransmitState_t state )
|
||
|
{
|
||
|
BaseClass::NotifyShouldTransmit(state);
|
||
|
|
||
|
if (state == SHOULDTRANSMIT_START)
|
||
|
{
|
||
|
if (m_bCharging)
|
||
|
StartCharging();
|
||
|
}
|
||
|
else if (state == SHOULDTRANSMIT_END)
|
||
|
{
|
||
|
if (m_bCharging)
|
||
|
StopCharging();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void C_WeaponCombat_ChargeablePlasma::OnDataChanged( DataUpdateType_t updateType )
|
||
|
{
|
||
|
BaseClass::OnDataChanged( updateType );
|
||
|
|
||
|
switch( updateType )
|
||
|
{
|
||
|
case DATA_UPDATE_CREATED:
|
||
|
// So we can update our lights
|
||
|
if ( GetTeamNumber() == 1 )
|
||
|
m_hMaterial.Init( "sprites/chargeball_team1" );
|
||
|
else
|
||
|
m_hMaterial.Init( "sprites/chargeball_team2" );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case DATA_UPDATE_DATATABLE_CHANGED:
|
||
|
if ( m_bCharging != m_bLastCharging )
|
||
|
{
|
||
|
if ( m_bCharging )
|
||
|
{
|
||
|
StartCharging();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
StopCharging();
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
};
|
||
|
|
||
|
if (WeaponState() == WEAPON_IS_ACTIVE)
|
||
|
{
|
||
|
// Start thinking so we can manipulate the light
|
||
|
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetNextClientThink( CLIENT_THINK_NEVER );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Deal with dynamic lighting
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void C_WeaponCombat_ChargeablePlasma::ClientThink( )
|
||
|
{
|
||
|
BaseClass::ClientThink();
|
||
|
|
||
|
C_BaseTFPlayer *pPlayer = (C_BaseTFPlayer *)GetOwner();
|
||
|
if ( !pPlayer || (pPlayer->GetHealth() <= 0))
|
||
|
{
|
||
|
SetNextClientThink( CLIENT_THINK_NEVER );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!m_bCharging)
|
||
|
return;
|
||
|
|
||
|
// Determine the ball size...
|
||
|
m_flPower = (gpGlobals->curtime - m_flChargeStartTime) / BALL_GROW_TIME;
|
||
|
m_flPower = clamp( m_flPower, 0, 1 );
|
||
|
|
||
|
// FIXME: dl->origin should be based on the attachment point
|
||
|
dlight_t *dl = effects->CL_AllocDlight( entindex() );
|
||
|
dl->origin = GetRenderOrigin();
|
||
|
|
||
|
if (GetTeamNumber() == 1)
|
||
|
{
|
||
|
dl->color.r = 40;
|
||
|
dl->color.g = 60;
|
||
|
dl->color.b = 250;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dl->color.r = 250;
|
||
|
dl->color.g = 60;
|
||
|
dl->color.b = 40;
|
||
|
}
|
||
|
|
||
|
dl->color.exponent = 5;
|
||
|
dl->radius = 20 * m_flPower + 10;
|
||
|
dl->die = gpGlobals->curtime + 0.01;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Remove the ball if we're switching away
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool C_WeaponCombat_ChargeablePlasma::Holster( C_BaseCombatWeapon *pSwitchingTo )
|
||
|
{
|
||
|
StopCharging();
|
||
|
|
||
|
return BaseClass::Holster( pSwitchingTo );
|
||
|
}
|
||
|
|
||
|
void C_WeaponCombat_ChargeablePlasma::StartCharging()
|
||
|
{
|
||
|
CLocalPlayerFilter filter;
|
||
|
EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, "WeaponCombat_ChargeablePlasma.Charging" );
|
||
|
m_flChargeStartTime = gpGlobals->curtime;
|
||
|
}
|
||
|
|
||
|
|
||
|
void C_WeaponCombat_ChargeablePlasma::StopCharging()
|
||
|
{
|
||
|
StopSound( SOUND_FROM_LOCAL_PLAYER, "WeaponCombat_ChargeablePlasma.Charging" );
|
||
|
m_bCharging = false;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// We're transparent because we draw a transparent charging effect
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool C_WeaponCombat_ChargeablePlasma::IsTransparent( )
|
||
|
{
|
||
|
if (m_bCharging)
|
||
|
return true;
|
||
|
return BaseClass::IsTransparent();
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Draws the charging effect
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void C_WeaponCombat_ChargeablePlasma::DrawChargingEffect( float flSize, C_BaseAnimating *pAttachedEnt )
|
||
|
{
|
||
|
if (!pAttachedEnt)
|
||
|
return;
|
||
|
|
||
|
Vector vecOrigin;
|
||
|
QAngle vecAngles;
|
||
|
int iAttachment = pAttachedEnt->LookupAttachment( "muzzle" );
|
||
|
if ( pAttachedEnt->GetAttachment( iAttachment, vecOrigin, vecAngles ) )
|
||
|
{
|
||
|
color32 color = { 255, 255, 255, 255 };
|
||
|
materials->Bind( m_hMaterial, (IClientRenderable*)this );
|
||
|
DrawSprite( vecOrigin, flSize, flSize, color );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Draws the model
|
||
|
//-----------------------------------------------------------------------------
|
||
|
int C_WeaponCombat_ChargeablePlasma::DrawModel( int flags )
|
||
|
{
|
||
|
int retval = BaseClass::DrawModel( flags );
|
||
|
if (retval == 0)
|
||
|
return 0;
|
||
|
|
||
|
if (m_bCharging && IsCarrierAlive())
|
||
|
{
|
||
|
// Draw the charging effect
|
||
|
float flSize = 20 * m_flPower + 10;
|
||
|
|
||
|
DrawChargingEffect( flSize, this );
|
||
|
}
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Draws the model
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void C_WeaponCombat_ChargeablePlasma::ViewModelDrawn( C_BaseViewModel *pBaseViewModel )
|
||
|
{
|
||
|
if (!m_bCharging)
|
||
|
return;
|
||
|
|
||
|
// Draw the charging effect
|
||
|
float flSize = 12 * m_flPower + 6;
|
||
|
|
||
|
if ( m_iClip1 > 0 )
|
||
|
{
|
||
|
DrawChargingEffect( flSize, pBaseViewModel );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Draw targeting reticle
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void C_WeaponCombat_ChargeablePlasma::DrawCrosshair( void )
|
||
|
{
|
||
|
BaseClass::DrawCrosshair();
|
||
|
|
||
|
// Find enemy players in front of me
|
||
|
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||
|
if ( !pPlayer )
|
||
|
return;
|
||
|
|
||
|
trace_t tr;
|
||
|
Vector vecStart, vecEnd;
|
||
|
VectorMA( CurrentViewOrigin(), 1500, CurrentViewForward(), vecEnd );
|
||
|
VectorMA( CurrentViewOrigin(), 48, CurrentViewForward(), vecStart );
|
||
|
UTIL_TraceLine( vecStart, vecEnd, MASK_SOLID, NULL, COLLISION_GROUP_NONE, &tr );
|
||
|
|
||
|
if ( tr.DidHitNonWorldEntity() )
|
||
|
{
|
||
|
C_BaseEntity *pEntity = tr.m_pEnt;
|
||
|
if ( pEntity && pEntity->IsPlayer() && !pPlayer->InSameTeam( pEntity ) )
|
||
|
{
|
||
|
// Draw a reticle
|
||
|
vgui::Color clr = gHUD.m_clrYellowish;
|
||
|
clr[3] = 128;
|
||
|
|
||
|
// Calculate circle size
|
||
|
int iRatio = 30;
|
||
|
|
||
|
// Draw the circle
|
||
|
int iDegrees = 0;
|
||
|
Vector vecPoint, vecLastPoint(0,0,0);
|
||
|
vecPoint.z = 0.0f;
|
||
|
for ( int i = 0; i < 360; i++ )
|
||
|
{
|
||
|
float flRadians = DEG2RAD( iDegrees );
|
||
|
iDegrees += (360 / 360);
|
||
|
|
||
|
float ca = cos( flRadians );
|
||
|
float sa = sin( flRadians );
|
||
|
|
||
|
// Rotate it around the circle
|
||
|
vecPoint.x = (int)((ScreenWidth() / 2) + (iRatio * sa));
|
||
|
vecPoint.y = (int)((ScreenHeight() / 2) - (iRatio * ca));
|
||
|
|
||
|
// Draw the point, if it's not on the previous point, to avoid smaller circles being brighter
|
||
|
if ( vecLastPoint != vecPoint )
|
||
|
{
|
||
|
vgui::surface()->DrawSetColor( clr );
|
||
|
vgui::surface()->DrawFilledRect( vecPoint.x, vecPoint.y, vecPoint.x + 1, vecPoint.y + 1 );
|
||
|
}
|
||
|
|
||
|
vecLastPoint = vecPoint;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|