summaryrefslogtreecommitdiff
path: root/game/shared/tf/tf_weapon_smg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/shared/tf/tf_weapon_smg.cpp')
-rw-r--r--game/shared/tf/tf_weapon_smg.cpp197
1 files changed, 197 insertions, 0 deletions
diff --git a/game/shared/tf/tf_weapon_smg.cpp b/game/shared/tf/tf_weapon_smg.cpp
new file mode 100644
index 0000000..6d5e11a
--- /dev/null
+++ b/game/shared/tf/tf_weapon_smg.cpp
@@ -0,0 +1,197 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+//
+//=============================================================================
+#include "cbase.h"
+#include "tf_weapon_smg.h"
+
+static const float DAMAGE_TO_FILL_MINICRIT_METER = 100.0f;
+
+// Client specific.
+#ifdef CLIENT_DLL
+#include "c_tf_player.h"
+// Server specific.
+#else
+#include "tf_player.h"
+#endif
+//=============================================================================
+//
+// Weapon tables.
+//
+
+// ---------- Regular SMG -------------
+
+CREATE_SIMPLE_WEAPON_TABLE( TFSMG, tf_weapon_smg )
+
+// Server specific.
+#ifndef CLIENT_DLL
+BEGIN_DATADESC( CTFSMG )
+END_DATADESC()
+#endif
+
+// ---------- Charged SMG -------------
+
+IMPLEMENT_NETWORKCLASS_ALIASED( TFChargedSMG, DT_WeaponChargedSMG )
+
+BEGIN_NETWORK_TABLE( CTFChargedSMG, DT_WeaponChargedSMG )
+// Client specific.
+#ifdef CLIENT_DLL
+RecvPropFloat( RECVINFO( m_flMinicritCharge ) ),
+// Server specific.
+#else
+SendPropFloat( SENDINFO( m_flMinicritCharge ), 4, SPROP_NOSCALE, 0.0f, DAMAGE_TO_FILL_MINICRIT_METER ),
+#endif
+END_NETWORK_TABLE()
+
+// Server specific
+#ifndef CLIENT_DLL
+BEGIN_DATADESC( CTFChargedSMG )
+END_DATADESC()
+#endif
+
+// Client specific
+#ifdef CLIENT_DLL
+BEGIN_PREDICTION_DATA( CTFChargedSMG )
+DEFINE_FIELD( m_flMinicritCharge, FIELD_FLOAT )
+END_PREDICTION_DATA()
+#endif
+
+LINK_ENTITY_TO_CLASS( tf_weapon_charged_smg, CTFChargedSMG );
+PRECACHE_WEAPON_REGISTER( tf_weapon_charged_smg );
+
+//=============================================================================
+//
+// Weapon SMG functions.
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CTFSMG::GetDamageType( void ) const
+{
+ if ( CanHeadshot() )
+ {
+ int iDamageType = BaseClass::GetDamageType() | DMG_USE_HITLOCATIONS;
+ return iDamageType;
+ }
+
+ return BaseClass::GetDamageType();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CTFSMG::CanFireCriticalShot( bool bIsHeadshot )
+{
+ if ( !BaseClass::CanFireCriticalShot( bIsHeadshot ) )
+ return false;
+
+ CTFPlayer *pPlayer = GetTFPlayerOwner();
+ if ( pPlayer && pPlayer->m_Shared.IsCritBoosted() )
+ return true;
+
+ if ( !bIsHeadshot )
+ return !CanHeadshot();
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Determine if secondary fire is available.
+//-----------------------------------------------------------------------------
+bool CTFChargedSMG::CanPerformSecondaryAttack() const
+{
+ return ( m_flMinicritCharge >= DAMAGE_TO_FILL_MINICRIT_METER && BaseClass::CanPerformSecondaryAttack() );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Determine whether to flash the HUD element showing the charge bar
+//-----------------------------------------------------------------------------
+bool CTFChargedSMG::ShouldFlashChargeBar()
+{
+ return m_flMinicritCharge >= DAMAGE_TO_FILL_MINICRIT_METER;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Get HUD charge bar progress amount
+//-----------------------------------------------------------------------------
+float CTFChargedSMG::GetProgress( void )
+{
+ // Progress bar shows charge amount if we're charging up, otherwise drains over time if we're mini-crit boosted.
+ CTFPlayer *pPlayer = ToTFPlayer( GetOwner() );
+ if ( pPlayer && pPlayer->m_Shared.InCond( TF_COND_ENERGY_BUFF ) )
+ {
+ int flBuffDuration = 0;
+ CALL_ATTRIB_HOOK_FLOAT( flBuffDuration, minicrit_boost_when_charged );
+ if ( flBuffDuration > 0 )
+ {
+ float flElapsed = gpGlobals->curtime - m_flMinicritStartTime;
+ float flRemainingPortion = Clamp( (flBuffDuration - flElapsed) / flBuffDuration, 0.0f, 1.0f );
+ return flRemainingPortion;
+ }
+ else
+ {
+ return 0.0f;
+ }
+ }
+ else
+ {
+ return m_flMinicritCharge / DAMAGE_TO_FILL_MINICRIT_METER;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Reset weapon state
+//-----------------------------------------------------------------------------
+void CTFChargedSMG::WeaponReset()
+{
+ BaseClass::WeaponReset();
+ m_flMinicritCharge = 0.0f;
+ m_flMinicritStartTime = 0.0f;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Perform secondary attack
+//-----------------------------------------------------------------------------
+void CTFChargedSMG::SecondaryAttack()
+{
+ BaseClass::SecondaryAttack();
+
+ m_flMinicritCharge = 0.0f;
+
+ CTFPlayer *pPlayer = ToTFPlayer( GetOwner() );
+ if ( pPlayer )
+ {
+ float flBuffDuration = 0;
+ CALL_ATTRIB_HOOK_FLOAT( flBuffDuration, minicrit_boost_when_charged );
+ if ( flBuffDuration > 0 )
+ {
+ pPlayer->m_Shared.AddCond( TF_COND_ENERGY_BUFF, flBuffDuration );
+ m_flMinicritStartTime = gpGlobals->curtime;
+ }
+ }
+}
+
+#ifdef GAME_DLL
+//-----------------------------------------------------------------------------
+// Purpose: Update state when we score a hit with this weapon
+//-----------------------------------------------------------------------------
+void CTFChargedSMG::ApplyOnHitAttributes( CBaseEntity *pVictimBaseEntity, CTFPlayer *pAttacker, const CTakeDamageInfo &info )
+{
+ BaseClass::ApplyOnHitAttributes( pVictimBaseEntity, pAttacker, info );
+ if ( pAttacker )
+ {
+ CTFPlayer *pPlayer = ToTFPlayer( GetOwner() );
+ if ( pPlayer && !pPlayer->m_Shared.InCond( TF_COND_ENERGY_BUFF ) )
+ {
+ float damage = info.GetDamage();
+ float flChargeRate = 0.0f;
+ CALL_ATTRIB_HOOK_FLOAT( flChargeRate, minicrit_boost_charge_rate );
+ m_flMinicritCharge += damage * flChargeRate;
+ if ( m_flMinicritCharge > DAMAGE_TO_FILL_MINICRIT_METER )
+ {
+ m_flMinicritCharge = DAMAGE_TO_FILL_MINICRIT_METER;
+ }
+ }
+ }
+}
+#endif