summaryrefslogtreecommitdiff
path: root/game/client/tf/tf_hud_itemeffectmeter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/client/tf/tf_hud_itemeffectmeter.cpp')
-rw-r--r--game/client/tf/tf_hud_itemeffectmeter.cpp1486
1 files changed, 1486 insertions, 0 deletions
diff --git a/game/client/tf/tf_hud_itemeffectmeter.cpp b/game/client/tf/tf_hud_itemeffectmeter.cpp
new file mode 100644
index 0000000..6f9bb2b
--- /dev/null
+++ b/game/client/tf/tf_hud_itemeffectmeter.cpp
@@ -0,0 +1,1486 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================
+
+#include "cbase.h"
+#include "tf_hud_itemeffectmeter.h"
+#include "tf_weapon_bat.h"
+#include "tf_weapon_jar.h"
+#include "tf_weapon_sword.h"
+#include "tf_weapon_buff_item.h"
+#include "tf_weapon_lunchbox.h"
+#include "tf_weapon_shotgun.h"
+#include "tf_weapon_sniperrifle.h"
+#include "tf_weapon_rocketlauncher.h"
+#include "tf_weapon_particle_cannon.h"
+#include "tf_weapon_raygun.h"
+#include "tf_weapon_flaregun.h"
+#include "tf_weapon_revolver.h"
+#include "tf_weapon_flamethrower.h"
+#include "tf_weapon_knife.h"
+#include "tf_item_powerup_bottle.h"
+#include "tf_imagepanel.h"
+#include "c_tf_weapon_builder.h"
+#include "tf_weapon_minigun.h"
+#include "tf_weapon_medigun.h"
+#include "tf_weapon_throwable.h"
+#include "tf_weapon_smg.h"
+#include "halloween/tf_weapon_spellbook.h"
+#include "tf_logic_halloween_2014.h"
+#include <game/client/iviewport.h>
+#ifdef STAGING_ONLY
+#include "tf_weapon_pda.h"
+#endif // STAGING_ONLY
+
+#include <vgui_controls/ImagePanel.h>
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+#define DECLARE_ITEM_EFFECT_METER( weaponClass, weaponType, beeps, resfile ) \
+ hNewMeter = new CHudItemEffectMeter_Weapon< weaponClass >( pszElementName, pPlayer, weaponType, beeps, resfile ); \
+ if ( hNewMeter ) \
+ { \
+ gHUD.AddHudElement( hNewMeter ); \
+ outMeters.AddToHead( hNewMeter ); \
+ hNewMeter->SetVisible( false ); \
+ }
+
+
+using namespace vgui;
+
+IMPLEMENT_AUTO_LIST( IHudItemEffectMeterAutoList );
+
+CItemEffectMeterManager g_ItemEffectMeterManager;
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CItemEffectMeterManager::~CItemEffectMeterManager()
+{
+ ClearExistingMeters();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CItemEffectMeterManager::ClearExistingMeters()
+{
+ for ( int i=0; i<m_Meters.Count(); i++ )
+ {
+ gHUD.RemoveHudElement( m_Meters[i].Get() );
+ delete m_Meters[i].Get();
+ }
+ m_Meters.RemoveAll();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CItemEffectMeterManager::GetNumEnabled( void )
+{
+ int nCount = 0;
+
+ for ( int i = 0; i < m_Meters.Count(); i++ )
+ {
+ if ( m_Meters[i] && m_Meters[i]->IsEnabled() )
+ {
+ nCount++;
+ }
+ }
+
+ return nCount;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CItemEffectMeterManager::SetPlayer( C_TFPlayer* pPlayer )
+{
+ StopListeningForAllEvents();
+ ListenForGameEvent( "post_inventory_application" );
+ ListenForGameEvent( "localplayer_pickup_weapon" );
+
+ ClearExistingMeters();
+
+ if ( pPlayer )
+ {
+ CHudItemEffectMeter::CreateHudElementsForClass( pPlayer, m_Meters );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CItemEffectMeterManager::Update( C_TFPlayer* pPlayer )
+{
+ for ( int i=0; i<m_Meters.Count(); i++ )
+ {
+ if ( m_Meters[i] )
+ {
+ m_Meters[i]->Update( pPlayer );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CItemEffectMeterManager::FireGameEvent( IGameEvent *event )
+{
+ const char *type = event->GetName();
+
+ bool bNeedsUpdate = false;
+
+ if ( FStrEq( "localplayer_pickup_weapon", type ) )
+ {
+ bNeedsUpdate = true;
+ }
+ else if ( FStrEq( "post_inventory_application", type ) )
+ {
+ // Force a refresh. Our items may have changed causing us to now draw, etc.
+ // This creates a new game logic object which will re-cache necessary item data.
+ int iUserID = event->GetInt( "userid" );
+ C_TFPlayer* pPlayer = ToTFPlayer( C_TFPlayer::GetLocalPlayer() );
+ if ( pPlayer && pPlayer->GetUserID() == iUserID )
+ {
+ bNeedsUpdate = true;
+ }
+ }
+
+ if ( bNeedsUpdate )
+ {
+ SetPlayer( C_TFPlayer::GetLocalTFPlayer() );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CHudItemEffectMeter::CHudItemEffectMeter( const char *pszElementName, C_TFPlayer* pPlayer ) : CHudElement( pszElementName ), BaseClass( NULL, "HudItemEffectMeter" )
+{
+ Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+
+ if ( !m_pProgressBar )
+ {
+ m_pProgressBar = new ContinuousProgressBar( this, "ItemEffectMeter" );
+ }
+
+ if ( !m_pLabel )
+ {
+ m_pLabel = new Label( this, "ItemEffectMeterLabel", "" );
+ }
+
+ SetHiddenBits( HIDEHUD_MISCSTATUS );
+
+ m_pPlayer = pPlayer;
+ m_bEnabled = true;
+ m_flOldProgress = 1.f;
+
+ RegisterForRenderGroup( "inspect_panel" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CHudItemEffectMeter::~CHudItemEffectMeter()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudItemEffectMeter::CreateHudElementsForClass( C_TFPlayer* pPlayer, CUtlVector< vgui::DHANDLE< CHudItemEffectMeter > >& outMeters )
+{
+ vgui::DHANDLE< CHudItemEffectMeter > hNewMeter;
+ const char* pszElementName = "HudItemEffectMeter";
+
+ switch ( pPlayer->GetPlayerClass()->GetClassIndex() )
+ {
+ case TF_CLASS_SCOUT:
+ DECLARE_ITEM_EFFECT_METER( CTFBat_Wood, TF_WEAPON_BAT_WOOD, true, NULL );
+ DECLARE_ITEM_EFFECT_METER( CTFBat_Giftwrap, TF_WEAPON_BAT_GIFTWRAP, true, NULL );
+ DECLARE_ITEM_EFFECT_METER( CTFLunchBox_Drink, TF_WEAPON_LUNCHBOX, true, "resource/UI/HudItemEffectMeter_Scout.res" );
+ DECLARE_ITEM_EFFECT_METER( CTFJarMilk, TF_WEAPON_JAR_MILK, true, "resource/UI/HudItemEffectMeter_Scout.res" );
+ DECLARE_ITEM_EFFECT_METER( CTFSodaPopper, TF_WEAPON_SODA_POPPER, true, "resource/UI/HudItemEffectMeter_SodaPopper.res" );
+ DECLARE_ITEM_EFFECT_METER( CTFPEPBrawlerBlaster, TF_WEAPON_PEP_BRAWLER_BLASTER, true, "resource/UI/HudItemEffectMeter_SodaPopper.res" );
+ DECLARE_ITEM_EFFECT_METER( CTFCleaver, TF_WEAPON_CLEAVER, true, "resource/UI/HudItemEffectMeter_Cleaver.res" );
+ break;
+
+ case TF_CLASS_HEAVYWEAPONS:
+ DECLARE_ITEM_EFFECT_METER( CTFLunchBox, TF_WEAPON_LUNCHBOX, true, NULL );
+ DECLARE_ITEM_EFFECT_METER( CTFMinigun, TF_WEAPON_MINIGUN, true, "resource/UI/HudItemEffectMeter_Heavy.res" );
+ break;
+
+ case TF_CLASS_SNIPER:
+ DECLARE_ITEM_EFFECT_METER( CTFJar, TF_WEAPON_JAR, true, NULL );
+ DECLARE_ITEM_EFFECT_METER( CTFSniperRifleDecap, TF_WEAPON_SNIPERRIFLE_DECAP, false, "resource/UI/HudItemEffectMeter_Sniper.res" );
+ DECLARE_ITEM_EFFECT_METER( CTFSniperRifle, TF_WEAPON_SNIPERRIFLE, true, "resource/UI/HudItemEffectMeter_SniperFocus.res" );
+ DECLARE_ITEM_EFFECT_METER( CTFChargedSMG, TF_WEAPON_CHARGED_SMG, false, NULL );
+ break;
+
+ case TF_CLASS_DEMOMAN:
+ DECLARE_ITEM_EFFECT_METER( CTFSword, TF_WEAPON_SWORD, false, "resource/UI/HudItemEffectMeter_Demoman.res" );
+ break;
+
+ case TF_CLASS_SOLDIER:
+ DECLARE_ITEM_EFFECT_METER( CTFBuffItem, TF_WEAPON_BUFF_ITEM, true, NULL );
+ DECLARE_ITEM_EFFECT_METER( CTFParticleCannon, TF_WEAPON_PARTICLE_CANNON, false, "resource/UI/HUDItemEffectMeter_ParticleCannon.res" );
+ DECLARE_ITEM_EFFECT_METER( CTFRaygun, TF_WEAPON_RAYGUN, false, "resource/UI/HUDItemEffectMeter_Raygun.res" );
+ DECLARE_ITEM_EFFECT_METER( CTFRocketLauncher_AirStrike, TF_WEAPON_ROCKETLAUNCHER, false, "resource/UI/HudItemEffectMeter_Demoman.res" );
+ break;
+
+ case TF_CLASS_SPY:
+ DECLARE_ITEM_EFFECT_METER( CTFKnife, TF_WEAPON_KNIFE, true, "resource/UI/HUDItemEffectMeter_SpyKnife.res" );
+
+ hNewMeter = new CHudItemEffectMeter( pszElementName, pPlayer );
+ if ( hNewMeter )
+ {
+ gHUD.AddHudElement( hNewMeter );
+ outMeters.AddToHead( hNewMeter );
+ hNewMeter->SetVisible( false );
+ }
+#ifdef STAGING_ONLY
+ //hNewMeter = new CHudItemEffectMeter_Tranq( pszElementName, pPlayer );
+ //if ( hNewMeter )
+ //{
+ // gHUD.AddHudElement( hNewMeter );
+ // outMeters.AddToHead( hNewMeter );
+ // hNewMeter->SetVisible( false );
+ //}
+#endif // STAGING_ONLY
+
+ DECLARE_ITEM_EFFECT_METER( C_TFWeaponBuilder, TF_WEAPON_BUILDER, true, "resource/UI/HudItemEffectMeter_Sapper.res" );
+ DECLARE_ITEM_EFFECT_METER( CTFRevolver, TF_WEAPON_REVOLVER, false, "resource/UI/HUDItemEffectMeter_Spy.res" );
+
+#ifdef STAGING_ONLY
+ DECLARE_ITEM_EFFECT_METER( CTFWeaponPDA_Spy_Build, TF_WEAPON_PDA_SPY_BUILD, false, "resource/UI/HudItemEffectMeter_Spy_Build.res" );
+#endif // STAGING_ONLY
+ break;
+
+ case TF_CLASS_ENGINEER:
+ DECLARE_ITEM_EFFECT_METER( CTFShotgun_Revenge, TF_WEAPON_SENTRY_REVENGE, false, "resource/UI/HUDItemEffectMeter_Engineer.res" );
+ DECLARE_ITEM_EFFECT_METER( CTFDRGPomson, TF_WEAPON_DRG_POMSON, false, "resource/UI/HUDItemEffectMeter_Pomson.res" );
+ DECLARE_ITEM_EFFECT_METER( CTFRevolver, TF_WEAPON_REVOLVER, false, "resource/UI/HUDItemEffectMeter_Spy.res" );
+ break;
+
+ case TF_CLASS_PYRO:
+ DECLARE_ITEM_EFFECT_METER( CTFFlameThrower, TF_WEAPON_FLAMETHROWER, true, NULL );
+ DECLARE_ITEM_EFFECT_METER( CTFFlareGun_Revenge, TF_WEAPON_FLAREGUN_REVENGE, false, "resource/UI/HUDItemEffectMeter_Engineer.res" );
+ break;
+
+
+ case TF_CLASS_MEDIC:
+#ifdef STAGING_ONLY
+ DECLARE_ITEM_EFFECT_METER( CTFCrossbow, TF_WEAPON_CROSSBOW, true, "resource/UI/HudItemEffectMeter_SodaPopper.res" );
+#endif // STAGING_ONLY
+ DECLARE_ITEM_EFFECT_METER( CWeaponMedigun, TF_WEAPON_MEDIGUN, true, "resource/UI/HudItemEffectMeter_Scout.res" );
+ break;
+ }
+
+ // ALL CLASS
+ DECLARE_ITEM_EFFECT_METER( CTFThrowable, TF_WEAPON_THROWABLE, true, "resource/UI/HudItemEffectMeter_Action.res" );
+
+ // Kill Streak
+ DECLARE_ITEM_EFFECT_METER( CTFWeaponBase, TF_WEAPON_NONE, false, "resource/UI/HudItemEffectMeter_KillStreak.res" );
+
+ DECLARE_ITEM_EFFECT_METER( CTFSpellBook, TF_WEAPON_SPELLBOOK, true, "resource/UI/HudItemEffectMeter_KartCharge.res" );
+ /*hNewMeter = new CHudItemEffectMeter_HalloweenSouls( pszElementName, pPlayer );
+ if ( hNewMeter )
+ {
+ gHUD.AddHudElement( hNewMeter );
+ outMeters.AddToHead( hNewMeter );
+ hNewMeter->SetVisible( false );
+ }*/
+
+ // Mvm canteen
+ hNewMeter = new CHudItemEffectMeter_Weapon< CTFPowerupBottle >( pszElementName, pPlayer, TF_WEAPON_NONE, true, "resource/UI/HudItemEffectMeter_PowerupBottle.res" );
+ if ( hNewMeter )
+ {
+ gHUD.AddHudElement( hNewMeter );
+ outMeters.AddToHead( hNewMeter );
+ hNewMeter->SetVisible( false );
+ }
+
+ hNewMeter = new CHudItemEffectMeter_Rune( pszElementName, pPlayer );
+ if ( hNewMeter )
+ {
+ gHUD.AddHudElement( hNewMeter );
+ outMeters.AddToHead( hNewMeter );
+ hNewMeter->SetVisible( false );
+ }
+
+#ifdef STAGING_ONLY
+ // Space jump
+ hNewMeter = new CHudItemEffectMeter_SpaceJump( pszElementName, pPlayer );
+ if ( hNewMeter )
+ {
+ gHUD.AddHudElement( hNewMeter );
+ outMeters.AddToHead( hNewMeter );
+ hNewMeter->SetVisible( false );
+ }
+#endif // STAGING_ONLY
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudItemEffectMeter::ApplySchemeSettings( IScheme *pScheme )
+{
+ // load control settings...
+ LoadControlSettings( GetResFile() );
+
+ // Update the label.
+ const wchar_t *pLocalized = g_pVGuiLocalize->Find( GetLabelText() );
+ if ( pLocalized )
+ {
+ wchar_t wszLabel[ 128 ];
+ V_wcsncpy( wszLabel, pLocalized, sizeof( wszLabel ) );
+
+ wchar_t wszFinalLabel[ 128 ];
+ UTIL_ReplaceKeyBindings( wszLabel, 0, wszFinalLabel, sizeof( wszFinalLabel ), GAME_ACTION_SET_FPSCONTROLS );
+
+ m_pLabel->SetText( wszFinalLabel, true );
+ }
+ else
+ {
+ m_pLabel->SetText( GetLabelText() );
+ }
+
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ CTFImagePanel *pIcon = dynamic_cast< CTFImagePanel* >( FindChildByName( "ItemEffectIcon" ) );
+ if ( pIcon )
+ {
+ pIcon->SetImage( GetIconName() );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudItemEffectMeter::PerformLayout()
+{
+ BaseClass::PerformLayout();
+
+ // slide over by 1 for medic
+ int iOffset = 0;
+ C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer();
+ if ( pPlayer && pPlayer->GetPlayerClass()->GetClassIndex() == TF_CLASS_MEDIC )
+ {
+ iOffset = 1;
+ }
+
+ if ( g_ItemEffectMeterManager.GetNumEnabled() + iOffset > 1 )
+ {
+ int xPos = 0, yPos = 0;
+ GetPos( xPos, yPos );
+ SetPos( xPos - m_iXOffset, yPos );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CHudItemEffectMeter::ShouldDraw( void )
+{
+ bool bShouldDraw = true;
+
+ C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer();
+ if ( !pPlayer || !pPlayer->IsAlive() || pPlayer->m_Shared.InCond( TF_COND_HALLOWEEN_GHOST_MODE ) )
+ {
+ bShouldDraw = false;
+ }
+ else if ( CTFMinigameLogic::GetMinigameLogic() && CTFMinigameLogic::GetMinigameLogic()->GetActiveMinigame() )
+ {
+ bShouldDraw = false;
+ }
+ else if ( TFGameRules() && TFGameRules()->ShowMatchSummary() )
+ {
+ bShouldDraw = false;
+ }
+ else if ( !m_pProgressBar )
+ {
+ bShouldDraw = false;
+ }
+ else if ( IsEnabled() )
+ {
+ bShouldDraw = CHudElement::ShouldDraw();
+ }
+ else
+ {
+ bShouldDraw = false;
+ }
+
+ if ( IsVisible() != bShouldDraw )
+ {
+ SetVisible( bShouldDraw );
+
+ if ( bShouldDraw )
+ {
+ // if we're going to be visible, redo our layout
+ InvalidateLayout( false, true );
+ }
+ }
+
+ return bShouldDraw;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudItemEffectMeter::Update( C_TFPlayer* pPlayer, const char* pSoundScript )
+{
+ if ( !IsEnabled() )
+ return;
+
+ if ( !m_pProgressBar )
+ return;
+
+ if ( !pPlayer )
+ return;
+
+ // Progress counts override progress bars.
+ int iCount = GetCount();
+ if ( iCount >= 0 )
+ {
+ if ( ShowPercentSymbol() )
+ {
+ SetDialogVariable( "progresscount", VarArgs( "%d%%", iCount ) );
+ }
+ else
+ {
+ SetDialogVariable( "progresscount", iCount );
+ }
+ }
+
+ float flProgress = GetProgress();
+
+ // Play a sound if we are refreshed.
+ if ( C_TFPlayer::GetLocalTFPlayer() && flProgress >= 1.f && m_flOldProgress < 1.f &&
+ pPlayer->IsAlive() && ShouldBeep() )
+ {
+ m_flOldProgress = flProgress;
+ C_TFPlayer::GetLocalTFPlayer()->EmitSound( pSoundScript );
+ }
+ else
+ {
+ m_flOldProgress = flProgress;
+ }
+
+ // Update the meter GUI element.
+ m_pProgressBar->SetProgress( flProgress );
+
+ // Flash the bar if this class implementation requires it.
+ if ( ShouldFlash() )
+ {
+ int color_offset = ((int)(gpGlobals->realtime*10)) % 10;
+ int red = 160 + (color_offset*10);
+ m_pProgressBar->SetFgColor( Color( red, 0, 0, 255 ) );
+ }
+ else
+ {
+ m_pProgressBar->SetFgColor( GetFgColor() );
+ }
+}
+
+const char* CHudItemEffectMeter::GetLabelText( void )
+{
+ CTFWeaponInvis *pWpn = (CTFWeaponInvis *)m_pPlayer->Weapon_OwnsThisID( TF_WEAPON_INVIS );
+ if ( pWpn )
+ {
+ if ( pWpn->HasFeignDeath() )
+ {
+ return "#TF_Feign";
+ }
+ else if ( pWpn->HasMotionCloak() )
+ {
+ return "#TF_CloakDagger";
+ }
+ }
+
+ return "#TF_CLOAK";
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+float CHudItemEffectMeter::GetProgress( void )
+{
+ if ( m_pPlayer )
+ return m_pPlayer->m_Shared.GetSpyCloakMeter() / 100.0f;
+ else
+ return 1.f;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Tracks the weapon's regen.
+//-----------------------------------------------------------------------------
+template <class T>
+CHudItemEffectMeter_Weapon<T>::CHudItemEffectMeter_Weapon( const char* pszElementName, C_TFPlayer* pPlayer, int iWeaponID, bool bBeeps, const char* pszResFile )
+ : CHudItemEffectMeter( pszElementName, pPlayer )
+{
+ m_iWeaponID = iWeaponID;
+ m_bBeeps = bBeeps;
+ m_pszResFile = pszResFile;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+template <class T>
+const char* CHudItemEffectMeter_Weapon<T>::GetResFile( void )
+{
+ if ( m_pszResFile )
+ {
+ return m_pszResFile;
+ }
+ else
+ {
+ return "resource/UI/HudItemEffectMeter.res";
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Caches the weapon reference.
+//-----------------------------------------------------------------------------
+template <class T>
+T* CHudItemEffectMeter_Weapon<T>::GetWeapon( void )
+{
+ if ( m_bEnabled && m_pPlayer && !m_pWeapon )
+ {
+ m_pWeapon = dynamic_cast<T*>( m_pPlayer->Weapon_OwnsThisID( m_iWeaponID ) );
+ if ( !m_pWeapon )
+ {
+ m_bEnabled = false;
+ }
+ }
+
+ return m_pWeapon;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+template <class T>
+bool CHudItemEffectMeter_Weapon<T>::IsEnabled( void )
+{
+ T *pWeapon = GetWeapon();
+ if ( pWeapon )
+ return true;
+
+ return CHudItemEffectMeter::IsEnabled();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+template <class T>
+float CHudItemEffectMeter_Weapon<T>::GetProgress( void )
+{
+ T *pWeapon = GetWeapon();
+ if ( pWeapon )
+ {
+ return pWeapon->GetProgress();
+ }
+ else
+ {
+ return 0.f;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+template <class T>
+void CHudItemEffectMeter_Weapon<T>::Update( C_TFPlayer* pPlayer, const char* pSoundScript )
+{
+ T *pWeapon = GetWeapon();
+ if ( pWeapon )
+ {
+ CTFSniperRifle *pRifle = dynamic_cast<CTFSniperRifle*>( pWeapon );
+ if ( pRifle && pRifle->GetBuffType() > 0 )
+ {
+ CHudItemEffectMeter::Update( pPlayer, "Weapon_Bison.SingleCrit" );
+ return;
+ }
+ }
+ CHudItemEffectMeter::Update( pPlayer, pSoundScript );
+}
+
+//-----------------------------------------------------------------------------
+template <class T>
+bool CHudItemEffectMeter_Weapon<T>::ShouldDraw( )
+{
+ return CHudItemEffectMeter::ShouldDraw();
+}
+//-----------------------------------------------------------------------------
+// Specializations for meters that do unique things follow...
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CTFWeaponBase>::IsEnabled( void )
+{
+ C_TFPlayer *pTFPlayer = C_TFPlayer::GetLocalTFPlayer();
+
+ if ( pTFPlayer )
+ {
+ int iKillStreak = 0;
+ CALL_ATTRIB_HOOK_INT_ON_OTHER( pTFPlayer, iKillStreak, killstreak_tier );
+ return iKillStreak != 0;
+ }
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+template <>
+int CHudItemEffectMeter_Weapon<CTFWeaponBase>::GetCount( void )
+{
+ C_TFPlayer *pTFPlayer = C_TFPlayer::GetLocalTFPlayer();
+
+ if ( pTFPlayer )
+ {
+ return pTFPlayer->m_Shared.GetStreak( CTFPlayerShared::kTFStreak_Kills );
+ }
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+template <>
+const char* CHudItemEffectMeter_Weapon<CTFWeaponBase>::GetLabelText( void )
+{
+ return "TF_KillStreak";
+}
+
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CTFWeaponBase>::IsKillstreakMeter( void )
+{
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Specialization for the sword (to differentiate it from other sword-type weapons)
+//-----------------------------------------------------------------------------
+template <>
+CTFSword* CHudItemEffectMeter_Weapon<CTFSword>::GetWeapon( void )
+{
+ if ( m_bEnabled && m_pPlayer && !m_pWeapon )
+ {
+ m_pWeapon = dynamic_cast<CTFSword*>( m_pPlayer->Weapon_OwnsThisID( m_iWeaponID ) );
+
+ if ( m_pWeapon && !m_pWeapon->CanDecapitate() )
+ m_pWeapon = NULL;
+
+ if ( !m_pWeapon )
+ {
+ m_bEnabled = false;
+ }
+ }
+
+ return m_pWeapon;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Specialization for demoman head count.
+//-----------------------------------------------------------------------------
+template <>
+int CHudItemEffectMeter_Weapon<CTFSword>::GetCount( void )
+{
+ CTFSword *pWeapon = GetWeapon();
+ if ( pWeapon )
+ {
+ return pWeapon->GetCount();
+ }
+ else
+ {
+ return 0.f;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Soldier buff charge bar specialization for flashing...
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CTFBuffItem>::ShouldFlash( void )
+{
+ CTFBuffItem *pWeapon = GetWeapon();
+ if ( pWeapon )
+ {
+ return pWeapon->EffectMeterShouldFlash();
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CTFBuffItem>::ShouldDraw()
+{
+ if ( !m_pPlayer )
+ return false;
+
+ CTFBuffItem *pWeapon = GetWeapon();
+ if ( !pWeapon )
+ return false;
+
+ // do not draw for the parachute
+ if ( pWeapon->GetBuffType() == EParachute )
+ return false;
+
+ return CHudItemEffectMeter::ShouldDraw();
+}
+
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CTFFlameThrower>::IsEnabled( void )
+{
+ if ( !m_pPlayer )
+ return false;
+
+ CTFFlameThrower *pWeapon = GetWeapon();
+ if ( !pWeapon )
+ return false;
+
+ return ( pWeapon->GetBuffType() > 0 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Pyro rage bar specialization for flashing...
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CTFFlameThrower>::ShouldFlash( void )
+{
+ CTFFlameThrower *pWeapon = GetWeapon();
+ if ( pWeapon )
+ {
+ return pWeapon->EffectMeterShouldFlash();
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Soda Popper Flash
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CTFSodaPopper>::ShouldFlash( void )
+{
+ if ( !m_pPlayer )
+ return false;
+
+ return m_pPlayer->m_Shared.GetScoutHypeMeter() >= 100.0f;
+}
+
+//-----------------------------------------------------------------------------
+// Charged SMG Flash
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CTFChargedSMG>::ShouldFlash( void )
+{
+ if ( !m_pPlayer )
+ return false;
+
+ CTFChargedSMG* pWeapon = GetWeapon();
+ if ( !pWeapon )
+ return false;
+
+ return pWeapon->ShouldFlashChargeBar();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Heavy rage bar in MvM
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon< CTFMinigun >::IsEnabled( void )
+{
+ if ( !m_pPlayer )
+ return false;
+
+ CTFMinigun *pWeapon = GetWeapon();
+ if ( !pWeapon )
+ return false;
+
+ bool bVisible = false;
+
+ float fKillComboFireRateBoost = 0.0f;
+ CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( pWeapon, fKillComboFireRateBoost, kill_combo_fire_rate_boost );
+ if ( fKillComboFireRateBoost > 0.0f )
+ {
+ m_pLabel->SetVisible( false );
+ m_pProgressBar->SetVisible( false );
+ bVisible = true;
+ }
+
+ int iRage = 0;
+ CALL_ATTRIB_HOOK_INT_ON_OTHER( m_pPlayer, iRage, generate_rage_on_dmg );
+ if ( iRage )
+ {
+ m_pLabel->SetVisible( true );
+ m_pProgressBar->SetVisible( true );
+ bVisible = true;
+ }
+
+ return bVisible;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon< CTFMinigun >::ShouldFlash( void )
+{
+ CTFMinigun *pWeapon = GetWeapon();
+ if ( pWeapon )
+ {
+ return pWeapon->EffectMeterShouldFlash();
+ }
+ else
+ {
+ return false;
+ }
+}
+
+static const char *pszClassIcons[] = {
+ "",
+ "../hud/leaderboard_class_scout",
+ "../hud/leaderboard_class_sniper",
+ "../hud/leaderboard_class_soldier",
+ "../hud/leaderboard_class_demo",
+ "../hud/leaderboard_class_medic",
+ "../hud/leaderboard_class_heavy",
+ "../hud/leaderboard_class_pyro",
+ "../hud/leaderboard_class_spy",
+ "../hud/leaderboard_class_engineer",
+};
+
+template <>
+void CHudItemEffectMeter_Weapon< CTFMinigun >::Update( C_TFPlayer* pPlayer, const char* pSoundScript )
+{
+ CTFMinigun *pWeapon = GetWeapon();
+ if ( pWeapon )
+ {
+ float fKillComboFireRateBoost = 0.0f;
+ CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( pWeapon, fKillComboFireRateBoost, kill_combo_fire_rate_boost );
+ if ( fKillComboFireRateBoost > 0.0f )
+ {
+ SetControlVisible( "ItemEffectMeterLabel2", true );
+
+ int nKillComboClass = pWeapon->GetKillComboClass();
+ int nKillComboCount = pWeapon->GetKillComboCount();
+
+ ImagePanel *( pImagePanel[3] ) =
+ {
+ assert_cast< ImagePanel* >( FindChildByName( "KillComboClassIcon1" ) ),
+ assert_cast< ImagePanel* >( FindChildByName( "KillComboClassIcon2" ) ),
+ assert_cast< ImagePanel* >( FindChildByName( "KillComboClassIcon3" ) )
+ };
+
+ for ( int i = 0; i < ARRAYSIZE( pImagePanel ); ++i )
+ {
+ if ( !pImagePanel[i] )
+ continue;
+
+ if ( nKillComboCount > i )
+ {
+ pImagePanel[i]->SetImage( pszClassIcons[nKillComboClass] );
+ pImagePanel[i]->SetVisible( true );
+ }
+ else
+ {
+ pImagePanel[i]->SetVisible( false );
+ }
+ }
+ }
+ else
+ {
+ SetControlVisible( "ItemEffectMeterLabel2", false );
+ SetControlVisible( "KillComboClassIcon1", false );
+ SetControlVisible( "KillComboClassIcon2", false );
+ SetControlVisible( "KillComboClassIcon3", false );
+ }
+ }
+ CHudItemEffectMeter::Update( pPlayer, pSoundScript );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Specialization for engineer revenge count.
+//-----------------------------------------------------------------------------
+template <>
+int CHudItemEffectMeter_Weapon<CTFShotgun_Revenge>::GetCount( void )
+{
+ CTFShotgun_Revenge *pWeapon = GetWeapon();
+ if ( pWeapon )
+ {
+ return pWeapon->GetCount();
+ }
+ else
+ {
+ return 0.f;
+ }
+}
+
+template <>
+bool CHudItemEffectMeter_Weapon<CTFFlareGun_Revenge>::IsEnabled( void )
+{
+ if ( !m_pPlayer )
+ return false;
+
+ CTFFlareGun_Revenge *pWeapon = GetWeapon();
+ return pWeapon && pWeapon->IsActiveByLocalPlayer();
+}
+
+template <>
+int CHudItemEffectMeter_Weapon<CTFFlareGun_Revenge>::GetCount( void )
+{
+ CTFFlareGun_Revenge *pWeapon = GetWeapon();
+ if ( pWeapon )
+ {
+ return pWeapon->GetCount();
+ }
+ else
+ {
+ return 0.f;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+template <>
+int CHudItemEffectMeter_Weapon<CTFSniperRifleDecap>::GetCount( void )
+{
+ CTFSniperRifleDecap *pWeapon = GetWeapon();
+ if ( pWeapon )
+ {
+ return pWeapon->GetCount();
+ }
+ else
+ {
+ return 0.f;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+template <>
+Color CHudItemEffectMeter_Weapon<CTFParticleCannon>::GetFgColor( void )
+{
+ CTFParticleCannon *pWeapon = GetWeapon();
+
+ if ( pWeapon && pWeapon->CanChargeFire() )
+ return Color( 255, 255, 255, 255 );
+ else
+ return Color( 255, 0, 0, 255 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+template <>
+int CHudItemEffectMeter_Weapon<CTFRevolver>::GetCount( void )
+{
+ CTFRevolver *pWeapon = GetWeapon();
+ if ( pWeapon )
+ {
+ return pWeapon->GetCount();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CTFRevolver>::IsEnabled( void )
+{
+ CTFRevolver *pWeapon = GetWeapon();
+ if ( pWeapon )
+ {
+ int iExtraDamageOnHit = 0;
+ CALL_ATTRIB_HOOK_INT_ON_OTHER( pWeapon, iExtraDamageOnHit, extra_damage_on_hit );
+ return pWeapon->SapperKillsCollectCrits() || iExtraDamageOnHit;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CTFRevolver>::ShowPercentSymbol( void )
+{
+ CTFRevolver *pWeapon = GetWeapon();
+ if ( pWeapon )
+ {
+ int iExtraDamageOnHit = 0;
+ CALL_ATTRIB_HOOK_INT_ON_OTHER( pWeapon, iExtraDamageOnHit, extra_damage_on_hit );
+ return iExtraDamageOnHit;
+ }
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CTFKnife>::IsEnabled( void )
+{
+ CTFKnife *pWeapon = GetWeapon();
+ if ( pWeapon )
+ {
+ return pWeapon->GetKnifeType() == KNIFE_ICICLE;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CTFSniperRifle>::IsEnabled( void )
+{
+ if ( !m_pPlayer )
+ return false;
+
+ CTFSniperRifle *pWeapon = GetWeapon();
+ if ( !pWeapon )
+ return false;
+
+ return ( pWeapon->GetBuffType() > 0 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CTFSniperRifle>::ShouldFlash( void )
+{
+ CTFSniperRifle *pWeapon = GetWeapon();
+ if ( pWeapon )
+ {
+ return pWeapon->EffectMeterShouldFlash();
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<C_TFWeaponBuilder>::IsEnabled( void )
+{
+ if ( !m_pPlayer )
+ return false;
+
+ return ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<C_TFWeaponBuilder>::ShouldBeep( void )
+{
+ if ( !m_pPlayer )
+ return false;
+
+ int iRoboSapper = 0;
+ CALL_ATTRIB_HOOK_INT_ON_OTHER( m_pPlayer, iRoboSapper, robo_sapper );
+
+ return ( iRoboSapper > 0 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<C_TFWeaponBuilder>::ShouldFlash( void )
+{
+ if ( !m_pPlayer )
+ return false;
+
+ C_TFWeaponBuilder *pWeapon = GetWeapon();
+ if ( pWeapon )
+ {
+ return pWeapon->EffectMeterShouldFlash();
+ }
+ else
+ {
+ return false;
+ }
+}
+
+template <>
+CTFPowerupBottle* CHudItemEffectMeter_Weapon<CTFPowerupBottle>::GetWeapon( void )
+{
+ if ( m_bEnabled && m_pPlayer && !m_pWeapon )
+ {
+ for ( int i = 0; i < m_pPlayer->GetNumWearables(); ++i )
+ {
+ m_pWeapon = dynamic_cast<CTFPowerupBottle*>( m_pPlayer->GetWearable( i ) );
+ if ( m_pWeapon )
+ {
+ break;
+ }
+ }
+
+ if ( !m_pWeapon )
+ {
+ m_bEnabled = false;
+ }
+ }
+
+ return m_pWeapon;
+}
+
+template <>
+bool CHudItemEffectMeter_Weapon<CTFPowerupBottle>::IsEnabled( void )
+{
+ if ( !m_pPlayer )
+ return false;
+
+ CTFPowerupBottle *pPowerupBottle = GetWeapon();
+ if ( pPowerupBottle )
+ {
+ return ( pPowerupBottle->GetNumCharges() > 0 );
+ }
+
+ return false;
+}
+
+template <>
+int CHudItemEffectMeter_Weapon<CTFPowerupBottle>::GetCount( void )
+{
+ CTFPowerupBottle *pPowerupBottle = GetWeapon();
+ if ( pPowerupBottle )
+ {
+ return pPowerupBottle->GetNumCharges();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+template <>
+const char* CHudItemEffectMeter_Weapon<CTFPowerupBottle>::GetIconName( void )
+{
+ CTFPowerupBottle *pPowerupBottle = GetWeapon();
+ if ( pPowerupBottle )
+ {
+ return pPowerupBottle->GetEffectIconName();
+ }
+
+ return CHudItemEffectMeter::GetIconName();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Medic "rage" bar in MvM
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon< CWeaponMedigun >::IsEnabled( void )
+{
+ if ( !m_pPlayer )
+ return false;
+
+ int iRage = 0;
+ CALL_ATTRIB_HOOK_INT_ON_OTHER( m_pPlayer, iRage, generate_rage_on_heal );
+ if ( !iRage )
+ return false;
+
+ CWeaponMedigun *pWeapon = GetWeapon();
+ if ( !pWeapon )
+ return false;
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CWeaponMedigun>::ShouldFlash( void )
+{
+ CWeaponMedigun *pWeapon = GetWeapon();
+ if ( pWeapon )
+ {
+ return pWeapon->EffectMeterShouldFlash();
+ }
+ else
+ {
+ return false;
+ }
+}
+
+#ifdef STAGING_ONLY
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon< CTFWeaponPDA_Spy_Build >::IsEnabled( void )
+{
+ if ( !m_pPlayer )
+ return false;
+
+ if ( !m_pPlayer->m_Shared.CanBuildSpyTraps() )
+ return false;
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Specialization for Spy traps in MvM
+//-----------------------------------------------------------------------------
+template <>
+int CHudItemEffectMeter_Weapon< CTFWeaponPDA_Spy_Build >::GetCount( void )
+{
+ if ( !m_pPlayer )
+ return false;
+
+ return m_pPlayer->GetAmmoCount( TF_AMMO_GRENADES1 );
+}
+#endif // STAGING_ONLY
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon< CTFLunchBox >::IsEnabled( void )
+{
+ return CHudItemEffectMeter::IsEnabled();
+}
+
+//-----------------------------------------------------------------------------
+// CTFThrowable
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CTFThrowable>::IsEnabled( void )
+{
+ CTFThrowable *pWep = dynamic_cast<CTFThrowable*>( GetWeapon() );
+ if ( pWep )
+ {
+ return pWep->ShowHudElement();
+ }
+ return false;
+}
+
+CHudItemEffectMeter_Rune::CHudItemEffectMeter_Rune( const char *pszElementName, C_TFPlayer* pPlayer ) : CHudItemEffectMeter( pszElementName, pPlayer )
+{
+
+}
+
+//-------------------------------------------------------------------------------
+bool CHudItemEffectMeter_Rune::IsEnabled( void )
+{
+ return m_pPlayer && m_pPlayer->m_Shared.CanRuneCharge();
+}
+
+//-------------------------------------------------------------------------------
+float CHudItemEffectMeter_Rune::GetProgress( void )
+{
+ if ( m_pPlayer )
+ return m_pPlayer->m_Shared.GetRuneCharge() / 100.0f;
+ return 0;
+}
+
+//-------------------------------------------------------------------------------
+bool CHudItemEffectMeter_Rune::ShouldFlash( void )
+{
+ if ( m_pPlayer )
+ return m_pPlayer->m_Shared.IsRuneCharged();
+ return false;
+}
+
+//-------------------------------------------------------------------------------
+bool CHudItemEffectMeter_Rune::ShouldDraw( void )
+{
+ return m_pPlayer && m_pPlayer->m_Shared.CanRuneCharge();
+}
+
+#ifdef STAGING_ONLY
+//---------------------------------------------------------------------------------------------------------------------------
+// SPACE JUMPS
+//---------------------------------------------------------------------------------------------------------------------------
+CHudItemEffectMeter_SpaceJump::CHudItemEffectMeter_SpaceJump( const char *pszElementName, C_TFPlayer* pPlayer ) : CHudItemEffectMeter( pszElementName, pPlayer )
+{
+
+}
+
+//-------------------------------------------------------------------------------
+bool CHudItemEffectMeter_SpaceJump::IsEnabled( void )
+{
+// if ( m_pPlayer && m_pPlayer->m_Shared.InCond( TF_COND_SPACE_GRAVITY ) )
+// return true;
+ return false;
+}
+//-------------------------------------------------------------------------------
+float CHudItemEffectMeter_SpaceJump::GetProgress( void )
+{
+ if ( m_pPlayer )
+ return m_pPlayer->m_Shared.GetSpaceJumpChargeMeter() / 100.0f;
+ return 0;
+}
+//-------------------------------------------------------------------------------
+bool CHudItemEffectMeter_SpaceJump::ShouldDraw( void )
+{
+// if ( m_pPlayer && m_pPlayer->m_Shared.InCond( TF_COND_SPACE_GRAVITY ) )
+// return true;
+ return false;
+}
+//-----------------------------------------------------------------------------
+// Purpose: TRANQ
+//------------------------------------------------------------------------------
+CHudItemEffectMeter_Tranq::CHudItemEffectMeter_Tranq( const char *pszElementName, C_TFPlayer* pPlayer ) : CHudItemEffectMeter( pszElementName, pPlayer )
+{
+
+}
+//------------------------------------------------------------------------------
+float CHudItemEffectMeter_Tranq::GetProgress( void )
+{
+ int iTranq = 0;
+ CALL_ATTRIB_HOOK_INT_ON_OTHER( m_pPlayer, iTranq, override_projectile_type );
+ if ( iTranq == TF_PROJECTILE_TRANQ )
+ {
+ float flDuration = Min( 60.0f, (float)m_pPlayer->m_Shared.m_flSpyTranqBuffDuration );
+ return flDuration / 60.0f;
+ }
+
+ return 0.0f;
+}
+//-----------------------------------------------------------------------------
+bool CHudItemEffectMeter_Tranq::IsEnabled( void )
+{
+ int iTranq = 0;
+ CALL_ATTRIB_HOOK_INT_ON_OTHER( m_pPlayer, iTranq, override_projectile_type );
+ return ( iTranq == TF_PROJECTILE_TRANQ );
+}
+
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CTFCrossbow>::IsEnabled( void )
+{
+ int iMilkBolt = 0;
+ CALL_ATTRIB_HOOK_INT_ON_OTHER( m_pPlayer, iMilkBolt, fires_milk_bolt );
+ return ( iMilkBolt > 0 );
+}
+
+#endif // STAGING_ONLY
+
+//-----------------------------------------------------------------------------
+// Rocket Launcher AirStrike Headcounter
+//-----------------------------------------------------------------------------
+template <>
+int CHudItemEffectMeter_Weapon<CTFRocketLauncher_AirStrike>::GetCount( void )
+{
+ CTFRocketLauncher_AirStrike *pWeapon = GetWeapon();
+ if ( pWeapon )
+ {
+ return pWeapon->GetCount();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CTFSpellBook>::IsEnabled( void )
+{
+ if ( !m_pPlayer )
+ return false;
+
+ if ( !m_pPlayer->m_Shared.InCond( TF_COND_HALLOWEEN_KART ) )
+ return false;
+
+ CTFSpellBook *pWep = dynamic_cast<CTFSpellBook*>( GetWeapon() );
+ if ( pWep )
+ {
+ return true;
+ }
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+template <>
+float CHudItemEffectMeter_Weapon<CTFSpellBook>::GetProgress( void )
+{
+ if ( !m_pPlayer )
+ return 0;
+
+ if ( !m_pPlayer->m_Shared.InCond( TF_COND_HALLOWEEN_KART ) )
+ return 0;
+
+ return m_pPlayer->GetKartSpeedBoost();
+}
+
+//-----------------------------------------------------------------------------
+template <>
+int CHudItemEffectMeter_Weapon<CTFSpellBook>::GetCount( void )
+{
+ if ( !m_pPlayer )
+ return 0;
+
+ if ( !m_pPlayer->m_Shared.InCond( TF_COND_HALLOWEEN_KART ) )
+ return 0;
+
+ return m_pPlayer->GetKartHealth();
+}
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CTFSpellBook>::ShowPercentSymbol( void )
+{
+ return true;
+}
+//-----------------------------------------------------------------------------
+template <>
+bool CHudItemEffectMeter_Weapon<CTFSpellBook>::ShouldDraw( void )
+{
+ if ( CTFMinigameLogic::GetMinigameLogic() && CTFMinigameLogic::GetMinigameLogic()->GetActiveMinigame() )
+ {
+ if ( m_pPlayer && m_pPlayer->m_Shared.InCond( TF_COND_HALLOWEEN_GHOST_MODE ) )
+ return false;
+
+ IViewPortPanel *scoreboard = gViewPortInterface->FindPanelByName( PANEL_SCOREBOARD );
+ if ( scoreboard && scoreboard->IsVisible() )
+ return false;
+
+ if ( TFGameRules() && ( TFGameRules()->State_Get() != GR_STATE_RND_RUNNING ) )
+ return false;
+
+ return true;
+ }
+
+ if ( TFGameRules() && TFGameRules()->ShowMatchSummary() )
+ {
+ return false;
+ }
+
+ return CHudItemEffectMeter::ShouldDraw();
+}