summaryrefslogtreecommitdiff
path: root/game/shared/tf/tf_weapon_flaregun.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/shared/tf/tf_weapon_flaregun.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/shared/tf/tf_weapon_flaregun.cpp')
-rw-r--r--game/shared/tf/tf_weapon_flaregun.cpp619
1 files changed, 619 insertions, 0 deletions
diff --git a/game/shared/tf/tf_weapon_flaregun.cpp b/game/shared/tf/tf_weapon_flaregun.cpp
new file mode 100644
index 0000000..b5a13fc
--- /dev/null
+++ b/game/shared/tf/tf_weapon_flaregun.cpp
@@ -0,0 +1,619 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+//
+//=============================================================================
+#include "cbase.h"
+#include "tf_weapon_flaregun.h"
+#include "tf_fx_shared.h"
+#include "in_buttons.h"
+
+// Client specific.
+#ifdef CLIENT_DLL
+#include "c_tf_player.h"
+#include "soundenvelope.h"
+// Server specific.
+#else
+#include "tf_gamestats.h"
+#include "tf_player.h"
+#endif
+
+//=============================================================================
+//
+// Weapon Flare Gun tables.
+//
+IMPLEMENT_NETWORKCLASS_ALIASED( TFFlareGun, DT_WeaponFlareGun )
+
+BEGIN_NETWORK_TABLE( CTFFlareGun, DT_WeaponFlareGun )
+#ifdef CLIENT_DLL
+ RecvPropFloat( RECVINFO( m_flChargeBeginTime ) ),
+#else
+ SendPropFloat( SENDINFO( m_flChargeBeginTime ) ),
+#endif
+END_NETWORK_TABLE()
+
+BEGIN_PREDICTION_DATA( CTFFlareGun )
+END_PREDICTION_DATA()
+
+LINK_ENTITY_TO_CLASS( tf_weapon_flaregun, CTFFlareGun );
+PRECACHE_WEAPON_REGISTER( tf_weapon_flaregun );
+
+// Server specific.
+#ifndef CLIENT_DLL
+BEGIN_DATADESC( CTFFlareGun )
+END_DATADESC()
+#endif
+
+
+//============================
+IMPLEMENT_NETWORKCLASS_ALIASED( TFFlareGun_Revenge, DT_WeaponFlareGun_Revenge )
+
+BEGIN_NETWORK_TABLE( CTFFlareGun_Revenge, DT_WeaponFlareGun_Revenge )
+#ifdef CLIENT_DLL
+RecvPropFloat( RECVINFO( m_fLastExtinguishTime ) ),
+#else
+SendPropFloat( SENDINFO( m_fLastExtinguishTime ) ),
+#endif
+END_NETWORK_TABLE()
+
+BEGIN_PREDICTION_DATA( CTFFlareGun_Revenge )
+END_PREDICTION_DATA()
+
+LINK_ENTITY_TO_CLASS( tf_weapon_flaregun_revenge, CTFFlareGun_Revenge );
+PRECACHE_WEAPON_REGISTER( tf_weapon_flaregun_revenge );
+
+
+//=============================================================================
+//
+// Weapon Flare Gun functions.
+//
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CTFFlareGun::CTFFlareGun()
+{
+ m_bEffectsThinking = false;
+ m_flLastDenySoundTime = 0.0f;
+
+#ifdef CLIENT_DLL
+ m_bReadyToFire = false;
+#endif
+
+ StopCharge();
+}
+
+CTFFlareGun::~CTFFlareGun()
+{
+ DestroySounds();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTFFlareGun::Precache()
+{
+ BaseClass::Precache();
+
+ PrecacheParticleSystem( "stickybombtrail_blue" );
+ PrecacheParticleSystem( "stickybombtrail_red" );
+ PrecacheParticleSystem( "critical_grenade_blue" );
+ PrecacheParticleSystem( "critical_grenade_red" );
+}
+
+void CTFFlareGun::DestroySounds( void )
+{
+ StopCharge();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTFFlareGun::PrimaryAttack( void )
+{
+ // Get the player owning the weapon.
+ CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() );
+ if ( !pOwner )
+ return;
+
+ if ( m_flChargeBeginTime > 0.0f )
+ return;
+
+ // Don't attack if we're underwater
+ if ( pOwner->GetWaterLevel() != WL_Eyes )
+ {
+ BaseClass::PrimaryAttack();
+ }
+ else
+ {
+ if ( gpGlobals->curtime > m_flLastDenySoundTime )
+ {
+ WeaponSound( SPECIAL2 );
+ m_flLastDenySoundTime = gpGlobals->curtime + 1.0f;
+ }
+ }
+
+#ifdef CLIENT_DLL
+ m_bReadyToFire = false;
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Detonate flare
+//-----------------------------------------------------------------------------
+void CTFFlareGun::SecondaryAttack( void )
+{
+ if ( GetFlareGunType() != FLAREGUN_DETONATE )
+ return;
+
+ if ( !CanAttack() )
+ return;
+
+ CTFPlayer *pPlayer = ToTFPlayer( GetOwner() );
+ if ( !pPlayer )
+ return;
+
+#ifdef GAME_DLL
+ if ( m_iFlareCount )
+ {
+ int iCount = m_Flares.Count();
+ for ( int i = 0; i < iCount; i++ )
+ {
+ CTFProjectile_Flare *pTemp = m_Flares[i];
+ if ( pTemp )
+ {
+ pTemp->Detonate();
+ }
+ }
+ }
+#endif // GAME_DLL
+}
+
+#ifdef GAME_DLL
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTFFlareGun::AddFlare( CTFProjectile_Flare *pFlare )
+{
+ FlareHandle hHandle;
+ hHandle = pFlare;
+ m_Flares.AddToTail( hHandle );
+
+ m_iFlareCount = m_Flares.Count();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTFFlareGun::DeathNotice( CBaseEntity *pVictim )
+{
+ Assert( dynamic_cast<CTFProjectile_Flare*>( pVictim ) );
+
+ FlareHandle hHandle;
+ hHandle = (CTFProjectile_Flare*)pVictim;
+ m_Flares.FindAndRemove( hHandle );
+
+ m_iFlareCount = m_Flares.Count();
+}
+#endif
+
+bool CTFFlareGun::Holster( CBaseCombatWeapon *pSwitchingTo )
+{
+#ifdef CLIENT_DLL
+ m_bEffectsThinking = false;
+ StopCharge();
+
+ m_bReadyToFire = false;
+#endif
+
+ return BaseClass::Holster( pSwitchingTo );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CTFFlareGun::Deploy( void )
+{
+#ifdef CLIENT_DLL
+ m_bEffectsThinking = true;
+ SetContextThink( &CTFFlareGun::ClientEffectsThink, gpGlobals->curtime + 0.25f, "EFFECTS_THINK" );
+
+ m_bReadyToFire = false;
+#endif
+
+ return BaseClass::Deploy();
+}
+
+void CTFFlareGun::WeaponReset( void )
+{
+ BaseClass::WeaponReset();
+
+#if defined( CLIENT_DLL )
+ StopCharge();
+#endif
+}
+
+void CTFFlareGun::ItemPostFrame( void )
+{
+ BaseClass::ItemPostFrame();
+
+ if ( m_flChargeBeginTime > 0.0f )
+ {
+ CTFPlayer *pPlayer = ToTFPlayer( GetPlayerOwner() );
+ if ( !pPlayer )
+ return;
+
+ // If we're not holding down the attack button
+ if ( !(pPlayer->m_nButtons & IN_ATTACK2) )
+ {
+ StopCharge();
+ }
+ else
+ {
+ ChargePostFrame();
+ }
+ }
+
+#ifdef CLIENT_DLL
+ if ( !m_bEffectsThinking )
+ {
+ m_bEffectsThinking = true;
+ SetContextThink( &CTFFlareGun::ClientEffectsThink, gpGlobals->curtime + 0.25f, "EFFECTS_THINK" );
+ }
+#endif
+}
+
+#ifdef CLIENT_DLL
+void CTFFlareGun::DispatchMuzzleFlash( const char* effectName, C_BaseEntity* pAttachEnt )
+{
+ DispatchParticleEffect( effectName, PATTACH_POINT_FOLLOW, pAttachEnt, "muzzle", GetParticleColor( 1 ), GetParticleColor( 2 ) );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTFFlareGun::ClientEffectsThink( void )
+{
+ CTFPlayer *pPlayer = GetTFPlayerOwner();
+ if ( !pPlayer )
+ return;
+
+ if ( !pPlayer->IsLocalPlayer() )
+ return;
+
+ if ( !pPlayer->GetViewModel() )
+ return;
+
+ if ( !m_bEffectsThinking )
+ return;
+
+ if ( !GetOwner() || GetOwner()->GetActiveWeapon() != this )
+ {
+ m_bEffectsThinking = false;
+ }
+ else
+ {
+ SetContextThink( &CTFFlareGun::ClientEffectsThink, gpGlobals->curtime + 0.25f, "EFFECTS_THINK" );
+ }
+
+ if ( GetFlareGunType() == FLAREGUN_GRORDBORT && m_flNextPrimaryAttack <= gpGlobals->curtime )
+ {
+ ParticleProp()->Init( this );
+ CNewParticleEffect* pEffect = ParticleProp()->Create( "drg_bison_idle", PATTACH_POINT_FOLLOW, "muzzle" );
+ if ( pEffect )
+ {
+ pEffect->SetControlPoint( CUSTOM_COLOR_CP1, GetParticleColor( 1 ) );
+ pEffect->SetControlPoint( CUSTOM_COLOR_CP2, GetParticleColor( 2 ) );
+ }
+
+ ParticleProp()->Create( "drg_manmelter_idle", PATTACH_POINT_FOLLOW, "muzzle" );
+
+ if ( !m_bReadyToFire )
+ {
+ m_bReadyToFire = true;
+
+ EmitSound( "Weapon_SniperRailgun.NonScoped" );
+ }
+ }
+}
+
+void CTFFlareGun::StartChargeEffects()
+{
+ CTFPlayer *pPlayer = ToTFPlayer( GetPlayerOwner() );
+ if ( pPlayer )
+ {
+ DispatchParticleEffect( GetChargeEffect(), PATTACH_POINT_FOLLOW, GetAppropriateWorldOrViewModel(), "muzzle", GetParticleColor( 1 ), GetParticleColor( 2 ) );
+ }
+}
+
+void CTFFlareGun::StopChargeEffects()
+{
+ CTFPlayer *pPlayer = ToTFPlayer( GetPlayerOwner() );
+ if ( pPlayer )
+ {
+ GetAppropriateWorldOrViewModel()->ParticleProp()->StopParticlesNamed( GetChargeEffect(), false );
+ }
+}
+
+#endif
+
+void CTFFlareGun::StartCharge( void )
+{
+ StartChargeStartTime();
+
+#ifdef CLIENT_DLL
+ if ( !m_pChargeLoop )
+ {
+ CLocalPlayerFilter filter;
+ CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
+ m_pChargeLoop = controller.SoundCreate( filter, entindex(), GetShootSound( WPN_DOUBLE ) );
+ controller.Play( m_pChargeLoop, 1.0, 100 );
+ }
+
+ StartChargeEffects();
+#endif
+}
+
+void CTFFlareGun::StopCharge( void )
+{
+ m_flChargeBeginTime = 0.0f;
+
+#ifdef CLIENT_DLL
+ if ( m_pChargeLoop )
+ {
+ CSoundEnvelopeController::GetController().SoundDestroy( m_pChargeLoop );
+ }
+
+ m_pChargeLoop = NULL;
+
+ StopChargeEffects();
+#endif
+}
+
+
+CTFFlareGun_Revenge::CTFFlareGun_Revenge()
+{
+ m_fLastExtinguishTime = 0.0f;
+
+#ifdef CLIENT_DLL
+ m_nOldRevengeCrits = 0;
+#endif
+}
+
+void CTFFlareGun_Revenge::Precache()
+{
+ BaseClass::Precache();
+
+ PrecacheParticleSystem( "drg_manmelter_vacuum" );
+ PrecacheParticleSystem( "drg_manmelter_vacuum_flames" );
+ PrecacheParticleSystem( "drg_manmelter_muzzleflash" );
+}
+
+int CTFFlareGun_Revenge::GetCustomDamageType() const
+{
+ CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() );
+ if ( pOwner )
+ {
+ int iRevengeCrits = pOwner->m_Shared.GetRevengeCrits();
+ return iRevengeCrits > 0 ? TF_DMG_CUSTOM_SHOTGUN_REVENGE_CRIT : TF_DMG_CUSTOM_NONE;
+ }
+ return TF_DMG_CUSTOM_NONE;
+}
+
+bool CTFFlareGun_Revenge::Holster( CBaseCombatWeapon *pSwitchingTo )
+{
+#ifdef GAME_DLL
+ CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() );
+ if ( pOwner && pOwner->m_Shared.GetRevengeCrits() )
+ {
+ pOwner->m_Shared.RemoveCond( TF_COND_CRITBOOSTED );
+ }
+#endif
+
+ StopCharge();
+
+ return BaseClass::Holster( pSwitchingTo );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CTFFlareGun_Revenge::Deploy( void )
+{
+#ifdef GAME_DLL
+ CTFPlayer *pOwner = ToTFPlayer( GetOwner() );
+ if ( pOwner && pOwner->m_Shared.GetRevengeCrits() )
+ {
+ pOwner->m_Shared.AddCond( TF_COND_CRITBOOSTED );
+ }
+#endif
+
+ StopCharge();
+
+ return BaseClass::Deploy();
+}
+
+#ifdef GAME_DLL
+//-----------------------------------------------------------------------------
+// Purpose: Reset revenge crits when the flaregun is changed
+//-----------------------------------------------------------------------------
+void CTFFlareGun_Revenge::Detach( void )
+{
+ CTFPlayer *pPlayer = GetTFPlayerOwner();
+ if ( pPlayer )
+ {
+ pPlayer->m_Shared.SetRevengeCrits( 0 );
+ pPlayer->m_Shared.RemoveCond( TF_COND_CRITBOOSTED );
+ }
+
+ BaseClass::Detach();
+}
+#endif
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CTFFlareGun_Revenge::GetCount( void )
+{
+ CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() );
+ if ( pOwner )
+ {
+ return pOwner->m_Shared.GetRevengeCrits();
+ }
+
+ return 0;
+}
+
+void CTFFlareGun_Revenge::PrimaryAttack()
+{
+ if ( !CanAttack() )
+ return;
+
+ BaseClass::PrimaryAttack();
+
+ // Lower the reveng crit count
+ CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() );
+ if ( pOwner )
+ {
+ int iNewRevengeCrits = MAX( pOwner->m_Shared.GetRevengeCrits() - 1, 0 );
+ pOwner->m_Shared.SetRevengeCrits( iNewRevengeCrits );
+ }
+}
+
+void CTFFlareGun_Revenge::SecondaryAttack( void )
+{
+ if ( m_flNextSecondaryAttack > gpGlobals->curtime )
+ {
+ return;
+ }
+
+ CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() );
+ if ( !pOwner )
+ return;
+
+ if ( GetChargeBeginTime() == 0.0f )
+ {
+ StartCharge();
+
+#ifdef GAME_DLL
+ //SendWeaponAnim( ACT_VM_PULLBACK );
+#endif
+ }
+
+ m_flNextSecondaryAttack = gpGlobals->curtime + 0.5f;
+}
+
+void CTFFlareGun_Revenge::ChargePostFrame( void )
+{
+ BaseClass::ChargePostFrame();
+
+ if ( gpGlobals->curtime > m_fLastExtinguishTime + 0.5f )
+ {
+ CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() );
+ if ( pOwner )
+ {
+ // Extinguish friends
+ Vector vecEye = pOwner->EyePosition();
+ Vector vecForward, vecRight, vecUp;
+ AngleVectors( pOwner->EyeAngles(), &vecForward, NULL, NULL );
+
+ const Vector vHull = Vector( 16.0f, 16.0f, 16.0f );
+
+ trace_t tr;
+ UTIL_TraceHull( vecEye, vecEye + vecForward * 256.0f, -vHull, vHull, MASK_SOLID, pOwner, COLLISION_GROUP_NONE, &tr );
+
+ CTFPlayer *pTarget = ToTFPlayer( tr.m_pEnt );
+ if ( pTarget )
+ {
+#ifdef GAME_DLL
+ // Get the player that ignited them before we extinguish
+ CTFPlayer *pBurner = pTarget->m_Shared.GetOriginalBurnAttacker();
+#endif
+
+ if ( ExtinguishPlayerInternal( pTarget, pOwner ) )
+ {
+ m_fLastExtinguishTime = gpGlobals->curtime;
+
+#ifdef GAME_DLL
+ // Make sure the team isn't burning themselves to earn crits
+ if ( pBurner && pBurner->GetTeamNumber() != pOwner->GetTeamNumber() )
+ {
+ // Grant revenge crits
+ pOwner->m_Shared.SetRevengeCrits( pOwner->m_Shared.GetRevengeCrits() + 1 );
+
+ // Return health to the Pyro.
+ int iRestoreHealthOnExtinguish = 0;
+ CALL_ATTRIB_HOOK_INT( iRestoreHealthOnExtinguish, extinguish_restores_health );
+ if ( iRestoreHealthOnExtinguish > 0 && pOwner->TakeHealth( 20, DMG_GENERIC ) > 0 )
+ {
+ IGameEvent *healevent = gameeventmanager->CreateEvent( "player_healonhit" );
+ if ( healevent )
+ {
+ healevent->SetInt( "amount", iRestoreHealthOnExtinguish );
+ healevent->SetInt( "entindex", pOwner->entindex() );
+ item_definition_index_t healingItemDef = INVALID_ITEM_DEF_INDEX;
+ if ( GetAttributeContainer() && GetAttributeContainer()->GetItem() )
+ {
+ healingItemDef = GetAttributeContainer()->GetItem()->GetItemDefIndex();
+ }
+ healevent->SetInt( "weapon_def_index", healingItemDef );
+
+ gameeventmanager->FireEvent( healevent );
+ }
+ }
+ }
+#endif
+ }
+ }
+ }
+ }
+}
+
+#ifdef GAME_DLL
+extern void ExtinguishPlayer( CEconEntity *pExtinguisher, CTFPlayer *pOwner, CTFPlayer *pTarget, const char *pExtinguisherName );
+#endif // GAME_DLL
+
+bool CTFFlareGun_Revenge::ExtinguishPlayerInternal( CTFPlayer *pTarget, CTFPlayer *pOwner )
+{
+ if ( pTarget->GetTeamNumber() == pOwner->GetTeamNumber() )
+ {
+ if ( pTarget->m_Shared.InCond( TF_COND_BURNING ) )
+ {
+#ifdef GAME_DLL
+ ExtinguishPlayer( this, pOwner, pTarget, GetName() );
+#endif // GAME_DLL
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+#ifdef CLIENT_DLL
+void CTFFlareGun_Revenge::OnDataChanged( DataUpdateType_t type )
+{
+ BaseClass::OnDataChanged( type );
+
+ CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() );
+ if ( pOwner )
+ {
+ if ( m_nOldRevengeCrits < pOwner->m_Shared.GetRevengeCrits() )
+ {
+ DoAbsorbEffect();
+ }
+
+ m_nOldRevengeCrits = pOwner->m_Shared.GetRevengeCrits();
+ }
+}
+
+void CTFFlareGun_Revenge::DoAbsorbEffect( void )
+{
+ WeaponSound( SPECIAL1 );
+
+ CTFPlayer *pPlayer = ToTFPlayer( GetPlayerOwner() );
+ if ( pPlayer )
+ {
+ DispatchParticleEffect( "drg_manmelter_vacuum_flames", PATTACH_POINT_FOLLOW, GetAppropriateWorldOrViewModel(), "muzzle", GetParticleColor( 1 ), GetParticleColor( 2 ) );
+ }
+}
+#endif