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.
358 lines
9.7 KiB
358 lines
9.7 KiB
//========= 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; |
|
} |
|
} |
|
} |
|
} |
|
|
|
|