mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-14 20:56:56 +00:00
1
This commit is contained in:
@@ -0,0 +1,346 @@
|
||||
//========= 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 <vgui/ILocalize.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include <vgui/IVGui.h>
|
||||
#include <vgui_controls/EditablePanel.h>
|
||||
#include <vgui_controls/ProgressBar.h>
|
||||
#include "tf_weapon_medigun.h"
|
||||
#include <vgui_controls/AnimationController.h>
|
||||
#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<vgui::ContinuousProgressBar*> 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; i<weapon_medigun_resist_num_chunks.GetInt(); ++i )
|
||||
{
|
||||
m_vecpChargeMeters.AddToTail( new ContinuousProgressBar( this, CFmtStr( "ChargeMeter%d", i+1 ) ) );
|
||||
}
|
||||
|
||||
m_pResistPanel = new CTFImagePanel( this, "ResistIcon" );
|
||||
m_pResistPanel->SetVisible( 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<Label*>( FindChildByName("ChargeLabel") );
|
||||
Assert( m_pUberchargeLabel );
|
||||
|
||||
m_pUberchargeCountLabel = dynamic_cast<Label*>( FindChildByName("IndividualChargesLabel") );
|
||||
Assert( m_pUberchargeCountLabel );
|
||||
if( m_pUberchargeCountLabel )
|
||||
{
|
||||
m_pUberchargeCountLabel->SetVisible( false );
|
||||
}
|
||||
|
||||
for( int i=0; i<weapon_medigun_resist_num_chunks.GetInt(); ++i )
|
||||
{
|
||||
m_vecpChargeMeters[i]->SetVisible( 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; i<weapon_medigun_resist_num_chunks.GetInt(); ++i )
|
||||
{
|
||||
float flChunkCharge = flCharge - (flChunkSize * i);
|
||||
float flProgress = MIN(flChunkCharge, flChunkSize) / flChunkSize;
|
||||
|
||||
// Not-full bars are dimmed a bit
|
||||
if( flProgress < 1.f && !pMedigun->IsReleasingCharge() )
|
||||
{
|
||||
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; i<m_vecpChargeMeters.Count(); ++i )
|
||||
{
|
||||
m_vecpChargeMeters[i]->SetVisible( bResistMedigun );
|
||||
}
|
||||
|
||||
m_pChargeMeter->SetVisible( !bResistMedigun );
|
||||
if( m_pUberchargeLabel )
|
||||
{
|
||||
m_pUberchargeLabel->SetVisible( !bResistMedigun );
|
||||
}
|
||||
if( m_pUberchargeCountLabel )
|
||||
{
|
||||
m_pUberchargeCountLabel->SetVisible( bResistMedigun );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user