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.
703 lines
21 KiB
703 lines
21 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
#include <KeyValues.h> |
|
#include <vgui/IVGui.h> |
|
#include <vgui/ISurface.h> |
|
#include <filesystem.h> |
|
#include <vgui_controls/AnimationController.h> |
|
#include "iclientmode.h" |
|
#include "clientmode_shared.h" |
|
#include "shareddefs.h" |
|
#include "tf_shareddefs.h" |
|
#include "tf_controls.h" |
|
#include "tf_gamerules.h" |
|
#ifdef WIN32 |
|
#include "winerror.h" |
|
#endif |
|
#include "ixboxsystem.h" |
|
#include "intromenu.h" |
|
#include "tf_intromenu.h" |
|
#include "inputsystem/iinputsystem.h" |
|
|
|
// used to determine the action the intro menu should take when OnTick handles a think for us |
|
enum |
|
{ |
|
INTRO_NONE, |
|
INTRO_STARTVIDEO, |
|
INTRO_BACK, |
|
INTRO_CONTINUE, |
|
}; |
|
|
|
using namespace vgui; |
|
|
|
// sort function for the list of captions that we're going to show |
|
int CaptionsSort( CVideoCaption* const *p1, CVideoCaption* const *p2 ) |
|
{ |
|
// check the start time |
|
if ( (*p2)->m_flStartTime < (*p1)->m_flStartTime ) |
|
{ |
|
return 1; |
|
} |
|
|
|
return -1; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Constructor |
|
//----------------------------------------------------------------------------- |
|
CTFIntroMenu::CTFIntroMenu( IViewPort *pViewPort ) : BaseClass( pViewPort ) |
|
{ |
|
m_pVideo = new CTFVideoPanel( this, "VideoPanel" ); |
|
m_pModel = new CModelPanel( this, "MenuBG" ); |
|
m_pCaptionLabel = new CExLabel( this, "VideoCaption", "" ); |
|
|
|
#ifdef _X360 |
|
m_pFooter = new CTFFooter( this, "Footer" ); |
|
#else |
|
m_pBack = new CExButton( this, "Back", "" ); |
|
m_pOK = new CExButton( this, "Skip", "" ); |
|
m_pReplayVideo = new CExButton( this, "ReplayVideo", "" ); |
|
m_pContinue = new CExButton( this, "Continue", "" ); |
|
#endif |
|
|
|
m_iCurrentCaption = 0; |
|
m_flVideoStartTime = 0; |
|
|
|
m_flActionThink = -1; |
|
m_iAction = INTRO_NONE; |
|
|
|
//============================================================================= |
|
// HPE_BEGIN |
|
// [msmith] Flag for weather or not we're playing an in game video. |
|
//============================================================================= |
|
m_bPlayingInGameVideo = false; |
|
//============================================================================= |
|
// HPE_END |
|
//============================================================================= |
|
|
|
vgui::ivgui()->AddTickSignal( GetVPanel() ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Destructor |
|
//----------------------------------------------------------------------------- |
|
CTFIntroMenu::~CTFIntroMenu() |
|
{ |
|
m_Captions.PurgeAndDeleteElements(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFIntroMenu::ApplySchemeSettings( IScheme *pScheme ) |
|
{ |
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
|
|
if ( ::input->IsSteamControllerActive() ) |
|
{ |
|
LoadControlSettings( "Resource/UI/IntroMenu_SC.res" ); |
|
SetMouseInputEnabled( false ); |
|
} |
|
else |
|
{ |
|
LoadControlSettings( "Resource/UI/IntroMenu.res" ); |
|
SetMouseInputEnabled( true ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFIntroMenu::SetNextThink( float flActionThink, int iAction ) |
|
{ |
|
m_flActionThink = flActionThink; |
|
m_iAction = iAction; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFIntroMenu::OnTick() |
|
{ |
|
// @note Tom Bui: (yuck) |
|
// in training, never show the back button |
|
// we do this late, because there's a race condition for when IsInTraining() will return true |
|
if ( m_pBack->IsVisible() && TFGameRules() && TFGameRules()->IsInTraining() ) |
|
{ |
|
m_pBack->SetVisible(false); |
|
} |
|
|
|
//============================================================================= |
|
// HPE_BEGIN |
|
// [msmith] Used to play a movie during a map. For training videos. |
|
//============================================================================= |
|
if ( PendingInGameVideo() && !BaseClass::IsVisible() ) |
|
{ |
|
m_pViewPort->ShowPanel( this, true ); |
|
} |
|
//============================================================================= |
|
// HPE_END |
|
//============================================================================= |
|
|
|
// do we have anything special to do? |
|
else if ( m_flActionThink > 0 && m_flActionThink < gpGlobals->curtime ) |
|
{ |
|
if ( m_iAction == INTRO_STARTVIDEO ) |
|
{ |
|
|
|
//============================================================================= |
|
// HPE_BEGIN |
|
// [msmith] Pulled start video into a separate function. |
|
//============================================================================= |
|
StartVideo(); |
|
//============================================================================= |
|
// HPE_END |
|
//============================================================================= |
|
} |
|
else if ( m_iAction == INTRO_BACK ) |
|
{ |
|
m_pViewPort->ShowPanel( this, false ); |
|
m_pViewPort->ShowPanel( PANEL_MAPINFO, true ); |
|
} |
|
else if ( m_iAction == INTRO_CONTINUE ) |
|
{ |
|
m_pViewPort->ShowPanel( this, false ); |
|
|
|
//============================================================================= |
|
// HPE_BEGIN |
|
// [msmith] Used for the client to tell the server that we're whatching a movie or not |
|
//============================================================================= |
|
tf_training_client_message.SetValue( "" ); |
|
tf_training_client_message.SetValue( TRAINING_CLIENT_MESSAGE_NONE ); |
|
//============================================================================= |
|
// HPE_END |
|
//============================================================================= |
|
|
|
|
|
if ( GetLocalPlayerTeam() == TEAM_UNASSIGNED ) |
|
{ |
|
if ( TFGameRules()->IsInArenaMode() == true && tf_arena_use_queue.GetBool() == true ) |
|
{ |
|
m_pViewPort->ShowPanel( PANEL_ARENA_TEAM, true ); |
|
} |
|
else if ( TFGameRules()->IsMannVsMachineMode() || TFGameRules()->IsCompetitiveMode() ) |
|
{ |
|
engine->ClientCmd( "autoteam" ); |
|
} |
|
else |
|
{ |
|
m_pViewPort->ShowPanel( PANEL_TEAM, true ); |
|
} |
|
} |
|
else |
|
{ |
|
C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer(); |
|
|
|
// only open the class menu if they're not on team Spectator and they haven't already picked a class |
|
if ( pPlayer && |
|
( GetLocalPlayerTeam() != TEAM_SPECTATOR ) && |
|
( pPlayer->GetPlayerClass()->GetClassIndex() == TF_CLASS_UNDEFINED ) ) |
|
{ |
|
if ( tf_arena_force_class.GetBool() == false ) |
|
{ |
|
switch( GetLocalPlayerTeam() ) |
|
{ |
|
case TF_TEAM_RED: |
|
m_pViewPort->ShowPanel( PANEL_CLASS_RED, true ); |
|
break; |
|
|
|
case TF_TEAM_BLUE: |
|
m_pViewPort->ShowPanel( PANEL_CLASS_BLUE, true ); |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
// reset our think |
|
SetNextThink( -1, INTRO_NONE ); |
|
} |
|
|
|
// check if we need to update our captions |
|
if ( m_pCaptionLabel && m_pCaptionLabel->IsVisible() ) |
|
{ |
|
UpdateCaptions(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFIntroMenu::OnThink() |
|
{ |
|
//Always hide the health... this needs to be done every frame because a message from the server keeps resetting this. |
|
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); |
|
if ( pLocalPlayer ) |
|
{ |
|
pLocalPlayer->m_Local.m_iHideHUD |= HIDEHUD_HEALTH; |
|
} |
|
|
|
BaseClass::OnThink(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
bool CTFIntroMenu::LoadCaptions( void ) |
|
{ |
|
bool bSuccess = false; |
|
|
|
// clear any current captions |
|
m_Captions.PurgeAndDeleteElements(); |
|
m_iCurrentCaption = 0; |
|
|
|
if ( m_pCaptionLabel ) |
|
{ |
|
const char *szVideoFileName = GetVideoFileName( false ); |
|
KeyValues *kvCaptions = NULL; |
|
char strFullpath[MAX_PATH]; |
|
if ( szVideoFileName != NULL ) |
|
{ |
|
//============================================================================= |
|
// HPE_BEGIN |
|
// [msmith] The video may now be either a map video or an in game video. |
|
// Made a function to decide which video name to give back. |
|
//============================================================================= |
|
Q_strncpy( strFullpath, szVideoFileName, MAX_PATH ); // Assume we must play out of the media directory |
|
//============================================================================= |
|
// HPE_END |
|
//============================================================================= |
|
|
|
Q_strncat( strFullpath, ".res", MAX_PATH ); // Assume we're a .res extension type |
|
|
|
if ( g_pFullFileSystem->FileExists( strFullpath ) ) |
|
{ |
|
kvCaptions = new KeyValues( strFullpath ); |
|
|
|
if ( kvCaptions ) |
|
{ |
|
if ( kvCaptions->LoadFromFile( g_pFullFileSystem, strFullpath ) ) |
|
{ |
|
for ( KeyValues *pData = kvCaptions->GetFirstSubKey(); pData != NULL; pData = pData->GetNextKey() ) |
|
{ |
|
CVideoCaption *pCaption = new CVideoCaption; |
|
if ( pCaption ) |
|
{ |
|
pCaption->m_pszString = ReadAndAllocStringValue( pData, "string" ); |
|
pCaption->m_flStartTime = pData->GetFloat( "start", 0.0 ); |
|
pCaption->m_flDisplayTime = pData->GetFloat( "length", 3.0 ); |
|
|
|
m_Captions.AddToTail( pCaption ); |
|
|
|
// we have at least one caption to show |
|
bSuccess = true; |
|
} |
|
} |
|
} |
|
|
|
kvCaptions->deleteThis(); |
|
} |
|
} |
|
} |
|
} |
|
|
|
if ( bSuccess ) |
|
{ |
|
// sort the captions so we show them in the correct order (they're not necessarily in order in the .res file) |
|
m_Captions.Sort( CaptionsSort ); |
|
} |
|
|
|
return bSuccess; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFIntroMenu::UpdateCaptions( void ) |
|
{ |
|
//============================================================================= |
|
// HPE_BEGIN |
|
// [msmith] Timing should be realtime when playing in game becase the curtime is paused. |
|
//============================================================================= |
|
float testTime = m_bPlayingInGameVideo ? gpGlobals->realtime : gpGlobals->curtime; |
|
//============================================================================= |
|
// HPE_END |
|
//============================================================================= |
|
|
|
if ( m_pCaptionLabel && m_pCaptionLabel->IsVisible() && ( m_Captions.Count() > 0 ) ) |
|
{ |
|
CVideoCaption *pCaption = m_Captions[m_iCurrentCaption]; |
|
|
|
if ( pCaption ) |
|
{ |
|
if ( ( pCaption->m_flCaptionStart >= 0 ) && ( pCaption->m_flCaptionStart + pCaption->m_flDisplayTime < testTime ) ) |
|
{ |
|
// fade out the caption |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "VideoCaptionFadeOut" ); |
|
|
|
// move to the next caption |
|
m_iCurrentCaption++; |
|
|
|
if ( !m_Captions.IsValidIndex( m_iCurrentCaption ) ) |
|
{ |
|
// we're done showing captions |
|
m_pCaptionLabel->SetVisible( false ); |
|
} |
|
} |
|
// is it time to show the caption? |
|
else if ( m_flVideoStartTime + pCaption->m_flStartTime < testTime ) |
|
{ |
|
// have we already started this video? |
|
if ( pCaption->m_flCaptionStart < 0 ) |
|
{ |
|
m_pCaptionLabel->SetText( pCaption->m_pszString ); |
|
pCaption->m_flCaptionStart = testTime; |
|
|
|
// fade in the next caption |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "VideoCaptionFadeIn" ); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFIntroMenu::ShowPanel( bool bShow ) |
|
{ |
|
|
|
//============================================================================= |
|
// HPE_BEGIN: |
|
// [msmith] Don't show the back button when in training. You can only skip intro |
|
// movies. |
|
//============================================================================= |
|
m_pBack->SetVisible(true); |
|
if ( TFGameRules() && TFGameRules()->IsInTraining() ) |
|
{ |
|
m_pBack->SetVisible( false ); |
|
if ( PendingInGameVideo() == false ) |
|
{ |
|
VideoSystem_t playbackSystem = VideoSystem::NONE; |
|
char resolvedFile[MAX_PATH]; |
|
if ( g_pVideo != NULL && g_pVideo->LocatePlayableVideoFile( GetVideoFileName(), "GAME", &playbackSystem, resolvedFile, sizeof(resolvedFile) ) != VideoResult::SUCCESS ) |
|
{ |
|
//If we have no movie, no need to show the intro screen on a training mission. |
|
bShow = false; |
|
} |
|
} |
|
} |
|
//============================================================================= |
|
// HPE_END |
|
//============================================================================= |
|
|
|
|
|
if ( BaseClass::IsVisible() == bShow ) |
|
return; |
|
|
|
// reset our think |
|
SetNextThink( -1, INTRO_NONE ); |
|
|
|
if ( bShow ) |
|
{ |
|
InvalidateLayout( true, true ); |
|
Activate(); |
|
|
|
if ( m_pVideo ) |
|
{ |
|
//============================================================================= |
|
// HPE_BEGIN |
|
// [msmith] Pulled shutting down the video into a separate function. |
|
// If we're showing an in game video, we need to enable pausing so that |
|
// we can pause the game during the video. |
|
// If we're showing an intro training movie, we also need to tell the server that |
|
// we're whatching the intro movie so that the round does not start until it's over. |
|
// If we are watching an in game video, we do NOT send a message for that because |
|
// tf_training_client_message will contain the name of the video we're watching. |
|
//============================================================================= |
|
ShutdownVideo(); |
|
SetNextThink( gpGlobals->curtime + m_pVideo->GetStartDelay(), INTRO_STARTVIDEO ); |
|
|
|
if ( TFGameRules() && TFGameRules()->IsInTraining() ) |
|
{ |
|
if ( PendingInGameVideo() ) |
|
{ |
|
engine->ClientCmd( "sv_pausable 1" ); |
|
} |
|
else |
|
{ |
|
tf_training_client_message.SetValue( TRAINING_CLIENT_MESSAGE_WATCHING_INTRO_MOVIE ); |
|
} |
|
} |
|
//============================================================================= |
|
// HPE_END |
|
//============================================================================= |
|
|
|
} |
|
|
|
if ( m_pModel ) |
|
{ |
|
m_pModel->SetPanelDirty(); |
|
} |
|
} |
|
else |
|
{ |
|
Shutdown(); |
|
|
|
SetVisible( false ); |
|
|
|
//============================================================================= |
|
// HPE_BEGIN |
|
// [msmith] We must disable the ability to pause. If we don't, it looks like |
|
// some other function in TF2 causes the entire game to pause if sv_pausable is enabled. |
|
//============================================================================= |
|
if ( TFGameRules() && TFGameRules()->IsInTraining() ) |
|
{ |
|
engine->ClientCmd( "sv_pausable 0" ); |
|
} |
|
//============================================================================= |
|
// HPE_END |
|
//============================================================================= |
|
|
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFIntroMenu::OnIntroFinished( void ) |
|
{ |
|
// in training we want to give the user the ability to replay the movie |
|
if ( TFGameRules() && TFGameRules()->IsInTraining() ) |
|
{ |
|
m_pReplayVideo->SetVisible( true ); |
|
m_pContinue->SetVisible( true ); |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "IntroMovieContinueBlink" ); |
|
m_pOK->SetVisible( false ); |
|
} |
|
else |
|
{ |
|
float flTime = gpGlobals->curtime; |
|
|
|
if ( m_pModel && m_pModel->SetSequence( "UpSlow" ) ) |
|
{ |
|
// wait for the model sequence to finish before going to the next menu |
|
flTime = gpGlobals->curtime + m_pVideo->GetEndDelay(); |
|
} |
|
|
|
Shutdown(); |
|
|
|
SetNextThink( flTime, INTRO_CONTINUE ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFIntroMenu::OnCommand( const char *command ) |
|
{ |
|
if ( !Q_strcmp( command, "back" ) ) |
|
{ |
|
float flTime = gpGlobals->curtime; |
|
|
|
Shutdown(); |
|
|
|
// try to play the screenup sequence |
|
if ( m_pModel && m_pModel->SetSequence( "Up" ) ) |
|
{ |
|
flTime = gpGlobals->curtime + 0.35f; |
|
} |
|
|
|
// wait for the model sequence to finish before going back to the mapinfo menu |
|
SetNextThink( flTime, INTRO_BACK ); |
|
} |
|
else if ( !Q_strcmp( command, "skip" ) ) |
|
{ |
|
Shutdown(); |
|
|
|
// continue right now |
|
SetNextThink( gpGlobals->curtime, INTRO_CONTINUE ); |
|
} |
|
else if ( !Q_strcmp( command, "replayVideo" ) ) |
|
{ |
|
ShutdownVideo(); |
|
SetNextThink( gpGlobals->curtime, INTRO_STARTVIDEO ); |
|
} |
|
else |
|
{ |
|
BaseClass::OnCommand( command ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFIntroMenu::OnKeyCodePressed( KeyCode code ) |
|
{ |
|
if ( code == KEY_XBUTTON_A || code == STEAMCONTROLLER_A ) |
|
{ |
|
OnCommand( "skip" ); |
|
} |
|
else if ( code == KEY_XBUTTON_B || code == STEAMCONTROLLER_B ) |
|
{ |
|
OnCommand( "back" ); |
|
} |
|
else |
|
{ |
|
BaseClass::OnKeyCodePressed( code ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFIntroMenu::Shutdown( void ) |
|
{ |
|
//============================================================================= |
|
// HPE_BEGIN |
|
// [msmith] Refactored the shutdown video logic into a containing function. |
|
//============================================================================= |
|
ShutdownVideo(); |
|
//============================================================================= |
|
// HPE_END |
|
//============================================================================= |
|
|
|
if ( m_pCaptionLabel && m_pCaptionLabel->IsVisible() ) |
|
{ |
|
m_pCaptionLabel->SetVisible( false ); |
|
} |
|
|
|
m_iCurrentCaption = 0; |
|
m_flVideoStartTime = 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
//============================================================================= |
|
// HPE_BEGIN |
|
// [msmith] New helper functions |
|
//============================================================================= |
|
void CTFIntroMenu::ShutdownVideo() |
|
{ |
|
if ( m_pVideo ) |
|
{ |
|
m_pVideo->Shutdown(); // make sure we're not currently running |
|
} |
|
|
|
//Make sure we unpause the game if it was paused from an in game play of a video. |
|
if ( m_bPlayingInGameVideo ) |
|
{ |
|
UnpauseGame(); |
|
} |
|
|
|
m_bPlayingInGameVideo = false; |
|
} |
|
|
|
bool CTFIntroMenu::PendingInGameVideo( void ) |
|
{ |
|
if ( TFGameRules() && TFGameRules()->IsInTraining() ) |
|
{ |
|
//If the message is a string, it's a video name. |
|
return strlen( tf_training_client_message.GetString() ) > 3; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
const char *CTFIntroMenu::GetVideoFileName( bool withExtension ) |
|
{ |
|
if ( PendingInGameVideo() ) |
|
{ |
|
return TFGameRules()->FormatVideoName( tf_training_client_message.GetString(), withExtension ); |
|
} |
|
|
|
if ( TFGameRules() && TFGameRules()->IsInTraining() ) |
|
{ |
|
ConVarRef training_map_video("training_map_video"); |
|
if ( strlen( training_map_video.GetString() ) > 3 ) |
|
{ |
|
return TFGameRules()->FormatVideoName( training_map_video.GetString(), withExtension ); |
|
} |
|
} |
|
|
|
return TFGameRules()->GetVideoFileForMap( withExtension ); |
|
} |
|
|
|
void CTFIntroMenu::StartVideo() |
|
{ |
|
m_pOK->SetVisible( true ); |
|
m_pReplayVideo->SetVisible( false ); |
|
m_pContinue->SetVisible( false ); |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "IntroMovieContinueBlinkStop" ); |
|
if ( m_pVideo ) |
|
{ |
|
// turn on the captions if we have them |
|
if ( LoadCaptions() ) |
|
{ |
|
if ( m_pCaptionLabel && !m_pCaptionLabel->IsVisible() ) |
|
{ |
|
m_pCaptionLabel->SetText( " " ); |
|
m_pCaptionLabel->SetVisible( true ); |
|
//Make sure the label is fully faded in when starting to play. |
|
//It could have been faded out from a prior animation event form an animation effect in a previous video instance. |
|
m_pCaptionLabel->SetAlpha( 255 ); |
|
} |
|
} |
|
else |
|
{ |
|
if ( m_pCaptionLabel && m_pCaptionLabel->IsVisible() ) |
|
{ |
|
m_pCaptionLabel->SetVisible( false ); |
|
} |
|
} |
|
|
|
m_pVideo->Activate(); |
|
|
|
if ( PendingInGameVideo() ) |
|
{ |
|
m_pVideo->BeginPlayback( GetVideoFileName() ); |
|
PauseGame(); |
|
m_bPlayingInGameVideo = true; |
|
|
|
//Since we have started playing the video, we can reset the message string to empty. |
|
tf_training_client_message.SetValue( "" ); |
|
} |
|
else |
|
{ |
|
m_pVideo->BeginPlayback( GetVideoFileName() ); |
|
} |
|
|
|
m_pVideo->MoveToFront(); |
|
|
|
m_flVideoStartTime = m_bPlayingInGameVideo ? gpGlobals->realtime : gpGlobals->curtime; |
|
} |
|
} |
|
|
|
void CTFIntroMenu::UnpauseGame( void ) |
|
{ |
|
if ( TFGameRules() && TFGameRules()->IsInTraining() ) |
|
{ |
|
engine->ClientCmd( "unpause" ); |
|
} |
|
} |
|
|
|
void CTFIntroMenu::PauseGame( void ) |
|
{ |
|
if ( TFGameRules() && TFGameRules()->IsInTraining() ) |
|
{ |
|
engine->ClientCmd( "pause" ); |
|
} |
|
} |
|
//============================================================================= |
|
// HPE_END |
|
//=============================================================================
|
|
|