|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include <vgui/ILocalize.h>
#include "vgui_controls/TextEntry.h"
#include "select_player_dialog.h"
#include "tf_controls.h"
#include "c_playerresource.h"
#include "ienginevgui.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
int CSelectPlayerDialog::SortPartnerInfoFunc( const partner_info_t *pA, const partner_info_t *pB ) { return Q_stricmp( pA->m_name.Get(), pB->m_name.Get() ); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CSelectPlayerDialog::CSelectPlayerDialog( vgui::Panel *parent ) : vgui::EditablePanel( parent, "SelectPlayerDialog" ) , m_bAllowSameTeam( true ) , m_bAllowOutsideServer( true ) { if ( parent == NULL ) { vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme"); SetScheme(scheme); SetProportional( true ); }
m_pSelectFromServerButton = NULL; m_pCancelButton = NULL; m_pButtonKV = NULL; m_bReapplyButtonKVs = false;
for ( int i = 0; i < SPDS_NUM_STATES; i++ ) { m_pStatePanels[i] = new vgui::EditablePanel( this, VarArgs("StatePanel%d",i) ); }
m_pPlayerList = new vgui::EditablePanel( this, "PlayerList" ); m_pPlayerListScroller = new vgui::ScrollableEditablePanel( this, m_pPlayerList, "PlayerListScroller" );
m_iCurrentState = SPDS_SELECTING_PLAYER; }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CSelectPlayerDialog::~CSelectPlayerDialog( void ) { if ( m_pButtonKV ) { m_pButtonKV->deleteThis(); m_pButtonKV = NULL; } }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CSelectPlayerDialog::Reset( void ) { m_iCurrentState = SPDS_SELECTING_PLAYER; }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CSelectPlayerDialog::ApplySettings( KeyValues *inResourceData ) { BaseClass::ApplySettings( inResourceData );
KeyValues *pItemKV = inResourceData->FindKey( "button_kv" ); if ( pItemKV ) { if ( m_pButtonKV ) { m_pButtonKV->deleteThis(); } m_pButtonKV = new KeyValues("button_kv"); pItemKV->CopySubkeys( m_pButtonKV );
m_bReapplyButtonKVs = true; } }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CSelectPlayerDialog::ApplySchemeSettings( vgui::IScheme *pScheme ) { BaseClass::ApplySchemeSettings( pScheme );
LoadControlSettings( GetResFile() );
m_pCancelButton = dynamic_cast<CExButton*>( FindChildByName( "CancelButton" ) );
// Find all the sub buttons, and set their action signals to point to this panel
for ( int i = 0; i < SPDS_NUM_STATES; i++ ) { int iButton = 0; CExButton *pButton = NULL; do { pButton = dynamic_cast<CExButton*>( m_pStatePanels[i]->FindChildByName( VarArgs("subbutton%d",iButton)) ); if ( pButton ) { pButton->AddActionSignalTarget( this );
// The second button on the first state is the server button
if ( iButton == 1 ) { m_pSelectFromServerButton = pButton; }
iButton++; } } while (pButton); }
UpdateState(); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CSelectPlayerDialog::PerformLayout( void ) { BaseClass::PerformLayout();
// Layout the player list buttons
if ( m_pPlayerPanels.Count() ) { int iButtonH = m_pPlayerPanels[0]->GetTall() + YRES(2); m_pPlayerList->SetSize( m_pPlayerList->GetWide(), YRES(2) + (iButtonH * m_pPlayerPanels.Count()) );
// These need to all be layout-complete before we can position the player panels,
// because the scrollbar will cause the playerlist entries to move when it lays out.
m_pPlayerList->InvalidateLayout( true ); m_pPlayerListScroller->InvalidateLayout( true ); m_pPlayerListScroller->GetScrollbar()->InvalidateLayout( true );
for ( int i = 0; i < m_pPlayerPanels.Count(); i++ ) { m_pPlayerPanels[i]->SetPos( 0, YRES(2) + (iButtonH * i) ); } } }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CSelectPlayerDialog::OnCommand( const char *command ) { if ( !Q_stricmp( command, "cancel" ) ) { if ( m_iCurrentState != SPDS_SELECTING_PLAYER ) { m_iCurrentState = SPDS_SELECTING_PLAYER; UpdateState(); return; }
TFModalStack()->PopModal( this ); SetVisible( false ); MarkForDeletion(); if ( GetParent() ) { PostMessage( GetParent(), new KeyValues("CancelSelection") ); } return; } else if ( !Q_stricmp( command, "friends" ) ) { m_iCurrentState = SPDS_SELECTING_FROM_FRIENDS; UpdateState(); return; } else if ( !Q_stricmp( command, "server" ) ) { m_iCurrentState = SPDS_SELECTING_FROM_SERVER; UpdateState(); return; } else if ( !Q_strnicmp( command, "select_player", 13 ) ) { int iPlayer = atoi( command + 13 ) - 1; if ( iPlayer >= 0 && iPlayer < m_PlayerInfoList.Count() ) { m_iCurrentState = SPDS_SELECTING_PLAYER; OnCommand( "cancel" ); OnSelectPlayer( m_PlayerInfoList[iPlayer].m_steamID ); } return; }
BaseClass::OnCommand( command ); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CSelectPlayerDialog::UpdateState( void ) { for ( int i = 0; i < SPDS_NUM_STATES; i++ ) { if ( !m_pStatePanels[i] ) continue;
m_pStatePanels[i]->SetVisible( m_iCurrentState == i ); }
if ( m_pSelectFromServerButton ) { m_pSelectFromServerButton->SetEnabled( engine->IsInGame() ); }
if ( m_iCurrentState == SPDS_SELECTING_PLAYER ) { m_pCancelButton->SetText( g_pVGuiLocalize->Find( "#Cancel" ) ); } else { m_pCancelButton->SetText( g_pVGuiLocalize->Find( "#TF_Back" ) ); }
switch ( m_iCurrentState ) { case SPDS_SELECTING_FROM_FRIENDS: SetupSelectFriends(); break; case SPDS_SELECTING_FROM_SERVER: SetupSelectServer( false ); break; case SPDS_SELECTING_PLAYER: default: m_pPlayerListScroller->SetVisible( false ); break; } }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CSelectPlayerDialog::SetupSelectFriends( void ) { // @todo optional check to see if friend is on my server
if ( m_bAllowOutsideServer == false ) { SetupSelectServer( true ); return; }
m_PlayerInfoList.Purge();
if ( steamapicontext && steamapicontext->SteamFriends() ) { // Get our game info so we can use that to test if our friends are connected to the same game as us
FriendGameInfo_t myGameInfo; CSteamID mySteamID = steamapicontext->SteamUser()->GetSteamID(); steamapicontext->SteamFriends()->GetFriendGamePlayed( mySteamID, &myGameInfo );
int iFriends = steamapicontext->SteamFriends()->GetFriendCount( k_EFriendFlagImmediate ); for ( int i = 0; i < iFriends; i++ ) { CSteamID friendSteamID = steamapicontext->SteamFriends()->GetFriendByIndex( i, k_EFriendFlagImmediate );
FriendGameInfo_t gameInfo; if ( !AllowOutOfGameFriends() && !steamapicontext->SteamFriends()->GetFriendGamePlayed( friendSteamID, &gameInfo ) ) continue;
// Friends is in-game. Make sure it's TF2.
if ( AllowOutOfGameFriends() || (gameInfo.m_gameID.IsValid() && gameInfo.m_gameID == myGameInfo.m_gameID) ) { const char *pszName = steamapicontext->SteamFriends()->GetFriendPersonaName( friendSteamID ); int idx = m_PlayerInfoList.AddToTail(); partner_info_t &info = m_PlayerInfoList[idx]; info.m_steamID = friendSteamID; info.m_name = pszName; } } }
UpdatePlayerList(); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CSelectPlayerDialog::SetupSelectServer( bool bFriendsOnly ) { m_PlayerInfoList.Purge();
if ( steamapicontext && steamapicontext->SteamUtils() ) { for( int iPlayerIndex = 1 ; iPlayerIndex <= MAX_PLAYERS; iPlayerIndex++ ) { // find all players who are on the local player's team
int iLocalPlayerIndex = GetLocalPlayerIndex(); if( ( iPlayerIndex != iLocalPlayerIndex ) && ( g_PR->IsConnected( iPlayerIndex ) ) ) { player_info_t pi; if ( !engine->GetPlayerInfo( iPlayerIndex, &pi ) ) continue; if ( !pi.friendsID ) continue;
CSteamID steamID( pi.friendsID, 1, GetUniverse(), k_EAccountTypeIndividual );
if ( bFriendsOnly ) { EFriendRelationship eRelationship = steamapicontext->SteamFriends()->GetFriendRelationship( steamID ); if ( eRelationship != k_EFriendRelationshipFriend ) { continue; } }
if ( g_PR->GetTeam( iPlayerIndex ) != TF_TEAM_RED && g_PR->GetTeam( iPlayerIndex ) != TF_TEAM_BLUE ) continue;
if ( m_bAllowSameTeam == false ) { if ( GetLocalPlayerTeam() == g_PR->GetTeam( iPlayerIndex ) ) { continue; } }
int idx = m_PlayerInfoList.AddToTail(); partner_info_t &info = m_PlayerInfoList[idx]; info.m_steamID = steamID; info.m_name = pi.name; } } }
UpdatePlayerList(); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CSelectPlayerDialog::UpdatePlayerList( void ) { vgui::Label *pLabelEmpty = dynamic_cast<vgui::Label*>( m_pStatePanels[m_iCurrentState]->FindChildByName("EmptyPlayerListLabel") ); vgui::Label *pLabelQuery = dynamic_cast<vgui::Label*>( m_pStatePanels[m_iCurrentState]->FindChildByName("QueryLabel") );
// If we have no players in our list, show the no-player label.
if ( m_PlayerInfoList.Count() == 0 ) { if ( pLabelEmpty ) { pLabelEmpty->SetVisible( true ); } if ( pLabelQuery ) { pLabelQuery->SetVisible( false ); } return; }
// First, reapply any KVs we have to reapply
if ( m_bReapplyButtonKVs ) { m_bReapplyButtonKVs = false;
if ( m_pButtonKV ) { FOR_EACH_VEC( m_pPlayerPanels, i ) { m_pPlayerPanels[i]->ApplySettings( m_pButtonKV ); } } }
// sort by name
m_PlayerInfoList.Sort( &SortPartnerInfoFunc );
// Otherwise, build the player panels from the list of steam IDs
for ( int i = 0; i < m_PlayerInfoList.Count(); i++ ) { if ( m_pPlayerPanels.Count() <= i ) { m_pPlayerPanels.AddToTail(); m_pPlayerPanels[i] = new CSelectPlayerTargetPanel( m_pPlayerList, VarArgs("player%d",i) ); m_pPlayerPanels[i]->GetButton()->SetCommand( VarArgs("select_player%d",i+1) ); m_pPlayerPanels[i]->GetButton()->AddActionSignalTarget( this ); m_pPlayerPanels[i]->GetAvatar()->SetShouldDrawFriendIcon( false ); m_pPlayerPanels[i]->GetAvatar()->SetMouseInputEnabled( false );
if ( m_pButtonKV ) { m_pPlayerPanels[i]->ApplySettings( m_pButtonKV ); m_pPlayerPanels[i]->InvalidateLayout( true ); } }
m_pPlayerPanels[i]->SetInfo( m_PlayerInfoList[i].m_steamID, m_PlayerInfoList[i].m_name ); }
m_pPlayerListScroller->GetScrollbar()->SetAutohideButtons( true ); m_pPlayerListScroller->GetScrollbar()->SetValue( 0 );
// Remove any extra player panels
for ( int i = m_pPlayerPanels.Count()-1; i >= m_PlayerInfoList.Count(); i-- ) { m_pPlayerPanels[i]->MarkForDeletion(); m_pPlayerPanels.Remove(i); }
if ( pLabelEmpty ) { pLabelEmpty->SetVisible( false ); } if ( pLabelQuery ) { pLabelQuery->SetVisible( true ); } m_pPlayerListScroller->SetVisible( true );
InvalidateLayout(); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CSelectPlayerTargetPanel::SetInfo( const CSteamID &steamID, const char *pszName ) { if ( !steamapicontext || !steamapicontext->SteamFriends() ) return;
m_pAvatar->SetPlayer( steamID, k_EAvatarSize64x64 );
m_pButton->SetText( pszName ); }
|