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();
|
|
}
|