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.
631 lines
20 KiB
631 lines
20 KiB
5 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
//=============================================================================//
|
||
|
|
||
|
#include "cbase.h"
|
||
|
|
||
|
#include "ienginevgui.h"
|
||
|
#include "vgui/IVGui.h"
|
||
|
#include "vgui/IInput.h"
|
||
|
#include "vgui_controls/MenuItem.h"
|
||
|
#include "vgui_controls/PropertySheet.h"
|
||
|
|
||
|
#include "tf_party.h"
|
||
|
#include "tf_lobbypanel.h"
|
||
|
#include "tf_pvp_rank_panel.h"
|
||
|
|
||
|
#include "tf_lobby_container_frame.h"
|
||
|
#include "tf_controls.h"
|
||
|
|
||
|
#include "tf_item_inventory.h"
|
||
|
#include "tf_lobbypanel.h"
|
||
|
#include "tf_hud_mainmenuoverride.h"
|
||
|
#include "tf_matchmaking_dashboard.h"
|
||
|
#include "tf_ping_panel.h"
|
||
|
|
||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||
|
#include <tier0/memdbgon.h>
|
||
|
|
||
|
bool BIsPartyLeader()
|
||
|
{
|
||
|
CTFParty *pParty = GTFGCClientSystem()->GetParty();
|
||
|
return ( pParty == NULL || pParty->GetLeader() == steamapicontext->SteamUser()->GetSteamID() );
|
||
|
}
|
||
|
|
||
|
bool BIsPartyInUIState()
|
||
|
{
|
||
|
if ( !GCClientSystem()->BConnectedtoGC() )
|
||
|
return false;
|
||
|
CTFParty *pParty = GTFGCClientSystem()->GetParty();
|
||
|
return ( pParty == NULL || pParty->GetState() == CSOTFParty_State_UI );
|
||
|
}
|
||
|
|
||
|
CSteamID SteamIDFromDecimalString( const char *pszUint64InDecimal )
|
||
|
{
|
||
|
uint64 ulSteamID = 0;
|
||
|
if ( sscanf( pszUint64InDecimal, "%llu", &ulSteamID ) )
|
||
|
{
|
||
|
return CSteamID( ulSteamID );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Assert( false );
|
||
|
return CSteamID();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CBaseLobbyContainerFrame::CBaseLobbyContainerFrame( const char* pszPanelName )
|
||
|
: vgui::PropertyDialog( NULL, pszPanelName )
|
||
|
, m_bNextButtonEnabled( false )
|
||
|
, m_pContextMenu( NULL )
|
||
|
{
|
||
|
vgui::VPANEL gameuiPanel = enginevgui->GetPanel( PANEL_GAMEUIDLL );
|
||
|
SetParent( gameuiPanel );
|
||
|
|
||
|
SetMoveable( false );
|
||
|
SetSizeable( false );
|
||
|
|
||
|
vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme");
|
||
|
SetScheme(scheme);
|
||
|
SetProportional( true );
|
||
|
|
||
|
ListenForGameEvent( "gameui_hidden" );
|
||
|
|
||
|
ListenForGameEvent( "lobby_updated" );
|
||
|
ListenForGameEvent( "party_updated" );
|
||
|
ListenForGameEvent( "client_beginconnect" );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CBaseLobbyContainerFrame::~CBaseLobbyContainerFrame( void )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseLobbyContainerFrame::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||
|
{
|
||
|
BaseClass::ApplySchemeSettings( pScheme );
|
||
|
|
||
|
// load control settings...
|
||
|
LoadControlSettings( GetResFile() );
|
||
|
|
||
|
m_pStartPartyButton = dynamic_cast<vgui::Button *>(FindChildByName( "StartPartyButton", true )); Assert( m_pStartPartyButton );
|
||
|
m_pBackButton = dynamic_cast<vgui::Button *>( FindChildByName( "BackButton", true ) ); Assert( m_pBackButton );
|
||
|
m_pNextButton = dynamic_cast<vgui::Button *>( FindChildByName( "NextButton", true ) ); Assert( m_pNextButton );
|
||
|
|
||
|
SetOKButtonVisible(false);
|
||
|
SetCancelButtonVisible(false);
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseLobbyContainerFrame::ShowPanel(bool bShow)
|
||
|
{
|
||
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ );
|
||
|
|
||
|
// Keep the MM dashboard on top of us
|
||
|
bShow ? GetMMDashboardParentManager()->PushModalFullscreenPopup( this )
|
||
|
: GetMMDashboardParentManager()->PopModalFullscreenPopup( this );
|
||
|
|
||
|
m_pContents->SetControlVisible( "PartyActiveGroupBox", false );
|
||
|
|
||
|
// Make sure we're signed on
|
||
|
if ( bShow )
|
||
|
{
|
||
|
if ( GetPropertySheet()->GetActivePage() != m_pContents )
|
||
|
{
|
||
|
GetPropertySheet()->SetActivePage( m_pContents );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// VGUI doesn't tell the starting active page that it's active, so we post a pageshow to it
|
||
|
vgui::ivgui()->PostMessage( m_pContents->GetVPanel(), new KeyValues("PageShow"), GetPropertySheet()->GetVPanel() );
|
||
|
}
|
||
|
|
||
|
Activate();
|
||
|
|
||
|
// I don't know why, I don't want to know why, I shouldn't
|
||
|
// have to wonder why, but for whatever reason this stupid
|
||
|
// panel isn't laying out correctly unless we do this terribleness
|
||
|
InvalidateLayout( true );
|
||
|
m_pContents->InvalidateLayout( true, true );
|
||
|
|
||
|
GTFGCClientSystem()->SetLocalPlayerSquadSurplus( false );
|
||
|
WriteControls();
|
||
|
m_pContents->UpdateControls();
|
||
|
|
||
|
Panel* pPvPRankPanel = FindChildByName( "RankPanel", true );
|
||
|
if ( pPvPRankPanel )
|
||
|
{
|
||
|
pPvPRankPanel->OnCommand( "update_base_state" );
|
||
|
pPvPRankPanel->OnCommand( "begin_xp_lerp" );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( m_hPingPanel )
|
||
|
{
|
||
|
m_hPingPanel->MarkForDeletion();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
OnCommand( "leave_party" );
|
||
|
|
||
|
SetVisible( bShow );
|
||
|
m_pContents->SetVisible( bShow );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseLobbyContainerFrame::SetNextButtonEnabled( bool bValue )
|
||
|
{
|
||
|
m_bNextButtonEnabled = bValue;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseLobbyContainerFrame::OnThink()
|
||
|
{
|
||
|
BaseClass::OnThink();
|
||
|
|
||
|
// Check if we don't want to be here, then get out!
|
||
|
if ( GTFGCClientSystem()->GetMatchmakingUIState() == eMatchmakingUIState_Inactive )
|
||
|
{
|
||
|
Msg( "Hiding LobbyContainerFrame" );
|
||
|
ShowPanel(false);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
WriteControls();
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseLobbyContainerFrame::FireGameEvent( IGameEvent *event )
|
||
|
{
|
||
|
if ( GTFGCClientSystem()->GetSearchMode() != GetHandledMode() )
|
||
|
return;
|
||
|
|
||
|
const char *pszEventname = event->GetName();
|
||
|
if ( !Q_stricmp( pszEventname, "lobby_updated" ) || !Q_stricmp( pszEventname, "party_updated" ) )
|
||
|
{
|
||
|
WriteControls();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Bail when we connect to any server
|
||
|
if ( !Q_stricmp( pszEventname, "client_beginconnect" ) )
|
||
|
{
|
||
|
ShowPanel( false );
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseLobbyContainerFrame::StartSearch( void )
|
||
|
{
|
||
|
// Is anyone banned from matchmaking?
|
||
|
RTime32 rtimeExpire = 0;
|
||
|
if ( m_pContents->IsAnyoneBanned( rtimeExpire ) )
|
||
|
{
|
||
|
CRTime timeExpire( rtimeExpire );
|
||
|
timeExpire.SetToGMT( false );
|
||
|
char out_buf[k_RTimeRenderBufferSize];
|
||
|
wchar_t wszExpire[512];
|
||
|
wchar_t wszLocalized[512];
|
||
|
g_pVGuiLocalize->ConvertANSIToUnicode( timeExpire.Render( out_buf ), wszExpire, sizeof( wszExpire ) );
|
||
|
g_pVGuiLocalize->ConstructString_safe( wszLocalized, g_pVGuiLocalize->Find( "#TF_Matchmaking_Banned" ), 1, wszExpire );
|
||
|
ShowMessageBox( "#TF_Matchmaking_Title", wszLocalized, "#GameUI_OK" );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( VerifyPartyAuthorization() )
|
||
|
{
|
||
|
GTFGCClientSystem()->RequestSelectWizardStep( TF_Matchmaking_WizardStep_SEARCHING );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseLobbyContainerFrame::OnCommand( const char *command )
|
||
|
{
|
||
|
if ( FStrEq( command, "options" ) )
|
||
|
{
|
||
|
OpenOptionsContextMenu();
|
||
|
}
|
||
|
else if ( FStrEq( command, "back" ) )
|
||
|
{
|
||
|
if ( !GCClientSystem()->BConnectedtoGC() || !BIsPartyLeader() )
|
||
|
{
|
||
|
// TODO: Remove this when we have the dashboard everywhere.
|
||
|
// Well...this entire panel should be gone.
|
||
|
GTFGCClientSystem()->EndMatchmaking();
|
||
|
// And hide us
|
||
|
ShowPanel( false );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
HandleBackPressed();
|
||
|
}
|
||
|
else if ( FStrEq( command, "leave_party" ) )
|
||
|
{
|
||
|
m_pStartPartyButton->SetVisible( true );
|
||
|
SetControlVisible( "PlayWithFriendsExplanation", true );
|
||
|
m_pContents->SetControlVisible( "PartyActiveGroupBox", false );
|
||
|
}
|
||
|
else if ( FStrEq( command, "start_party" ) )
|
||
|
{
|
||
|
m_pStartPartyButton->SetVisible( false );
|
||
|
SetControlVisible( "PlayWithFriendsExplanation", false );
|
||
|
m_pContents->SetControlVisible( "PartyActiveGroupBox", true );
|
||
|
|
||
|
Assert( steamapicontext );
|
||
|
|
||
|
IGameEvent *pEvent = gameeventmanager->CreateEvent( "mm_lobby_member_join" );
|
||
|
if ( pEvent )
|
||
|
{
|
||
|
pEvent->SetString( "steamid", CFmtStr( "%llu", steamapicontext->SteamUser()->GetSteamID().ConvertToUint64() ) );
|
||
|
pEvent->SetInt( "solo", 1 );
|
||
|
gameeventmanager->FireEventClientSide( pEvent );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
// What other commands are there?
|
||
|
Assert( false );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseLobbyContainerFrame::PerformLayout( void )
|
||
|
{
|
||
|
if ( GetVParent() )
|
||
|
{
|
||
|
int w,h;
|
||
|
vgui::ipanel()->GetSize( GetVParent(), w, h );
|
||
|
SetBounds(0,0,w,h);
|
||
|
}
|
||
|
|
||
|
BaseClass::PerformLayout();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
static void LeaveSearch( bool bConfirmed, void *pContext )
|
||
|
{
|
||
|
if ( bConfirmed )
|
||
|
{
|
||
|
switch ( GTFGCClientSystem()->GetSearchMode() )
|
||
|
{
|
||
|
case TF_Matchmaking_MVM:
|
||
|
GTFGCClientSystem()->RequestSelectWizardStep( TF_Matchmaking_WizardStep_MVM_CHALLENGE );
|
||
|
break;
|
||
|
|
||
|
case TF_Matchmaking_LADDER:
|
||
|
GTFGCClientSystem()->RequestSelectWizardStep( TF_Matchmaking_WizardStep_LADDER );
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
AssertMsg1( false, "Unknown search mode %d", (int)GTFGCClientSystem()->GetSearchMode() );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseLobbyContainerFrame::OnKeyCodeTyped(vgui::KeyCode code)
|
||
|
{
|
||
|
if ( code == KEY_ESCAPE )
|
||
|
{
|
||
|
if ( m_pContents->IsPartyActiveGroupBoxVisible() )
|
||
|
{
|
||
|
ShowConfirmDialog( "#TF_MM_LeaveParty_Title", "#TF_MM_LeaveParty_Confirm",
|
||
|
"#TF_Coach_Yes", "#TF_Coach_No",
|
||
|
&CBaseLobbyContainerFrame::LeaveLobbyPanel );
|
||
|
return;
|
||
|
}
|
||
|
else if ( GTFGCClientSystem()->GetWizardStep() == TF_Matchmaking_WizardStep_SEARCHING )
|
||
|
{
|
||
|
ShowConfirmDialog( "#TF_MM_LeaveQueue_Title", "#TF_MM_LeaveQueue_Confirm",
|
||
|
"#TF_Coach_Yes", "#TF_Coach_No",
|
||
|
&LeaveSearch );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
OnCommand( "back" );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
BaseClass::OnKeyCodeTyped( code );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseLobbyContainerFrame::OnKeyCodePressed(vgui::KeyCode code)
|
||
|
{
|
||
|
ButtonCode_t nButtonCode = GetBaseButtonCode( code );
|
||
|
|
||
|
if ( nButtonCode == KEY_XBUTTON_B || nButtonCode == STEAMCONTROLLER_B || nButtonCode == STEAMCONTROLLER_START )
|
||
|
{
|
||
|
OnCommand( "back" );
|
||
|
return;
|
||
|
}
|
||
|
else if ( nButtonCode == KEY_XBUTTON_X )
|
||
|
{
|
||
|
m_pContents->ToggleJoinLateCheckButton();
|
||
|
}
|
||
|
|
||
|
BaseClass::OnKeyCodePressed( code );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseLobbyContainerFrame::WriteControls()
|
||
|
{
|
||
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ );
|
||
|
|
||
|
if ( !IsVisible() )
|
||
|
return;
|
||
|
|
||
|
// Make sure we want to be in matchmaking. (If we don't, the frame should hide us pretty quickly.)
|
||
|
// We might get an event or something right at the transition point occasionally when the UI should
|
||
|
// not be visible
|
||
|
if ( GTFGCClientSystem()->GetMatchmakingUIState() == eMatchmakingUIState_Inactive )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
bool bNoGC = false;
|
||
|
if ( !GCClientSystem()->BConnectedtoGC() ||
|
||
|
GTFGCClientSystem()->BHaveLiveMatch() ||
|
||
|
( GTFGCClientSystem()->GetParty() && GTFGCClientSystem()->GetParty()->BOffline() ) )
|
||
|
{
|
||
|
bNoGC = true;
|
||
|
}
|
||
|
|
||
|
SetControlVisible( "PlayWithFriendsExplanation", !bNoGC && ShouldShowPartyButton(), true );
|
||
|
SetControlVisible( "RankPanel", !bNoGC, true );
|
||
|
SetControlVisible( "NoGCGroupBox", bNoGC, true );
|
||
|
|
||
|
GetPropertySheet()->SetTabWidth( -1 );
|
||
|
|
||
|
// Check if we already have a party, then make sure and show it
|
||
|
if ( !m_pStartPartyButton->IsVisible() && m_pContents->NumPlayersInParty() > 1 )
|
||
|
{
|
||
|
m_pContents->SetControlVisible( "PartyActiveGroupBox", true );
|
||
|
}
|
||
|
|
||
|
// Show/hide start party button as appropriate
|
||
|
bool bShowPartyButton = ShouldShowPartyButton();
|
||
|
|
||
|
m_pStartPartyButton->SetVisible( bShowPartyButton && !bNoGC );
|
||
|
|
||
|
// Check for matchmaking bans and display time remaining if we're banned
|
||
|
if ( steamapicontext == NULL || steamapicontext->SteamUser() == NULL )
|
||
|
return;
|
||
|
|
||
|
CEconGameAccountClient *pGameAccountClient = NULL;
|
||
|
if ( InventoryManager() && TFInventoryManager()->GetLocalTFInventory() && TFInventoryManager()->GetLocalTFInventory()->GetSOC() )
|
||
|
{
|
||
|
pGameAccountClient = TFInventoryManager()->GetLocalTFInventory()->GetSOC()->GetSingleton<CEconGameAccountClient>();
|
||
|
}
|
||
|
|
||
|
const IMatchGroupDescription *pMatchDesc = GetMatchGroupDescription( m_pContents->GetMatchGroup() );
|
||
|
EMMPenaltyPool ePenaltyPool = pMatchDesc ? pMatchDesc->m_params.m_ePenaltyPool : eMMPenaltyPool_Invalid;
|
||
|
|
||
|
CRTime timeExpire = CRTime::RTime32TimeCur();
|
||
|
int nDuration = -1;
|
||
|
bool bBanned = false;
|
||
|
|
||
|
if ( pGameAccountClient && ePenaltyPool != eMMPenaltyPool_Invalid )
|
||
|
{
|
||
|
switch ( ePenaltyPool )
|
||
|
{
|
||
|
case eMMPenaltyPool_Casual:
|
||
|
timeExpire = pGameAccountClient->Obj().matchmaking_casual_ban_expiration();
|
||
|
nDuration = pGameAccountClient->Obj().matchmaking_casual_ban_last_duration();
|
||
|
bBanned = timeExpire > CRTime::RTime32TimeCur();
|
||
|
break;
|
||
|
case eMMPenaltyPool_Ranked:
|
||
|
timeExpire = pGameAccountClient->Obj().matchmaking_ranked_ban_expiration();
|
||
|
nDuration = pGameAccountClient->Obj().matchmaking_ranked_ban_last_duration();
|
||
|
bBanned = timeExpire > CRTime::RTime32TimeCur();
|
||
|
break;
|
||
|
default: Assert( false );
|
||
|
}
|
||
|
|
||
|
SetControlVisible( "MatchmakingBanPanel", bBanned );
|
||
|
|
||
|
if ( bBanned )
|
||
|
{
|
||
|
CExLabel *pBanLabel = FindControl<CExLabel>( "MatchmakingBanDurationLabel", true );
|
||
|
|
||
|
if ( pBanLabel )
|
||
|
{
|
||
|
timeExpire.SetToGMT( false );
|
||
|
|
||
|
CRTime rtNow = CRTime::RTime32TimeCur();
|
||
|
|
||
|
int nSecondsRemaining = timeExpire.GetRTime32() - rtNow.GetRTime32();
|
||
|
|
||
|
if ( nSecondsRemaining >= 0 )
|
||
|
{
|
||
|
|
||
|
const int nDaysForLongBan = 2;
|
||
|
|
||
|
int nDaysRemaining = nSecondsRemaining / 86400;
|
||
|
int nHoursRemaining = nSecondsRemaining / 3600;
|
||
|
int nMinutesRemaining = ( nSecondsRemaining % 3600 ) / 60;
|
||
|
|
||
|
int nDurationDays = nDuration / 86400;
|
||
|
int nDurationHours = nDuration / 3600;
|
||
|
int nDurationMinutes = ( nDuration % 3600 ) / 60;
|
||
|
|
||
|
// Want the remainder hours if we're going to display 'days' remaining
|
||
|
if ( nDurationDays >= nDaysForLongBan )
|
||
|
{
|
||
|
nDurationHours = ( nDuration % ( 86400 * nDurationDays ) ) / 3600;
|
||
|
|
||
|
if ( nDaysRemaining >= nDaysForLongBan )
|
||
|
{
|
||
|
nHoursRemaining = ( nSecondsRemaining % ( 86400 * nDaysRemaining ) ) / 3600;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
wchar_t wszDaysRemaining[16];
|
||
|
wchar_t wszHoursRemaining[16];
|
||
|
wchar_t wszMinutesRemaining[16];
|
||
|
wchar_t wszDurationDays[16];
|
||
|
wchar_t wszDurationHours[16];
|
||
|
wchar_t wszDurationMinutes[16];
|
||
|
|
||
|
_snwprintf( wszDaysRemaining, ARRAYSIZE( wszDaysRemaining ), L"%d", nDaysRemaining );
|
||
|
_snwprintf( wszHoursRemaining, ARRAYSIZE( wszHoursRemaining ), L"%d", nHoursRemaining );
|
||
|
_snwprintf( wszMinutesRemaining, ARRAYSIZE( wszMinutesRemaining ), L"%d", nMinutesRemaining );
|
||
|
_snwprintf( wszDurationDays, ARRAYSIZE( wszDurationDays ), L"%d", nDurationDays );
|
||
|
_snwprintf( wszDurationHours, ARRAYSIZE( wszDurationHours ), L"%d", nDurationHours );
|
||
|
_snwprintf( wszDurationMinutes, ARRAYSIZE( wszDurationMinutes ), L"%d", nDurationMinutes );
|
||
|
|
||
|
wchar_t wszLocalized[512];
|
||
|
|
||
|
// Short ban (less than "nDaysForLongBan" days and thus less than that remaining)
|
||
|
if ( nDurationDays < nDaysForLongBan )
|
||
|
{
|
||
|
// Less than an hour ban
|
||
|
if ( nDurationHours < 1 )
|
||
|
{
|
||
|
g_pVGuiLocalize->ConstructString_safe( wszLocalized, g_pVGuiLocalize->Find( "#TF_Matchmaking_Ban_Duration_Remaining_Short" ), 2, wszDurationMinutes, wszMinutesRemaining );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
g_pVGuiLocalize->ConstructString_safe( wszLocalized, g_pVGuiLocalize->Find( "#TF_Matchmaking_Ban_Duration_Remaining" ), 4, wszDurationHours, wszDurationMinutes, wszHoursRemaining, wszMinutesRemaining );
|
||
|
}
|
||
|
}
|
||
|
// Long ban (at least "nDaysForLongBan" days) but less than that remaining
|
||
|
else if ( nDaysRemaining < nDaysForLongBan )
|
||
|
{
|
||
|
g_pVGuiLocalize->ConstructString_safe( wszLocalized, g_pVGuiLocalize->Find( "#TF_Matchmaking_Ban_Duration_Remaining_Long_Penalty_Short_Duration" ), 4, wszDurationDays, wszDurationHours, wszHoursRemaining, wszMinutesRemaining );
|
||
|
}
|
||
|
// Long ban and at least that long remaining)
|
||
|
else
|
||
|
{
|
||
|
g_pVGuiLocalize->ConstructString_safe( wszLocalized, g_pVGuiLocalize->Find( "TF_Matchmaking_Ban_Duration_Remaining_Long_Penalty" ), 4, wszDurationDays, wszDurationHours, wszDaysRemaining, wszHoursRemaining );
|
||
|
}
|
||
|
pBanLabel->SetText( wszLocalized );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pBanLabel->SetText( "#TF_Matchmaking_Ban_Duration_Remaining_Shortly" );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_pNextButton->SetEnabled( m_bNextButtonEnabled && !bBanned && !bNoGC );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Handle cases not handled by our derived classes
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseLobbyContainerFrame::HandleBackPressed()
|
||
|
{
|
||
|
// We dont know how or why we got here. Failsafe and just leave.
|
||
|
if( GTFGCClientSystem()->GetSearchMode() != GetHandledMode() )
|
||
|
{
|
||
|
Msg( "Lobby handles mode %d, but search mode is %d. Ending matchmaking", (int)( GetHandledMode() ), (int)( GTFGCClientSystem()->GetSearchMode() ) );
|
||
|
}
|
||
|
|
||
|
GTFGCClientSystem()->EndMatchmaking();
|
||
|
ShowPanel( false );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CBaseLobbyContainerFrame::ShouldShowPartyButton() const
|
||
|
{
|
||
|
return !m_pContents->IsPartyActiveGroupBoxVisible() &&
|
||
|
GTFGCClientSystem()->GetWizardStep() != TF_Matchmaking_WizardStep_SEARCHING &&
|
||
|
GCClientSystem()->BConnectedtoGC() &&
|
||
|
BIsPartyLeader();
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseLobbyContainerFrame::OpenOptionsContextMenu()
|
||
|
{
|
||
|
if ( m_pContextMenu )
|
||
|
delete m_pContextMenu;
|
||
|
|
||
|
m_pContextMenu = new Menu( this, "ContextMenu" );
|
||
|
MenuBuilder contextMenuBuilder( m_pContextMenu, this );
|
||
|
const char *pszContextMenuBorder = "NotificationDefault";
|
||
|
const char *pszContextMenuFont = "HudFontMediumSecondary";
|
||
|
m_pContextMenu->SetBorder( scheme()->GetIScheme( GetScheme() )->GetBorder( pszContextMenuBorder ) );
|
||
|
m_pContextMenu->SetFont( scheme()->GetIScheme( GetScheme() )->GetFont( pszContextMenuFont ) );
|
||
|
|
||
|
contextMenuBuilder.AddMenuItem( "#TF_LobbyContainer_Ping", new KeyValues( "Context_Ping" ), "ping" );
|
||
|
contextMenuBuilder.AddMenuItem( "#TF_LobbyContainer_Help", "show_explanations", "help" );
|
||
|
|
||
|
m_pContextMenu->SetVisible(true);
|
||
|
m_pContextMenu->AddActionSignalTarget(this);
|
||
|
|
||
|
m_pContextMenu->MakeReadyForUse();
|
||
|
|
||
|
Panel* pOptionsButton = FindChildByName( "OptionsButton" );
|
||
|
|
||
|
if ( !pOptionsButton )
|
||
|
{
|
||
|
// Position to the cursor's position
|
||
|
int nX, nY;
|
||
|
g_pVGuiInput->GetCursorPosition( nX, nY );
|
||
|
m_pContextMenu->SetPos( nX - 1, nY - 1 );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
int nOptionsX = pOptionsButton->GetXPos();
|
||
|
int nX = Min( nOptionsX, GetWide() - m_pContextMenu->GetWide() );
|
||
|
int nY = pOptionsButton->GetYPos() + pOptionsButton->GetTall();
|
||
|
m_pContextMenu->SetPos( nX - 1, nY - 1 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseLobbyContainerFrame::OpenPingOptions()
|
||
|
{
|
||
|
// just create a new one. panel will destroy itself on close.
|
||
|
m_hPingPanel = new CTFPingPanel( this, "PingPanel", m_pContents->GetMatchGroup() );
|
||
|
}
|