//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTeamRoundTimer::SetActiveTimer( CTeamRoundTimer *pNewlyActive ) { CBaseEntity *pChosenTimer = pNewlyActive; // Ensure all other timers are off. CBaseEntity *pEntity = NULL; while ((pEntity = gEntList.FindEntityByClassname( pEntity, "team_round_timer" )) != NULL) { if ( pEntity == pNewlyActive ) continue; CTeamRoundTimer *pTimer = assert_cast< CTeamRoundTimer* >( pEntity ); if ( !pTimer->IsDisabled() && pTimer->ShowInHud() ) { if ( pChosenTimer ) { // Turn off all other hud timers pTimer->SetShowInHud( false ); } else { // Found a timer. Use it. pChosenTimer = pTimer; } } } ObjectiveResource()->SetTimerInHUD( pChosenTimer ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFHudObjectiveStatus::Think() { if ( !TeamplayRoundBasedRules() ) return; SetVisiblePanels(); // check for an active timer and turn the time panel on or off if we need to if ( m_pTimePanel ) { // Don't draw in freezecam, or when the game's not running C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); bool bDisplayTimer = !( pPlayer && pPlayer->GetObserverMode() == OBS_MODE_FREEZECAM ); if ( bDisplayTimer ) { // is the time panel still pointing at an active timer? int iCurrentTimer = m_pTimePanel->GetTimerIndex(); CTeamRoundTimer *pTimer = dynamic_cast< CTeamRoundTimer* >( ClientEntityList().GetEnt( iCurrentTimer ) ); if ( pTimer && !pTimer->IsDormant() && !pTimer->IsDisabled() && pTimer->ShowInHud() ) { // the current timer is fine, make sure the panel is visible bDisplayTimer = true; } else if ( ObjectiveResource() ) { // check for a different timer int iActiveTimer = ObjectiveResource()->GetTimerToShowInHUD(); pTimer = dynamic_cast< CTeamRoundTimer* >( ClientEntityList().GetEnt( iActiveTimer ) ); bDisplayTimer = ( iActiveTimer != 0 && pTimer && !pTimer->IsDormant() ); if ( bDisplayTimer ) m_pTimePanel->SetTimerIndex( iActiveTimer ); } } if ( bDisplayTimer ) { if ( !m_pTimePanel->IsVisible() ) { m_pTimePanel->SetVisible( true ); // If our spectator GUI is visible, invalidate its layout so that it moves the reinforcement label if ( g_pSpectatorGUI ) { g_pSpectatorGUI->InvalidateLayout(); } } } else if ( m_pTimePanel->IsVisible() ) { m_pTimePanel->SetVisible( false ); } } }
// Use this proxy to flash the round timer whenever the timer is restarted // because trapping the round start event doesn't work ( the event also flushes // all hud events and obliterates our TimerFlash event ) static void RecvProxy_TimerPaused( const CRecvProxyData *pData, void *pStruct, void *pOut ) { CTeamRoundTimer *pTimer = (CTeamRoundTimer *) pStruct; bool bTimerPaused = ( pData->m_Value.m_Int > 0 ); if ( bTimerPaused == false ) { g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "TimerFlash" ); } if ( pTimer ) { pTimer->InternalSetPaused( bTimerPaused ); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFHudTimeStatus::OnThink() { if ( m_flNextThink < gpGlobals->curtime ) { CTeamRoundTimer *pTimer = dynamic_cast< CTeamRoundTimer* >( ClientEntityList().GetEnt( m_iTimerIndex ) ); // get the time remaining (in seconds) if ( pTimer ) { int nTotalTime = pTimer->GetTimerMaxLength(); int nTimeRemaining = pTimer->GetTimeRemaining(); if ( m_pTimeValue && m_pTimeValue->IsVisible() ) { // set our label int nMinutes = 0; int nSeconds = 0; char temp[256]; if ( nTimeRemaining <= 0 ) { nMinutes = 0; nSeconds = 0; } else { nMinutes = nTimeRemaining / 60; nSeconds = nTimeRemaining % 60; } Q_snprintf( temp, sizeof( temp ), "%d:%02d", nMinutes, nSeconds ); m_pTimeValue->SetText( temp ); } // let the progress bar know the percentage of time that's passed ( 0.0 -> 1.0 ) if ( m_pProgressBar && m_pProgressBar->IsVisible() ) { m_pProgressBar->SetPercentage( ( (float)nTotalTime - nTimeRemaining ) / (float)nTotalTime ); } } m_flNextThink = gpGlobals->curtime + 0.1f; } }
//----------------------------------------------------------------------------- // Purpose: Check that the points aren't all held by one team if they are // this will reset the round and will reset all the points //----------------------------------------------------------------------------- int CTeamControlPointRound::CheckWinConditions( void ) { int iWinners = TeamOwnsAllPoints(); if ( ( m_iInvalidCapWinner != 1 ) && ( iWinners >= FIRST_GAME_TEAM ) && ( iWinners != m_iInvalidCapWinner ) ) { bool bWinner = true; #if defined( TF_DLL) if ( TFGameRules() && TFGameRules()->IsInKothMode() ) { CTeamRoundTimer *pTimer = NULL; if ( iWinners == TF_TEAM_RED ) { pTimer = TFGameRules()->GetRedKothRoundTimer(); } else if ( iWinners == TF_TEAM_BLUE ) { pTimer = TFGameRules()->GetBlueKothRoundTimer(); } if ( pTimer ) { if ( pTimer->GetTimeRemaining() > 0 || TFGameRules()->TimerMayExpire() == false ) { bWinner = false; } } } #endif if ( bWinner ) { FireTeamWinOutput( iWinners ); return iWinners; } } return -1; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTeamRoundTimer::SendTimeWarning( int nWarning ) { // don't play sounds if the level designer has turned them off or if it's during the WaitingForPlayers time if ( !m_bTimerPaused && m_bAutoCountdown && !TeamplayRoundBasedRules()->IsInWaitingForPlayers() ) { C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( pPlayer ) { if ( ObjectiveResource() ) { bool bShouldPlaySound = false; if ( TeamplayRoundBasedRules()->IsInTournamentMode() == true && TeamplayRoundBasedRules()->IsInStopWatch() == true ) { int iActiveTimer = ObjectiveResource()->GetTimerToShowInHUD(); int iStopWatchTimer = ObjectiveResource()->GetStopWatchTimer(); if ( IsStopWatchTimer() == true && IsWatchingTimeStamps() == false ) { CTeamRoundTimer *pTimer = dynamic_cast< CTeamRoundTimer* >( ClientEntityList().GetEnt( iActiveTimer ) ); if ( pTimer && pTimer->IsTimerPaused() == false && pTimer->GetTimeRemaining() > GetTimeRemaining() ) { bShouldPlaySound = true; } } else { CTeamRoundTimer *pStopWatch = dynamic_cast< CTeamRoundTimer* >( ClientEntityList().GetEnt( iStopWatchTimer ) ); if ( ObjectiveResource()->GetTimerToShowInHUD() == entindex() ) { if ( pStopWatch ) { if ( pStopWatch->IsTimerPaused() == true ) { bShouldPlaySound = true; } if ( pStopWatch->GetTimeRemaining() > GetTimeRemaining() && pStopWatch->IsWatchingTimeStamps() == false ) { bShouldPlaySound = true; } if ( pStopWatch->IsWatchingTimeStamps() == true ) { bShouldPlaySound = true; } } else { bShouldPlaySound = true; } } } } else { if( ObjectiveResource()->GetTimerToShowInHUD() == entindex()) { bShouldPlaySound = true; } } if ( bShouldPlaySound == true ) { pPlayer->EmitSound( GetTimeWarningSound( nWarning ) ); } } } } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFHudTimeStatus::SetExtraTimePanels() { if ( !TFGameRules() ) return; CTeamRoundTimer *pTimer = dynamic_cast< CTeamRoundTimer* >( ClientEntityList().GetEnt( m_iTimerIndex ) ); if ( !pTimer ) return; if ( m_pSetupLabel ) { // get the time remaining (in seconds) if ( pTimer ) { bool bInSetup = TFGameRules()->InSetup(); if ( m_pSetupBG ) m_pSetupBG->SetVisible( bInSetup ); m_pSetupLabel->SetVisible( bInSetup ); } } // Set the Sudden Death panels to be visible if ( m_pSuddenDeathLabel ) { bool bInSD = TFGameRules()->InStalemate(); if ( m_pSuddenDeathBG ) m_pSuddenDeathBG->SetVisible( bInSD ); m_pSuddenDeathLabel->SetVisible( bInSD ); } if ( m_pOvertimeLabel ) { bool bInOver = TFGameRules()->InOvertime(); if ( TFGameRules()->IsInKothMode() ) { bInOver = pTimer->GetTimeRemaining() <= 0.0f; } if ( bInOver ) { if ( m_pOvertimeBG && !m_pOvertimeBG->IsVisible() ) { m_pOvertimeLabel->SetAlpha( 0 ); m_pOvertimeBG->SetAlpha( 0 ); g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "OvertimeShow" ); // need to turn off the SuddenDeath images if they're on if ( m_pSuddenDeathBG ) m_pSuddenDeathBG->SetVisible( false ); m_pSuddenDeathLabel->SetVisible( false ); } if ( m_pOvertimeBG ) m_pOvertimeBG->SetVisible( true ); m_pOvertimeLabel->SetVisible( true ); CheckClockLabelLength( m_pOvertimeLabel, m_pOvertimeBG ); } else { if ( m_pOvertimeBG ) m_pOvertimeBG->SetVisible( false ); m_pOvertimeLabel->SetVisible( false ); } } if ( m_pWaitingForPlayersLabel ) { bool bInWaitingForPlayers = TFGameRules()->IsInWaitingForPlayers(); m_pWaitingForPlayersLabel->SetVisible( bInWaitingForPlayers ); if ( m_pWaitingForPlayersBG ) m_pWaitingForPlayersBG->SetVisible( bInWaitingForPlayers ); if ( bInWaitingForPlayers ) { // can't be waiting for players *AND* in setup at the same time if ( m_pSetupLabel ) m_pSetupLabel->SetVisible( false ); if ( m_pSetupBG ) m_pSetupBG->SetVisible( false ); CheckClockLabelLength( m_pWaitingForPlayersLabel, m_pWaitingForPlayersBG ); } } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFHudKothTimeStatus::Think( void ) { if ( !TFGameRules() ) return; // check for an active timer and turn the time panel on or off if we need to if ( m_pBlueKothTimer && m_pRedKothTimer ) { // Don't draw in freezecam, or when the game's not running C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); bool bDisplayTimers = !( pPlayer && pPlayer->GetObserverMode() == OBS_MODE_FREEZECAM ); if ( bDisplayTimers ) { bool bDisplayBlueTimer = false; bool bDisplayRedTimer = false; bool bDisplayGreenTimer = false; bool bDisplayYellowTimer = false; // is the time panel still pointing at an active timer? CTeamRoundTimer *pTimer = dynamic_cast< CTeamRoundTimer* >( ClientEntityList().GetEnt( m_pBlueKothTimer->GetTimerIndex() ) ); // Check for the current active timer (used for the pulsating HUD animation) CTFHudTimeStatus *pActiveKothTimerPanel = NULL; if ( !pTimer ) { pTimer = TFGameRules()->GetBlueKothRoundTimer(); if ( pTimer && m_pBlueKothTimer->GetTimerIndex() != pTimer->index ) m_pBlueKothTimer->SetTimerIndex( pTimer->index ); } if ( pTimer && !pTimer->IsDormant() && !pTimer->IsDisabled() ) { // the current timer is fine, make sure the panel is visible bDisplayBlueTimer = true; if ( !pTimer->IsTimerPaused() ) pActiveKothTimerPanel = m_pBlueKothTimer; } // And now let's check the other timer // is the time panel still pointing at an active timer? pTimer = dynamic_cast< CTeamRoundTimer* >( ClientEntityList().GetEnt( m_pRedKothTimer->GetTimerIndex() ) ); if ( !pTimer ) { pTimer = TFGameRules()->GetRedKothRoundTimer(); if ( pTimer && m_pRedKothTimer->GetTimerIndex() != pTimer->index ) m_pRedKothTimer->SetTimerIndex( pTimer->index ); } if ( pTimer && !pTimer->IsDormant() && !pTimer->IsDisabled() ) { // the current timer is fine, make sure the panel is visible bDisplayRedTimer = true; if ( !pTimer->IsTimerPaused() ) pActiveKothTimerPanel = m_pRedKothTimer; } if ( TFGameRules()->IsFourTeamGame() ) { // Check GRN timer pTimer = dynamic_cast< CTeamRoundTimer* >( ClientEntityList().GetEnt( m_pGreenKothTimer->GetTimerIndex() ) ); if ( !pTimer ) { pTimer = TFGameRules()->GetGreenKothRoundTimer(); if ( pTimer ) m_pGreenKothTimer->SetTimerIndex( pTimer->index ); } if ( pTimer && !pTimer->IsDormant() && !pTimer->IsDisabled() ) { // the current timer is fine, make sure the panel is visible bDisplayGreenTimer = true; if ( !pTimer->IsTimerPaused() ) pActiveKothTimerPanel = m_pGreenKothTimer; } // Check YLW timer pTimer = dynamic_cast< CTeamRoundTimer* >( ClientEntityList().GetEnt( m_pYellowKothTimer->GetTimerIndex() ) ); if ( !pTimer ) { pTimer = TFGameRules()->GetYellowKothRoundTimer(); if ( pTimer ) m_pYellowKothTimer->SetTimerIndex( pTimer->index ); } if ( pTimer && !pTimer->IsDormant() && !pTimer->IsDisabled() ) { // the current timer is fine, make sure the panel is visible bDisplayYellowTimer = true; if ( !pTimer->IsTimerPaused() ) pActiveKothTimerPanel = m_pYellowKothTimer; } } if ( !m_pBlueKothTimer->IsVisible() || !m_pRedKothTimer->IsVisible() ) { m_pBlueKothTimer->SetVisible( true ); // bDisplayBlueTimer m_pRedKothTimer->SetVisible( true ); // bDisplayRedTimer // If our spectator GUI is visible, invalidate its layout so that it moves the reinforcement label if ( g_pSpectatorGUI ) { g_pSpectatorGUI->InvalidateLayout(); } } if ( TFGameRules()->IsFourTeamGame() ) { if ( !m_pGreenKothTimer->IsVisible() || !m_pYellowKothTimer->IsVisible() ) { m_pGreenKothTimer->SetVisible( true ); m_pYellowKothTimer->SetVisible( true ); // If our spectator GUI is visible, invalidate its layout so that it moves the reinforcement label if ( g_pSpectatorGUI ) { g_pSpectatorGUI->InvalidateLayout(); } } } else { m_pGreenKothTimer->SetVisible( false ); m_pYellowKothTimer->SetVisible( false ); } // Set overtime panels active on our active panel (if needed) if ( m_pActiveKothTimerPanel ) m_pActiveKothTimerPanel->SetExtraTimePanels(); // Do NOT put a null check here, otherwise the white active timer BG will linger around after a round end if ( pActiveKothTimerPanel != m_pActiveKothTimerPanel ) { m_pActiveKothTimerPanel = pActiveKothTimerPanel; UpdateActiveTeam(); } } else { m_pBlueKothTimer->SetVisible( false ); m_pRedKothTimer->SetVisible( false ); m_pGreenKothTimer->SetVisible( false ); m_pYellowKothTimer->SetVisible( false ); m_pActiveTimerBG->SetVisible( false ); } } }