You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
323 lines
8.6 KiB
323 lines
8.6 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: Present a list of sessions from which the player can choose a game to join. |
|
// |
|
//=============================================================================// |
|
|
|
#include "sessionbrowserdialog.h" |
|
#include "engine/imatchmaking.h" |
|
#include "EngineInterface.h" |
|
#include "vgui_controls/ImagePanel.h" |
|
#include "vgui_controls/Label.h" |
|
#include "KeyValues.h" |
|
#include "vgui/ISurface.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
CSessionBrowserDialog *g_pBrowserDialog; |
|
|
|
//-------------------------------- |
|
// CSessionBrowserDialog |
|
//-------------------------------- |
|
CSessionBrowserDialog::CSessionBrowserDialog( vgui::Panel *pParent, KeyValues *pDialogKeys ) : BaseClass( pParent, "" ) |
|
{ |
|
g_pBrowserDialog = this; |
|
m_pDialogKeys = pDialogKeys; |
|
|
|
SetDeleteSelfOnClose( true ); |
|
} |
|
|
|
CSessionBrowserDialog::~CSessionBrowserDialog() |
|
{ |
|
m_pScenarioInfos.PurgeAndDeleteElements(); |
|
} |
|
|
|
//--------------------------------------------------------------------- |
|
// Purpose: Center the dialog on the screen |
|
//--------------------------------------------------------------------- |
|
void CSessionBrowserDialog::PerformLayout() |
|
{ |
|
BaseClass::PerformLayout(); |
|
|
|
MoveToCenterOfScreen(); |
|
UpdateScenarioDisplay(); |
|
} |
|
|
|
//--------------------------------------------------------------------- |
|
// Purpose: Parse session properties and contexts from the resource file |
|
//--------------------------------------------------------------------- |
|
void CSessionBrowserDialog::ApplySettings( KeyValues *pResourceData ) |
|
{ |
|
BaseClass::ApplySettings( pResourceData ); |
|
|
|
KeyValues *pScenarios = pResourceData->FindKey( "ScenarioInfoPanels" ); |
|
if ( pScenarios ) |
|
{ |
|
for ( KeyValues *pScenario = pScenarios->GetFirstSubKey(); pScenario != NULL; pScenario = pScenario->GetNextKey() ) |
|
{ |
|
CScenarioInfoPanel *pScenarioInfo = new CScenarioInfoPanel( this, "ScenarioInfoPanel" ); |
|
SETUP_PANEL( pScenarioInfo ); |
|
pScenarioInfo->m_pTitle->SetText( pScenario->GetString( "title" ) ); |
|
pScenarioInfo->m_pSubtitle->SetText( pScenario->GetString( "subtitle" ) ); |
|
pScenarioInfo->m_pMapImage->SetImage( pScenario->GetString( "image" ) ); |
|
|
|
int nTall = pScenario->GetInt( "tall", -1 ); |
|
if ( nTall > 0 ) |
|
{ |
|
pScenarioInfo->SetTall( nTall ); |
|
} |
|
|
|
int nXPos = pScenario->GetInt( "xpos", -1 ); |
|
if ( nXPos >= 0 ) |
|
{ |
|
int x, y; |
|
pScenarioInfo->GetPos( x, y ); |
|
pScenarioInfo->SetPos( nXPos, y ); |
|
} |
|
|
|
int nDescOneYpos = pScenario->GetInt( "descOneY", -1 ); |
|
if ( nDescOneYpos > 0 ) |
|
{ |
|
int x, y; |
|
pScenarioInfo->m_pDescOne->GetPos( x, y ); |
|
pScenarioInfo->m_pDescOne->SetPos( x, nDescOneYpos ); |
|
} |
|
|
|
int nDescTwoYpos = pScenario->GetInt( "descTwoY", -1 ); |
|
if ( nDescTwoYpos > 0 ) |
|
{ |
|
int x, y; |
|
pScenarioInfo->m_pDescTwo->GetPos( x, y ); |
|
pScenarioInfo->m_pDescTwo->SetPos( x, nDescTwoYpos ); |
|
} |
|
|
|
m_pScenarioInfos.AddToTail( pScenarioInfo ); |
|
} |
|
} |
|
} |
|
|
|
//--------------------------------------------------------------------- |
|
// Purpose: Set up colors and other such stuff |
|
//--------------------------------------------------------------------- |
|
void CSessionBrowserDialog::ApplySchemeSettings( vgui::IScheme *pScheme ) |
|
{ |
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
|
|
for ( int i = 0; i < m_pScenarioInfos.Count(); ++i ) |
|
{ |
|
m_pScenarioInfos[i]->SetBgColor( pScheme->GetColor( "TanDark", Color( 0, 0, 0, 255 ) ) ); |
|
} |
|
} |
|
|
|
//--------------------------------------------------------------------- |
|
// Purpose: Info about a session, sent from matchmaking |
|
//--------------------------------------------------------------------- |
|
void CSessionBrowserDialog::SessionSearchResult( int searchIdx, void *pHostData, XSESSION_SEARCHRESULT *pResult, int ping ) |
|
{ |
|
char *pPing; |
|
switch ( ping ) |
|
{ |
|
case 0: |
|
pPing = "#TF_Icon_Ping_Green"; |
|
break; |
|
case 1: |
|
pPing = "#TF_Icon_Ping_Yellow"; |
|
break; |
|
case 2: |
|
default: |
|
pPing = "#TF_Icon_Ping_Red"; |
|
break; |
|
} |
|
|
|
int nScenarioId = 0; |
|
uint nContextId = m_pDialogKeys->GetInt( "scenario", -1 ); |
|
for ( uint i = 0; i < pResult->cContexts; ++i ) |
|
{ |
|
if ( pResult->pContexts[i].dwContextId == nContextId ) |
|
{ |
|
nScenarioId = pResult->pContexts[i].dwValue; |
|
break; |
|
} |
|
} |
|
|
|
hostData_s *pData = (hostData_s*)pHostData; |
|
|
|
int filledSlots = pResult->dwFilledPublicSlots + pResult->dwFilledPrivateSlots; |
|
int totalSlots = filledSlots + pResult->dwOpenPublicSlots + pResult->dwOpenPrivateSlots; |
|
|
|
m_GameStates.AddToTail( pData->gameState ); |
|
m_GameTimes.AddToTail( pData->gameTime ); |
|
m_XUIDs.AddToTail( pData->xuid ); |
|
|
|
char szSlots[16] = {0}; |
|
Q_snprintf( szSlots, sizeof( szSlots ), "%d/%d", filledSlots, totalSlots ); |
|
|
|
int ct = 0; |
|
const char *ppStrings[4]; |
|
ppStrings[ct++] = pData->hostName; |
|
ppStrings[ct++] = szSlots; |
|
ppStrings[ct++] = pData->scenario; |
|
if ( ping != -1 ) |
|
{ |
|
ppStrings[ct++] = pPing; |
|
} |
|
m_Menu.AddSectionedItem( ppStrings, ct ); |
|
|
|
m_ScenarioIndices.AddToTail( nScenarioId ); |
|
m_SearchIndices.AddToTail( searchIdx ); |
|
|
|
if ( m_Menu.GetItemCount() == 1 ) |
|
{ |
|
m_Menu.SetFocus( 0 ); |
|
} |
|
|
|
UpdateScenarioDisplay(); |
|
} |
|
|
|
//----------------------------------------------------------------- |
|
// Purpose: Show the correct scenario image and text |
|
//----------------------------------------------------------------- |
|
void CSessionBrowserDialog::UpdateScenarioDisplay( void ) |
|
{ |
|
if ( !m_ScenarioIndices.Count() ) |
|
return; |
|
|
|
// Check if the selected map has changed (first menu item) |
|
int idx = m_Menu.GetActiveItemIndex(); |
|
for ( int i = 0; i < m_pScenarioInfos.Count(); ++i ) |
|
{ |
|
m_pScenarioInfos[i]->SetVisible( i == m_ScenarioIndices[idx] ); |
|
} |
|
|
|
// Get the screen size |
|
int wide, tall; |
|
vgui::surface()->GetScreenSize(wide, tall); |
|
bool bLodef = ( tall <= 480 ); |
|
|
|
const char *pState = ""; |
|
switch( m_GameStates[idx] ) |
|
{ |
|
case 0: |
|
if ( bLodef ) |
|
{ |
|
pState = "#TF_GameState_InLobby_lodef"; |
|
} |
|
else |
|
{ |
|
pState = "#TF_GameState_InLobby"; |
|
} |
|
break; |
|
|
|
case 1: |
|
if ( bLodef ) |
|
{ |
|
pState = "#TF_GameState_GameInProgress_lodef"; |
|
} |
|
else |
|
{ |
|
pState = "#TF_GameState_GameInProgress"; |
|
} |
|
break; |
|
} |
|
|
|
char szTime[32] = {0}; |
|
if ( m_GameTimes[idx] >= NO_TIME_LIMIT ) |
|
{ |
|
Q_strncpy( szTime, "#TF_NoTimeLimit", sizeof( szTime) ); |
|
} |
|
else |
|
{ |
|
Q_snprintf( szTime, sizeof( szTime), "%d:00", m_GameTimes[idx] ); |
|
} |
|
|
|
if ( !m_pScenarioInfos.IsValidIndex( m_ScenarioIndices[idx] ) ) |
|
return; |
|
|
|
CScenarioInfoPanel *pPanel = m_pScenarioInfos[ m_ScenarioIndices[idx] ]; |
|
pPanel->m_pDescOne->SetText( pState ); |
|
pPanel->m_pDescTwo->SetText( szTime ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------- |
|
// helper to swap two ints in a utlvector |
|
//----------------------------------------------------------------- |
|
static void Swap( CUtlVector< int > &vec, int iOne, int iTwo ) |
|
{ |
|
int temp = vec[iOne]; |
|
vec[iOne] = vec[iTwo]; |
|
vec[iTwo] = temp; |
|
} |
|
|
|
//----------------------------------------------------------------- |
|
// Purpose: Swap the order of two menu items |
|
//----------------------------------------------------------------- |
|
void CSessionBrowserDialog::SwapMenuItems( int iOne, int iTwo ) |
|
{ |
|
Swap( m_ScenarioIndices, iOne, iTwo ); |
|
Swap( m_SearchIndices, iOne, iTwo ); |
|
Swap( m_GameStates, iOne, iTwo ); |
|
Swap( m_GameTimes, iOne, iTwo ); |
|
|
|
// swap the XUIDs, too |
|
XUID temp = m_XUIDs[iOne]; |
|
m_XUIDs[iOne] = m_XUIDs[iTwo]; |
|
m_XUIDs[iTwo] = temp; |
|
} |
|
|
|
//----------------------------------------------------------------- |
|
// Purpose: Handle commands from the dialog menu |
|
//----------------------------------------------------------------- |
|
void CSessionBrowserDialog::OnCommand( const char *pCommand ) |
|
{ |
|
if ( !Q_stricmp( pCommand, "SelectSession" ) ) |
|
{ |
|
int idx = m_SearchIndices[ m_Menu.GetActiveItemIndex() ]; |
|
matchmaking->SelectSession( idx ); |
|
} |
|
|
|
m_pParent->OnCommand( pCommand ); |
|
} |
|
|
|
//----------------------------------------------------------------- |
|
// Purpose: Send key presses to the dialog's menu |
|
//----------------------------------------------------------------- |
|
void CSessionBrowserDialog::OnKeyCodePressed( vgui::KeyCode code ) |
|
{ |
|
switch( code ) |
|
{ |
|
case KEY_XBUTTON_B: |
|
matchmaking->KickPlayerFromSession( 0 ); |
|
break; |
|
case KEY_XBUTTON_X: |
|
#ifdef _X360 |
|
int idx = m_Menu.GetActiveItemIndex(); |
|
if ( m_XUIDs.IsValidIndex( idx ) ) |
|
{ |
|
XShowGamerCardUI( XBX_GetPrimaryUserId(), m_XUIDs[idx] ); |
|
} |
|
#endif |
|
break; |
|
} |
|
|
|
BaseClass::OnKeyCodePressed( code ); |
|
|
|
// Selected session may have been updated |
|
UpdateScenarioDisplay(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CSessionBrowserDialog::OnThink() |
|
{ |
|
vgui::KeyCode code = m_KeyRepeat.KeyRepeated(); |
|
if ( code ) |
|
{ |
|
m_Menu.HandleKeyCode( code ); |
|
UpdateScenarioDisplay(); |
|
} |
|
|
|
BaseClass::OnThink(); |
|
}
|
|
|