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.
826 lines
27 KiB
826 lines
27 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
#include "cbase.h" |
|
|
|
#include "tf_party.h" |
|
#include "vgui_controls/PropertySheet.h" |
|
#include "vgui_controls/ScrollableEditablePanel.h" |
|
|
|
#include "tf_lobbypanel_comp.h" |
|
#include "tf_lobby_container_frame_comp.h" |
|
|
|
#include "vgui/ISystem.h" |
|
|
|
#include "tf_streams.h" |
|
#include "tf_badge_panel.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include <tier0/memdbgon.h> |
|
|
|
ConVar tf_mm_ladder_ui_last_rating_change( "tf_mm_ladder_ui_last_rating_change", "0", FCVAR_HIDDEN | FCVAR_ARCHIVE, "Track last match skillrating change for UI." ); |
|
ConVar tf_mm_ladder_ui_last_rating_time( "tf_mm_ladder_ui_last_rating_time", "-1", FCVAR_HIDDEN | FCVAR_ARCHIVE, "Track last match skillrating change time for UI." ); |
|
|
|
class CLobbyPanel_Comp; |
|
|
|
#include "iclientmode.h" |
|
#include <vgui_controls/AnimationController.h> |
|
|
|
class CMatchHistoryEntryPanel : public CExpandablePanel |
|
{ |
|
public: |
|
DECLARE_CLASS_SIMPLE( CMatchHistoryEntryPanel, CExpandablePanel ); |
|
CMatchHistoryEntryPanel( Panel* pParent, const char *pszPanelname ) |
|
: BaseClass( pParent, pszPanelname ) |
|
{} |
|
|
|
virtual void ApplySchemeSettings( IScheme *pScheme ) OVERRIDE |
|
{ |
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
|
|
LoadControlSettings( "resource/ui/MatchHistoryEntryPanel.res" ); |
|
} |
|
|
|
void SetMatchData( const CSOTFMatchResultPlayerStats& stats ) |
|
{ |
|
EditablePanel* pContainer = FindControl< EditablePanel >( "Container" ); |
|
if ( !pContainer ) |
|
return; |
|
|
|
// Match date |
|
CRTime matchdate( stats.endtime() ); |
|
char rtime_buf[k_RTimeRenderBufferSize]; |
|
matchdate.Render( rtime_buf ); |
|
pContainer->SetDialogVariable( "match_date", rtime_buf ); |
|
|
|
// Map name |
|
const MapDef_t* pMapDef = GetItemSchema()->GetMasterMapDefByIndex( stats.map_index() ); |
|
const char* pszMapToken = "#TF_Map_Unknown"; |
|
if ( pMapDef ) |
|
{ |
|
pszMapToken = pMapDef->pszMapNameLocKey; |
|
} |
|
pContainer->SetDialogVariable( "map_name", g_pVGuiLocalize->Find( pszMapToken ) ); |
|
|
|
// KD ratio |
|
float flKDRatio = stats.kills(); |
|
if ( stats.deaths() > 0 ) |
|
{ |
|
flKDRatio /= (float)stats.deaths(); |
|
} |
|
pContainer->SetDialogVariable( "kd_ratio", CFmtStr( "%.1f", flKDRatio ) ); |
|
|
|
pContainer->SetControlVisible( "WinLabel", stats.display_rating_change() > 0 ); |
|
pContainer->SetControlVisible( "LossLabel", stats.display_rating_change() < 0 ); |
|
|
|
EditablePanel* pStatsContainer = FindControl< EditablePanel >( "SlidingStatsContainer", true ); |
|
if ( pStatsContainer ) |
|
{ |
|
pStatsContainer->SetDialogVariable( "stat_kills", LocalizeNumberWithToken( "TF_Competitive_Kills", stats.kills() ) ); |
|
pStatsContainer->SetDialogVariable( "stat_deaths", LocalizeNumberWithToken( "TF_Competitive_Deaths", stats.deaths() ) ); |
|
pStatsContainer->SetDialogVariable( "stat_damage", LocalizeNumberWithToken( "TF_Competitive_Damage", stats.damage() ) ); |
|
pStatsContainer->SetDialogVariable( "stat_healing", LocalizeNumberWithToken( "TF_Competitive_Healing", stats.healing() ) ); |
|
pStatsContainer->SetDialogVariable( "stat_support", LocalizeNumberWithToken( "TF_Competitive_Support", stats.support() ) ); |
|
pStatsContainer->SetDialogVariable( "stat_score", LocalizeNumberWithToken( "TF_Competitive_Score", stats.score() ) ); |
|
|
|
ScalableImagePanel* pMapImage = pStatsContainer->FindControl< ScalableImagePanel >( "BGImage", true ); |
|
if ( pMapImage && pMapDef ) |
|
{ |
|
char imagename[ 512 ]; |
|
Q_snprintf( imagename, sizeof( imagename ), "..\\vgui\\maps\\menu_thumb_%s", pMapDef->pszMapName ); |
|
pMapImage->SetImage( imagename ); |
|
} |
|
|
|
// Lambdas, wherefore art thou... |
|
SetupClassIcon( pStatsContainer, "scout", TF_CLASS_SCOUT, stats ); |
|
SetupClassIcon( pStatsContainer, "soldier", TF_CLASS_SOLDIER, stats ); |
|
SetupClassIcon( pStatsContainer, "pyro", TF_CLASS_PYRO, stats ); |
|
SetupClassIcon( pStatsContainer, "demo", TF_CLASS_DEMOMAN, stats ); |
|
SetupClassIcon( pStatsContainer, "heavy", TF_CLASS_HEAVYWEAPONS, stats ); |
|
SetupClassIcon( pStatsContainer, "engineer", TF_CLASS_ENGINEER, stats ); |
|
SetupClassIcon( pStatsContainer, "medic", TF_CLASS_MEDIC, stats ); |
|
SetupClassIcon( pStatsContainer, "sniper", TF_CLASS_SNIPER, stats ); |
|
SetupClassIcon( pStatsContainer, "spy", TF_CLASS_SPY, stats ); |
|
|
|
SetupMedalForStat( pStatsContainer, stats.kills_medal(), "kills" ); |
|
SetupMedalForStat( pStatsContainer, stats.damage_medal(), "damage" ); |
|
SetupMedalForStat( pStatsContainer, stats.healing_medal(), "healing" ); |
|
SetupMedalForStat( pStatsContainer, stats.support_medal(), "support" ); |
|
SetupMedalForStat( pStatsContainer, stats.score_medal(), "score" ); |
|
} |
|
} |
|
private: |
|
|
|
void SetupMedalForStat( EditablePanel* pParent, int nStat, const char* pszStatName ) |
|
{ |
|
ScalableImagePanel* pMedalImage = pParent->FindControl< ScalableImagePanel >( CFmtStr( "%sMedal", pszStatName ) ); |
|
if ( pMedalImage ) |
|
{ |
|
if ( nStat != StatMedal_None ) |
|
{ |
|
pMedalImage->SetImage( g_pszCompetitiveMedalImages[ nStat ] ); |
|
} |
|
pMedalImage->SetVisible( nStat != StatMedal_None ); |
|
} |
|
} |
|
|
|
void SetupClassIcon( EditablePanel* pParent, const char* pszClassName, int nBit, const CSOTFMatchResultPlayerStats& stats ) |
|
{ |
|
ScalableImagePanel* pClassIcon = pParent->FindControl< ScalableImagePanel >( CFmtStr( "%sIcon", pszClassName ), true ); |
|
if( pClassIcon ) |
|
{ |
|
pClassIcon->SetImage( stats.classes_played() & (1<<nBit) ? CFmtStr( "class_icons/filter_%s_on", pszClassName ) : CFmtStr( "class_icons/filter_%s", pszClassName ) ); |
|
} |
|
} |
|
}; |
|
|
|
DECLARE_BUILD_FACTORY( CMatchHistoryEntryPanel ); |
|
|
|
extern Color s_colorChallengeHeader; |
|
|
|
DECLARE_BUILD_FACTORY( CLadderLobbyLeaderboard ); |
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CLadderLobbyLeaderboard::CLadderLobbyLeaderboard( Panel *pParent, const char *pszPanelName ) |
|
: CTFLeaderboardPanel( pParent, pszPanelName ) |
|
{ |
|
m_pScoreList = new vgui::EditablePanel( this, "ScoreList" ); |
|
m_pScoreListScroller = new vgui::ScrollableEditablePanel( this, m_pScoreList, "ScoreListScroller" ); |
|
m_pScoreListScroller->AddActionSignalTarget( this ); |
|
|
|
m_pszLeaderboardName = "tf2_ladder_6v6"; |
|
|
|
for ( int i = 0; i < 100; ++i ) |
|
{ |
|
vgui::EditablePanel *pEntryUI = new vgui::EditablePanel( m_pScoreList, "LeaderboardEntry" ); |
|
m_vecLeaderboardEntries.AddToTail( pEntryUI ); |
|
} |
|
|
|
m_pToolTip = new CTFTextToolTip( this ); |
|
m_pToolTipEmbeddedPanel = new vgui::EditablePanel( this, "TooltipPanel" ); |
|
m_pToolTipEmbeddedPanel->SetKeyBoardInputEnabled( false ); |
|
m_pToolTipEmbeddedPanel->SetMouseInputEnabled( false ); |
|
m_pToolTip->SetEmbeddedPanel( m_pToolTipEmbeddedPanel ); |
|
m_pToolTip->SetTooltipDelay( 0 ); |
|
|
|
m_bIsDataValid = false; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CLadderLobbyLeaderboard::ApplySchemeSettings( vgui::IScheme *pScheme ) |
|
{ |
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
|
|
LoadControlSettings( "Resource/UI/econ/LobbyLeaderboard.res" ); |
|
|
|
FOR_EACH_VEC( m_vecLeaderboardEntries, i ) |
|
{ |
|
m_vecLeaderboardEntries[i]->ApplySchemeSettings( pScheme ); |
|
m_vecLeaderboardEntries[i]->LoadControlSettings( "Resource/UI/LeaderboardEntryRank.res" ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CLadderLobbyLeaderboard::PerformLayout() |
|
{ |
|
BaseClass::PerformLayout(); |
|
|
|
UpdateLeaderboards(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CLadderLobbyLeaderboard::OnCommand( const char *command ) |
|
{ |
|
if ( Q_strnicmp( command, "stream", 6 ) == 0 ) |
|
{ |
|
vgui::system()->ShellExecute( "open", command + 7 ); |
|
return; |
|
} |
|
else if ( FStrEq( "global", command ) ) |
|
{ |
|
if ( m_bGlobal != true ) |
|
{ |
|
m_bGlobal = true; |
|
UpdateLeaderboards(); |
|
} |
|
|
|
return; |
|
} |
|
else if ( FStrEq( "local", command ) ) |
|
{ |
|
if ( m_bGlobal == true ) |
|
{ |
|
m_bGlobal = false; |
|
UpdateLeaderboards(); |
|
} |
|
} |
|
|
|
BaseClass::OnCommand( command ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
bool CLadderLobbyLeaderboard::GetLeaderboardData( CUtlVector< LeaderboardEntry_t* >& scores ) |
|
{ |
|
CUtlVector< LeaderboardEntry_t* > vecLadderScores; |
|
if ( Leaderboards_GetLadderLeaderboard( vecLadderScores, m_pszLeaderboardName, m_bGlobal ) ) |
|
{ |
|
scores.AddVectorToTail( vecLadderScores ); |
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
bool CLadderLobbyLeaderboard::UpdateLeaderboards() |
|
{ |
|
CUtlVector< LeaderboardEntry_t* > scores; |
|
m_bIsDataValid = GetLeaderboardData( scores ); |
|
if ( !m_bIsDataValid ) |
|
return false; |
|
|
|
int nScoreListHeight = scores.Count() * m_yEntryStep; |
|
int nScrollerWidth, nScrollerHeight; |
|
m_pScoreListScroller->GetSize( nScrollerWidth, nScrollerHeight ); |
|
|
|
m_pScoreList->SetSize( nScrollerWidth, Max( nScoreListHeight, nScrollerHeight ) ); |
|
|
|
m_pScoreList->InvalidateLayout( true ); |
|
m_pScoreListScroller->InvalidateLayout( true ); |
|
m_pScoreListScroller->GetScrollbar()->InvalidateLayout( true ); |
|
static int nScrollWidth = m_pScoreListScroller->GetScrollbar()->GetWide(); |
|
m_pScoreListScroller->GetScrollbar()->SetWide( nScrollWidth>>1 ); |
|
if ( m_pScoreListScroller->GetScrollbar()->GetButton( 0 ) && |
|
m_pScoreListScroller->GetScrollbar()->GetButton( 1 ) ) |
|
{ |
|
m_pScoreListScroller->GetScrollbar()->GetButton( 0 )->SetVisible( false ); |
|
m_pScoreListScroller->GetScrollbar()->GetButton( 1 )->SetVisible( false ); |
|
} |
|
|
|
FOR_EACH_VEC( m_vecLeaderboardEntries, i ) |
|
{ |
|
EditablePanel *pContainer = dynamic_cast< EditablePanel* >( m_vecLeaderboardEntries[i] ); |
|
if ( !pContainer ) |
|
continue; |
|
|
|
Color colorToUse = i % 2 == 1 ? m_OddTextColor : m_EvenTextColor; |
|
|
|
bool bIsEntryVisible = i < scores.Count(); |
|
pContainer->SetVisible( bIsEntryVisible ); |
|
pContainer->SetPos( 0, i * m_yEntryStep ); |
|
if ( bIsEntryVisible ) |
|
{ |
|
const LeaderboardEntry_t *pLeaderboardEntry = scores[i]; |
|
const CSteamID &steamID = pLeaderboardEntry->m_steamIDUser; |
|
|
|
#ifdef TWITCH_LEADERBOARD |
|
TwitchTvAccountInfo_t *pTwitchInfo = StreamManager()->GetTwitchTvAccountInfo( steamID.ConvertToUint64() ); |
|
ETwitchTvState_t twitchState = pTwitchInfo ? pTwitchInfo->m_eTwitchTvState : k_ETwitchTvState_Error; |
|
// still waiting for twitch info to load |
|
if ( twitchState <= k_ETwitchTvState_Loading ) |
|
return false; |
|
#endif // TWITCH_LEADERBOARD |
|
|
|
bool bIsLocalPlayer = steamapicontext && steamapicontext->SteamUser() && steamapicontext->SteamUser()->GetSteamID() == steamID; |
|
pContainer->SetDialogVariable( "position", m_bGlobal ? CFmtStr( "%d.", pLeaderboardEntry->m_nGlobalRank ) : "" ); |
|
pContainer->SetDialogVariable( "username", InventoryManager()->PersonaName_Get( steamID.GetAccountID() ) ); |
|
|
|
CExLabel *pNameText = dynamic_cast< CExLabel* >( pContainer->FindChildByName( "UserName" ) ); |
|
if ( pNameText ) |
|
{ |
|
pNameText->SetColorStr( bIsLocalPlayer ? m_LocalPlayerTextColor : colorToUse ); |
|
} |
|
|
|
CAvatarImagePanel *pAvatar = dynamic_cast< CAvatarImagePanel* >( pContainer->FindChildByName( "AvatarImage" ) ); |
|
if ( pAvatar ) |
|
{ |
|
pAvatar->SetShouldDrawFriendIcon( false ); |
|
pAvatar->SetPlayer( steamID, k_EAvatarSize32x32 ); |
|
} |
|
|
|
CTFBadgePanel *pRankImage = dynamic_cast< CTFBadgePanel* >( pContainer->FindChildByName( "RankImage" ) ); |
|
if ( pRankImage ) |
|
{ |
|
const IMatchGroupDescription* pMatchDesc = GetMatchGroupDescription( k_nMatchGroup_Ladder_6v6 ); |
|
const LevelInfo_t& levelInfo = pMatchDesc->m_pProgressionDesc->GetLevelForExperience( pLeaderboardEntry->m_nScore ); |
|
pRankImage->SetupBadge( pMatchDesc->m_pProgressionDesc, levelInfo ); |
|
|
|
wchar_t wszOutString[ 128 ]; |
|
char szLocalized[512]; |
|
wchar_t wszCount[ 16 ]; |
|
_snwprintf( wszCount, ARRAYSIZE( wszCount ), L"%d", levelInfo.m_nLevelNum ); |
|
const wchar_t *wpszFormat = g_pVGuiLocalize->Find( pMatchDesc->m_pProgressionDesc->m_pszLevelToken ); |
|
g_pVGuiLocalize->ConstructString_safe( wszOutString, wpszFormat, 2, wszCount, g_pVGuiLocalize->Find( levelInfo.m_pszLevelTitle ) ); |
|
g_pVGuiLocalize->ConvertUnicodeToANSI( wszOutString, szLocalized, sizeof( szLocalized ) ); |
|
|
|
pRankImage->SetMouseInputEnabled( true ); |
|
pRankImage->SetVisible( true ); |
|
pRankImage->SetTooltip( m_pToolTip, szLocalized ); |
|
} |
|
|
|
CExImageButton *pStreamImage = dynamic_cast< CExImageButton* >( pContainer->FindChildByName( "StreamImageButton" ) ); |
|
if ( pStreamImage ) |
|
{ |
|
#ifdef TWITCH_LEADERBOARD |
|
if ( twitchState == k_ETwitchTvState_Linked ) |
|
{ |
|
pStreamImage->SetVisible( true ); |
|
pStreamImage->SetCommand( CFmtStr( "stream %s", pTwitchInfo->m_sTwitchTvChannel.String() ) ); |
|
} |
|
else |
|
#endif // TWITCH_LEADERBOARD |
|
{ |
|
pStreamImage->SetVisible( false ); |
|
pStreamImage->SetCommand( "" ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
return true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CLadderLobbyLeaderboard::SetLeaderboard( const char *pszLeaderboardName, bool bGlobal ) |
|
{ |
|
m_pszLeaderboardName = pszLeaderboardName; |
|
m_bGlobal = bGlobal; |
|
|
|
UpdateLeaderboards(); |
|
} |
|
|
|
static void GetPlayerNameForSteamID( wchar_t *wCharPlayerName, int nBufSizeBytes, const CSteamID &steamID ) |
|
{ |
|
const char *pszName = steamapicontext->SteamFriends()->GetFriendPersonaName( steamID ); |
|
V_UTF8ToUnicode( pszName, wCharPlayerName, nBufSizeBytes ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CLobbyPanel_Comp::CLobbyPanel_Comp( vgui::Panel *pParent, CBaseLobbyContainerFrame* pLobbyContainer ) |
|
: CBaseLobbyPanel( pParent, pLobbyContainer ) |
|
, m_pCompetitiveModeLeaderboard( NULL ) |
|
, m_pMatchHistoryScroller( NULL ) |
|
, m_eMatchSortMethod( SORT_BY_DATE ) |
|
, m_bDescendingMatchHistorySort( true ) |
|
{ |
|
// Comp |
|
m_fontMedalsCount = 0; |
|
|
|
m_flCompetitiveRankProgress = -1.f; |
|
m_flCompetitiveRankPrevProgress = -1.f; |
|
m_flRefreshPlayerListTime = -1.f; |
|
m_bCompetitiveRankChangePlayedSound = false; |
|
m_bMatchHistoryLoaded = false; |
|
m_bMatchDataForLocalPlayerDirty = true; |
|
|
|
ListenForGameEvent( "gc_new_session" ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CLobbyPanel_Comp::~CLobbyPanel_Comp() |
|
{ |
|
delete m_pImageList; |
|
m_pImageList = NULL; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CLobbyPanel_Comp::OnCommand( const char *command ) |
|
{ |
|
|
|
if ( FStrEq( command, "medals_help" ) ) |
|
{ |
|
CExplanationPopup *pPopup = dynamic_cast< CExplanationPopup* >( GetParent()->FindChildByName( "MedalsHelp" ) ); |
|
if ( pPopup ) |
|
{ |
|
pPopup->Popup(); |
|
} |
|
return; |
|
} |
|
else if ( FStrEq( command, "show_leaderboards" ) ) |
|
{ |
|
if ( m_pCompetitiveModeLeaderboard ) |
|
{ |
|
m_pCompetitiveModeLeaderboard->SetVisible( true ); |
|
} |
|
|
|
SetControlVisible( "MatchHistoryCategories", false, true ); |
|
SetControlVisible( "MatchHistoryContainer", false, true ); |
|
|
|
return; |
|
} |
|
else if ( FStrEq( command, "show_match_history" ) ) |
|
{ |
|
m_bMatchDataForLocalPlayerDirty = true; |
|
|
|
if ( m_pCompetitiveModeLeaderboard ) |
|
{ |
|
m_pCompetitiveModeLeaderboard->SetVisible( false ); |
|
} |
|
|
|
SetControlVisible( "MatchHistoryCategories", true, true ); |
|
SetControlVisible( "MatchHistoryContainer", true, true ); |
|
|
|
return; |
|
} |
|
else if ( !Q_strncmp( "sort", command, 4 ) ) |
|
{ |
|
EMatchHistorySortMethods_t eNewMethod = (EMatchHistorySortMethods_t)atoi( command + 4 ); |
|
|
|
if ( eNewMethod == m_eMatchSortMethod ) |
|
{ |
|
m_bDescendingMatchHistorySort = !m_bDescendingMatchHistorySort; |
|
} |
|
else |
|
{ |
|
m_eMatchSortMethod = eNewMethod; |
|
m_bDescendingMatchHistorySort = true; |
|
} |
|
|
|
m_bMatchDataForLocalPlayerDirty = true; |
|
|
|
return; |
|
} |
|
|
|
BaseClass::OnCommand( command ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
bool CLobbyPanel_Comp::ShouldShowLateJoin() const |
|
{ |
|
return false; // For now |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CLobbyPanel_Comp::ApplyChatUserSettings( const CBaseLobbyPanel::LobbyPlayerInfo &player, KeyValues *pKV ) const |
|
{ |
|
pKV->SetInt( "has_ticket", 0 ); |
|
pKV->SetInt( "squad_surplus", 0 ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CLobbyPanel_Comp::WriteGameSettingsControls() |
|
{ |
|
BaseClass::WriteGameSettingsControls(); |
|
|
|
// 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; |
|
} |
|
|
|
++m_iWritingPanel; |
|
|
|
m_pContainer->SetNextButtonEnabled( true ); |
|
|
|
SetControlVisible( "ScrollableContainer", GTFGCClientSystem()->GetWizardStep()== TF_Matchmaking_WizardStep_LADDER ); |
|
|
|
--m_iWritingPanel; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
int CLobbyPanel_Comp::GetMedalCountForStat( EMatchGroup unLadderType, RankStatType_t nStatType, int nMedalLevel ) |
|
{ |
|
CSOTFLadderData *pData = GetLocalPlayerLadderData( unLadderType ); |
|
if ( !pData ) |
|
return 0; |
|
|
|
switch ( nStatType ) |
|
{ |
|
case RankStat_Score: |
|
if ( nMedalLevel == StatMedal_Bronze ) |
|
{ |
|
return pData->Obj().score_bronze(); |
|
} |
|
else if ( nMedalLevel == StatMedal_Silver ) |
|
{ |
|
return pData->Obj().score_silver(); |
|
} |
|
else if ( nMedalLevel == StatMedal_Gold ) |
|
{ |
|
return pData->Obj().score_gold(); |
|
} |
|
break; |
|
case RankStat_Kills: |
|
if ( nMedalLevel == StatMedal_Bronze ) |
|
{ |
|
return pData->Obj().kills_bronze(); |
|
} |
|
else if ( nMedalLevel == StatMedal_Silver ) |
|
{ |
|
return pData->Obj().kills_silver(); |
|
} |
|
else if ( nMedalLevel == StatMedal_Gold ) |
|
{ |
|
return pData->Obj().kills_gold(); |
|
} |
|
break; |
|
case RankStat_Damage: |
|
if ( nMedalLevel == StatMedal_Bronze ) |
|
{ |
|
return pData->Obj().damage_bronze(); |
|
} |
|
else if ( nMedalLevel == StatMedal_Silver ) |
|
{ |
|
return pData->Obj().damage_silver(); |
|
} |
|
else if ( nMedalLevel == StatMedal_Gold ) |
|
{ |
|
return pData->Obj().damage_gold(); |
|
} |
|
break; |
|
case RankStat_Healing: |
|
if ( nMedalLevel == StatMedal_Bronze ) |
|
{ |
|
return pData->Obj().healing_bronze(); |
|
} |
|
else if ( nMedalLevel == StatMedal_Silver ) |
|
{ |
|
return pData->Obj().healing_silver(); |
|
} |
|
else if ( nMedalLevel == StatMedal_Gold ) |
|
{ |
|
return pData->Obj().healing_gold(); |
|
} |
|
break; |
|
case RankStat_Support: |
|
if ( nMedalLevel == StatMedal_Bronze ) |
|
{ |
|
return pData->Obj().support_bronze(); |
|
} |
|
else if ( nMedalLevel == StatMedal_Silver ) |
|
{ |
|
return pData->Obj().support_silver(); |
|
} |
|
else if ( nMedalLevel == StatMedal_Gold ) |
|
{ |
|
return pData->Obj().support_gold(); |
|
} |
|
break; |
|
case RankStat_Deaths: |
|
// Not supported |
|
break; |
|
default: |
|
Assert( 0 ); |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CLobbyPanel_Comp::OnThink() |
|
{ |
|
BaseClass::OnThink(); |
|
|
|
if ( m_bMatchDataForLocalPlayerDirty ) |
|
{ |
|
UpdateMatchDataForLocalPlayer(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CLobbyPanel_Comp::FireGameEvent( IGameEvent *event ) |
|
{ |
|
const char *pszEventname = event->GetName(); |
|
if ( !Q_stricmp( pszEventname, "gc_new_session" ) ) |
|
{ |
|
// This is loaded on demand by the GC - if we have a new session, we need to re-request |
|
if ( m_bMatchHistoryLoaded ) |
|
{ |
|
m_bMatchHistoryLoaded = false; |
|
m_bMatchDataForLocalPlayerDirty = true; |
|
} |
|
} |
|
|
|
BaseClass::FireGameEvent( event ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
EMatchGroup CLobbyPanel_Comp::GetMatchGroup( void ) const |
|
{ |
|
return k_nMatchGroup_Ladder_6v6; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CLobbyPanel_Comp::SOCreated( const CSteamID & steamIDOwner, const CSharedObject *pObject, ESOCacheEvent eEvent ) |
|
{ |
|
if ( pObject->GetTypeID() != CSOTFMatchResultPlayerInfo::k_nTypeID ) |
|
return; |
|
|
|
m_bMatchDataForLocalPlayerDirty = true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CLobbyPanel_Comp::SOUpdated( const CSteamID & steamIDOwner, const CSharedObject *pObject, ESOCacheEvent eEvent ) |
|
{ |
|
if ( pObject->GetTypeID() != CSOTFMatchResultPlayerInfo::k_nTypeID ) |
|
return; |
|
|
|
m_bMatchDataForLocalPlayerDirty = true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CLobbyPanel_Comp::PerformLayout() |
|
{ |
|
BaseClass::PerformLayout(); |
|
|
|
m_bMatchDataForLocalPlayerDirty = true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CLobbyPanel_Comp::ApplySchemeSettings( vgui::IScheme *pScheme ) |
|
{ |
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
|
|
EditablePanel* pPlaylistBGPanel = FindControl< EditablePanel >( "PlaylistBGPanel", true ); |
|
m_pCompetitiveModeLeaderboard = pPlaylistBGPanel->FindControl< CLadderLobbyLeaderboard >( "Leaderboard", true ); |
|
|
|
m_pMatchHistoryScroller = pPlaylistBGPanel->FindControl< CScrollableList >( "MatchHistoryContainer" ); |
|
|
|
int nAvatarWidth = ( ( m_iAvatarWidth * 5 / 4 ) + 1 ); |
|
int nExtraWidth = ( m_pChatPlayerList->GetWide() - ( 2 * nAvatarWidth ) - m_iPlayerNameWidth - m_iBannedWidth - m_iHasPassWidth ); |
|
|
|
m_pChatPlayerList->AddColumnToSection( 0, "avatar", "#TF_Players", vgui::SectionedListPanel::COLUMN_IMAGE, nAvatarWidth ); |
|
m_pChatPlayerList->AddColumnToSection( 0, "name", "", 0, m_iPlayerNameWidth + nExtraWidth ); |
|
m_pChatPlayerList->AddColumnToSection( 0, "is_banned", "", vgui::SectionedListPanel::COLUMN_IMAGE | vgui::SectionedListPanel::COLUMN_CENTER, m_iBannedWidth ); |
|
m_pChatPlayerList->AddColumnToSection( 0, "has_competitive_access", "", vgui::SectionedListPanel::COLUMN_IMAGE | vgui::SectionedListPanel::COLUMN_CENTER, m_iHasPassWidth ); |
|
m_pChatPlayerList->AddColumnToSection( 0, "rank", "", vgui::SectionedListPanel::COLUMN_IMAGE | vgui::SectionedListPanel::COLUMN_CENTER, nAvatarWidth ); |
|
m_pChatPlayerList->SetDrawHeaders( false ); |
|
m_fontMedalsCount = pScheme->GetFont( "HudFontSmallestBold", true ); |
|
} |
|
|
|
static int SortResult( const CSOTFMatchResultPlayerStats * a, const CSOTFMatchResultPlayerStats * b ) |
|
{ |
|
return a->display_rating_change() < b->display_rating_change(); |
|
} |
|
|
|
static int SortDate( const CSOTFMatchResultPlayerStats * a, const CSOTFMatchResultPlayerStats * b ) |
|
{ |
|
return a->endtime() < b->endtime(); |
|
} |
|
|
|
static int SortMap( const CSOTFMatchResultPlayerStats * a, const CSOTFMatchResultPlayerStats * b ) |
|
{ |
|
const MapDef_t* pMapDef = GetItemSchema()->GetMasterMapDefByIndex( a->map_index() ); |
|
const wchar_t* pszAMapName = g_pVGuiLocalize->Find( pMapDef ? pMapDef->pszMapNameLocKey : "#TF_Map_Unknown" ); |
|
|
|
pMapDef = GetItemSchema()->GetMasterMapDefByIndex( b->map_index() ); |
|
const wchar_t* pszBMapName = g_pVGuiLocalize->Find( pMapDef ? pMapDef->pszMapNameLocKey : "#TF_Map_Unknown" ); |
|
|
|
return wcscoll( pszAMapName, pszBMapName ); |
|
} |
|
|
|
static int SortKDR( const CSOTFMatchResultPlayerStats * a, const CSOTFMatchResultPlayerStats * b ) |
|
{ |
|
float flAKDRatio = a->kills(); |
|
if ( a->deaths() > 0 ) |
|
{ |
|
flAKDRatio /= (float)a->deaths(); |
|
} |
|
|
|
float flBKDRatio = b->kills(); |
|
if ( b->deaths() > 0 ) |
|
{ |
|
flBKDRatio /= (float)b->deaths(); |
|
} |
|
|
|
return ( flBKDRatio - flAKDRatio ) * 1000.f; |
|
} |
|
|
|
void CLobbyPanel_Comp::UpdateMatchDataForLocalPlayer() |
|
{ |
|
m_bMatchDataForLocalPlayerDirty = false; |
|
|
|
CUtlVector < CSOTFMatchResultPlayerStats > vecMatches; |
|
GetLocalPlayerMatchHistory( GetMatchGroup(), vecMatches ); |
|
|
|
if ( !m_bMatchHistoryLoaded ) |
|
{ |
|
GCSDK::CProtoBufMsg< CMsgGCMatchHistoryLoad > msg( k_EMsgGCMatchHistoryLoad ); |
|
GCClientSystem()->BSendMessage( msg ); |
|
|
|
m_bMatchHistoryLoaded = true; |
|
} |
|
|
|
if ( m_pMatchHistoryScroller ) |
|
{ |
|
m_pMatchHistoryScroller->ClearAutoLayoutPanels(); |
|
|
|
typedef int (*MatchSortFunc)( const CSOTFMatchResultPlayerStats * a, const CSOTFMatchResultPlayerStats * b ); |
|
|
|
struct SortMethodData_t |
|
{ |
|
MatchSortFunc m_pfnSort; |
|
CExButton* m_pSortButton; |
|
}; |
|
|
|
EditablePanel* pPlaylistBGPanel = FindControl< EditablePanel >( "PlaylistBGPanel", true ); |
|
Assert( pPlaylistBGPanel ); |
|
if ( !pPlaylistBGPanel ) |
|
return; |
|
|
|
SortMethodData_t sortMethods[ NUM_SORT_METHODS ] = { { &SortResult, pPlaylistBGPanel->FindControl< CExButton >( "ResultButton", true ) } |
|
, { &SortDate, pPlaylistBGPanel->FindControl< CExButton >( "DateButton", true ) } |
|
, { &SortMap, pPlaylistBGPanel->FindControl< CExButton >( "MapButton", true ) } |
|
, { &SortKDR, pPlaylistBGPanel->FindControl< CExButton >( "KDRButton", true ) } }; |
|
|
|
// Sort |
|
vecMatches.Sort( sortMethods[ m_eMatchSortMethod ].m_pfnSort ); |
|
|
|
Label* pSortArrow = pPlaylistBGPanel->FindControl< Label >( "SortArrow", true ); |
|
Assert( pSortArrow ); |
|
if ( !pSortArrow ) |
|
return; |
|
|
|
// Update controls |
|
for( int i=0; i<ARRAYSIZE( sortMethods ); ++i ) |
|
{ |
|
if( sortMethods[ i ].m_pSortButton ) |
|
{ |
|
bool bSelected = i == m_eMatchSortMethod; |
|
sortMethods[ i ].m_pSortButton->SetSelected( bSelected ); |
|
|
|
if ( bSelected ) |
|
{ |
|
int nDummy, nX; |
|
sortMethods[ i ].m_pSortButton->GetContentSize( nX, nDummy ); |
|
// Move the sort arrow to the right edge of the selected panel |
|
pSortArrow->SetPos( sortMethods[ i ].m_pSortButton->GetXPos() + nX , pSortArrow->GetYPos() ); |
|
// Fixup the label to be an up or down arrow |
|
pSortArrow->SetText( m_bDescendingMatchHistorySort ? L"6" : L"5" ); |
|
} |
|
} |
|
} |
|
|
|
// Potentially go backwards |
|
if ( m_bDescendingMatchHistorySort ) |
|
{ |
|
FOR_EACH_VEC( vecMatches, i ) |
|
{ |
|
CMatchHistoryEntryPanel* pMatchEntryPanel = new CMatchHistoryEntryPanel( m_pMatchHistoryScroller, "MatchEntry" ); |
|
pMatchEntryPanel->MakeReadyForUse(); |
|
pMatchEntryPanel->SetMatchData( vecMatches[ i ] ); |
|
m_pMatchHistoryScroller->AddPanel( pMatchEntryPanel, 5 ); |
|
} |
|
} |
|
else |
|
{ |
|
FOR_EACH_VEC_BACK( vecMatches, i ) |
|
{ |
|
CMatchHistoryEntryPanel* pMatchEntryPanel = new CMatchHistoryEntryPanel( m_pMatchHistoryScroller, "MatchEntry" ); |
|
pMatchEntryPanel->MakeReadyForUse(); |
|
pMatchEntryPanel->SetMatchData( vecMatches[ i ] ); |
|
m_pMatchHistoryScroller->AddPanel( pMatchEntryPanel, 5 ); |
|
} |
|
} |
|
|
|
m_pMatchHistoryScroller->MakeReadyForUse(); |
|
} |
|
}
|
|
|