//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //============================================================================= #include "cbase.h" #include "c_tf_player.h" #include "iclientmode.h" #include "ienginevgui.h" #include #include #include #include #include #include "tf_imagepanel.h" #include "tf_gamerules.h" #include "c_tf_team.h" #include "c_team_objectiveresource.h" #include "tf_hud_match_status.h" #include "tf_hud_teamgoal_tournament.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" using namespace vgui; void AddSubKeyNamed( KeyValues *pKeys, const char *pszName ); DECLARE_HUDELEMENT( CHudTeamGoalTournament ); //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- CHudTeamGoalTournament::CHudTeamGoalTournament( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudTeamGoalTournament" ) { Panel *pParent = g_pClientMode->GetViewport(); SetParent( pParent ); SetHiddenBits( HIDEHUD_MISCSTATUS ); m_flShowAt = -1.f; RegisterForRenderGroup( "commentary" ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHudTeamGoalTournament::LevelInit( void ) { m_flShowAt = -1.f; ListenForGameEvent( "tournament_stateupdate" ); ListenForGameEvent( "teamplay_round_start" ); ListenForGameEvent( "competitive_state_changed" ); } C_TFTeam *GetTeamRoles( int iTeamRole ) { for ( int i = LAST_SHARED_TEAM+1; i < GetNumberOfTeams(); i++ ) { C_TFTeam *pTeam = GetGlobalTFTeam( i ); if ( pTeam ) { if ( pTeam->GetRole() == iTeamRole ) { return pTeam; } } } return NULL; } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- int CHudTeamGoalTournament::HudElementKeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding ) { if ( IsVisible() && TFGameRules() && TFGameRules()->IsInTournamentMode() && TFGameRules()->IsInStopWatch() ) { if ( ( TFGameRules()->State_Get() == GR_STATE_PREROUND ) || TFGameRules()->InSetup() ) { if ( down && ( keynum == KEY_F1 ) ) { m_flShowAt = -1.f; return 0; } } } return 1; } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHudTeamGoalTournament::FireGameEvent( IGameEvent * event ) { const char *pEventName = event->GetName(); if ( FStrEq( "tournament_stateupdate", pEventName ) ) { m_flShowAt = -1.f; } else if ( FStrEq( "teamplay_round_start", pEventName ) ) { if ( TFGameRules() && TFGameRules()->IsInTournamentMode() && TFGameRules()->IsInStopWatch() ) { C_TFTeam *pAttacker = GetTeamRoles( TEAM_ROLE_ATTACKERS ); C_TFTeam *pDefender = GetTeamRoles( TEAM_ROLE_DEFENDERS ); if( !pAttacker || !pDefender ) return; if ( ( pAttacker->Get_Score() != 0 ) && ( pDefender->Get_Score() != 0 ) ) return; m_flShowAt = gpGlobals->curtime + 1.f; } } else if ( FStrEq( "competitive_state_changed", pEventName ) ) { InvalidateLayout( false, true ); } } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHudTeamGoalTournament::ApplySchemeSettings( IScheme *pScheme ) { KeyValues *pConditions = NULL; if ( ShouldUseMatchHUD() ) { pConditions = new KeyValues( "conditions" ); AddSubKeyNamed( pConditions, "if_comp" ); } // load control settings... LoadControlSettings( "resource/UI/HudTeamGoalTournament.res", NULL, NULL, pConditions ); BaseClass::ApplySchemeSettings( pScheme ); if ( pConditions ) { pConditions->deleteThis(); } m_cRegularColor = pScheme->GetColor( "TanLight", Color( 0, 0, 0 ) ); m_cHighlightColor = pScheme->GetColor( "GoalOrange", Color( 0, 0, 0 ) ); m_pStopWatchGoal = dynamic_cast( FindChildByName( "HudStopWatchObjective" ) ); if ( m_pStopWatchGoal ) { m_pStopWatchGoalText = dynamic_cast( m_pStopWatchGoal->FindChildByName( "HudStopWatchObjectiveText1" ) ); } if ( m_pStopWatchGoalText ) { m_pStopWatchGoalText->SetVisible( true ); m_pStopWatchGoalText->InsertColorChange( m_cRegularColor ); } if ( m_pStopWatchGoal ) { m_pStopWatchGoalText2 = dynamic_cast( m_pStopWatchGoal->FindChildByName( "HudStopWatchObjectiveText2" ) ); } if ( m_pStopWatchGoalText2 ) { m_pStopWatchGoalText2->SetVisible( true ); m_pStopWatchGoalText2->InsertColorChange( m_cRegularColor ); } if ( m_pStopWatchGoal ) { m_pStopWatchGoalBGLarge = m_pStopWatchGoal->FindChildByName( "HudStopWatchObjectiveBG" ); m_pStopWatchGoalBGSmall = m_pStopWatchGoal->FindChildByName( "HudStopWatchObjectiveBGSmall" ); m_pStopWatchGoalDivider = m_pStopWatchGoal->FindChildByName( "HudStopWatchObjectiveShadedBar" ); } m_pStopWatchGoalArrow = FindChildByName( "HudStopWatchObjectiveArrow" ); } inline wchar_t *CloneWString( const wchar_t *str ); enum { STOPWATCH_COLOR_NORMAL = 1, STOPWATCH_COLOR_SUB = 3, }; //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHudTeamGoalTournament::SetVisible( bool bState ) { if ( bState ) { SetupStopWatchLabel(); } BaseClass::SetVisible( bState ); } //----------------------------------------------------------------------------- // Purpose: Prepares the string with the different colors // This is kinda nasty since I just copied this code from the chat // This should be abstracted and made all nice. //----------------------------------------------------------------------------- void CHudTeamGoalTournament::PrepareStopWatchString( wchar_t *pszString, CExRichText *pText ) { if ( m_text ) { delete[] m_text; m_text = NULL; } m_textRanges.RemoveAll(); m_text = CloneWString( pszString ); wchar_t *txt = m_text; int lineLen = wcslen( m_text ); TextRange range; range.start = 0; range.end = wcslen( m_text ); range.color = Color( 235, 226, 202 ); m_textRanges.AddToTail( range ); while ( txt && *txt ) { switch ( *txt ) { case STOPWATCH_COLOR_SUB: case STOPWATCH_COLOR_NORMAL: { // save this start range.start = (txt-m_text) + 1; if ( *txt == STOPWATCH_COLOR_NORMAL ) range.color = m_cRegularColor; else range.color = m_cHighlightColor; range.end = lineLen; int count = m_textRanges.Count(); if ( count ) { m_textRanges[count-1].end = range.start - 1; } m_textRanges.AddToTail( range ); } ++txt; break; default: ++txt; } } for ( int i=0; i 0 && *start < COLOR_MAX ) { m_textRanges[i].start += 1; } } wchar_t wText[4096]; Color color; for ( int i=0; i 1 ) { wcsncpy( wText, start, len ); wText[len-1] = 0; color = m_textRanges[i].color; color[3] = 255; pText->InsertColorChange( color ); pText->InsertString( wText ); } } } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHudTeamGoalTournament::SetupStopWatchLabel( void ) { int iPoints = 0; if ( !TFGameRules() ) return; if ( !ObjectiveResource() ) return; C_TFTeam *pAttacker = GetTeamRoles( TEAM_ROLE_ATTACKERS ); C_TFTeam *pDefender = GetTeamRoles( TEAM_ROLE_DEFENDERS ); if( !pAttacker || !pDefender ) return; int iActiveTimer = ObjectiveResource()->GetStopWatchTimer(); CTeamRoundTimer *pTimer = dynamic_cast< CTeamRoundTimer* >( ClientEntityList().GetEnt( iActiveTimer ) ); if ( !pTimer ) return; if ( !pTimer->IsWatchingTimeStamps() ) { iPoints = pDefender->Get_Score(); if ( m_pStopWatchGoal ) { m_pStopWatchGoal->SetVisible( true ); } if ( m_pStopWatchGoalArrow ) { m_pStopWatchGoalArrow->SetVisible( true ); } } else { if ( m_pStopWatchGoal ) { m_pStopWatchGoal->SetVisible( false ); } if ( m_pStopWatchGoalArrow ) { m_pStopWatchGoalArrow->SetVisible( false ); } return; } C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( !pLocalPlayer ) return; wchar_t wzHelp[256]; C_TFTeam *pBlueTeam = GetGlobalTFTeam( TF_TEAM_BLUE ); const wchar_t *pBlueTeamName = pBlueTeam ? pBlueTeam->Get_Localized_Name() : L"BLU"; C_TFTeam *pRedTeam = GetGlobalTFTeam( TF_TEAM_RED ); const wchar_t *pRedTeamName = pRedTeam ? pRedTeam->Get_Localized_Name() : L"RED"; wchar_t wszAttackersName[MAX_TEAM_NAME_LENGTH]; wchar_t wszDefendersName[MAX_TEAM_NAME_LENGTH]; V_wcscpy_safe( wszAttackersName, ( pAttacker->GetTeamNumber() == TF_TEAM_BLUE ) ? pBlueTeamName : pRedTeamName ); V_wcscpy_safe( wszDefendersName, ( pDefender->GetTeamNumber() == TF_TEAM_BLUE ) ? pBlueTeamName : pRedTeamName ); #ifdef WIN32 #define INT_CHAR_FMT L"%d %s" #else #define INT_CHAR_FMT L"%d %S" #endif wchar_t wszPoints[256]; _snwprintf( wszPoints, ARRAYSIZE( wszPoints ), INT_CHAR_FMT, iPoints, iPoints == 1 ? g_pVGuiLocalize->Find( "Tournament_StopWatch_Point" ) : g_pVGuiLocalize->Find( "Tournament_StopWatch_Points" ) ); wchar_t wszTime[256]; wchar_t wszLabel[256]; int iMinutes = pTimer->GetTimeRemaining() / 60; int iSeconds = ((int)pTimer->GetTimeRemaining()) % 60; if ( iMinutes > 0 ) { #ifdef WIN32 _snwprintf( wszTime, ARRAYSIZE( wszTime ) , L"%d %s %d %s", iMinutes, iMinutes == 1 ? g_pVGuiLocalize->Find( "Tournament_WinConditionsMinute" ) : g_pVGuiLocalize->Find( "Tournament_WinConditionsMinutes" ), iSeconds, iSeconds == 1 ? g_pVGuiLocalize->Find( "Tournament_WinConditionsSecond" ) : g_pVGuiLocalize->Find( "Tournament_WinConditionsSeconds" ) ); #else _snwprintf( wszTime, ARRAYSIZE( wszTime ) , L"%d %S %d %S", iMinutes, iMinutes == 1 ? g_pVGuiLocalize->Find( "Tournament_WinConditionsMinute" ) : g_pVGuiLocalize->Find( "Tournament_WinConditionsMinutes" ), iSeconds, iSeconds == 1 ? g_pVGuiLocalize->Find( "Tournament_WinConditionsSecond" ) : g_pVGuiLocalize->Find( "Tournament_WinConditionsSeconds" ) ); #endif } else { _snwprintf( wszTime, ARRAYSIZE( wszTime ), INT_CHAR_FMT, iSeconds, iSeconds == 1 ? g_pVGuiLocalize->Find( "Tournament_WinConditionsSecond" ) : g_pVGuiLocalize->Find( "Tournament_WinConditionsSeconds" ) ); } if ( m_pStopWatchGoalText ) { m_pStopWatchGoalText->SetText(""); } if ( m_pStopWatchGoalText2 ) { m_pStopWatchGoalText2->SetText(""); } if ( m_pStopWatchGoal ) { m_pStopWatchGoal->SetDialogVariable( "objectivelabel", "" ); } if ( pLocalPlayer->GetTeam() == pDefender ) { g_pVGuiLocalize->ConstructString_safe( wszLabel, g_pVGuiLocalize->Find( "Tournament_StopWatch_LabelDefender" ), 1, wszAttackersName ); if ( m_pStopWatchGoal ) { m_pStopWatchGoal->SetDialogVariable( "objectivelabel", wszLabel ); } } //Attackers capped something last round case if ( iPoints > 0 ) { bool bCappedAllPoints = ( iPoints == ObjectiveResource()->GetNumControlPoints() ); g_pVGuiLocalize->ConstructString_safe( wzHelp, g_pVGuiLocalize->Find( bCappedAllPoints ? "Tournament_StopWatch_GoalTextPointsAndTimeAndClose" : "Tournament_StopWatch_GoalTextPointsAndTime" ), 5, wszDefendersName, wszPoints, wszTime, wszAttackersName, wszPoints ); if ( m_pStopWatchGoalText ) { PrepareStopWatchString( wzHelp, m_pStopWatchGoalText ); } if ( bCappedAllPoints ) { if ( m_pStopWatchGoalText2 ) { m_pStopWatchGoalText2->SetVisible( false ); } if ( m_pStopWatchGoalBGLarge ) { m_pStopWatchGoalBGLarge->SetVisible( false ); } if ( m_pStopWatchGoalBGSmall ) { m_pStopWatchGoalBGSmall->SetVisible( true ); } if ( m_pStopWatchGoalDivider ) { m_pStopWatchGoalDivider->SetVisible( false ); } } else { if ( m_pStopWatchGoalText2 ) { m_pStopWatchGoalText2->SetVisible( true ); } if ( m_pStopWatchGoalBGLarge ) { m_pStopWatchGoalBGLarge->SetVisible( true ); } if ( m_pStopWatchGoalBGSmall ) { m_pStopWatchGoalBGSmall->SetVisible( false ); } if ( m_pStopWatchGoalDivider ) { m_pStopWatchGoalDivider->SetVisible( true ); } iPoints += 1; _snwprintf( wszPoints, ARRAYSIZE( wszPoints ), INT_CHAR_FMT, iPoints, iPoints == 1 ? g_pVGuiLocalize->Find( "Tournament_StopWatch_Point" ) : g_pVGuiLocalize->Find( "Tournament_StopWatch_Points" ) ); g_pVGuiLocalize->ConstructString_safe( wzHelp, g_pVGuiLocalize->Find( "Tournament_StopWatch_GoalTextPointsAndTime2" ), 4, wszAttackersName, wszDefendersName, wszAttackersName, wszPoints ); if ( m_pStopWatchGoalText2 ) { PrepareStopWatchString( wzHelp, m_pStopWatchGoalText2 ); } } if ( pLocalPlayer->GetTeam() == pAttacker ) { g_pVGuiLocalize->ConstructString_safe( wszLabel, g_pVGuiLocalize->Find( "Tournament_StopWatch_TimeVictory" ), 1, wszDefendersName ); if ( m_pStopWatchGoal ) { m_pStopWatchGoal->SetDialogVariable( "objectivelabel", wszLabel ); } } } else { if ( m_pStopWatchGoalText2 ) { m_pStopWatchGoalText2->SetVisible( false ); } if ( m_pStopWatchGoalBGLarge ) { m_pStopWatchGoalBGLarge->SetVisible( false ); } if ( m_pStopWatchGoalBGSmall ) { m_pStopWatchGoalBGSmall->SetVisible( true ); } if ( m_pStopWatchGoalDivider ) { m_pStopWatchGoalDivider->SetVisible( false ); } g_pVGuiLocalize->ConstructString_safe( wzHelp, g_pVGuiLocalize->Find( "Tournament_StopWatch_GoalTextPoints" ), 4, wszDefendersName, wszAttackersName ); if ( m_pStopWatchGoalText ) { PrepareStopWatchString( wzHelp, m_pStopWatchGoalText ); } if ( pLocalPlayer->GetTeam() == pAttacker ) { g_pVGuiLocalize->ConstructString_safe( wszLabel, g_pVGuiLocalize->Find( "Tournament_StopWatch_AttackerScore" ), 1, wszDefendersName ); if ( m_pStopWatchGoal ) { m_pStopWatchGoal->SetDialogVariable( "objectivelabel", wszLabel ); } } } } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool CHudTeamGoalTournament::ShouldDraw( void ) { if ( !TFGameRules() || !TFGameRules()->IsInTournamentMode() || !TFGameRules()->IsInStopWatch() || ( ( TFGameRules()->State_Get() != GR_STATE_PREROUND ) && !TFGameRules()->InSetup() ) ) { m_flShowAt = -1.f; return false; } if ( ObjectiveResource() ) { int iActiveTimer = ObjectiveResource()->GetStopWatchTimer(); CTeamRoundTimer *pTimer = dynamic_cast( ClientEntityList().GetEnt( iActiveTimer ) ); if ( pTimer && pTimer->IsWatchingTimeStamps() ) { m_flShowAt = -1.f; return false; } } if ( ( m_flShowAt < 0 ) || ( m_flShowAt > gpGlobals->curtime ) ) { return false; } // only show the panel for 15 seconds after it is first draws if ( gpGlobals->curtime - m_flShowAt > 15.f ) { m_flShowAt = -1.f; return false; } C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( pPlayer && pPlayer->IsAlive() && ( pPlayer->GetTeamNumber() >= FIRST_GAME_TEAM ) ) { if ( CHudElement::ShouldDraw() ) { CHudElement *pHudSwitch = gHUD.FindElement( "CHudTeamSwitch" ); if ( pHudSwitch && pHudSwitch->ShouldDraw() ) return false; return true; } } return false; }