//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //============================================================================= #include "cbase.h" #include "hud.h" #include "hudelement.h" #include "c_tf_player.h" #include "iclientmode.h" #include "ienginevgui.h" #include #include #include #include #include #include "tf_weapon_medigun.h" #include #include "tf_imagepanel.h" #include "vgui_controls/Label.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" using namespace vgui; extern ConVar weapon_medigun_resist_num_chunks; //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- class CHudMedicChargeMeter : public CHudElement, public EditablePanel { DECLARE_CLASS_SIMPLE( CHudMedicChargeMeter, EditablePanel ); public: CHudMedicChargeMeter( const char *pElementName ); virtual void ApplySchemeSettings( IScheme *scheme ); virtual bool ShouldDraw( void ); virtual void OnTick( void ); private: void UpdateKnownChargeType( bool bForce ); void UpdateControlVisibility(); vgui::ContinuousProgressBar* m_pChargeMeter; CTFImagePanel* m_pResistPanel; CUtlVector m_vecpChargeMeters; Label* m_pUberchargeLabel; Label* m_pUberchargeCountLabel; bool m_bCharged; float m_flLastChargeValue; int m_nLastActiveResist; medigun_weapontypes_t m_eLastKnownMedigunType; }; DECLARE_HUDELEMENT( CHudMedicChargeMeter ); struct ResistIcons_t { const char* m_pzsRed; const char* m_pzsBlue; }; static ResistIcons_t g_ResistIcons[MEDIGUN_NUM_RESISTS] = { { "../HUD/defense_buff_bullet_blue", "../HUD/defense_buff_bullet_red" }, { "../HUD/defense_buff_explosion_blue", "../HUD/defense_buff_explosion_red" }, { "../HUD/defense_buff_fire_blue", "../HUD/defense_buff_fire_red" }, }; //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- CHudMedicChargeMeter::CHudMedicChargeMeter( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudMedicCharge" ) { Panel *pParent = g_pClientMode->GetViewport(); SetParent( pParent ); m_pChargeMeter = new ContinuousProgressBar( this, "ChargeMeter" ); for( int i=0; iSetVisible( false ); SetHiddenBits( HIDEHUD_MISCSTATUS ); vgui::ivgui()->AddTickSignal( GetVPanel() ); m_bCharged = false; m_flLastChargeValue = -1; m_eLastKnownMedigunType = MEDIGUN_STANDARD; m_nLastActiveResist = MEDIGUN_BULLET_RESIST; SetDialogVariable( "charge", 0 ); SetDialogVariable( "charge_count", 0 ); RegisterForRenderGroup( "inspect_panel" ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHudMedicChargeMeter::ApplySchemeSettings( IScheme *pScheme ) { // load control settings... LoadControlSettings( "resource/UI/HudMedicCharge.res" ); m_pUberchargeLabel = dynamic_cast( FindChildByName("ChargeLabel") ); Assert( m_pUberchargeLabel ); m_pUberchargeCountLabel = dynamic_cast( FindChildByName("IndividualChargesLabel") ); Assert( m_pUberchargeCountLabel ); if( m_pUberchargeCountLabel ) { m_pUberchargeCountLabel->SetVisible( false ); } for( int i=0; iSetVisible( false ); } m_pResistPanel->SetVisible( false ); // Figure out which controls to show UpdateKnownChargeType( true ); BaseClass::ApplySchemeSettings( pScheme ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool CHudMedicChargeMeter::ShouldDraw( void ) { C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( !pPlayer || !pPlayer->IsPlayerClass( TF_CLASS_MEDIC ) || !pPlayer->IsAlive() ) { return false; } CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon(); if ( !pWpn ) { return false; } if ( pWpn->GetWeaponID() != TF_WEAPON_MEDIGUN && pWpn->GetWeaponID() != TF_WEAPON_BONESAW && !( pWpn->GetWeaponID() == TF_WEAPON_SYRINGEGUN_MEDIC && pWpn->UberChargeAmmoPerShot() > 0.0f ) ) { return false; } return CHudElement::ShouldDraw(); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHudMedicChargeMeter::OnTick( void ) { C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( !pPlayer ) return; CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon(); // Might have switched medigun types UpdateKnownChargeType( false); if ( !pWpn ) return; if ( pWpn->GetWeaponID() == TF_WEAPON_BONESAW || ( pWpn->GetWeaponID() == TF_WEAPON_SYRINGEGUN_MEDIC && pWpn->UberChargeAmmoPerShot() > 0.0f ) ) { pWpn = pPlayer->Weapon_OwnsThisID( TF_WEAPON_MEDIGUN ); } if ( !pWpn || ( pWpn->GetWeaponID() != TF_WEAPON_MEDIGUN ) ) return; CWeaponMedigun *pMedigun = assert_cast< CWeaponMedigun *>( pWpn ); // We need to update the resist that we show here. Only do so if the medigun is actually // the gun that's eruipped if( pMedigun->GetMedigunType() == MEDIGUN_RESIST && pPlayer->GetActiveTFWeapon() == pMedigun ) { int nCurrentActiveResist = pMedigun->GetResistType(); CBaseEntity* pOwner = pMedigun->GetOwner(); // Figure out which image to show based on team const char* pzsImage = g_ResistIcons[nCurrentActiveResist].m_pzsBlue; if( pOwner && pOwner->GetTeamNumber() == TF_TEAM_BLUE ) { pzsImage = g_ResistIcons[nCurrentActiveResist].m_pzsRed; } // Resist Medigun is equipped. Update visibulity m_pResistPanel->SetVisible( true ); m_pResistPanel->MoveToFront(); m_pResistPanel->SetPos( 0, 0 ); m_pResistPanel->SetImage( pzsImage ); } else { m_pResistPanel->SetVisible( false ); } float flCharge = pMedigun->GetChargeLevel(); if ( flCharge != m_flLastChargeValue ) { if( pMedigun->GetMedigunType() == MEDIGUN_RESIST ) { float flChunkSize = 1.f / weapon_medigun_resist_num_chunks.GetFloat(); for( int i=0; iIsReleasingCharge() ) { m_vecpChargeMeters[i]->SetFgColor( Color( 190, 190, 190, 255 ) ); } else // Full bars are white { m_vecpChargeMeters[i]->SetFgColor( Color( 255, 255, 255, 255 ) ); } m_vecpChargeMeters[i]->SetProgress( flProgress ); } // We want to count full bars SetDialogVariable( "charge_count", int(floor(flCharge / flChunkSize)) ); } else if ( m_pChargeMeter ) // Regular uber { m_pChargeMeter->SetProgress( flCharge ); SetDialogVariable( "charge", (int)( flCharge * 100 ) ); } if ( !m_bCharged ) { if ( flCharge >= 1.0 ) { g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "HudMedicCharged" ); m_bCharged = true; } } else { // we've got invuln charge or we're using our invuln if ( !pMedigun->IsReleasingCharge() ) { g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "HudMedicChargedStop" ); m_bCharged = false; } } } m_flLastChargeValue = flCharge; } void CHudMedicChargeMeter::UpdateKnownChargeType( bool bForce ) { C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( !pPlayer ) return; CTFWeaponBase *pWpn = pPlayer->Weapon_OwnsThisID( TF_WEAPON_MEDIGUN ); if( !pWpn ) return; CWeaponMedigun *pMedigun = static_cast< CWeaponMedigun *>( pWpn ); if( pMedigun->GetMedigunType() != m_eLastKnownMedigunType || bForce ) { m_eLastKnownMedigunType = (medigun_weapontypes_t)pMedigun->GetMedigunType(); UpdateControlVisibility(); } } void CHudMedicChargeMeter::UpdateControlVisibility() { C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( !pPlayer ) return; CTFWeaponBase *pWpn = pPlayer->Weapon_OwnsThisID( TF_WEAPON_MEDIGUN ); if ( !pWpn || ( pWpn->GetWeaponID() != TF_WEAPON_MEDIGUN ) ) return; CWeaponMedigun *pMedigun = static_cast< CWeaponMedigun *>( pWpn ); if ( !pMedigun ) return; bool bResistMedigun = m_eLastKnownMedigunType == MEDIGUN_RESIST; // Using the resist medigun if( !bResistMedigun ) { m_pResistPanel->SetVisible( false ); } // Conditionally show the medigun chunks for( int i=0; iSetVisible( bResistMedigun ); } m_pChargeMeter->SetVisible( !bResistMedigun ); if( m_pUberchargeLabel ) { m_pUberchargeLabel->SetVisible( !bResistMedigun ); } if( m_pUberchargeCountLabel ) { m_pUberchargeCountLabel->SetVisible( bResistMedigun ); } }