diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/shared/tf2/weapon_arcwelder.cpp | |
| download | archived-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.cpp | 322 |
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 |