summaryrefslogtreecommitdiff
path: root/game/client/tf/tf_hud_building_status.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/tf/tf_hud_building_status.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/client/tf/tf_hud_building_status.cpp')
-rw-r--r--game/client/tf/tf_hud_building_status.cpp1720
1 files changed, 1720 insertions, 0 deletions
diff --git a/game/client/tf/tf_hud_building_status.cpp b/game/client/tf/tf_hud_building_status.cpp
new file mode 100644
index 0000000..e27637b
--- /dev/null
+++ b/game/client/tf/tf_hud_building_status.cpp
@@ -0,0 +1,1720 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: HUD Target ID element
+//
+// $NoKeywords: $
+//=============================================================================
+#include "cbase.h"
+#include "hud.h"
+#include "iclientmode.h"
+#include "c_baseobject.h"
+#include "c_tf_player.h"
+#include "ienginevgui.h"
+#include "vgui/ILocalize.h"
+#include "vgui/ISurface.h"
+#include <vgui/IVGui.h>
+#include <vgui_controls/ProgressBar.h>
+#include <vgui_controls/AnimationController.h>
+#include "game_controls/IconPanel.h"
+#include "teamplay_round_timer.h"
+
+#include "tf_hud_building_status.h"
+
+#include "c_obj_sentrygun.h"
+#include "c_obj_dispenser.h"
+#include "c_obj_teleporter.h"
+#include "c_obj_sapper.h"
+
+#include "tf_gamerules.h"
+#include "tf_logic_halloween_2014.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+class C_ObjectSentrygun;
+
+extern CUtlVector<int> g_TeamRoundTimers;
+
+using namespace vgui;
+
+ConVar tf_hud_num_building_alert_beeps( "tf_hud_num_building_alert_beeps", "2", FCVAR_ARCHIVE, "Number of times to play warning sound when a new alert displays on building hud objects", true, 0, false, 0 );
+
+//============================================================================
+
+DECLARE_BUILD_FACTORY( CBuildingHealthBar );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CBuildingHealthBar::CBuildingHealthBar(Panel *parent, const char *panelName) : vgui::ProgressBar( parent, panelName )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBuildingHealthBar::Paint()
+{
+ if ( _progress < 0.5 )
+ {
+ SetFgColor( m_cLowHealthColor );
+ }
+ else
+ {
+ SetFgColor( m_cHealthColor );
+ }
+
+ BaseClass::Paint();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBuildingHealthBar::PaintBackground()
+{
+ // save progress and real fg color
+ float flProgress = _progress;
+ Color fgColor = GetFgColor();
+
+ // stuff our fake info
+ _progress = 1.0;
+ SetFgColor( GetBgColor() );
+
+ BaseClass::Paint();
+
+ // restore actual progress / color
+ _progress = flProgress;
+ SetFgColor( fgColor );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBuildingHealthBar::ApplySchemeSettings(vgui::IScheme *pScheme)
+{
+ BaseClass::ApplySchemeSettings(pScheme);
+
+ SetBgColor(GetSchemeColor("BuildingHealthBar.BgColor", pScheme));
+ m_cHealthColor = GetSchemeColor("BuildingHealthBar.Health", pScheme);
+ m_cLowHealthColor = GetSchemeColor("BuildingHealthBar.LowHealth", pScheme);
+ SetBorder(NULL);
+}
+
+//============================================================================
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CBuildingStatusItem::CBuildingStatusItem( Panel *parent, const char *szLayout, int iObjectType, int iObjectMode=0 ) :
+BaseClass( parent, "BuildingStatusItem" )
+{
+ SetProportional( true );
+
+ // Save our layout file for re-loading
+ Q_strncpy( m_szLayout, szLayout, sizeof(m_szLayout) );
+
+ // load control settings...
+ LoadControlSettings( szLayout );
+
+ SetPositioned( false );
+
+ m_pObject = NULL;
+ m_iObjectType = iObjectType;
+ m_iObjectMode = iObjectMode;
+
+ m_pBuiltPanel = new vgui::EditablePanel( this, "BuiltPanel" );
+ m_pNotBuiltPanel = new vgui::EditablePanel( this, "NotBuiltPanel" );
+
+ // sub panels
+ m_pBuildingPanel = new vgui::EditablePanel( m_pBuiltPanel, "BuildingPanel" );
+ m_pRunningPanel = new vgui::EditablePanel( m_pBuiltPanel, "RunningPanel" );
+
+ // Shared between All sub panels
+ m_pBackground = new CIconPanel( this, "Background" );
+
+ // Running and Building sub panels only
+ m_pHealthBar = new CBuildingHealthBar( m_pBuiltPanel, "Health" );
+ m_pHealthBar->SetSegmentInfo( YRES(1), YRES(3) );
+ m_pHealthBar->SetProgressDirection( ProgressBar::PROGRESS_NORTH );
+ m_pHealthBar->SetBarInset( 0 );
+
+ m_pBuildingProgress = new vgui::ContinuousProgressBar( m_pBuildingPanel, "BuildingProgress" );
+
+ m_pAlertTray = new CBuildingStatusAlertTray( m_pBuiltPanel, "AlertTray" );
+ m_pWrenchIcon = new CIconPanel( m_pBuiltPanel, "WrenchIcon" );
+ m_pSapperIcon = new CIconPanel( m_pBuiltPanel, "SapperIcon" );
+
+ m_pUpgradeIcons[0] = new CIconPanel( m_pBuiltPanel, "Icon_Upgrade_1" );
+ m_pUpgradeIcons[1] = new CIconPanel( m_pBuiltPanel, "Icon_Upgrade_2" );
+ m_pUpgradeIcons[2] = new CIconPanel( m_pBuiltPanel, "Icon_Upgrade_3" );
+
+ m_iUpgradeLevel = 1;
+
+ vgui::ivgui()->AddTickSignal( GetVPanel() );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem::ApplySchemeSettings( IScheme *pScheme )
+{
+ // This lets us use hud_reloadscheme to reload the status items
+ int x, y;
+ GetPos( x, y );
+
+ LoadControlSettings( m_szLayout );
+
+ SetPos( x, y );
+
+ BaseClass::ApplySchemeSettings( pScheme );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Calc visibility of subpanels
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem::PerformLayout( void )
+{
+ BaseClass::PerformLayout();
+
+ C_BaseObject *pObj = m_pObject.Get();
+
+ m_bActive = ( pObj != NULL );
+
+ m_pHealthBar->SetVisible( m_bActive );
+
+ m_pNotBuiltPanel->SetVisible( !m_bActive );
+ m_pBuiltPanel->SetVisible( m_bActive );
+
+ if ( pObj )
+ {
+ // redo the background
+ m_pBackground->SetIcon( GetBackgroundImage() );
+
+ if ( pObj->IsBuilding() )
+ {
+ m_pBuildingPanel->SetVisible( true );
+ m_pRunningPanel->SetVisible( false );
+
+ m_pUpgradeIcons[0]->SetVisible( false );
+ m_pUpgradeIcons[1]->SetVisible( false );
+ m_pUpgradeIcons[2]->SetVisible( false );
+ }
+ else
+ {
+ m_pBuildingPanel->SetVisible( false );
+ m_pRunningPanel->SetVisible( true );
+
+ int iUpgradeLevel = pObj->GetUpgradeLevel();
+
+ Assert( iUpgradeLevel >= 1 && iUpgradeLevel <= 3 );
+
+ m_pUpgradeIcons[0]->SetVisible( false );
+ m_pUpgradeIcons[1]->SetVisible( false );
+ m_pUpgradeIcons[2]->SetVisible( false );
+
+ // show the correct upgrade level icon
+ if ( !pObj->IsMiniBuilding() )
+ {
+ m_pUpgradeIcons[iUpgradeLevel-1]->SetVisible( true );
+ }
+ }
+ }
+ else
+ {
+ // redo the background
+ m_pBackground->SetIcon( GetInactiveBackgroundImage() );
+
+ if ( m_pAlertTray->IsTrayOut() )
+ {
+ m_pAlertTray->HideTray();
+ m_pWrenchIcon->SetVisible( false );
+ m_pSapperIcon->SetVisible( false );
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Setup
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem::LevelInit( void )
+{
+ if ( m_pAlertTray )
+ m_pAlertTray->LevelInit();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Setup
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem::SetObject( C_BaseObject *pObj )
+{
+ m_pObject = pObj;
+
+ Assert( !pObj || ( pObj && !pObj->IsMarkedForDeletion() ) );
+
+ if ( !pObj )
+ {
+ m_pAlertTray->HideTray();
+ m_pWrenchIcon->SetVisible( false );
+ m_pSapperIcon->SetVisible( false );
+ m_pAlertTray->SetAlertType( BUILDING_HUD_ALERT_NONE );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem::Paint( void )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem::PaintBackground( void )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+const char *CBuildingStatusItem::GetBackgroundImage( void )
+{
+ C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
+
+ const char *pResult = "obj_status_background_blue";
+
+ if ( !pLocalPlayer )
+ {
+ Assert( 0 );
+ return pResult;
+ }
+
+ switch( pLocalPlayer->GetTeamNumber() )
+ {
+ case TF_TEAM_BLUE:
+ pResult = "obj_status_background_blue";
+ break;
+ case TF_TEAM_RED:
+ pResult = "obj_status_background_red";
+ break;
+ default:
+ break;
+ }
+
+ return pResult;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+const char *CBuildingStatusItem::GetInactiveBackgroundImage( void )
+{
+ return "obj_status_background_disabled";
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem::OnTick()
+{
+ // We only tick while active and with a valid built object
+ C_BaseObject *pObj = GetRepresentativeObject();
+
+ if ( !pObj ) // implies not active
+ {
+ if ( m_bActive )
+ {
+ // we lost our object. force relayout to inactive mode
+ InvalidateLayout();
+
+ // tell our parent that we're gone
+ IGameEvent *event = gameeventmanager->CreateEvent( "building_info_changed" );
+ if ( event )
+ {
+ event->SetInt( "building_type", GetRepresentativeObjectType() );
+ event->SetInt( "object_mode", GetRepresentativeObjectMode() );
+ gameeventmanager->FireEventClientSide( event );
+ }
+ }
+
+ // We don't want to tick while inactive regardless
+ return;
+ }
+
+ float flHealth = (float)pObj->GetHealth() / (float)pObj->GetMaxHealth();
+
+ m_pHealthBar->SetProgress( flHealth );
+
+ if ( pObj->IsBuilding() )
+ {
+ m_pBuildingPanel->SetVisible( true );
+ m_pRunningPanel->SetVisible( false );
+
+ m_pBuildingProgress->SetProgress( pObj->GetPercentageConstructed() );
+ }
+ else
+ {
+ m_pBuildingPanel->SetVisible( false );
+ m_pRunningPanel->SetVisible( true );
+ }
+
+ // what is our current alert state?
+ BuildingHudAlert_t alertLevel = pObj->GetBuildingAlertLevel();
+
+ if ( alertLevel <= BUILDING_HUD_ALERT_NONE )
+ {
+ // if the tray is out, hide it
+ if ( m_pAlertTray->IsTrayOut() )
+ {
+ m_pAlertTray->HideTray();
+ m_pWrenchIcon->SetVisible( false );
+ m_pSapperIcon->SetVisible( false );
+ }
+ }
+ else
+ {
+ m_pWrenchIcon->SetVisible( false );
+ m_pSapperIcon->SetVisible( false );
+
+ bool bShowAlertTray = false;
+ bool bAlertTrayFullyDeployed = m_pAlertTray->GetPercentDeployed() >= 1.0f;
+ switch( alertLevel )
+ {
+ // show low ammo for normal sentry and mini-sentry
+ case BUILDING_HUD_ALERT_LOW_AMMO:
+ case BUILDING_HUD_ALERT_VERY_LOW_AMMO:
+ bShowAlertTray = true;
+ m_pWrenchIcon->SetVisible( bAlertTrayFullyDeployed );
+ break;
+
+ // do not show low health for mini-sentry
+ case BUILDING_HUD_ALERT_LOW_HEALTH:
+ case BUILDING_HUD_ALERT_VERY_LOW_HEALTH:
+ bShowAlertTray = pObj->IsMiniBuilding() == false;
+ m_pWrenchIcon->SetVisible( bAlertTrayFullyDeployed && bShowAlertTray );
+ break;
+
+ // always show when being sapped
+ case BUILDING_HUD_ALERT_SAPPER:
+ bShowAlertTray = true;
+ m_pSapperIcon->SetVisible( bAlertTrayFullyDeployed );
+ break;
+
+ default:
+ bShowAlertTray = false;
+ break;
+ }
+
+ if ( bShowAlertTray && !pObj->IsDisposableBuilding() )
+ {
+ if ( !m_pAlertTray->IsTrayOut() )
+ {
+ m_pAlertTray->ShowTray();
+ }
+ m_pAlertTray->SetAlertType( alertLevel );
+ }
+ else
+ {
+ if ( m_pAlertTray->IsTrayOut() )
+ {
+ m_pAlertTray->HideTray();
+ }
+ m_pAlertTray->SetAlertType( BUILDING_HUD_ALERT_NONE );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_BaseObject *CBuildingStatusItem::GetRepresentativeObject( void )
+{
+ if ( !m_bActive )
+ {
+ return NULL;
+ }
+ else
+ {
+ return m_pObject.Get();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CBuildingStatusItem::GetRepresentativeObjectType( void )
+{
+ return m_iObjectType;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CBuildingStatusItem::GetRepresentativeObjectMode( void )
+{
+ return m_iObjectMode;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CBuildingStatusItem::GetObjectPriority( void )
+{
+ int nPriority = GetObjectInfo( GetRepresentativeObjectType() )->m_iDisplayPriority;
+
+ // MvM hack to sort buildings properly since we can have more than one sentry via upgrades
+ if ( GetRepresentativeObjectType() == OBJ_SENTRYGUN && GetRepresentativeObjectMode() == MODE_SENTRYGUN_DISPOSABLE )
+ {
+ nPriority = 0;
+ }
+
+ return nPriority;
+}
+
+//============================================================================
+
+
+DECLARE_BUILD_FACTORY( CBuildingStatusAlertTray );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CBuildingStatusAlertTray::CBuildingStatusAlertTray(Panel *parent, const char *panelName) : BaseClass( parent, panelName )
+{
+ m_pAlertPanelMaterial = NULL;
+ m_flAlertDeployedPercent = 0.0f;
+ m_bIsTrayOut = false;
+
+ m_pAlertPanelHudTexture = NULL;
+ m_pAlertPanelMaterial = NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBuildingStatusAlertTray::ApplySettings( KeyValues *inResourceData )
+{
+ m_pAlertPanelHudTexture = gHUD.GetIcon( inResourceData->GetString( "icon", "" ) );
+
+ if ( m_pAlertPanelHudTexture )
+ {
+ m_pAlertPanelMaterial = materials->FindMaterial( m_pAlertPanelHudTexture->szTextureFile, TEXTURE_GROUP_VGUI );
+ }
+
+ BaseClass::ApplySettings( inResourceData );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBuildingStatusAlertTray::Paint( void )
+{
+ // Paint the alert tray
+ if ( !m_pAlertPanelMaterial || !m_pAlertPanelHudTexture )
+ {
+ return;
+ }
+
+ int x = 0;
+ int y = 0;
+ ipanel()->GetAbsPos(GetVPanel(), x,y );
+ int iWidth = GetWide();
+ int iHeight = GetTall();
+
+ // Position the alert panel image based on the deployed percent
+ float flXa = m_pAlertPanelHudTexture->texCoords[0];
+ float flXb = m_pAlertPanelHudTexture->texCoords[2];
+ float flYa = m_pAlertPanelHudTexture->texCoords[1];
+ float flYb = m_pAlertPanelHudTexture->texCoords[3];
+
+ float flMaskXa = flXa;
+ float flMaskXb = flXb;
+ float flMaskYa = flYa;
+ float flMaskYb = flYb;
+
+ float flFrameDelta = ( flXb - flXa ) * ( 1.0 - m_flAlertDeployedPercent );
+
+ flXa += flFrameDelta;
+ flXb += flFrameDelta;
+
+ CMatRenderContextPtr pRenderContext( materials );
+ pRenderContext->Bind( m_pAlertPanelMaterial );
+ IMesh* pMesh = pRenderContext->GetDynamicMesh( true );
+
+ int r, g, b, a;
+ r = a = 255;
+
+ switch( m_lastAlertType )
+ {
+ case BUILDING_HUD_ALERT_VERY_LOW_AMMO:
+ case BUILDING_HUD_ALERT_VERY_LOW_HEALTH:
+ g = b = (int)( 127.0f + 127.0f * cos( gpGlobals->curtime * 2.0f * M_PI * 0.5 ) );
+ break;
+
+ case BUILDING_HUD_ALERT_SAPPER:
+ g = b = (int)( 127.0f + 127.0f * cos( gpGlobals->curtime * 2.0f * M_PI * 1.5 ) );
+ break;
+
+ case BUILDING_HUD_ALERT_LOW_AMMO:
+ case BUILDING_HUD_ALERT_LOW_HEALTH:
+ case BUILDING_HUD_ALERT_NONE:
+ default:
+ g = b = 255;
+ break;
+ }
+
+ CMeshBuilder meshBuilder;
+ meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
+
+ meshBuilder.Position3f( x, y, 0.0f );
+ meshBuilder.TexCoord2f( 0, flXa, flYa );
+ meshBuilder.TexCoord2f( 1, flMaskXa, flMaskYa );
+ meshBuilder.Color4ub( r, g, b, a );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3f( x + iWidth, y, 0.0f );
+ meshBuilder.TexCoord2f( 0, flXb, flYa );
+ meshBuilder.TexCoord2f( 1, flMaskXb, flMaskYa );
+ meshBuilder.Color4ub( r, g, b, a );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3f( x + iWidth, y + iHeight, 0.0f );
+ meshBuilder.TexCoord2f( 0, flXb, flYb );
+ meshBuilder.TexCoord2f( 1, flMaskXb, flMaskYb );
+ meshBuilder.Color4ub( r, g, b, a );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3f( x, y + iHeight, 0.0f );
+ meshBuilder.TexCoord2f( 0, flXa, flYb );
+ meshBuilder.TexCoord2f( 1, flMaskXa, flMaskYb );
+ meshBuilder.Color4ub( r, g, b, a );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.End();
+ pMesh->Draw();
+}
+
+void CBuildingStatusAlertTray::PaintBackground( void )
+{
+}
+
+void CBuildingStatusAlertTray::ShowTray( void )
+{
+ if ( m_bIsTrayOut == false )
+ {
+ m_flAlertDeployedPercent = 0.0;
+ g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( this, "deployed", 1.0, 0.0, 0.3, AnimationController::INTERPOLATOR_LINEAR );
+
+ m_bIsTrayOut = true;
+ }
+}
+
+void CBuildingStatusAlertTray::HideTray( void )
+{
+ if ( m_bIsTrayOut == true )
+ {
+ m_flAlertDeployedPercent = 1.0;
+ g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( this, "deployed", 0.0, 0.0, 0.3, AnimationController::INTERPOLATOR_LINEAR );
+
+ m_bIsTrayOut = false;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Setup
+//-----------------------------------------------------------------------------
+void CBuildingStatusAlertTray::LevelInit( void )
+{
+ m_bIsTrayOut = false;
+ m_flAlertDeployedPercent = 0.0f;
+}
+
+void CBuildingStatusAlertTray::SetAlertType( BuildingHudAlert_t alertLevel )
+{
+ m_lastAlertType = alertLevel;
+}
+
+//============================================================================
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CBuildingStatusItem_SentryGun::CBuildingStatusItem_SentryGun( Panel *parent ) :
+CBuildingStatusItem( parent, "resource/UI/hud_obj_sentrygun.res", OBJ_SENTRYGUN, MODE_SENTRYGUN_NORMAL )
+{
+ m_pShellsProgress = new vgui::ContinuousProgressBar( GetRunningPanel(), "Shells" );
+ m_pRocketsProgress = new vgui::ContinuousProgressBar( GetRunningPanel(), "Rockets" );
+ m_pUpgradeProgress = new vgui::ContinuousProgressBar( GetRunningPanel(), "Upgrade" );
+
+ m_pRocketIcon = new vgui::ImagePanel( GetRunningPanel(), "RocketIcon" );
+ m_pUpgradeIcon = new CIconPanel( GetRunningPanel(), "UpgradeIcon" );
+
+ m_pSentryIcons[0] = new CIconPanel( this, "Icon_Sentry_1" );
+ m_pSentryIcons[1] = new CIconPanel( this, "Icon_Sentry_2" );
+ m_pSentryIcons[2] = new CIconPanel( this, "Icon_Sentry_3" );
+
+ m_iUpgradeLevel = 1;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem_SentryGun::ApplySchemeSettings( vgui::IScheme *scheme )
+{
+ BaseClass::ApplySchemeSettings( scheme );
+
+ m_cLowAmmoColor = scheme->GetColor( "LowHealthRed", Color(255,0,0,255) );
+ m_cNormalAmmoColor = scheme->GetColor( "ProgressOffWhite", Color(255,255,255,255) );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Calc visibility of subpanels
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem_SentryGun::PerformLayout( void )
+{
+ BaseClass::PerformLayout();
+
+ C_ObjectSentrygun *pSentrygun = dynamic_cast<C_ObjectSentrygun *>( GetRepresentativeObject() );
+
+ if ( !pSentrygun || ( pSentrygun && pSentrygun->IsDisposableBuilding() ) )
+ {
+ return;
+ }
+
+ GetRunningPanel()->SetDialogVariable( "numkills", pSentrygun->GetKills() );
+ GetRunningPanel()->SetDialogVariable( "numassists", pSentrygun->GetAssists() );
+
+ int iShells, iMaxShells;
+ int iRockets, iMaxRockets;
+ pSentrygun->GetAmmoCount( iShells, iMaxShells, iRockets, iMaxRockets );
+
+ // Shells label
+ float flShells = (float)iShells / (float)iMaxShells;
+ m_pShellsProgress->SetProgress( flShells );
+
+ if ( flShells < 0.25f )
+ {
+ m_pShellsProgress->SetFgColor( m_cLowAmmoColor );
+ }
+ else
+ {
+ m_pShellsProgress->SetFgColor( m_cNormalAmmoColor );
+ }
+
+ // Rockets label
+ float flRockets = (float)iRockets / (float)SENTRYGUN_MAX_ROCKETS;
+ m_pRocketsProgress->SetProgress( flRockets );
+
+ if ( flRockets < 0.25f )
+ {
+ m_pRocketsProgress->SetFgColor( m_cLowAmmoColor );
+ }
+ else
+ {
+ m_pRocketsProgress->SetFgColor( m_cNormalAmmoColor );
+ }
+
+ int iUpgradeLevel = pSentrygun->GetUpgradeLevel();
+
+ Assert( iUpgradeLevel >= 1 && iUpgradeLevel <= 3 );
+
+ // show the correct icon
+ m_pSentryIcons[0]->SetVisible( false );
+ m_pSentryIcons[1]->SetVisible( false );
+ m_pSentryIcons[2]->SetVisible( false );
+ m_pSentryIcons[iUpgradeLevel-1]->SetVisible( true );
+
+ // upgrade progress
+ int iMetal = pSentrygun->GetUpgradeMetal();
+ int iMetalRequired = pSentrygun->GetUpgradeMetalRequired();
+ float flUpgrade = (float)iMetal / (float)iMetalRequired;
+ m_pUpgradeProgress->SetProgress( flUpgrade );
+
+ // upgrade label only in 1 or 2
+ m_pUpgradeIcon->SetVisible( iUpgradeLevel < 3 );
+ m_pUpgradeProgress->SetVisible( iUpgradeLevel < 3 );
+
+ // rockets label only in 3
+ m_pRocketIcon->SetVisible( iUpgradeLevel == 3 );
+ m_pRocketsProgress->SetVisible( iUpgradeLevel == 3 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem_SentryGun::OnTick()
+{
+ BaseClass::OnTick();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+const char *CBuildingStatusItem_SentryGun::GetBackgroundImage( void )
+{
+ C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
+
+ const char *pResult = "obj_status_background_tall_blue";
+
+ if ( !pLocalPlayer )
+ {
+ return pResult;
+ }
+
+ switch( pLocalPlayer->GetTeamNumber() )
+ {
+ case TF_TEAM_BLUE:
+ pResult = "obj_status_background_tall_blue";
+ break;
+ case TF_TEAM_RED:
+ pResult = "obj_status_background_tall_red";
+ break;
+ default:
+ break;
+ }
+
+ return pResult;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+const char *CBuildingStatusItem_SentryGun::GetInactiveBackgroundImage( void )
+{
+ return "obj_status_background_tall_disabled";
+}
+
+//============================================================================
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CBuildingStatusItem_SentryGun_Disposable::CBuildingStatusItem_SentryGun_Disposable( Panel *parent ) :
+CBuildingStatusItem( parent, "resource/UI/hud_obj_sentrygun_disp.res", OBJ_SENTRYGUN, MODE_SENTRYGUN_DISPOSABLE )
+{
+ m_pShellsProgress = new vgui::ContinuousProgressBar( GetRunningPanel(), "Shells" );
+
+ m_pUpgradeIcon = new CIconPanel( GetRunningPanel(), "UpgradeIcon" );
+
+ m_pSentryIcons[0] = new CIconPanel( this, "Icon_Sentry_1" );
+ m_pSentryIcons[1] = new CIconPanel( this, "Icon_Sentry_2" );
+ m_pSentryIcons[2] = new CIconPanel( this, "Icon_Sentry_3" );
+
+ m_iUpgradeLevel = 1;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem_SentryGun_Disposable::ApplySchemeSettings( vgui::IScheme *scheme )
+{
+ BaseClass::ApplySchemeSettings( scheme );
+
+ m_cLowAmmoColor = scheme->GetColor( "LowHealthRed", Color(255,0,0,255) );
+ m_cNormalAmmoColor = scheme->GetColor( "ProgressOffWhite", Color(255,255,255,255) );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Calc visibility of subpanels
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem_SentryGun_Disposable::PerformLayout( void )
+{
+ BaseClass::PerformLayout();
+
+ C_ObjectSentrygun *pSentrygun = dynamic_cast<C_ObjectSentrygun *>( GetRepresentativeObject() );
+
+ if ( !pSentrygun || ( pSentrygun && !pSentrygun->IsDisposableBuilding() ) )
+ {
+ return;
+ }
+
+ GetRunningPanel()->SetDialogVariable( "numkills", pSentrygun->GetKills() );
+ GetRunningPanel()->SetDialogVariable( "numassists", pSentrygun->GetAssists() );
+
+ int iShells, iMaxShells;
+ int iRockets, iMaxRockets;
+ pSentrygun->GetAmmoCount( iShells, iMaxShells, iRockets, iMaxRockets );
+
+ // Shells label
+ float flShells = (float)iShells / (float)iMaxShells;
+ m_pShellsProgress->SetProgress( flShells );
+
+ if ( flShells < 0.25f )
+ {
+ m_pShellsProgress->SetFgColor( m_cLowAmmoColor );
+ }
+ else
+ {
+ m_pShellsProgress->SetFgColor( m_cNormalAmmoColor );
+ }
+
+ int iUpgradeLevel = pSentrygun->GetUpgradeLevel();
+
+ Assert( iUpgradeLevel >= 1 && iUpgradeLevel <= 3 );
+
+ // show the correct icon
+ m_pSentryIcons[0]->SetVisible( false );
+ m_pSentryIcons[1]->SetVisible( false );
+ m_pSentryIcons[2]->SetVisible( false );
+ m_pSentryIcons[iUpgradeLevel-1]->SetVisible( true );
+
+ m_pUpgradeIcon->SetEnabled( false );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem_SentryGun_Disposable::OnTick()
+{
+ BaseClass::OnTick();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+const char *CBuildingStatusItem_SentryGun_Disposable::GetBackgroundImage( void )
+{
+ C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
+
+ const char *pResult = "obj_status_background_tall_blue";
+
+ if ( !pLocalPlayer )
+ {
+ return pResult;
+ }
+
+ switch( pLocalPlayer->GetTeamNumber() )
+ {
+ case TF_TEAM_BLUE:
+ pResult = "obj_status_background_blue";
+ break;
+ case TF_TEAM_RED:
+ pResult = "obj_status_background_red";
+ break;
+ default:
+ break;
+ }
+
+ return pResult;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+const char *CBuildingStatusItem_SentryGun_Disposable::GetInactiveBackgroundImage( void )
+{
+ return "obj_status_background_disabled";
+}
+
+//============================================================================
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CBuildingStatusItem_Dispenser::CBuildingStatusItem_Dispenser( Panel *parent ) :
+CBuildingStatusItem( parent, "resource/UI/hud_obj_dispenser.res", OBJ_DISPENSER )
+{
+ m_pAmmoProgress = new vgui::ContinuousProgressBar( GetRunningPanel(), "Ammo" );
+ m_pUpgradeProgress = new vgui::ContinuousProgressBar( GetRunningPanel(), "Upgrade" );
+
+ m_pUpgradeIcon = new CIconPanel( GetRunningPanel(), "UpgradeIcon" );
+
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Calc visibility of subpanels
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem_Dispenser::PerformLayout( void )
+{
+ BaseClass::PerformLayout();
+
+ C_ObjectDispenser *pDispenser = static_cast<C_ObjectDispenser*>(GetRepresentativeObject());
+
+ if ( !pDispenser )
+ {
+ return;
+ }
+
+ int iAmmo = pDispenser->GetMetalAmmoCount();
+
+ float flMaxMetal = pDispenser->IsMiniBuilding() ? MINI_DISPENSER_MAX_METAL : DISPENSER_MAX_METAL_AMMO;
+ float flProgress = (float)iAmmo / flMaxMetal;
+ m_pAmmoProgress->SetProgress( flProgress );
+
+ int iUpgradeLevel = pDispenser->GetUpgradeLevel();
+
+ Assert( iUpgradeLevel >= 1 && iUpgradeLevel <= 3 );
+
+ // upgrade progress
+ int iMetal = pDispenser->GetUpgradeMetal();
+ int iMetalRequired = pDispenser->GetUpgradeMetalRequired();
+ flProgress = (float)iMetal / (float)iMetalRequired;
+
+ m_pUpgradeProgress->SetProgress( flProgress );
+
+ // upgrade label only in 1 or 2
+ bool bShowUpgradeInfo = iUpgradeLevel < 3;
+ m_pUpgradeIcon->SetVisible( bShowUpgradeInfo );
+ m_pUpgradeProgress->SetVisible( bShowUpgradeInfo );
+}
+
+
+
+//============================================================================
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CBuildingStatusItem_TeleporterEntrance::CBuildingStatusItem_TeleporterEntrance( Panel *parent ) :
+CBuildingStatusItem( parent, "resource/UI/hud_obj_tele_entrance.res", OBJ_TELEPORTER, MODE_TELEPORTER_ENTRANCE )
+{
+ // Panel and children when we are charging
+ m_pChargingPanel = new vgui::EditablePanel( GetRunningPanel(), "ChargingPanel" );
+ m_pRechargeTimer = new vgui::ContinuousProgressBar( m_pChargingPanel, "Recharge" );
+
+ // Panel and children when we are fully charged
+ m_pFullyChargedPanel = new vgui::EditablePanel( GetRunningPanel(), "FullyChargedPanel" );
+
+ m_iTimesUsed = -1; // force first update of 0
+ m_iTeleporterState = -1;
+
+ m_pUpgradeProgress = new vgui::ContinuousProgressBar( GetRunningPanel(), "Upgrade" );
+ m_pUpgradeIcon = new CIconPanel( GetRunningPanel(), "UpgradeIcon" );
+
+ vgui::ivgui()->AddTickSignal( GetVPanel() );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem_TeleporterEntrance::OnTick( void )
+{
+ // We only tick while active and with a valid built object
+ C_ObjectTeleporter *pTeleporter = static_cast<C_ObjectTeleporter*>(GetRepresentativeObject());
+
+ if ( pTeleporter && IsActive() )
+ {
+ if ( pTeleporter->GetState() == TELEPORTER_STATE_RECHARGING )
+ {
+ // Update the recharge
+ float flMaxRecharge = pTeleporter->GetCurrentRechargeDuration();
+ float flChargeTime = pTeleporter->GetChargeTime();
+ m_pRechargeTimer->SetProgress( 1.0 - ( flChargeTime / flMaxRecharge ) );
+ }
+ }
+
+ BaseClass::OnTick();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem_TeleporterEntrance::PerformLayout( void )
+{
+ BaseClass::PerformLayout();
+
+ // We only tick while active and with a valid built object
+ C_ObjectTeleporter *pTeleporter = static_cast<C_ObjectTeleporter*>(GetRepresentativeObject());
+
+ if ( !IsActive() || !pTeleporter )
+ {
+ return;
+ }
+
+ bool bRecharging = ( pTeleporter->GetState() == TELEPORTER_STATE_RECHARGING );
+
+ m_pChargingPanel->SetVisible( bRecharging );
+ m_pFullyChargedPanel->SetVisible( !bRecharging );
+
+ // How many times has this teleporter been used?
+ m_pFullyChargedPanel->SetDialogVariable( "timesused", pTeleporter->GetTimesUsed() );
+
+ int iUpgradeLevel = pTeleporter->GetUpgradeLevel();
+
+ Assert( iUpgradeLevel >= 1 && iUpgradeLevel <= 3 );
+
+ // upgrade progress
+ int iMetal = pTeleporter->GetUpgradeMetal();
+ int iMetalRequired = pTeleporter->GetUpgradeMetalRequired();
+ float flUpgrade = (float)iMetal / (float)iMetalRequired;
+ m_pUpgradeProgress->SetProgress( flUpgrade );
+
+ // upgrade label only in 1 or 2
+ m_pUpgradeIcon->SetVisible( iUpgradeLevel < 3 );
+ m_pUpgradeProgress->SetVisible( iUpgradeLevel < 3 );
+}
+
+//============================================================================
+
+CBuildingStatusItem_TeleporterExit::CBuildingStatusItem_TeleporterExit( Panel *parent ) :
+CBuildingStatusItem( parent, "resource/UI/hud_obj_tele_exit.res", OBJ_TELEPORTER, MODE_TELEPORTER_EXIT )
+{
+ m_pUpgradeProgress = new vgui::ContinuousProgressBar( GetRunningPanel(), "Upgrade" );
+ m_pUpgradeIcon = new CIconPanel( GetRunningPanel(), "UpgradeIcon" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem_TeleporterExit::PerformLayout( void )
+{
+ BaseClass::PerformLayout();
+
+ // We only tick while active and with a valid built object
+ C_ObjectTeleporter *pTeleporter = static_cast<C_ObjectTeleporter*>(GetRepresentativeObject());
+
+ if ( !IsActive() || !pTeleporter )
+ {
+ return;
+ }
+
+ int iUpgradeLevel = pTeleporter->GetUpgradeLevel();
+
+ Assert( iUpgradeLevel >= 1 && iUpgradeLevel <= 3 );
+
+ // upgrade progress
+ int iMetal = pTeleporter->GetUpgradeMetal();
+ int iMetalRequired = pTeleporter->GetUpgradeMetalRequired();
+ float flUpgrade = (float)iMetal / (float)iMetalRequired;
+ m_pUpgradeProgress->SetProgress( flUpgrade );
+
+ // upgrade label only in 1 or 2
+ m_pUpgradeIcon->SetVisible( iUpgradeLevel < 3 );
+ m_pUpgradeProgress->SetVisible( iUpgradeLevel < 3 );
+}
+
+#ifdef STAGING_ONLY
+//============================================================================
+CBuildingStatusItem_TeleporterSpeed::CBuildingStatusItem_TeleporterSpeed( Panel *parent, int ETeleporterMode ) :
+CBuildingStatusItem( parent, "resource/UI/hud_obj_tele_speedpad.res", OBJ_TELEPORTER, ETeleporterMode )
+{
+ // Panel and children when we are charging
+ m_pChargingPanel = new vgui::EditablePanel( GetRunningPanel(), "ChargingPanel" );
+ m_pRechargeTimer = new vgui::ContinuousProgressBar( m_pChargingPanel, "Recharge" );
+
+ // Panel and children when we are fully charged
+ m_pFullyChargedPanel = new vgui::EditablePanel( GetRunningPanel(), "FullyChargedPanel" );
+
+ m_iTimesUsed = -1; // force first update of 0
+ m_iTeleporterState = -1;
+
+ m_pUpgradeProgress = new vgui::ContinuousProgressBar( GetRunningPanel(), "Upgrade" );
+ m_pUpgradeIcon = new CIconPanel( GetRunningPanel(), "UpgradeIcon" );
+
+ vgui::ivgui()->AddTickSignal( GetVPanel() );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem_TeleporterSpeed::OnTick( void )
+{
+ // We only tick while active and with a valid built object
+ C_ObjectTeleporter *pTeleporter = static_cast<C_ObjectTeleporter*>( GetRepresentativeObject() );
+
+ if ( pTeleporter && IsActive() )
+ {
+ if ( pTeleporter->GetState() == TELEPORTER_STATE_RECHARGING )
+ {
+ // Update the recharge
+ float flMaxRecharge = pTeleporter->GetCurrentRechargeDuration();
+ float flChargeTime = pTeleporter->GetChargeTime();
+ m_pRechargeTimer->SetProgress( 1.0 - ( flChargeTime / flMaxRecharge ) );
+ }
+ }
+
+ BaseClass::OnTick();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBuildingStatusItem_TeleporterSpeed::PerformLayout( void )
+{
+ BaseClass::PerformLayout();
+
+ // We only tick while active and with a valid built object
+ C_ObjectTeleporter *pTeleporter = static_cast<C_ObjectTeleporter*>( GetRepresentativeObject() );
+
+ if ( !IsActive() || !pTeleporter )
+ {
+ return;
+ }
+
+ bool bRecharging = ( pTeleporter->GetState() == TELEPORTER_STATE_RECHARGING );
+
+ m_pChargingPanel->SetVisible( bRecharging );
+ m_pFullyChargedPanel->SetVisible( !bRecharging );
+
+ // How many times has this teleporter been used?
+ m_pFullyChargedPanel->SetDialogVariable( "timesused", pTeleporter->GetTimesUsed() );
+
+ int iUpgradeLevel = pTeleporter->GetUpgradeLevel();
+
+ Assert( iUpgradeLevel >= 1 && iUpgradeLevel <= 3 );
+
+ // upgrade progress
+ int iMetal = pTeleporter->GetUpgradeMetal();
+ int iMetalRequired = pTeleporter->GetUpgradeMetalRequired();
+ float flUpgrade = (float)iMetal / (float)iMetalRequired;
+ m_pUpgradeProgress->SetProgress( flUpgrade );
+
+ // upgrade label only in 1 or 2
+ m_pUpgradeIcon->SetVisible( iUpgradeLevel < 3 );
+ m_pUpgradeProgress->SetVisible( iUpgradeLevel < 3 );
+}
+#endif
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CBuildingStatusItem_Sapper::CBuildingStatusItem_Sapper( Panel *parent ) :
+CBuildingStatusItem( parent, "resource/UI/hud_obj_sapper.res", OBJ_ATTACHMENT_SAPPER )
+{
+ // health of target building
+ m_pTargetHealthBar = new ContinuousProgressBar( GetRunningPanel(), "TargetHealth" );
+
+ // image of target building
+ m_pTargetIcon = new CIconPanel( GetRunningPanel(), "TargetIcon" );
+
+ // force first think to set the icon
+ m_iTargetType = -1;
+}
+
+void CBuildingStatusItem_Sapper::PerformLayout( void )
+{
+ BaseClass::PerformLayout();
+
+ // We only tick while active and with a valid built object
+ C_ObjectSapper *pSapper = static_cast<C_ObjectSapper*>(GetRepresentativeObject());
+
+ // only visible
+ SetVisible( pSapper != NULL );
+
+ if ( !IsActive() || !pSapper )
+ {
+ return;
+ }
+
+ C_BaseObject *pTarget = pSapper->GetParentObject();
+
+ if ( pTarget )
+ {
+ float flHealth = (float)pTarget->GetHealth() / (float)pTarget->GetMaxHealth();
+
+ m_pTargetHealthBar->SetProgress( flHealth );
+
+ int iTargetType = pTarget->GetType();
+
+ if ( m_iTargetType != iTargetType )
+ {
+ m_pTargetIcon->SetIcon( pTarget->GetHudStatusIcon() );
+
+ m_iTargetType = iTargetType;
+ }
+ }
+ else
+ {
+ m_pTargetHealthBar->SetProgress( 0.0f );
+ }
+}
+
+
+//============================================================================
+
+
+DECLARE_HUDELEMENT( CHudBuildingStatusContainer_Spy );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CHudBuildingStatusContainer_Spy::CHudBuildingStatusContainer_Spy( const char *pElementName ) :
+BaseClass( "BuildingStatus_Spy" )
+{
+ AddBuildingPanel( OBJ_ATTACHMENT_SAPPER );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CHudBuildingStatusContainer_Spy::ShouldDraw( void )
+{
+ // Don't draw in freezecam
+ C_TFPlayer *pPlayer = CTFPlayer::GetLocalTFPlayer();
+ if ( !pPlayer || !pPlayer->IsPlayerClass( TF_CLASS_SPY ) || pPlayer->GetObserverMode() == OBS_MODE_FREEZECAM )
+ {
+ return false;
+ }
+
+ if ( pPlayer->GetTeamNumber() <= TEAM_SPECTATOR )
+ {
+ return false;
+ }
+
+ return CHudElement::ShouldDraw();
+}
+
+//============================================================================
+
+DECLARE_HUDELEMENT( CHudBuildingStatusContainer_Engineer );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CHudBuildingStatusContainer_Engineer::CHudBuildingStatusContainer_Engineer( const char *pElementName ) :
+BaseClass( "BuildingStatus_Engineer" )
+{
+ AddBuildingPanel( OBJ_SENTRYGUN, MODE_SENTRYGUN_NORMAL );
+ AddBuildingPanel( OBJ_DISPENSER );
+ AddBuildingPanel( OBJ_TELEPORTER, MODE_TELEPORTER_ENTRANCE );
+ AddBuildingPanel( OBJ_TELEPORTER, MODE_TELEPORTER_EXIT );
+ AddBuildingPanel( OBJ_SENTRYGUN, MODE_SENTRYGUN_DISPOSABLE );
+#ifdef STAGING_ONLY
+ AddBuildingPanel( OBJ_TELEPORTER, MODE_TELEPORTER_SPEED );
+ AddBuildingPanel( OBJ_TELEPORTER, MODE_TELEPORTER_SPEED2 );
+#endif
+
+ vgui::ivgui()->AddTickSignal( GetVPanel(), 500 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CHudBuildingStatusContainer_Engineer::ShouldDraw( void )
+{
+ // Don't draw in freezecam
+ C_TFPlayer *pPlayer = CTFPlayer::GetLocalTFPlayer();
+ if ( !pPlayer || !pPlayer->IsPlayerClass( TF_CLASS_ENGINEER ) || pPlayer->GetObserverMode() == OBS_MODE_FREEZECAM )
+ return false;
+
+ if ( pPlayer->GetTeamNumber() <= TEAM_SPECTATOR )
+ return false;
+
+ if ( CTFMinigameLogic::GetMinigameLogic() && CTFMinigameLogic::GetMinigameLogic()->GetActiveMinigame() )
+ return false;
+
+ if ( TFGameRules() && TFGameRules()->ShowMatchSummary() )
+ return false;
+
+ return CHudElement::ShouldDraw();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudBuildingStatusContainer_Engineer::OnTick()
+{
+ BaseClass::OnTick();
+
+ if ( !ShouldDraw() )
+ return;
+
+ C_TFPlayer *pLocalPlayer = CTFPlayer::GetLocalTFPlayer();
+ if ( pLocalPlayer )
+ {
+ bool bDisposableSentriesVisible = false;
+
+ if ( TFGameRules() && TFGameRules()->GameModeUsesUpgrades() )
+ {
+ int nDisposableSentries = 0;
+ CALL_ATTRIB_HOOK_INT_ON_OTHER( pLocalPlayer, nDisposableSentries, engy_disposable_sentries );
+ if ( nDisposableSentries )
+ {
+ bDisposableSentriesVisible = true;
+ }
+ }
+
+#ifdef STAGING_ONLY
+ int iSpeedPad = 0;
+ CALL_ATTRIB_HOOK_INT_ON_OTHER( pLocalPlayer, iSpeedPad, teleporter_is_speedpad );
+#endif // STAGING_ONLY
+
+ for ( int i = 0 ; i < m_BuildingPanels.Count() ; i++ )
+ {
+ CBuildingStatusItem *pItem = m_BuildingPanels.Element( i );
+
+ if ( pItem && ( pItem->GetRepresentativeObjectType() == OBJ_SENTRYGUN ) && ( pItem->GetRepresentativeObjectMode() == MODE_SENTRYGUN_DISPOSABLE ) )
+ {
+ if ( pItem->IsVisible() != bDisposableSentriesVisible )
+ {
+ pItem->SetVisible( bDisposableSentriesVisible );
+ }
+
+#ifndef STAGING_ONLY
+ break;
+#endif // !STAGING_ONLY
+ }
+
+#ifdef STAGING_ONLY
+ // Disable entrance and exit
+ if ( pItem && ( pItem->GetRepresentativeObjectType() == OBJ_TELEPORTER ) )
+ {
+ if ( pItem->GetRepresentativeObjectMode() == MODE_TELEPORTER_SPEED || pItem->GetRepresentativeObjectMode() == MODE_TELEPORTER_SPEED2 )
+ {
+ pItem->SetVisible( iSpeedPad );
+ }
+ else
+ {
+ pItem->SetVisible( !(bool)(iSpeedPad) );
+ }
+ }
+#endif // STAGING_ONLY
+ }
+ }
+}
+
+//============================================================================
+
+// order the buildings in our m_BuildingsList by their object priority
+typedef CBuildingStatusItem *BUILDINGSTATUSITEM_PTR;
+static bool BuildingOrderLessFunc( const BUILDINGSTATUSITEM_PTR &left, const BUILDINGSTATUSITEM_PTR &right )
+{
+ return ( left->GetObjectPriority() <= right->GetObjectPriority() );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CHudBuildingStatusContainer::CHudBuildingStatusContainer( const char *pElementName ) :
+CHudElement( pElementName ), BaseClass( NULL, pElementName )
+{
+ vgui::Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+
+ SetHiddenBits( HIDEHUD_MISCSTATUS );
+
+ SetProportional(true);
+
+ ListenForGameEvent( "building_info_changed" );
+
+ m_BuildingPanels.SetLessFunc( BuildingOrderLessFunc );
+
+ m_AlertLevel = BUILDING_HUD_ALERT_NONE;
+ m_flNextBeep = 0;
+ m_iNumBeepsToBeep = 0;
+
+ // for beeping
+ vgui::ivgui()->AddTickSignal( GetVPanel() );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CHudBuildingStatusContainer::ShouldDraw( void )
+{
+ // Don't draw in freezecam
+ C_TFPlayer *pPlayer = CTFPlayer::GetLocalTFPlayer();
+ if ( pPlayer && pPlayer->GetObserverMode() == OBS_MODE_FREEZECAM )
+ return false;
+
+ return CHudElement::ShouldDraw();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudBuildingStatusContainer::LevelInit( void )
+{
+ CHudElement::LevelInit();
+
+ for ( int i = 0; i < m_BuildingPanels.Count(); i++ )
+ {
+ CBuildingStatusItem *pItem = m_BuildingPanels.Element(i);
+
+ if ( pItem )
+ {
+ pItem->LevelInit();
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Create the appropriate info panel for the object
+//-----------------------------------------------------------------------------
+CBuildingStatusItem *CHudBuildingStatusContainer::CreateItemPanel( int iObjectType, int iObjectMode )
+{
+ CBuildingStatusItem *pBuildingItem = NULL;
+
+ switch( iObjectType )
+ {
+ case OBJ_SENTRYGUN:
+ if ( iObjectMode == 0 )
+ {
+ pBuildingItem = new CBuildingStatusItem_SentryGun( this );
+ }
+ else
+ {
+ pBuildingItem = new CBuildingStatusItem_SentryGun_Disposable( this );
+ }
+ break;
+ case OBJ_DISPENSER:
+ pBuildingItem = new CBuildingStatusItem_Dispenser( this );
+ break;
+ case OBJ_TELEPORTER:
+ if ( iObjectMode == 0 )
+ {
+ pBuildingItem = new CBuildingStatusItem_TeleporterEntrance( this );
+ }
+ else if ( iObjectMode == 1 )
+ {
+ pBuildingItem = new CBuildingStatusItem_TeleporterExit( this );
+ }
+#ifdef STAGING_ONLY
+ else if ( iObjectMode == 2 )
+ {
+ pBuildingItem = new CBuildingStatusItem_TeleporterSpeed( this, MODE_TELEPORTER_SPEED );
+ }
+ else
+ {
+ pBuildingItem = new CBuildingStatusItem_TeleporterSpeed( this, MODE_TELEPORTER_SPEED2 );
+ }
+#endif
+ break;
+ case OBJ_ATTACHMENT_SAPPER:
+ pBuildingItem = new CBuildingStatusItem_Sapper( this );
+ break;
+ default:
+ pBuildingItem = NULL;
+ break;
+ }
+
+ Assert( pBuildingItem );
+
+ return pBuildingItem;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudBuildingStatusContainer::AddBuildingPanel( int iObjectType, int iObjectMode )
+{
+ CBuildingStatusItem *pBuildingItem = CreateItemPanel( iObjectType, iObjectMode );
+
+ Assert( pBuildingItem );
+
+ pBuildingItem->SetPos( 0, 0 );
+ pBuildingItem->InvalidateLayout();
+
+ m_BuildingPanels.Insert( pBuildingItem );
+
+ RepositionObjectPanels();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudBuildingStatusContainer::UpdateAllBuildings( void )
+{
+ C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
+ if ( !pLocalPlayer )
+ return;
+
+ for ( int i = 0; i < m_BuildingPanels.Count(); i++ )
+ {
+ CBuildingStatusItem *pItem = m_BuildingPanels.Element(i);
+
+ if ( pItem )
+ {
+ // find the item that represents this building type
+ C_BaseObject *pObj = NULL;
+ if ( pObj )
+ {
+ // find the object
+ pObj = pLocalPlayer->GetObjectOfType( pItem->GetRepresentativeObjectType(), pItem->GetRepresentativeObjectMode() );
+
+ pItem->SetObject( pObj );
+
+ pItem->InvalidateLayout( true );
+ RecalculateAlertState();
+ }
+ }
+ }
+}
+
+
+void CHudBuildingStatusContainer::OnBuildingChanged( int iBuildingType, int iBuildingMode, bool bBuildingIsDead )
+{
+ bool bFound = false;
+ for ( int i = 0; i < m_BuildingPanels.Count() && !bFound; i++ )
+ {
+ CBuildingStatusItem *pItem = m_BuildingPanels.Element(i);
+
+ if ( pItem && pItem->GetRepresentativeObjectType() == iBuildingType && pItem->GetRepresentativeObjectMode() == iBuildingMode )
+ {
+ // find the item that represents this building type
+ C_BaseObject *pObj = NULL;
+
+ // find the object
+ C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
+ if ( pLocalPlayer )
+ {
+ pObj = pLocalPlayer->GetObjectOfType( iBuildingType, iBuildingMode );
+ pItem->SetObject( pObj );
+ pItem->InvalidateLayout( true );
+ bFound = true;
+
+ RecalculateAlertState();
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudBuildingStatusContainer::ApplySchemeSettings( vgui::IScheme *scheme )
+{
+ BaseClass::ApplySchemeSettings( scheme );
+
+ SetPaintBackgroundEnabled( false );
+
+ RepositionObjectPanels();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Contents of object list has changed, reposition the panels
+//-----------------------------------------------------------------------------
+void CHudBuildingStatusContainer::RepositionObjectPanels( void )
+{
+ float flXPos = XRES(9);
+ float flYPos = YRES(9);
+
+ float flTeleEntranceY = YRES(9);
+ float flTeleExitY = YRES(9);
+
+ // Regular Panels
+ for ( int i = 0; i < m_BuildingPanels.Count(); i++ )
+ {
+ CBuildingStatusItem *pItem = m_BuildingPanels.Element(i);
+
+ if ( pItem )
+ {
+ // set position directly
+ pItem->SetPos( flXPos, flYPos );
+
+ // do not increment for speed pad (this is a minor hack)
+ // OBJ_TELEPORTER, MODE_TELEPORTER_SPEED
+ if ( pItem->GetRepresentativeObjectType() == OBJ_TELEPORTER )
+ {
+ switch ( pItem->GetRepresentativeObjectMode() )
+ {
+ case MODE_TELEPORTER_ENTRANCE:
+ flTeleEntranceY = flYPos;
+ flYPos += pItem->GetTall();
+ break;
+ case MODE_TELEPORTER_EXIT:
+ flTeleExitY = flYPos;
+ flYPos += pItem->GetTall();
+ break;
+#ifdef STAGING_ONLY
+ case MODE_TELEPORTER_SPEED:
+ pItem->SetPos( flXPos, flTeleEntranceY );
+ break;
+ case MODE_TELEPORTER_SPEED2:
+ pItem->SetPos( flXPos, flTeleExitY );
+ break;
+#endif
+ }
+ }
+ else
+ {
+ flYPos += pItem->GetTall(); // the fade around the panels gives a gap
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudBuildingStatusContainer::FireGameEvent( IGameEvent *event )
+{
+ const char * type = event->GetName();
+
+ if ( Q_strcmp(type, "building_info_changed" ) == 0 )
+ {
+ int iBuildingType = event->GetInt( "building_type" );
+ int iBuildingMode = event->GetInt( "object_mode" );
+
+ if ( iBuildingType >= 0 )
+ {
+ bool bRemove = ( event->GetInt( "remove" ) > 0 );
+
+ OnBuildingChanged( iBuildingType, iBuildingMode, bRemove );
+ }
+ else
+ {
+ UpdateAllBuildings();
+ }
+ }
+ else
+ {
+ CHudElement::FireGameEvent( event );
+ }
+}
+
+void CHudBuildingStatusContainer::RecalculateAlertState( void )
+{
+ BuildingHudAlert_t maxAlertLevel = BUILDING_HUD_ALERT_NONE;
+
+ // find our highest warning level
+ for ( int i = 0; i < m_BuildingPanels.Count(); i++ )
+ {
+ CBuildingStatusItem *pItem = m_BuildingPanels.Element(i);
+ C_BaseObject * pObj = pItem->GetRepresentativeObject();
+
+ if ( pObj )
+ {
+ BuildingHudAlert_t alertLevel = pObj->GetBuildingAlertLevel();
+ if ( alertLevel > maxAlertLevel )
+ {
+ if ( pObj->IsMiniBuilding() && alertLevel != BUILDING_HUD_ALERT_LOW_HEALTH && alertLevel != BUILDING_HUD_ALERT_VERY_LOW_HEALTH && alertLevel != BUILDING_HUD_ALERT_SAPPER )
+ continue;
+ maxAlertLevel = alertLevel;
+ }
+ }
+ }
+
+ if ( maxAlertLevel != m_AlertLevel )
+ {
+ if ( maxAlertLevel >= BUILDING_HUD_ALERT_VERY_LOW_AMMO )
+ {
+ m_flNextBeep = gpGlobals->curtime; // beep asap
+ m_iNumBeepsToBeep = tf_hud_num_building_alert_beeps.GetInt();
+ }
+
+ m_AlertLevel = maxAlertLevel;
+ }
+}
+
+void CHudBuildingStatusContainer::OnTick( void )
+{
+ if ( m_AlertLevel >= BUILDING_HUD_ALERT_VERY_LOW_AMMO &&
+ gpGlobals->curtime >= m_flNextBeep &&
+ m_iNumBeepsToBeep > 0 )
+ {
+ C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
+
+ if ( !pLocalPlayer )
+ return;
+
+ pLocalPlayer->EmitSound( "Hud.Warning" );
+
+ switch( m_AlertLevel )
+ {
+ case BUILDING_HUD_ALERT_VERY_LOW_AMMO:
+ case BUILDING_HUD_ALERT_VERY_LOW_HEALTH:
+ m_flNextBeep = gpGlobals->curtime + 2.0f;
+ m_iNumBeepsToBeep--;
+ break;
+
+ case BUILDING_HUD_ALERT_SAPPER:
+ m_flNextBeep = gpGlobals->curtime + 1.0f;
+ // don't decrement beeps, we want them to go on forever
+ break;
+ }
+ }
+} \ No newline at end of file