summaryrefslogtreecommitdiff
path: root/game/client/tf/vgui/tf_playerpanel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/client/tf/vgui/tf_playerpanel.cpp')
-rw-r--r--game/client/tf/vgui/tf_playerpanel.cpp411
1 files changed, 411 insertions, 0 deletions
diff --git a/game/client/tf/vgui/tf_playerpanel.cpp b/game/client/tf/vgui/tf_playerpanel.cpp
new file mode 100644
index 0000000..c541922
--- /dev/null
+++ b/game/client/tf/vgui/tf_playerpanel.cpp
@@ -0,0 +1,411 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "hud.h"
+#include "c_team.h"
+#include "tf_shareddefs.h"
+#include "tf_gamerules.h"
+#include "tf_hud_objectivestatus.h"
+#include "tf_hud_statpanel.h"
+#include "iclientmode.h"
+#include "c_playerresource.h"
+#include "tf_hud_building_status.h"
+#include "tf_hud_mann_vs_machine_status.h"
+#include "tf_hud_tournament.h"
+#include "tf_hud_winpanel.h"
+#include "tf_tips.h"
+#include "tf_mapinfomenu.h"
+#include "econ_wearable.h"
+#include "c_tf_playerresource.h"
+#include "playerspawncache.h"
+#include "econ_notifications.h"
+#include <spectatorgui.h>
+#include "hudelement.h"
+#include "tf_spectatorgui.h"
+#include "tf_hud_playerstatus.h"
+#include "item_model_panel.h"
+#include "tf_gamerules.h"
+#include "tf_playerpanel.h"
+
+#include "tf_gc_client.h"
+#include "tf_lobby_server.h"
+
+#include <vgui/ILocalize.h>
+#include <vgui/ISurface.h>
+#include <VGuiMatSurface/IMatSystemSurface.h>
+#include "vgui_avatarimage.h"
+
+using namespace vgui;
+
+extern ConVar tf_max_health_boost;
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CTFPlayerPanel::CTFPlayerPanel( vgui::Panel *parent, const char *name ) : vgui::EditablePanel( parent, name )
+{
+ m_pHealthIcon = new CTFPlayerPanelGUIHealth( this, "HealthIcon" );
+ m_pClassImage = NULL;
+ m_bPlayerReadyModeActive = false;
+ m_pReadyBG = new ScalableImagePanel( this , "ReadyBG" );
+ m_pReadyImage = new ImagePanel( this, "ReadyImage" );
+
+ SetDialogVariable( "chargeamount", "" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTFPlayerPanel::Reset( void )
+{
+ m_pHealthIcon->Reset();
+ m_iPrevHealth = -999;
+ m_iPrevClass = -999;
+ m_bPrevAlive = false;
+ m_iPrevRespawnWait = -999;
+ m_iPrevCharge = -1;
+ m_bPrevReady = true;
+ m_iPrevState = GR_STATE_PREGAME;
+ m_bPlayerReadyModeActive = false;
+ m_nGCTeam = TEAM_INVALID;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CTFPlayerPanel::Update( void )
+{
+ if ( !g_TF_PR || !TFGameRules() )
+ return false;
+
+ C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pLocalPlayer )
+ return false;
+
+ bool bChanged = false;
+ bool bObserver = pLocalPlayer->GetObserverMode() != OBS_MODE_NONE;
+ bool bVisible = GetTeam() >= FIRST_GAME_TEAM;
+ int iRespawnWait = -1;
+ m_bPlayerReadyModeActive = ( !bObserver &&
+ TFGameRules()->UsePlayerReadyStatusMode() &&
+ TFGameRules()->State_Get() == GR_STATE_BETWEEN_RNDS );
+
+ CTFGSLobby *pLobby = GTFGCClientSystem()->GetLobby();
+ if ( pLobby )
+ {
+ const CTFLobbyMember *pMember = pLobby->GetMemberDetails( m_steamID );
+ if ( pMember )
+ {
+ // Keep this updated
+ m_nGCTeam = pMember->team();
+
+ if ( !m_iPlayerIndex && pMember->has_last_connect_time() )
+ {
+ iRespawnWait = CRTime::RTime32DateAdd( pMember->last_connect_time(), 180, k_ETimeUnitSecond ) - CRTime::RTime32TimeCur();
+ if ( iRespawnWait <= 0 )
+ iRespawnWait = -1;
+ }
+ }
+ }
+
+ if ( IsVisible() != bVisible )
+ {
+ SetVisible( bVisible );
+ bChanged = true;
+ }
+
+ if ( bVisible )
+ {
+ if ( g_TF_PR )
+ {
+ // Are we connected with a class?
+ Assert( TF_CLASS_UNDEFINED == 0 );
+ int iClass = -1;
+ bool bAlive = false;
+ const int k_Health_Dead = -1;
+ const int k_Health_NotINGame = -2;
+ int iHealth = k_Health_NotINGame;
+ if ( m_iPlayerIndex > 0 )
+ {
+ iClass = g_TF_PR->GetPlayerClass( m_iPlayerIndex );
+
+ if ( iClass != TF_CLASS_UNDEFINED )
+ {
+ bAlive = g_TF_PR->IsAlive( m_iPlayerIndex );
+ iHealth = k_Health_Dead;
+ }
+ if ( bAlive )
+ iHealth = g_TF_PR->GetHealth( m_iPlayerIndex );
+
+ // Calc respawn time remaining
+ if ( iClass != TF_CLASS_UNDEFINED && !bAlive )
+ {
+ float flRespawnAt = g_TF_PR->GetNextRespawnTime( m_iPlayerIndex );
+ iRespawnWait = (flRespawnAt - gpGlobals->curtime);
+ if ( iRespawnWait <= 0 )
+ iRespawnWait = -1;
+ }
+
+ // Hide class info from the other team?
+ if ( !bObserver &&
+ TFGameRules()->IsCompetitiveMode() &&
+ GetTeam() != g_TF_PR->GetTeam( pLocalPlayer->entindex() ) )
+ {
+ iClass = TF_CLASS_UNDEFINED;
+ }
+ }
+
+ // Update live state
+ if ( m_pClassImage )
+ {
+ if ( m_bPrevAlive != bAlive )
+ {
+ bChanged = true;
+ m_bPrevAlive = bAlive;
+ if ( bAlive )
+ {
+ m_pClassImage->SetDrawColor( Color( 255, 255, 255, 255 ) );
+ }
+ else
+ {
+ m_pClassImage->SetDrawColor( Color( 96, 96, 96, 255 ) );
+ }
+
+ UpdateBorder();
+ }
+
+ // Update class image
+ if ( m_iPrevClass != iClass )
+ {
+ bChanged = true;
+ m_iPrevClass = iClass;
+ if ( iClass < 0 )
+ {
+ m_pClassImage->SetImage( "hud_connecting" );
+ }
+ else if ( iClass == TF_CLASS_UNDEFINED )
+ {
+ m_pClassImage->SetImage( "hud_class_not_chosen" );
+ }
+ else
+ {
+ m_pClassImage->SetImage( VarArgs( "%s_alpha", ( GetTeam() == TF_TEAM_RED ) ? g_pszItemClassImagesRed[iClass] : g_pszItemClassImagesBlue[iClass] ) );
+ }
+ }
+ }
+
+ // update health indicator
+ if ( iHealth != m_iPrevHealth && m_pHealthIcon )
+ {
+ m_iPrevHealth = iHealth;
+ if ( iHealth == k_Health_NotINGame )
+ {
+ m_pHealthIcon->SetVisible( false );
+ }
+ else
+ {
+ m_pHealthIcon->SetVisible( true );
+ if ( iHealth < 0 )
+ {
+ Assert( iHealth == k_Health_Dead );
+ m_pHealthIcon->SetHealth( -1, 1, 1 );
+ }
+ else
+ {
+ float flMaxHealth = g_TF_PR->GetMaxHealth( m_iPlayerIndex );
+ float iMaxBuffedHealth = flMaxHealth * tf_max_health_boost.GetFloat(); // Hacky, but it'll work.
+ m_pHealthIcon->SetHealth( iHealth, flMaxHealth, iMaxBuffedHealth );
+ bChanged = true;
+ }
+ }
+ }
+
+ // Update respawn time text
+ if ( iRespawnWait != m_iPrevRespawnWait )
+ {
+ m_iPrevRespawnWait = iRespawnWait;
+ if ( iRespawnWait < 0 )
+ {
+ SetDialogVariable( "respawntime", "" );
+ }
+ else
+ {
+ SetDialogVariable( "respawntime", VarArgs( "%d s", iRespawnWait ) );
+ bChanged = true;
+ }
+ }
+
+ bool bReadyMode = TFGameRules()->UsePlayerReadyStatusMode();
+
+ int iCharge = ( iClass == TF_CLASS_MEDIC ) ? g_TF_PR->GetChargeLevel( m_iPlayerIndex ) : 0;
+ if ( iCharge != m_iPrevCharge )
+ {
+ if ( iCharge > 0 && !( bReadyMode && !bObserver ) )
+ {
+ SetDialogVariable( "chargeamount", VarArgs( "%d%%", iCharge ) );
+ bChanged = true;
+ }
+ else
+ {
+ SetDialogVariable( "chargeamount", "" );
+ }
+ m_iPrevCharge = iCharge;
+ }
+
+ if ( bReadyMode )
+ {
+ bool bPlayerReady = false;
+
+ if ( m_bPlayerReadyModeActive )
+ {
+ if ( m_iPlayerIndex && g_TF_PR->IsConnected( m_iPlayerIndex ) )
+ {
+ bPlayerReady = TFGameRules()->IsPlayerReady( m_iPlayerIndex );
+ }
+ }
+
+ if ( m_pReadyImage && ( m_pReadyImage->IsVisible() != bPlayerReady ) )
+ {
+ m_pReadyImage->SetVisible( bPlayerReady );
+ }
+
+ if ( m_pHealthIcon && ( m_pHealthIcon->IsVisible() == m_bPlayerReadyModeActive ) )
+ {
+ m_pHealthIcon->SetVisible( !m_bPlayerReadyModeActive );
+ }
+
+ if ( m_pReadyBG && ( m_pReadyBG->IsVisible() != m_bPlayerReadyModeActive ) )
+ {
+ m_pReadyBG->SetVisible( m_bPlayerReadyModeActive );
+ }
+
+ if ( TFGameRules()->State_Get() != m_iPrevState )
+ {
+ bChanged = true;
+ }
+ m_iPrevState = TFGameRules()->State_Get();
+ }
+ }
+ }
+
+ return bChanged;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTFPlayerPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ m_pClassImage = dynamic_cast<CTFClassImage*>( FindChildByName( "classimage" ) );
+
+ Reset();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTFPlayerPanel::SetPlayerIndex( int iIndex )
+{
+ if ( iIndex <= 0 )
+ {
+ Setup( iIndex, CSteamID(), "" );
+ }
+ else
+ {
+ Setup( iIndex, GetSteamIDForPlayerIndex( iIndex ), g_TF_PR->GetPlayerName( iIndex ) );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTFPlayerPanel::Setup( int iPlayerIndex, CSteamID steamID, const char *pszPlayerName, int nLobbyTeam /*= TEAM_INVALID*/ )
+{
+ if ( pszPlayerName == NULL )
+ pszPlayerName = "";
+ if ( m_iPlayerIndex != iPlayerIndex
+ || m_steamID != steamID
+ || Q_strcmp( m_sPlayerName, pszPlayerName ) )
+ {
+ Reset();
+ m_iPlayerIndex = iPlayerIndex;
+ m_steamID = steamID;
+ m_sPlayerName = pszPlayerName;
+ SetDialogVariable( "playername", m_sPlayerName );
+ m_nGCTeam = nLobbyTeam;
+ }
+
+ if ( m_iPlayerIndex > 0 || m_steamID.IsValid() )
+ {
+ UpdateBorder();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTFPlayerPanel::SetSpecIndex( int iIndex )
+{
+ m_iSpecIndex = iIndex;
+
+ if ( m_iSpecIndex > 0 && m_iSpecIndex <= 12 && !m_bPlayerReadyModeActive )
+ {
+ SetDialogVariable( "specindex", VarArgs( "%d", m_iSpecIndex ) );
+ }
+ else
+ {
+ SetDialogVariable( "specindex", "" );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTFPlayerPanel::UpdateBorder( void )
+{
+ if ( !g_TF_PR )
+ return;
+
+ vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() );
+ if ( !m_bPrevAlive )
+ {
+ SetBorder( pScheme->GetBorder("TFFatLineBorder") );
+ }
+ else
+ {
+ if ( GetTeam() == TF_TEAM_RED )
+ {
+ SetBorder( pScheme->GetBorder( "TFFatLineBorderRedBG" ) );
+ }
+ else
+ {
+ SetBorder( pScheme->GetBorder( "TFFatLineBorderBlueBG" ) );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CTFPlayerPanel::GetTeam( void )
+{
+ if ( m_nGCTeam != TEAM_INVALID && TFGameRules() )
+ {
+ return TFGameRules()->GetGameTeamForGCTeam( (TF_GC_TEAM)m_nGCTeam );
+ }
+ else if ( GetPlayerIndex() && g_TF_PR )
+ {
+ return g_TF_PR->GetTeam( GetPlayerIndex() );
+ }
+
+ return TEAM_INVALID;
+}
+
+