diff options
Diffstat (limited to 'game/client/cstrike/VGUI/win_panel_round.cpp')
| -rw-r--r-- | game/client/cstrike/VGUI/win_panel_round.cpp | 470 |
1 files changed, 470 insertions, 0 deletions
diff --git a/game/client/cstrike/VGUI/win_panel_round.cpp b/game/client/cstrike/VGUI/win_panel_round.cpp new file mode 100644 index 0000000..7c05f26 --- /dev/null +++ b/game/client/cstrike/VGUI/win_panel_round.cpp @@ -0,0 +1,470 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Create and display a win panel at the end of a round displaying interesting stats and info about the round. +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "win_panel_round.h" +#include "vgui_controls/AnimationController.h" +#include "iclientmode.h" +#include "c_playerresource.h" +#include <vgui_controls/Label.h> +#include <vgui/ILocalize.h> +#include <vgui/ISurface.h> +#include <vgui/ISystem.h> +#include "fmtstr.h" +#include "cs_gamestats_shared.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +ConVar cl_round_win_fade_time( "cl_round_win_fade_time", "1.5", FCVAR_CLIENTDLL | FCVAR_ARCHIVE ); + +DECLARE_HUDELEMENT_DEPTH( WinPanel_Round, 1 ); // 1 is foreground +extern const wchar_t *LocalizeFindSafe( const char *pTokenName ); + + +// helper function for converting wstrings to upper-case inline +// NB: this returns a pointer to a static buffer +wchar_t* UpperCaseWideString( const wchar_t* wszSource ) +{ + static wchar_t wszBuffer[256]; + V_wcsncpy(wszBuffer, wszSource, sizeof(wszBuffer)); + V_wcsupr(wszBuffer); + return wszBuffer; +} + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +WinPanel_Round::WinPanel_Round( const char *pElementName ) : + BorderedPanel( NULL, pElementName ), + CHudElement( pElementName ), + m_bIsFading(false), + m_fFadeBeginTime(0.0f) +{ + SetSize( 10, 10 ); // Quiet "parent not sized yet" spew + SetParent(g_pClientMode->GetViewport()); + + SetScheme( "ClientScheme" ); + + RegisterForRenderGroup( "hide_for_scoreboard" ); + + m_bShouldBeVisible = false; +} + +WinPanel_Round::~WinPanel_Round() +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void WinPanel_Round::Reset() +{ + Hide(); +} + +void WinPanel_Round::Init() +{ + CHudElement::Init(); + + // listen for events + ListenForGameEvent( "round_end" ); + ListenForGameEvent( "round_start" ); + ListenForGameEvent( "cs_win_panel_round" ); + ListenForGameEvent( "cs_win_panel_match" ); + ListenForGameEvent( "round_mvp" ); + + InitLayout(); + + m_bShouldBeVisible = false; + m_bShowTimerDefend = false; + m_bShowTimerAttack = false; +} + + +void WinPanel_Round::InitLayout() +{ + // reload control settings when resolution changes to force update of proportional layout + LoadControlSettings("Resource/UI/Win_Round.res"); + + CAvatarImagePanel* pMVP_Avatar = dynamic_cast<CAvatarImagePanel*>(FindChildByName("MVP_Avatar")); + pMVP_Avatar->SetDefaultAvatar(scheme()->GetImage( CSTRIKE_DEFAULT_AVATAR, true)); + pMVP_Avatar->SetShouldDrawFriendIcon(false); +} + + +void WinPanel_Round::VidInit() +{ +} + +//============================================================================= +// HPE_BEGIN: +// [Forrest] Allow win panel to be turned off on client +//============================================================================= +ConVar cl_nowinpanel( + "cl_nowinpanel", + "0", + FCVAR_ARCHIVE, + "Turn on/off win panel on client" + ); +//============================================================================= +// HPE_END +//============================================================================= + +void WinPanel_Round::FireGameEvent( IGameEvent* event ) +{ + const char *pEventName = event->GetName(); + + if ( Q_strcmp( "round_end", pEventName ) == 0 ) + { + } + else if ( Q_strcmp( "round_start", pEventName ) == 0 ) + { + Hide(); + } + else if( Q_strcmp( "cs_win_panel_match", pEventName ) == 0 ) + { + Hide(); + } + else if( Q_strcmp( "round_mvp", pEventName ) == 0 ) + { + C_BasePlayer *basePlayer = UTIL_PlayerByUserId( event->GetInt( "userid" ) ); + CSMvpReason_t mvpReason = (CSMvpReason_t)event->GetInt( "reason" ); + + if( basePlayer ) + { + SetMVP( ToCSPlayer( basePlayer ), mvpReason ); + } + } + else if ( Q_strcmp( "cs_win_panel_round", pEventName ) == 0 ) + { + /* + "show_timer_defend" "bool" + "show_timer_attack" "bool" + "timer_time" "int" + + "final_event" "byte" // 0 - no event, 1 - bomb exploded, 2 - flag capped, 3 - timer expired + + "funfact_type" "byte" //WINPANEL_FUNFACT in cs_shareddef.h + "funfact_player" "byte" + "funfact_data1" "long" + "funfact_data2" "long" + "funfact_data3" "long" + */ + + if ( !g_PR ) + return; + + //============================================================================= + // HPE_BEGIN: + // [Forrest] Check if win panel is disabled. + //============================================================================= + static ConVarRef sv_nowinpanel( "sv_nowinpanel" ); + if ( sv_nowinpanel.GetBool() || cl_nowinpanel.GetBool() ) + return; + //============================================================================= + // HPE_END + //============================================================================= + + m_bShowTimerDefend = event->GetBool( "show_timer_defend" ); + m_bShowTimerAttack = event->GetBool( "show_timer_attack" ); + int iTimerTime = event->GetInt( "timer_time" ); + + int minutes = clamp( iTimerTime / 60, 0, 99 ); + int seconds = clamp( iTimerTime % 60, 0, 59 ); + + wchar_t time[8]; + _snwprintf( time, ARRAYSIZE( time ), L"%d:%02d", minutes, seconds ); + + SetDialogVariable("TIMER_TEXT", time); + + // Final Fun Fact + SetFunFactLabel( L""); + int iFunFactPlayer = event->GetInt("funfact_player"); + const char* funfactToken = event->GetString("funfact_token", ""); + + if (strlen(funfactToken) != 0) + { + wchar_t funFactText[256]; + wchar_t playerText[64]; + wchar_t dataText1[8], dataText2[8], dataText3[8]; + int param1 = event->GetInt("funfact_data1"); + int param2 = event->GetInt("funfact_data2"); + int param3 = event->GetInt("funfact_data3"); + if ( iFunFactPlayer >= 1 && iFunFactPlayer <= MAX_PLAYERS ) + { + const char* playerName = g_PR->GetPlayerName( iFunFactPlayer ); + if( playerName && Q_strcmp( playerName, PLAYER_UNCONNECTED_NAME ) != 0 && Q_strcmp( playerName, PLAYER_ERROR_NAME ) != 0 ) + { + V_strtowcs( g_PR->GetPlayerName( iFunFactPlayer ), 64, playerText, sizeof( playerText ) ); + } + else + { +#ifdef WIN32 + _snwprintf( playerText, ARRAYSIZE( playerText ), L"%s", LocalizeFindSafe( "#winpanel_former_player" ) ); +#else + _snwprintf( playerText, ARRAYSIZE( playerText ), L"%S", LocalizeFindSafe( "#winpanel_former_player" ) ); +#endif + } + } + else + { + _snwprintf( playerText, ARRAYSIZE( playerText ), L"" ); + } + _snwprintf( dataText1, ARRAYSIZE( dataText1 ), L"%i", param1 ); + _snwprintf( dataText2, ARRAYSIZE( dataText2 ), L"%i", param2 ); + _snwprintf( dataText3, ARRAYSIZE( dataText3 ), L"%i", param3 ); + g_pVGuiLocalize->ConstructString( funFactText, sizeof(funFactText), (wchar_t *)LocalizeFindSafe(funfactToken), 4, + playerText, dataText1, dataText2, dataText3 ); + SetFunFactLabel(funFactText); + } + + int iEndEvent = event->GetInt( "final_event" ); + + //Map the round end events onto localized strings + const char* endEventToString[RoundEndReason_Count]; + V_memset(endEventToString, 0, sizeof(endEventToString)); + + //terrorist win events + endEventToString[Target_Bombed] = "#winpanel_end_target_bombed"; + endEventToString[VIP_Assassinated] = "#winpanel_end_vip_assassinated"; + endEventToString[Terrorists_Escaped] = "#winpanel_end_terrorists_escaped"; + endEventToString[Terrorists_Win] = "#winpanel_end_terrorists__kill"; + endEventToString[Hostages_Not_Rescued] = "#winpanel_end_hostages_not_rescued"; + endEventToString[VIP_Not_Escaped] = "#winpanel_end_vip_not_escaped"; + + //CT win events + endEventToString[VIP_Escaped] = "#winpanel_end_vip_escaped"; + endEventToString[CTs_PreventEscape] = "#winpanel_end_cts_prevent_escape"; + endEventToString[Escaping_Terrorists_Neutralized] = "#winpanel_end_escaping_terrorists_neutralized"; + endEventToString[Bomb_Defused] = "#winpanel_end_bomb_defused"; + endEventToString[CTs_Win] = "#winpanel_end_cts_win"; + endEventToString[All_Hostages_Rescued] = "#winpanel_end_all_hostages_rescued"; + endEventToString[Target_Saved] = "#winpanel_end_target_saved"; + endEventToString[Terrorists_Not_Escaped] = "#winpanel_end_terrorists_not_escaped"; + + //We don't show a round end panel for these + endEventToString[Game_Commencing] = ""; + endEventToString[Round_Draw] = ""; + + const wchar_t* wszEventMessage = NULL; + if(iEndEvent >=0 && iEndEvent < RoundEndReason_Count) + wszEventMessage = LocalizeFindSafe(endEventToString[iEndEvent]); + + if ( wszEventMessage != NULL ) + { + SetDialogVariable("WIN_DESCRIPTION", UpperCaseWideString(wszEventMessage)); + } + else + { + SetDialogVariable("WIN_DESCRIPTION", ""); + } + + Label* pWinLabel = dynamic_cast<Label*>(FindChildByName("WinLabel")); + switch(iEndEvent) + { + case Target_Bombed: + case VIP_Assassinated: + case Terrorists_Escaped: + case Terrorists_Win: + case Hostages_Not_Rescued: + case VIP_Not_Escaped: + pWinLabel->SetText(UpperCaseWideString(LocalizeFindSafe("#winpanel_t_win"))); + pWinLabel->SetFgColor(Color(184,0,0,255)); + break; + + case VIP_Escaped: + case CTs_PreventEscape: + case Escaping_Terrorists_Neutralized: + case Bomb_Defused: + case CTs_Win: + case All_Hostages_Rescued: + case Target_Saved: + case Terrorists_Not_Escaped: + pWinLabel->SetText(UpperCaseWideString(LocalizeFindSafe("#winpanel_ct_win"))); + pWinLabel->SetFgColor(Color(71,152,237,255)); + break; + + case Round_Draw: + pWinLabel->SetText(UpperCaseWideString(LocalizeFindSafe("#winpanel_draw"))); + pWinLabel->SetFgColor(Color(204,204,204,255)); + break; + } + + //[tj] We set the icon to the generic one right before we show it. + // The expected result is that we replace it immediately with + // the round MVP. if there is none, we just use the generic. + SetMVP( NULL, CSMVP_UNDEFINED ); + + Show(); + } +} + +void WinPanel_Round::SetMVP( C_CSPlayer* pPlayer, CSMvpReason_t reason ) +{ + CAvatarImagePanel* pMVP_Avatar = dynamic_cast<CAvatarImagePanel*>(FindChildByName("MVP_Avatar")); + + if ( pMVP_Avatar ) + { + pMVP_Avatar->ClearAvatar(); + } + + //First set the text to the name of the player + //============================================================================= + // HPE_BEGIN: + // [Forrest] Allow MVP to be turned off for a server + //============================================================================= + bool isThereAnMVP = ( pPlayer != NULL ); + if ( isThereAnMVP ) + //============================================================================= + // HPE_END + //============================================================================= + { + + const char* mvpReasonToken = NULL; + switch ( reason ) + { + case CSMVP_ELIMINATION: + mvpReasonToken = "winpanel_mvp_award_kills"; + break; + case CSMVP_BOMBPLANT: + mvpReasonToken = "winpanel_mvp_award_bombplant"; + break; + case CSMVP_BOMBDEFUSE: + mvpReasonToken = "winpanel_mvp_award_bombdefuse"; + break; + case CSMVP_HOSTAGERESCUE: + mvpReasonToken = "winpanel_mvp_award_rescue"; + break; + default: + mvpReasonToken = "winpanel_mvp_award"; + break; + } + + wchar_t wszBuf[256], wszPlayerName[64]; + g_pVGuiLocalize->ConvertANSIToUnicode(UTIL_SafeName(pPlayer->GetPlayerName()), wszPlayerName, sizeof(wszPlayerName)); + + wchar_t *pReason = (wchar_t *)LocalizeFindSafe( mvpReasonToken ); + if ( !pReason ) + { + pReason = L"%s1"; + } + + g_pVGuiLocalize->ConstructString( wszBuf, sizeof( wszBuf ), pReason, 1, wszPlayerName ); + SetDialogVariable( "MVP_TEXT", wszBuf ); + + player_info_t pi; + if ( engine->GetPlayerInfo(pPlayer->entindex(), &pi) ) + { + if ( pMVP_Avatar ) + { + pMVP_Avatar->SetDefaultAvatar( GetDefaultAvatarImage( pPlayer ) ); + pMVP_Avatar->SetPlayer( pPlayer, k_EAvatarSize64x64 ); + } + } + } + else + { + SetDialogVariable( "MVP_TEXT", ""); + } + + //============================================================================= + // HPE_BEGIN: + // [Forrest] Allow MVP to be turned off for a server + //============================================================================= + // The avatar image and its accompanying elements should be hidden if there is no MVP for the round. + if ( pMVP_Avatar ) + { + pMVP_Avatar->SetVisible( isThereAnMVP ); + } + ImagePanel* pMVP_AvatarGlow = dynamic_cast<ImagePanel*>(FindChildByName("MVP_AvatarGlow")); + if ( pMVP_AvatarGlow ) + { + pMVP_AvatarGlow->SetVisible( isThereAnMVP ); + } + ImagePanel* pMVP_Foreground_Star = dynamic_cast<ImagePanel*>(FindChildByName("MVP_Foreground_Star")); + if ( pMVP_Foreground_Star ) + { + pMVP_Foreground_Star->SetVisible( isThereAnMVP ); + } + //============================================================================= + // HPE_END + //============================================================================= +} + +void WinPanel_Round::SetFunFactLabel( const wchar *szFunFact ) +{ + SetDialogVariable( "FUNFACT", szFunFact ); +} + +void WinPanel_Round::Show( void ) +{ + int iRenderGroup = gHUD.LookupRenderGroupIndexByName( "hide_for_round_panel" ); + if ( iRenderGroup >= 0) + { + gHUD.LockRenderGroup( iRenderGroup ); + } + + m_bShouldBeVisible = true; + SetAlpha(255); + m_bIsFading = false; +} + +void WinPanel_Round::Hide( void ) +{ + if ( m_bShouldBeVisible && !m_bIsFading ) + { + m_bIsFading = true; + m_fFadeBeginTime = gpGlobals->realtime; + } +} + +void WinPanel_Round::OnThink() +{ + if ( m_bShouldBeVisible && m_bIsFading ) + { + float fAlpha = 1.0f - (gpGlobals->realtime - m_fFadeBeginTime) / cl_round_win_fade_time.GetFloat(); + + if (fAlpha >= 0.0f) + { + SetAlpha(RoundFloatToInt(fAlpha * 255.0f)); + } + else + { + int iRenderGroup = gHUD.LookupRenderGroupIndexByName( "hide_for_round_panel" ); + if ( iRenderGroup >= 0 ) + { + gHUD.UnlockRenderGroup( iRenderGroup ); + } + m_bShouldBeVisible = false; + SetAlpha(0); + m_bIsFading = false; + } + } +} + +void WinPanel_Round::ApplySchemeSettings( vgui::IScheme *pScheme ) +{ + BaseClass::ApplySchemeSettings( pScheme ); + + SetFgColor(Color(251,176,59,255)); + SetBgColor(Color(0,0,0,212)); +} + +void WinPanel_Round::OnScreenSizeChanged( int nOldWide, int nOldTall ) +{ + BaseClass::OnScreenSizeChanged(nOldWide, nOldTall); + + InitLayout(); + + +} + +bool WinPanel_Round::ShouldDraw( void ) +{ + return ( m_bShouldBeVisible && CHudElement::ShouldDraw()); +} |