//-----------------------------------------------------------------------------
// 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 );
}
예제 #2
0
//-----------------------------------------------------------------------------
// 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 );
		}
	}
}