summaryrefslogtreecommitdiff
path: root/game/shared/tf2/weapon_arcwelder.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/tf2/weapon_arcwelder.cpp
downloadarchived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.tar.xz
archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.zip
Diffstat (limited to 'game/shared/tf2/weapon_arcwelder.cpp')
-rw-r--r--game/shared/tf2/weapon_arcwelder.cpp322
1 files changed, 322 insertions, 0 deletions
diff --git a/game/shared/tf2/weapon_arcwelder.cpp b/game/shared/tf2/weapon_arcwelder.cpp
new file mode 100644
index 0000000..27c6ae3
--- /dev/null
+++ b/game/shared/tf2/weapon_arcwelder.cpp
@@ -0,0 +1,322 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "basetfplayer_shared.h"
+#include "in_buttons.h"
+#include "tf_gamerules.h"
+#include "weapon_combatshield.h"
+
+#if defined( CLIENT_DLL )
+
+#include "particles_simple.h"
+#include "fx.h"
+#include "fx_quad.h"
+#include "clienteffectprecachesystem.h"
+
+#define CWeaponArcWelder C_WeaponArcWelder
+#else
+#endif
+
+#include "weapon_repairgun.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+
+// Buff ranges
+ConVar weapon_arcwelder_target_range( "weapon_arcwelder_target_range", "90", FCVAR_REPLICATED, "The farthest away you can be for the arcwelder to initially lock onto a target." );
+ConVar weapon_arcwelder_stick_range( "weapon_arcwelder_stick_range", "100", FCVAR_REPLICATED, "How far away the arcwelder can stay locked onto someone." );
+ConVar weapon_arcwelder_rate( "weapon_arcwelder_rate", "15", FCVAR_REPLICATED );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class CWeaponArcWelder : public CWeaponRepairGun
+{
+ DECLARE_CLASS( CWeaponArcWelder, CWeaponRepairGun );
+public:
+ DECLARE_NETWORKCLASS();
+ DECLARE_PREDICTABLE();
+
+ CWeaponArcWelder( void );
+
+ virtual void Precache();
+
+ virtual float GetTargetRange( void );
+ virtual float GetStickRange( void );
+ virtual float GetHealRate( void );
+ virtual bool AppliesModifier( void ) { return false; }
+ virtual bool TargetsPlayers( void ) { return false; }
+ virtual CBaseEntity *GetTargetToHeal( CBaseEntity *pCurHealing );
+
+ // All predicted weapons need to implement and return true
+ virtual bool IsPredicted( void ) const
+ {
+ return true;
+ }
+
+#if defined( CLIENT_DLL )
+ virtual void ClientThink( void );
+ virtual bool OnFireEvent( C_BaseViewModel *pViewModel, const Vector& origin, const QAngle& angles, int event, const char *options );
+ virtual void ViewModelDrawn( C_BaseViewModel *pViewModel );
+
+ virtual bool ShouldPredict( void )
+ {
+ if ( GetOwner() == C_BasePlayer::GetLocalPlayer() )
+ return true;
+
+ return BaseClass::ShouldPredict();
+ }
+#endif
+
+private:
+ bool m_bWelding;
+
+#if defined( CLIENT_DLL )
+ float m_flNextEffectTime;
+#endif
+
+private:
+ CWeaponArcWelder( const CWeaponArcWelder & );
+};
+
+LINK_ENTITY_TO_CLASS( weapon_arcwelder, CWeaponArcWelder );
+
+PRECACHE_WEAPON_REGISTER( weapon_arcwelder );
+
+IMPLEMENT_NETWORKCLASS_ALIASED( WeaponArcWelder, DT_WeaponArcWelder )
+
+BEGIN_NETWORK_TABLE( CWeaponArcWelder, DT_WeaponArcWelder )
+END_NETWORK_TABLE()
+
+BEGIN_PREDICTION_DATA( CWeaponArcWelder )
+END_PREDICTION_DATA()
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CWeaponArcWelder::CWeaponArcWelder()
+{
+ SetPredictionEligible( true );
+ m_bWelding = false;
+#ifdef CLIENT_DLL
+ m_flNextEffectTime = 0;
+#endif
+}
+
+void CWeaponArcWelder::Precache()
+{
+ BaseClass::Precache();
+
+ PrecacheScriptSound( "WeaponRepairGun.Healing" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+float CWeaponArcWelder::GetTargetRange( void )
+{
+ return weapon_arcwelder_target_range.GetFloat();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+float CWeaponArcWelder::GetStickRange( void )
+{
+ return weapon_arcwelder_target_range.GetFloat();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+float CWeaponArcWelder::GetHealRate( void )
+{
+ return weapon_arcwelder_rate.GetFloat();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns a pointer to a healable target
+//-----------------------------------------------------------------------------
+CBaseEntity *CWeaponArcWelder::GetTargetToHeal( CBaseEntity *pCurHealing )
+{
+ CBaseEntity *pTarget = BaseClass::GetTargetToHeal(pCurHealing);
+ if ( !pTarget )
+ return pTarget;
+
+ // Make sure the target is within our field of view
+ CBaseTFPlayer *pOwner = ToBaseTFPlayer( GetOwner() );
+ if ( !pOwner )
+ return NULL;
+
+ Vector vecAiming;
+ pOwner->EyeVectors( &vecAiming );
+
+ // Find a player in range of this player, and make sure they're healable.
+ Vector vecSrc = pOwner->Weapon_ShootPosition( );
+ Vector vecEnd = vecSrc + vecAiming * GetTargetRange();
+ trace_t tr;
+
+ // Use WeaponTraceLine so shields are tested...
+ TFGameRules()->WeaponTraceLine( vecSrc, vecEnd, (MASK_SHOT & ~CONTENTS_HITBOX), pOwner, DMG_PROBE, &tr );
+ if ( tr.fraction != 1.0 && tr.m_pEnt == pTarget )
+ return pTarget;
+
+ return NULL;
+}
+
+#ifdef CLIENT_DLL
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CWeaponArcWelder::ClientThink( void )
+{
+ CBasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ if ( m_hHealingTarget == NULL )
+ return;
+
+ // Don't show it while the player is dead. Ideally, we'd respond to m_bHealing in OnDataChanged,
+ // but it stops sending the weapon when it's holstered, and it gets holstered when the player dies.
+ C_BasePlayer *pFiringPlayer = dynamic_cast< C_BasePlayer* >( GetOwner() );
+ if ( !pFiringPlayer || pFiringPlayer->IsPlayerDead() )
+ {
+ ClientThinkList()->SetNextClientThink( GetClientHandle(), CLIENT_THINK_NEVER );
+ m_bPlayingSound = false;
+ StopRepairSound();
+ return;
+ }
+
+ // Start playing the heal sound, if we're not already
+ if ( !m_bPlayingSound )
+ {
+ m_bPlayingSound = true;
+ CLocalPlayerFilter filter;
+ EmitSound( filter, entindex(), "WeaponRepairGun.Healing" );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CWeaponArcWelder::OnFireEvent( C_BaseViewModel *pViewModel, const Vector& origin, const QAngle& angles, int event, const char *options )
+{
+ CBaseTFPlayer *pPlayer = static_cast<CBaseTFPlayer*>( GetOwner() );
+ if ( !pPlayer )
+ return true;
+
+ switch ( event )
+ {
+ case 7001:
+ m_bWelding = true;
+ return true;
+ case 7002:
+ m_bWelding = false;
+ return true;
+ default:
+ break;
+ };
+
+ return BaseClass::OnFireEvent( pViewModel, origin, angles, event, options );
+}
+
+CLIENTEFFECT_REGISTER_BEGIN( PrecacheArcWelderEffect )
+CLIENTEFFECT_MATERIAL( "particle/smoke_arcwelder" )
+CLIENTEFFECT_MATERIAL( "effects/spark2" )
+CLIENTEFFECT_MATERIAL( "effects/blueflare" )
+CLIENTEFFECT_MATERIAL( "effects/blueflare2" )
+CLIENTEFFECT_REGISTER_END()
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CWeaponArcWelder::ViewModelDrawn( C_BaseViewModel *pViewModel )
+{
+ if ( !m_bWelding || !m_hHealingTarget.Get() )
+ return;
+
+ if ( m_flNextEffectTime > gpGlobals->curtime )
+ return;
+ m_flNextEffectTime = gpGlobals->curtime + 0.1;
+
+ // Get our weldpoint
+ Vector attachOrigin;
+ QAngle attachAngles;
+ pViewModel->GetAttachment( pViewModel->LookupAttachment("muzzle"), attachOrigin, attachAngles );
+ Vector vecEnd = m_hHealingTarget->WorldSpaceCenter();
+ trace_t tr;
+
+ // Use WeaponTraceLine so shields are tested...
+ TFGameRules()->WeaponTraceLine( attachOrigin, vecEnd, (MASK_SHOT & ~CONTENTS_HITBOX), GetOwner(), DMG_PROBE, &tr );
+
+ // Smoke
+ unsigned char color[3];
+ int iColOff = random->RandomInt(-16,16);
+ color[0] = 120 + iColOff;
+ color[1] = 230 + iColOff;
+ color[2] = 235 + iColOff;
+ /*
+ // Pull out from the target a bit
+ Vector vecOrigin = vecEnd;
+ Vector vecFromTarget = (vecEnd - attachOrigin);
+ VectorNormalize( vecFromTarget );
+ vecOrigin -= (vecFromTarget * 24);
+ */
+
+ Vector vecOrigin = attachOrigin;
+ // Velocity
+ Vector vecVelocity = tr.plane.normal;
+ vecVelocity.z += random->RandomFloat( 8, 12 );
+ // Add it
+ CSmartPtr<CSimpleEmitter> pSimple = FX_Smoke( vecOrigin, vecVelocity,
+ random->RandomFloat( 4, 8 ), // Scale
+ 1,
+ random->RandomFloat( 0.5, 3.0 ), // Dietime
+ color,
+ random->RandomInt( 64, 200 ), // Alpha
+ "particle/smoke_arcwelder",
+ random->RandomInt(0,255), // Roll
+ 0 ); // Rolldelta
+
+ // Sparks
+ FX_Sparks( vecOrigin, 1, 4, tr.plane.normal, 2.5, 8, 64, "effects/spark2" );
+
+ // Bright Glow
+ SimpleParticle *sParticle;
+ sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/blueflare" ), vecOrigin );
+ if ( sParticle == NULL )
+ return;
+ sParticle->m_flLifetime = 0.0f;
+ sParticle->m_flDieTime = 0.5f;
+ sParticle->m_vecVelocity.Init();
+ sParticle->m_uchColor[0] = 255;
+ sParticle->m_uchColor[1] = 255;
+ sParticle->m_uchColor[2] = 255;
+ sParticle->m_uchStartSize = random->RandomInt(5,7);
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize;
+ sParticle->m_flRoll = random->RandomInt(0,360);
+ sParticle->m_flRollDelta = 0;
+
+ // Dull Glow
+ sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/blueflare2" ), vecOrigin );
+ if ( sParticle == NULL )
+ return;
+ sParticle->m_flLifetime = 0.0f;
+ sParticle->m_flDieTime = 0.2f;
+ sParticle->m_vecVelocity.Init();
+ sParticle->m_uchColor[0] = 255;
+ sParticle->m_uchColor[1] = 255;
+ sParticle->m_uchColor[2] = 255;
+ sParticle->m_uchStartSize = random->RandomInt(15,20);
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize;
+ sParticle->m_flRoll = random->RandomInt(0,360);
+ sParticle->m_flRollDelta = 0;
+}
+#endif