|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "BasePanel.h"
#include "NewGameDialog.h"
#include "EngineInterface.h"
#include "vgui_controls/Button.h"
#include "vgui_controls/CheckButton.h"
#include "KeyValues.h"
#include "vgui/ISurface.h"
#include "vgui/IInput.h"
#include "vgui/ILocalize.h"
#include <vgui/ISystem.h>
#include "vgui_controls/RadioButton.h"
#include "vgui_controls/ComboBox.h"
#include "vgui_controls/ImagePanel.h"
#include "vgui_controls/Frame.h"
#include "vgui_controls/ControllerMap.h"
#include "filesystem.h"
#include "ModInfo.h"
#include "tier1/convar.h"
#include "GameUI_Interface.h"
#include "tier0/icommandline.h"
#include "vgui_controls/AnimationController.h"
#include "CommentaryExplanationDialog.h"
#include "vgui_controls/BitmapImagePanel.h"
#include "BonusMapsDatabase.h"
#include <stdio.h>
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace vgui;
static float g_ScrollSpeedSlow; static float g_ScrollSpeedFast;
// sort function used in displaying chapter list
struct chapter_t { char filename[32]; }; static int __cdecl ChapterSortFunc(const void *elem1, const void *elem2) { chapter_t *c1 = (chapter_t *)elem1; chapter_t *c2 = (chapter_t *)elem2;
// compare chapter number first
static int chapterlen = strlen("chapter"); if (atoi(c1->filename + chapterlen) > atoi(c2->filename + chapterlen)) return 1; else if (atoi(c1->filename + chapterlen) < atoi(c2->filename + chapterlen)) return -1;
// compare length second (longer string show up later in the list, eg. chapter9 before chapter9a)
if (strlen(c1->filename) > strlen(c2->filename)) return 1; else if (strlen(c1->filename) < strlen(c2->filename)) return -1;
// compare strings third
return strcmp(c1->filename, c2->filename); }
//-----------------------------------------------------------------------------
// Purpose: invisible panel used for selecting a chapter panel
//-----------------------------------------------------------------------------
class CSelectionOverlayPanel : public vgui::Panel { DECLARE_CLASS_SIMPLE( CSelectionOverlayPanel, Panel ); int m_iChapterIndex; CNewGameDialog *m_pSelectionTarget; public: CSelectionOverlayPanel( Panel *parent, CNewGameDialog *selectionTarget, int chapterIndex ) : BaseClass( parent, NULL ) { m_iChapterIndex = chapterIndex; m_pSelectionTarget = selectionTarget; SetPaintEnabled(false); SetPaintBackgroundEnabled(false); }
virtual void OnMousePressed( vgui::MouseCode code ) { if (GetParent()->IsEnabled()) { m_pSelectionTarget->SetSelectedChapterIndex( m_iChapterIndex ); } }
virtual void OnMouseDoublePressed( vgui::MouseCode code ) { // call the panel
OnMousePressed( code ); if (GetParent()->IsEnabled()) { PostMessage( m_pSelectionTarget, new KeyValues("Command", "command", "play") ); } } };
//-----------------------------------------------------------------------------
// Purpose: selectable item with screenshot for an individual chapter in the dialog
//-----------------------------------------------------------------------------
class CGameChapterPanel : public vgui::EditablePanel { DECLARE_CLASS_SIMPLE( CGameChapterPanel, vgui::EditablePanel );
ImagePanel *m_pLevelPicBorder; ImagePanel *m_pLevelPic; ImagePanel *m_pCommentaryIcon; Label *m_pChapterLabel; Label *m_pChapterNameLabel;
Color m_TextColor; Color m_DisabledColor; Color m_SelectedColor; Color m_FillColor;
char m_szConfigFile[_MAX_PATH]; char m_szChapter[32];
bool m_bTeaserChapter; bool m_bHasBonus; bool m_bCommentaryMode;
bool m_bIsSelected;
public: CGameChapterPanel( CNewGameDialog *parent, const char *name, const char *chapterName, int chapterIndex, const char *chapterNumber, const char *chapterConfigFile, bool bCommentary ) : BaseClass( parent, name ) { Q_strncpy( m_szConfigFile, chapterConfigFile, sizeof(m_szConfigFile) ); Q_strncpy( m_szChapter, chapterNumber, sizeof(m_szChapter) );
m_pLevelPicBorder = SETUP_PANEL( new ImagePanel( this, "LevelPicBorder" ) ); m_pLevelPic = SETUP_PANEL( new ImagePanel( this, "LevelPic" ) ); m_pCommentaryIcon = NULL; m_bCommentaryMode = bCommentary; m_bIsSelected = false;
wchar_t text[32]; wchar_t num[32]; wchar_t *chapter = g_pVGuiLocalize->Find("#GameUI_Chapter"); g_pVGuiLocalize->ConvertANSIToUnicode( chapterNumber, num, sizeof(num) ); _snwprintf( text, ARRAYSIZE(text), L"%ls %ls", chapter ? chapter : L"CHAPTER", num );
if ( ModInfo().IsSinglePlayerOnly() ) { m_pChapterLabel = new Label( this, "ChapterLabel", text ); m_pChapterNameLabel = new Label( this, "ChapterNameLabel", chapterName ); } else { m_pChapterLabel = new Label( this, "ChapterLabel", chapterName ); m_pChapterNameLabel = new Label( this, "ChapterNameLabel", "#GameUI_LoadCommentary" ); }
SetPaintBackgroundEnabled( false );
// the image has the same name as the config file
char szMaterial[ MAX_PATH ]; Q_snprintf( szMaterial, sizeof(szMaterial), "chapters/%s", chapterConfigFile ); char *ext = strstr( szMaterial, "." ); if ( ext ) { *ext = 0; } m_pLevelPic->SetImage( szMaterial );
KeyValues *pKeys = NULL; if ( GameUI().IsConsoleUI() ) { pKeys = BasePanel()->GetConsoleControlSettings()->FindKey( "NewGameChapterPanel.res" ); } LoadControlSettings( "Resource/NewGameChapterPanel.res", NULL, pKeys );
int px, py; m_pLevelPicBorder->GetPos( px, py ); SetSize( m_pLevelPicBorder->GetWide(), py + m_pLevelPicBorder->GetTall() );
// create a selection panel the size of the page
CSelectionOverlayPanel *overlay = new CSelectionOverlayPanel( this, parent, chapterIndex ); overlay->SetBounds(0, 0, GetWide(), GetTall()); overlay->MoveToFront();
// HACK: Detect new episode teasers by the "Coming Soon" text
wchar_t w_szStrTemp[256]; m_pChapterNameLabel->GetText( w_szStrTemp, sizeof(w_szStrTemp) ); m_bTeaserChapter = !wcscmp(w_szStrTemp, L"Coming Soon"); m_bHasBonus = false; }
virtual void ApplySchemeSettings( IScheme *pScheme ) { m_TextColor = pScheme->GetColor( "NewGame.TextColor", Color(255, 255, 255, 255) ); m_FillColor = pScheme->GetColor( "NewGame.FillColor", Color(255, 255, 255, 255) ); m_DisabledColor = pScheme->GetColor( "NewGame.DisabledColor", Color(255, 255, 255, 255) ); m_SelectedColor = pScheme->GetColor( "NewGame.SelectionColor", Color(255, 255, 255, 255) );
BaseClass::ApplySchemeSettings( pScheme );
// Hide chapter numbers for new episode teasers
if ( m_bTeaserChapter ) { m_pChapterLabel->SetVisible( false ); } if ( GameUI().IsConsoleUI() ) { m_pChapterNameLabel->SetVisible( false ); }
m_pCommentaryIcon = dynamic_cast<ImagePanel*>( FindChildByName( "CommentaryIcon" ) ); if ( m_pCommentaryIcon ) m_pCommentaryIcon->SetVisible( m_bCommentaryMode ); }
bool IsSelected( void ) const { return m_bIsSelected; }
void SetSelected( bool state ) { m_bIsSelected = state;
// update the text/border colors
if ( !IsEnabled() ) { m_pChapterLabel->SetFgColor( m_DisabledColor ); m_pChapterNameLabel->SetFgColor( Color(0, 0, 0, 0) ); m_pLevelPicBorder->SetFillColor( m_DisabledColor ); m_pLevelPic->SetAlpha( GameUI().IsConsoleUI() ? 64 : 128 ); return; }
if ( state ) { if ( !GameUI().IsConsoleUI() ) { m_pChapterLabel->SetFgColor( m_SelectedColor ); m_pChapterNameLabel->SetFgColor( m_SelectedColor ); } m_pLevelPicBorder->SetFillColor( m_SelectedColor ); } else { m_pChapterLabel->SetFgColor( m_TextColor ); m_pChapterNameLabel->SetFgColor( m_TextColor ); m_pLevelPicBorder->SetFillColor( m_FillColor ); } m_pLevelPic->SetAlpha( 255 ); }
const char *GetConfigFile() { return m_szConfigFile; }
const char *GetChapter() { return m_szChapter; }
bool IsTeaserChapter() { return m_bTeaserChapter; }
bool HasBonus() { return m_bHasBonus; }
void SetCommentaryMode( bool bCommentaryMode ) { m_bCommentaryMode = bCommentaryMode; if ( m_pCommentaryIcon ) m_pCommentaryIcon->SetVisible( m_bCommentaryMode ); } };
const char *COM_GetModDirectory() { static char modDir[MAX_PATH]; if ( Q_strlen( modDir ) == 0 ) { const char *gamedir = CommandLine()->ParmValue("-game", CommandLine()->ParmValue( "-defaultgamedir", "hl2" ) ); Q_strncpy( modDir, gamedir, sizeof(modDir) ); if ( strchr( modDir, '/' ) || strchr( modDir, '\\' ) ) { Q_StripLastDir( modDir, sizeof(modDir) ); int dirlen = Q_strlen( modDir ); Q_strncpy( modDir, gamedir + dirlen, sizeof(modDir) - dirlen ); } }
return modDir; }
//-----------------------------------------------------------------------------
// Purpose: new game chapter selection
//-----------------------------------------------------------------------------
CNewGameDialog::CNewGameDialog(vgui::Panel *parent, bool bCommentaryMode) : BaseClass(parent, "NewGameDialog") { SetDeleteSelfOnClose(true); SetBounds(0, 0, 372, 160); SetSizeable( false ); m_iSelectedChapter = -1; m_ActiveTitleIdx = 0;
m_bCommentaryMode = bCommentaryMode; m_bMapStarting = false; m_bScrolling = false; m_ScrollCt = 0; m_ScrollSpeed = 0.f; m_ButtonPressed = SCROLL_NONE; m_ScrollDirection = SCROLL_NONE; m_pCommentaryLabel = NULL;
m_iBonusSelection = 0; m_bScrollToFirstBonusMap = false;
SetTitle("#GameUI_NewGame", true);
m_pNextButton = new Button( this, "Next", "#gameui_next" ); m_pPrevButton = new Button( this, "Prev", "#gameui_prev" ); m_pPlayButton = new CNewGamePlayButton( this, "Play", "#GameUI_Play" ); m_pPlayButton->SetCommand( "Play" );
vgui::Button *cancel = new vgui::Button( this, "Cancel", "#GameUI_Cancel" ); cancel->SetCommand( "Close" );
m_pCenterBg = SETUP_PANEL( new Panel( this, "CenterBG" ) ); m_pCenterBg->SetVisible( false );
if ( GameUI().IsConsoleUI() ) { m_pNextButton->SetVisible( false ); m_pPrevButton->SetVisible( false ); m_pPlayButton->SetVisible( false ); cancel->SetVisible( false );
m_pCenterBg->SetPaintBackgroundType( 2 ); m_pCenterBg->SetVisible( true );
m_pChapterTitleLabels[0] = SETUP_PANEL( new Label( this, "ChapterTitleLabel", "" ) ); m_pChapterTitleLabels[0]->SetVisible( true ); m_pChapterTitleLabels[0]->SetFgColor( Color( 255, 255, 255, 255 ) );
m_pChapterTitleLabels[1] = SETUP_PANEL( new Label( this, "ChapterTitleLabel2", "" ) ); m_pChapterTitleLabels[1]->SetVisible( true ); m_pChapterTitleLabels[1]->SetAlpha( 0 ); m_pChapterTitleLabels[1]->SetFgColor( Color( 255, 255, 255, 255 ) );
m_pBonusSelection = SETUP_PANEL( new Label( this, "BonusSelectionLabel", "#GameUI_BonusMapsStandard" ) ); m_pBonusSelectionBorder = SETUP_PANEL( new ImagePanel( this, "BonusSelectionBorder" ) );
m_pFooter = new CFooterPanel( parent, "NewGameFooter" ); m_pFooter->AddNewButtonLabel( "#GameUI_Play", "#GameUI_Icons_A_BUTTON" ); m_pFooter->AddNewButtonLabel( "#GameUI_Close", "#GameUI_Icons_B_BUTTON" ); } else { m_pFooter = NULL; }
// parse out the chapters off disk
static const int MAX_CHAPTERS = 32; chapter_t chapters[MAX_CHAPTERS];
char szFullFileName[MAX_PATH]; int chapterIndex = 0;
if ( IsPC() || !IsX360() ) { FileFindHandle_t findHandle = FILESYSTEM_INVALID_FIND_HANDLE; const char *fileName = "cfg/chapter*.cfg"; fileName = g_pFullFileSystem->FindFirst( fileName, &findHandle ); while ( fileName && chapterIndex < MAX_CHAPTERS ) { if ( fileName[0] ) { // Only load chapter configs from the current mod's cfg dir
// or else chapters appear that we don't want!
Q_snprintf( szFullFileName, sizeof(szFullFileName), "cfg/%s", fileName ); FileHandle_t f = g_pFullFileSystem->Open( szFullFileName, "rb", "MOD" ); if ( f ) { // don't load chapter files that are empty, used in the demo
if ( g_pFullFileSystem->Size(f) > 0 ) { Q_strncpy(chapters[chapterIndex].filename, fileName, sizeof(chapters[chapterIndex].filename)); ++chapterIndex; } g_pFullFileSystem->Close( f ); } } fileName = g_pFullFileSystem->FindNext(findHandle); } } else if ( IsX360() ) { int ChapterStringIndex = 0; bool bExists = true; while ( bExists && chapterIndex < MAX_CHAPTERS ) { Q_snprintf( szFullFileName, sizeof( szFullFileName ), "cfg/chapter%d.cfg", ChapterStringIndex+1 );
FileHandle_t f = g_pFullFileSystem->Open( szFullFileName, "rb", "MOD" ); if ( f ) { Q_strncpy(chapters[chapterIndex].filename, szFullFileName + 4, sizeof(chapters[chapterIndex].filename)); ++chapterIndex; ++ChapterStringIndex; g_pFullFileSystem->Close( f ); } else { bExists = false; } //Hack to account for xbox360 missing chapter9a
if ( ChapterStringIndex == 10 ) { Q_snprintf( szFullFileName, sizeof( szFullFileName ), "cfg/chapter9a.cfg" ); FileHandle_t fChap = g_pFullFileSystem->Open( szFullFileName, "rb", "MOD" ); if ( fChap ) { Q_strncpy(chapters[chapterIndex].filename, szFullFileName + 4, sizeof(chapters[chapterIndex].filename)); ++chapterIndex; g_pFullFileSystem->Close( fChap ); } }
} }
bool bBonusesUnlocked = false;
if ( GameUI().IsConsoleUI() ) { if ( !m_bCommentaryMode ) { // Scan to see if the bonus maps have been unlocked
bBonusesUnlocked = BonusMapsDatabase()->BonusesUnlocked(); } }
// sort the chapters
qsort(chapters, chapterIndex, sizeof(chapter_t), &ChapterSortFunc);
// work out which chapters are unlocked
ConVarRef var( "sv_unlockedchapters" );
if ( bBonusesUnlocked ) { // Bonuses are unlocked so we need to unlock all the chapters too
var.SetValue( 15 ); }
const char *unlockedChapter = var.IsValid() ? var.GetString() : "1"; int iUnlockedChapter = atoi(unlockedChapter);
// add chapters to combobox
for (int i = 0; i < chapterIndex; i++) { const char *fileName = chapters[i].filename; char chapterID[32] = { 0 }; sscanf(fileName, "chapter%s", chapterID); // strip the extension
char *ext = V_stristr(chapterID, ".cfg"); if (ext) { *ext = 0; }
const char *pGameDir = COM_GetModDirectory();
char chapterName[64]; Q_snprintf(chapterName, sizeof(chapterName), "#%s_Chapter%s_Title", pGameDir, chapterID);
Q_snprintf( szFullFileName, sizeof( szFullFileName ), "%s", fileName ); CGameChapterPanel *chapterPanel = SETUP_PANEL( new CGameChapterPanel( this, NULL, chapterName, i, chapterID, szFullFileName, m_bCommentaryMode ) ); chapterPanel->SetVisible( false );
UpdatePanelLockedStatus( iUnlockedChapter, i + 1, chapterPanel );
if ( GameUI().IsConsoleUI() ) { if ( bBonusesUnlocked ) { // check to see if it has associated challenges
for ( int iBonusMap = 0; iBonusMap < BonusMapsDatabase()->BonusCount(); ++iBonusMap ) { BonusMapDescription_t *pMap = BonusMapsDatabase()->GetBonusData( iBonusMap ); if ( Q_stricmp( pMap->szChapterName, szFullFileName ) == 0 && !pMap->bLocked ) { chapterPanel->m_bHasBonus = true; chapterPanel->SetControlVisible( "HasBonusLabel", true ); } } } }
m_ChapterPanels.AddToTail( chapterPanel ); }
KeyValues *pKeys = NULL; if ( GameUI().IsConsoleUI() ) { pKeys = BasePanel()->GetConsoleControlSettings()->FindKey( "NewGameDialog.res" ); } LoadControlSettings( "Resource/NewGameDialog.res", NULL, pKeys );
// Reset all properties
for ( int i = 0; i < NUM_SLOTS; ++i ) { m_PanelIndex[i] = INVALID_INDEX; }
if ( !m_ChapterPanels.Count() ) { UpdateMenuComponents( SCROLL_NONE ); return; }
// Layout panel positions relative to the dialog center.
int panelWidth = m_ChapterPanels[0]->GetWide() + 16; int dialogWidth = GetWide(); m_PanelXPos[2] = ( dialogWidth - panelWidth ) / 2 + 8; if (m_ChapterPanels.Count() > 1) { m_PanelXPos[1] = m_PanelXPos[2] - panelWidth; m_PanelXPos[0] = m_PanelXPos[1]; m_PanelXPos[3] = m_PanelXPos[2] + panelWidth; m_PanelXPos[4] = m_PanelXPos[3]; } else { m_PanelXPos[0] = m_PanelXPos[1] = m_PanelXPos[3] = m_PanelXPos[4] = m_PanelXPos[2]; }
m_PanelAlpha[0] = 0; m_PanelAlpha[1] = 255; m_PanelAlpha[2] = 255; m_PanelAlpha[3] = 255; m_PanelAlpha[4] = 0;
int panelHeight; m_ChapterPanels[0]->GetSize( panelWidth, panelHeight ); m_pCenterBg->SetWide( panelWidth + 16 ); m_pCenterBg->SetPos( m_PanelXPos[2] - 8, m_PanelYPos[2] - (m_pCenterBg->GetTall() - panelHeight) + 8 ); m_pCenterBg->SetBgColor( Color( 190, 115, 0, 255 ) );
// start the first item selected
SetSelectedChapterIndex( 0 ); }
CNewGameDialog::~CNewGameDialog() { delete m_pFooter; m_pFooter = NULL; }
void CNewGameDialog::Activate( void ) { m_bMapStarting = false;
if ( GameUI().IsConsoleUI() ) { // Stop blinking the menu item now that we've seen the unlocked stuff
CBasePanel *pBasePanel = BasePanel(); if ( pBasePanel ) pBasePanel->SetMenuItemBlinkingState( "OpenNewGameDialog", false );
BonusMapsDatabase()->SetBlink( false ); }
// Commentary stuff is set up on activate because in XBox the new game menu is never deleted
SetTitle( ( ( m_bCommentaryMode ) ? ( "#GameUI_LoadCommentary" ) : ( "#GameUI_NewGame") ), true);
if ( m_pCommentaryLabel ) m_pCommentaryLabel->SetVisible( m_bCommentaryMode );
// work out which chapters are unlocked
ConVarRef var( "sv_unlockedchapters" ); const char *unlockedChapter = var.IsValid() ? var.GetString() : "1"; int iUnlockedChapter = atoi(unlockedChapter);
for ( int i = 0; i < m_ChapterPanels.Count(); i++) { CGameChapterPanel *pChapterPanel = m_ChapterPanels[ i ];
if ( pChapterPanel ) { pChapterPanel->SetCommentaryMode( m_bCommentaryMode );
UpdatePanelLockedStatus( iUnlockedChapter, i + 1, pChapterPanel ); } }
BaseClass::Activate(); }
//-----------------------------------------------------------------------------
// Purpose: Apply special properties of the menu
//-----------------------------------------------------------------------------
void CNewGameDialog::ApplySettings( KeyValues *inResourceData ) { BaseClass::ApplySettings( inResourceData );
int ypos = inResourceData->GetInt( "chapterypos", 40 ); for ( int i = 0; i < NUM_SLOTS; ++i ) { m_PanelYPos[i] = ypos; }
m_pCenterBg->SetTall( inResourceData->GetInt( "centerbgtall", 0 ) );
g_ScrollSpeedSlow = inResourceData->GetFloat( "scrollslow", 0.0f ); g_ScrollSpeedFast = inResourceData->GetFloat( "scrollfast", 0.0f ); SetFastScroll( false ); }
void CNewGameDialog::ApplySchemeSettings( vgui::IScheme *pScheme ) { BaseClass::ApplySchemeSettings( pScheme );
if ( m_pFooter ) { KeyValues *pFooterControlSettings = BasePanel()->GetConsoleControlSettings()->FindKey( "NewGameFooter.res" ); m_pFooter->LoadControlSettings( "null", NULL, pFooterControlSettings ); }
UpdateMenuComponents( SCROLL_NONE );
m_pCommentaryLabel = dynamic_cast<vgui::Label*>( FindChildByName( "CommentaryUnlock" ) ); if ( m_pCommentaryLabel ) m_pCommentaryLabel->SetVisible( m_bCommentaryMode );
if ( GameUI().IsConsoleUI() ) { if ( !m_bCommentaryMode && BonusMapsDatabase()->BonusesUnlocked() && !m_ChapterPanels[ m_PanelIndex[SLOT_CENTER] ]->HasBonus() ) { // Find the first bonus
ScrollSelectionPanels( SCROLL_LEFT ); m_bScrollToFirstBonusMap = true; } } }
static float GetArrowAlpha( void ) { // X360TBD: Pulsing arrows
return 255.f; }
//-----------------------------------------------------------------------------
// Purpose: sets the correct properties for visible components
//-----------------------------------------------------------------------------
void CNewGameDialog::UpdateMenuComponents( EScrollDirection dir ) { // This is called prior to any scrolling,
// so we need to look ahead to the post-scroll state
int centerIdx = SLOT_CENTER; if ( dir == SCROLL_LEFT ) { ++centerIdx; } else if ( dir == SCROLL_RIGHT ) { --centerIdx; } int leftIdx = centerIdx - 1; int rightIdx = centerIdx + 1;
if ( GameUI().IsConsoleUI() ) { bool bHasBonus = false; if ( m_PanelIndex[centerIdx] != INVALID_INDEX ) { wchar_t buffer[ MAX_PATH ]; m_ChapterPanels[ m_PanelIndex[centerIdx] ]->m_pChapterNameLabel->GetText( buffer, sizeof(buffer) ); m_pChapterTitleLabels[(unsigned)m_ActiveTitleIdx]->SetText( buffer );
// If it has bonuses show the scroll up and down arrows
bHasBonus = m_ChapterPanels[ m_PanelIndex[centerIdx] ]->HasBonus(); }
vgui::Panel *leftArrow = this->FindChildByName( "LeftArrow" ); vgui::Panel *rightArrow = this->FindChildByName( "RightArrow" ); if ( leftArrow ) { if ( m_PanelIndex[leftIdx] != INVALID_INDEX ) { leftArrow->SetFgColor( Color( 255, 255, 255, GetArrowAlpha() ) ); } else { leftArrow->SetFgColor( Color( 128, 128, 128, 64 ) ); } } if ( rightArrow ) { if ( m_PanelIndex[rightIdx] != INVALID_INDEX ) { rightArrow->SetFgColor( Color( 255, 255, 255, GetArrowAlpha() ) ); } else { rightArrow->SetFgColor( Color( 128, 128, 128, 64 ) ); } }
if ( bHasBonus ) { // Find the bonus description for this panel
for ( int iBonus = 0; iBonus < BonusMapsDatabase()->BonusCount(); ++iBonus ) { m_pBonusMapDescription = BonusMapsDatabase()->GetBonusData( iBonus ); if ( Q_stricmp( m_pBonusMapDescription->szChapterName, m_ChapterPanels[ m_PanelIndex[centerIdx] ]->GetConfigFile() ) == 0 ) break; } } else { m_pBonusMapDescription = NULL; }
vgui::Panel *upArrow = this->FindChildByName( "UpArrow" ); vgui::Panel *downArrow = this->FindChildByName( "DownArrow" );
if ( upArrow ) upArrow->SetVisible( bHasBonus ); if ( downArrow ) downArrow->SetVisible( bHasBonus );
m_pBonusSelection->SetVisible( bHasBonus ); m_pBonusSelectionBorder->SetVisible( bHasBonus );
UpdateBonusSelection(); }
// No buttons in the xbox ui
if ( !GameUI().IsConsoleUI() ) { if ( m_PanelIndex[leftIdx] == INVALID_INDEX || m_PanelIndex[leftIdx] == 0 ) { m_pPrevButton->SetVisible( false ); m_pPrevButton->SetEnabled( false ); } else { m_pPrevButton->SetVisible( true ); m_pPrevButton->SetEnabled( true ); }
if ( m_ChapterPanels.Count() < 4 ) // if there are less than 4 chapters show the next button but disabled
{ m_pNextButton->SetVisible( true ); m_pNextButton->SetEnabled( false ); } else if ( m_PanelIndex[rightIdx] == INVALID_INDEX || m_PanelIndex[rightIdx] == m_ChapterPanels.Count()-1 ) { m_pNextButton->SetVisible( false ); m_pNextButton->SetEnabled( false ); } else { m_pNextButton->SetVisible( true ); m_pNextButton->SetEnabled( true ); } } }
void CNewGameDialog::UpdateBonusSelection( void ) { int iNumChallenges = 0; if ( m_pBonusMapDescription ) { if ( m_pBonusMapDescription->m_pChallenges ) iNumChallenges = m_pBonusMapDescription->m_pChallenges->Count();
// Wrap challenge selection to fit number of possible selections
if ( m_iBonusSelection < 0 ) m_iBonusSelection = iNumChallenges + 1; else if ( m_iBonusSelection >= iNumChallenges + 2 ) m_iBonusSelection = 0; } else { // No medals to show
SetControlVisible( "ChallengeEarnedMedal", false ); SetControlVisible( "ChallengeBestLabel", false ); SetControlVisible( "ChallengeNextMedal", false ); SetControlVisible( "ChallengeNextLabel", false ); return; }
if ( m_iBonusSelection == 0 ) { m_pBonusSelection->SetText( "#GameUI_BonusMapsStandard" ); SetControlVisible( "ChallengeEarnedMedal", false ); SetControlVisible( "ChallengeBestLabel", false ); SetControlVisible( "ChallengeNextMedal", false ); SetControlVisible( "ChallengeNextLabel", false ); } else if ( m_iBonusSelection == 1 ) { m_pBonusSelection->SetText( "#GameUI_BonusMapsAdvanced" ); SetControlVisible( "ChallengeEarnedMedal", false ); SetControlVisible( "ChallengeBestLabel", false ); SetControlVisible( "ChallengeNextMedal", false ); SetControlVisible( "ChallengeNextLabel", false );
char szMapAdvancedName[ 256 ] = ""; if ( m_pBonusMapDescription ) { Q_snprintf( szMapAdvancedName, sizeof( szMapAdvancedName ), "%s_advanced", m_pBonusMapDescription->szMapFileName ); }
BonusMapDescription_t *pAdvancedDescription = NULL;
// Find the bonus description for this panel
for ( int iBonus = 0; iBonus < BonusMapsDatabase()->BonusCount(); ++iBonus ) { pAdvancedDescription = BonusMapsDatabase()->GetBonusData( iBonus ); if ( Q_stricmp( szMapAdvancedName, pAdvancedDescription->szMapFileName ) == 0 ) break; }
if ( pAdvancedDescription && pAdvancedDescription->bComplete ) { CBitmapImagePanel *pBitmap = dynamic_cast<CBitmapImagePanel*>( FindChildByName( "ChallengeEarnedMedal" ) ); pBitmap->SetVisible( true ); pBitmap->setTexture( "hud/icon_complete" ); } } else { int iChallenge = m_iBonusSelection - 2; ChallengeDescription_t *pChallengeDescription = &((*m_pBonusMapDescription->m_pChallenges)[ iChallenge ]);
// Set the display text for the selected challenge
m_pBonusSelection->SetText( pChallengeDescription->szName );
int iBest, iEarnedMedal, iNext, iNextMedal; GetChallengeMedals( pChallengeDescription, iBest, iEarnedMedal, iNext, iNextMedal );
char szBuff[ 512 ];
// Set earned medal
if ( iEarnedMedal > -1 && iBest != -1 ) { if ( iChallenge < 10 ) Q_snprintf( szBuff, sizeof( szBuff ), "medals/medal_0%i_%s", iChallenge, g_pszMedalNames[ iEarnedMedal ] ); else Q_snprintf( szBuff, sizeof( szBuff ), "medals/medal_%i_%s", iChallenge, g_pszMedalNames[ iEarnedMedal ] );
CBitmapImagePanel *pBitmap = dynamic_cast<CBitmapImagePanel*>( FindChildByName( "ChallengeEarnedMedal" ) ); pBitmap->SetVisible( true ); pBitmap->setTexture( szBuff ); } else { CBitmapImagePanel *pBitmap = dynamic_cast<CBitmapImagePanel*>( FindChildByName( "ChallengeEarnedMedal" ) ); pBitmap->SetVisible( false ); }
// Set next medal
if ( iNextMedal > 0 ) { if ( iChallenge < 10 ) Q_snprintf( szBuff, sizeof( szBuff ), "medals/medal_0%i_%s", iChallenge, g_pszMedalNames[ iNextMedal ] ); else Q_snprintf( szBuff, sizeof( szBuff ), "medals/medal_%i_%s", iChallenge, g_pszMedalNames[ iNextMedal ] );
CBitmapImagePanel *pBitmap = dynamic_cast<CBitmapImagePanel*>( FindChildByName( "ChallengeNextMedal" ) ); pBitmap->SetVisible( true ); pBitmap->setTexture( szBuff ); } else { SetControlVisible( "ChallengeNextMedal", false ); }
wchar_t szWideBuff[ 64 ]; wchar_t szWideBuff2[ 64 ];
// Best label
if ( iBest != -1 ) { Q_snprintf( szBuff, sizeof( szBuff ), "%i", iBest ); g_pVGuiLocalize->ConvertANSIToUnicode( szBuff, szWideBuff2, sizeof( szWideBuff2 ) ); g_pVGuiLocalize->ConstructString( szWideBuff, sizeof( szWideBuff ), g_pVGuiLocalize->Find( "#GameUI_BonusMapsBest" ), 1, szWideBuff2 ); g_pVGuiLocalize->ConvertUnicodeToANSI( szWideBuff, szBuff, sizeof( szBuff ) );
SetControlString( "ChallengeBestLabel", szBuff ); SetControlVisible( "ChallengeBestLabel", true ); } else { SetControlVisible( "ChallengeBestLabel", false ); }
// Next label
if ( iNext != -1 ) { Q_snprintf( szBuff, sizeof( szBuff ), "%i", iNext ); g_pVGuiLocalize->ConvertANSIToUnicode( szBuff, szWideBuff2, sizeof( szWideBuff2 ) ); g_pVGuiLocalize->ConstructString( szWideBuff, sizeof( szWideBuff ), g_pVGuiLocalize->Find( "#GameUI_BonusMapsGoal" ), 1, szWideBuff2 ); g_pVGuiLocalize->ConvertUnicodeToANSI( szWideBuff, szBuff, sizeof( szBuff ) );
SetControlString( "ChallengeNextLabel", szBuff ); SetControlVisible( "ChallengeNextLabel", true ); } else { SetControlVisible( "ChallengeNextLabel", false ); } } }
//-----------------------------------------------------------------------------
// Purpose: sets a chapter as selected
//-----------------------------------------------------------------------------
void CNewGameDialog::SetSelectedChapterIndex( int index ) { m_iSelectedChapter = index;
for (int i = 0; i < m_ChapterPanels.Count(); i++) { if ( i == index ) { m_ChapterPanels[i]->SetSelected( true ); } else { m_ChapterPanels[i]->SetSelected( false ); } }
if ( m_pPlayButton ) { m_pPlayButton->SetEnabled( true ); }
// Setup panels to the left of the selected panel
int selectedSlot = GameUI().IsConsoleUI() ? SLOT_CENTER : index % 3 + 1; int currIdx = index; for ( int i = selectedSlot; i >= 0 && currIdx >= 0; --i ) { m_PanelIndex[i] = currIdx; --currIdx; InitPanelIndexForDisplay( i ); }
// Setup panels to the right of the selected panel
currIdx = index + 1; for ( int i = selectedSlot + 1; i < NUM_SLOTS && currIdx < m_ChapterPanels.Count(); ++i ) { m_PanelIndex[i] = currIdx; ++currIdx; InitPanelIndexForDisplay( i ); }
UpdateMenuComponents( SCROLL_NONE ); }
//-----------------------------------------------------------------------------
// Purpose: sets a chapter as selected
//-----------------------------------------------------------------------------
void CNewGameDialog::SetSelectedChapter( const char *chapter ) { Assert( chapter ); for (int i = 0; i < m_ChapterPanels.Count(); i++) { if ( chapter && !Q_stricmp(m_ChapterPanels[i]->GetChapter(), chapter) ) { m_iSelectedChapter = i; m_ChapterPanels[m_iSelectedChapter]->SetSelected( true ); } else { m_ChapterPanels[i]->SetSelected( false ); } }
if ( m_pPlayButton ) { m_pPlayButton->SetEnabled( true ); } }
//-----------------------------------------------------------------------------
// iUnlockedChapter - the value of sv_unlockedchapters, 1-based. A value of 0
// is treated as a 1, since at least one chapter must be unlocked.
//
// i - the 1-based index of the chapter we're considering.
//-----------------------------------------------------------------------------
void CNewGameDialog::UpdatePanelLockedStatus( int iUnlockedChapter, int i, CGameChapterPanel *pChapterPanel ) { if ( iUnlockedChapter <= 0 ) { iUnlockedChapter = 1; }
// Commentary mode requires chapters to be finished before they can be chosen
bool bLocked = false;
if ( m_bCommentaryMode ) { bLocked = ( iUnlockedChapter <= i ); } else { if ( iUnlockedChapter < i ) { // Never lock the first chapter
bLocked = ( i != 0 ); } }
pChapterPanel->SetEnabled( !bLocked ); }
//-----------------------------------------------------------------------------
// Purpose: Called before a panel scroll starts.
//-----------------------------------------------------------------------------
void CNewGameDialog::PreScroll( EScrollDirection dir ) { int hideIdx = INVALID_INDEX; if ( dir == SCROLL_LEFT ) { hideIdx = m_PanelIndex[SLOT_LEFT]; } else if ( dir == SCROLL_RIGHT ) { hideIdx = m_PanelIndex[SLOT_RIGHT]; } if ( hideIdx != INVALID_INDEX ) { // Push back the panel that's about to be hidden
// so the next panel scrolls over the top of it.
m_ChapterPanels[hideIdx]->SetZPos( 0 ); }
// Flip the active title label prior to the crossfade
m_ActiveTitleIdx ^= 0x01; }
//-----------------------------------------------------------------------------
// Purpose: Called after a panel scroll finishes.
//-----------------------------------------------------------------------------
void CNewGameDialog::PostScroll( EScrollDirection dir ) { int index = INVALID_INDEX; if ( dir == SCROLL_LEFT ) { index = m_PanelIndex[SLOT_RIGHT]; } else if ( dir == SCROLL_RIGHT ) { index = m_PanelIndex[SLOT_LEFT]; }
// Fade in the revealed panel
if ( index != INVALID_INDEX ) { CGameChapterPanel *panel = m_ChapterPanels[index]; panel->SetZPos( 50 ); GetAnimationController()->RunAnimationCommand( panel, "alpha", 255, 0, m_ScrollSpeed, vgui::AnimationController::INTERPOLATOR_LINEAR ); }
if ( GameUI().IsConsoleUI() ) { if ( BonusMapsDatabase()->BonusesUnlocked() && m_bScrollToFirstBonusMap ) { if ( !m_ChapterPanels[ m_PanelIndex[SLOT_CENTER] ]->HasBonus() ) { // Find the first bonus
ScrollSelectionPanels( SCROLL_LEFT ); } else { // Found a bonus, stop scrolling
m_bScrollToFirstBonusMap = false; } } } }
//-----------------------------------------------------------------------------
// Purpose: Initiates a panel scroll and starts the animation.
//-----------------------------------------------------------------------------
void CNewGameDialog::ScrollSelectionPanels( EScrollDirection dir ) { // Only initiate a scroll if panels aren't currently scrolling
if ( !m_bScrolling ) { // Handle any pre-scroll setup
PreScroll( dir );
if ( dir == SCROLL_LEFT) { m_ScrollCt += SCROLL_LEFT; } else if ( dir == SCROLL_RIGHT && m_PanelIndex[SLOT_CENTER] != 0 ) { m_ScrollCt += SCROLL_RIGHT; }
m_bScrolling = true; AnimateSelectionPanels();
// Update the arrow colors, help text, and buttons. Doing it here looks better than having
// the components change after the entire scroll animation has finished.
UpdateMenuComponents( m_ScrollDirection ); } }
void CNewGameDialog::ScrollBonusSelection( EScrollDirection dir ) { // Don't scroll if there's no bonuses for this panel
if ( !m_pBonusMapDescription ) return;
m_iBonusSelection += dir;
vgui::surface()->PlaySound( "UI/buttonclick.wav" );
UpdateBonusSelection(); }
//-----------------------------------------------------------------------------
// Purpose: Initiates the scripted scroll and fade effects of all five slotted panels
//-----------------------------------------------------------------------------
void CNewGameDialog::AnimateSelectionPanels( void ) { int idxOffset = 0; int startIdx = SLOT_LEFT; int endIdx = SLOT_RIGHT;
// Don't scroll outside the bounds of the panel list
if ( m_ScrollCt >= SCROLL_LEFT && (m_PanelIndex[SLOT_CENTER] < m_ChapterPanels.Count() - 1 || !GameUI().IsConsoleUI()) ) { idxOffset = -1; endIdx = SLOT_OFFRIGHT; m_ScrollDirection = SCROLL_LEFT; } else if ( m_ScrollCt <= SCROLL_RIGHT && (m_PanelIndex[SLOT_CENTER] > 0 || !GameUI().IsConsoleUI()) ) { idxOffset = 1; startIdx = SLOT_OFFLEFT; m_ScrollDirection = SCROLL_RIGHT; }
if ( 0 == idxOffset ) { // Kill the scroll, it's outside the bounds
m_ScrollCt = 0; m_bScrolling = false; m_ScrollDirection = SCROLL_NONE; vgui::surface()->PlaySound( "player/suit_denydevice.wav" ); return; }
// Should never happen
if ( startIdx > endIdx ) return;
for ( int i = startIdx; i <= endIdx; ++i ) { if ( m_PanelIndex[i] != INVALID_INDEX ) { int nextIdx = i + idxOffset; CGameChapterPanel *panel = m_ChapterPanels[ m_PanelIndex[i] ]; GetAnimationController()->RunAnimationCommand( panel, "xpos", m_PanelXPos[nextIdx], 0, m_ScrollSpeed, vgui::AnimationController::INTERPOLATOR_LINEAR ); GetAnimationController()->RunAnimationCommand( panel, "ypos", m_PanelYPos[nextIdx], 0, m_ScrollSpeed, vgui::AnimationController::INTERPOLATOR_LINEAR ); GetAnimationController()->RunAnimationCommand( panel, "alpha", m_PanelAlpha[nextIdx], 0, m_ScrollSpeed, vgui::AnimationController::INTERPOLATOR_LINEAR ); } }
if ( GameUI().IsConsoleUI() ) { vgui::surface()->PlaySound( "UI/buttonclick.wav" );
// Animate the center background panel
GetAnimationController()->RunAnimationCommand( m_pCenterBg, "alpha", 0, 0, m_ScrollSpeed * 0.25f, vgui::AnimationController::INTERPOLATOR_LINEAR ); // Crossfade the chapter title labels
int inactiveTitleIdx = m_ActiveTitleIdx ^ 0x01; GetAnimationController()->RunAnimationCommand( m_pChapterTitleLabels[(unsigned)m_ActiveTitleIdx], "alpha", 255, 0, m_ScrollSpeed, vgui::AnimationController::INTERPOLATOR_LINEAR ); GetAnimationController()->RunAnimationCommand( m_pChapterTitleLabels[inactiveTitleIdx], "alpha", 0, 0, m_ScrollSpeed, vgui::AnimationController::INTERPOLATOR_LINEAR ); // Scrolling up through chapters, offset is negative
m_iSelectedChapter -= idxOffset; }
PostMessage( this, new KeyValues( "FinishScroll" ), m_ScrollSpeed ); }
//-----------------------------------------------------------------------------
// Purpose: After a scroll, each panel slot holds the index of a panel that has
// scrolled to an adjacent slot. This function updates each slot so
// it holds the index of the panel that is actually in that slot's position.
//-----------------------------------------------------------------------------
void CNewGameDialog::ShiftPanelIndices( int offset ) { // Shift all the elements over one slot, then calculate what the last slot's index should be.
int lastSlot = NUM_SLOTS - 1; if ( offset > 0 ) { // Hide the panel that's dropping out of the slots
if ( IsValidPanel( m_PanelIndex[0] ) ) { m_ChapterPanels[ m_PanelIndex[0] ]->SetVisible( false ); }
// Scrolled panels to the right, so shift the indices one slot to the left
Q_memmove( &m_PanelIndex[0], &m_PanelIndex[1], lastSlot * sizeof( m_PanelIndex[0] ) ); if ( m_PanelIndex[lastSlot] != INVALID_INDEX ) { int num = m_PanelIndex[ lastSlot ] + 1; if ( IsValidPanel( num ) ) { m_PanelIndex[lastSlot] = num; InitPanelIndexForDisplay( lastSlot ); } else { m_PanelIndex[lastSlot] = INVALID_INDEX; } } } else { // Hide the panel that's dropping out of the slots
if ( IsValidPanel( m_PanelIndex[lastSlot] ) ) { m_ChapterPanels[ m_PanelIndex[lastSlot] ]->SetVisible( false ); }
// Scrolled panels to the left, so shift the indices one slot to the right
Q_memmove( &m_PanelIndex[1], &m_PanelIndex[0], lastSlot * sizeof( m_PanelIndex[0] ) ); if ( m_PanelIndex[0] != INVALID_INDEX ) { int num = m_PanelIndex[0] - 1; if ( IsValidPanel( num ) ) { m_PanelIndex[0] = num; InitPanelIndexForDisplay( 0 ); } else { m_PanelIndex[0] = INVALID_INDEX; } } } }
//-----------------------------------------------------------------------------
// Purpose: Validates an index into the selection panels vector
//-----------------------------------------------------------------------------
bool CNewGameDialog::IsValidPanel( const int idx ) { if ( idx < 0 || idx >= m_ChapterPanels.Count() ) return false; return true; }
//-----------------------------------------------------------------------------
// Purpose: Sets up a panel's properties before it is displayed
//-----------------------------------------------------------------------------
void CNewGameDialog::InitPanelIndexForDisplay( const int idx ) { CGameChapterPanel *panel = m_ChapterPanels[ m_PanelIndex[idx] ]; if ( panel ) { panel->SetPos( m_PanelXPos[idx], m_PanelYPos[idx] ); panel->SetAlpha( m_PanelAlpha[idx] ); panel->SetVisible( true ); if ( m_PanelAlpha[idx] ) { panel->SetZPos( 50 ); } } }
//-----------------------------------------------------------------------------
// Purpose: Sets which scroll speed should be used
//-----------------------------------------------------------------------------
void CNewGameDialog::SetFastScroll( bool fast ) { m_ScrollSpeed = fast ? g_ScrollSpeedFast : g_ScrollSpeedSlow; }
//-----------------------------------------------------------------------------
// Purpose: Checks if a button is being held down, and speeds up the scroll
//-----------------------------------------------------------------------------
void CNewGameDialog::ContinueScrolling( void ) { if ( !GameUI().IsConsoleUI() ) { if ( m_PanelIndex[SLOT_CENTER-1] % 3 ) { // m_ButtonPressed = m_ScrollDirection;
ScrollSelectionPanels( m_ScrollDirection ); } return; }
if ( m_ButtonPressed == m_ScrollDirection ) { SetFastScroll( true ); ScrollSelectionPanels( m_ScrollDirection ); } else if ( m_ButtonPressed != SCROLL_NONE ) { // The other direction has been pressed - start a slow scroll
SetFastScroll( false ); ScrollSelectionPanels( (EScrollDirection)m_ButtonPressed ); } else { SetFastScroll( false ); } }
//-----------------------------------------------------------------------------
// Purpose: Called when a scroll distance of one slot has been completed
//-----------------------------------------------------------------------------
void CNewGameDialog::FinishScroll( void ) { // Fade the center bg panel back in
GetAnimationController()->RunAnimationCommand( m_pCenterBg, "alpha", 255, 0, m_ScrollSpeed * 0.25f, vgui::AnimationController::INTERPOLATOR_LINEAR );
ShiftPanelIndices( m_ScrollDirection ); m_bScrolling = false; m_ScrollCt = 0; // End of scroll step
PostScroll( m_ScrollDirection );
// Continue scrolling if necessary
ContinueScrolling(); }
//-----------------------------------------------------------------------------
// Purpose: starts the game at the specified skill level
//-----------------------------------------------------------------------------
void CNewGameDialog::StartGame( void ) { if ( m_ChapterPanels.IsValidIndex( m_iSelectedChapter ) ) { char mapcommand[512]; mapcommand[0] = 0; Q_snprintf( mapcommand, sizeof( mapcommand ), "disconnect\ndeathmatch 0\nprogress_enable\nexec %s\n", m_ChapterPanels[m_iSelectedChapter]->GetConfigFile() );
// Set commentary
ConVarRef commentary( "commentary" ); commentary.SetValue( m_bCommentaryMode );
ConVarRef sv_cheats( "sv_cheats" ); sv_cheats.SetValue( m_bCommentaryMode );
if ( IsPC() ) { // If commentary is on, we go to the explanation dialog (but not for teaser trailers)
if ( m_bCommentaryMode && !m_ChapterPanels[m_iSelectedChapter]->IsTeaserChapter() ) { // Check our current state and disconnect us from any multiplayer server we're connected to.
// This fixes an exploit where players would click "start" on the commentary dialog to enable
// sv_cheats on the client (via the code above) and then hit <esc> to get out of the explanation dialog.
if ( GameUI().IsInMultiplayer() ) { engine->ExecuteClientCmd( "disconnect" ); }
DHANDLE<CCommentaryExplanationDialog> hCommentaryExplanationDialog; if ( !hCommentaryExplanationDialog.Get() ) { hCommentaryExplanationDialog = new CCommentaryExplanationDialog( BasePanel(), mapcommand ); } hCommentaryExplanationDialog->Activate(); } else { // start map
BasePanel()->FadeToBlackAndRunEngineCommand( mapcommand ); } } else if ( IsX360() ) { if ( m_ChapterPanels[m_iSelectedChapter]->HasBonus() && m_iBonusSelection > 0 ) { if ( m_iBonusSelection == 1 ) { // Run the advanced chamber instead of the config file
char *pLastSpace = Q_strrchr( mapcommand, '\n' ); pLastSpace[ 0 ] = '\0'; pLastSpace = Q_strrchr( mapcommand, '\n' );
Q_snprintf( pLastSpace, sizeof( mapcommand ) - Q_strlen( mapcommand ), "\nmap %s_advanced\n", m_pBonusMapDescription->szMapFileName ); } else { char sz[ 256 ];
int iChallenge = m_iBonusSelection - 1;
// Set up the challenge mode
Q_snprintf( sz, sizeof( sz ), "sv_bonus_challenge %i\n", iChallenge ); engine->ClientCmd_Unrestricted( sz );
ChallengeDescription_t *pChallengeDescription = &((*m_pBonusMapDescription->m_pChallenges)[ iChallenge - 1 ]);
// Set up medal goals
BonusMapsDatabase()->SetCurrentChallengeObjectives( pChallengeDescription->iBronze, pChallengeDescription->iSilver, pChallengeDescription->iGold ); BonusMapsDatabase()->SetCurrentChallengeNames( m_pBonusMapDescription->szFileName, m_pBonusMapDescription->szMapName, pChallengeDescription->szName ); } }
m_bMapStarting = true; BasePanel()->FadeToBlackAndRunEngineCommand( mapcommand ); }
OnClose(); } }
void CNewGameDialog::OnClose( void ) { m_KeyRepeat.Reset();
if ( GameUI().IsConsoleUI() && !m_bMapStarting ) { BasePanel()->RunCloseAnimation( "CloseNewGameDialog_OpenMainMenu" ); BonusMapsDatabase()->WriteSaveData(); // Closing this dialog is a good time to save
} BaseClass::OnClose(); }
//-----------------------------------------------------------------------------
// Purpose: handles button commands
//-----------------------------------------------------------------------------
void CNewGameDialog::OnCommand( const char *command ) { bool bReset = true;
if ( !stricmp( command, "Play" ) ) { if ( m_bMapStarting ) return;
if ( GameUI().IsConsoleUI() ) { if ( m_ChapterPanels[m_iSelectedChapter]->IsEnabled() ) { if ( !GameUI().HasSavedThisMenuSession() && GameUI().IsInLevel() && engine->GetMaxClients() == 1 ) { vgui::surface()->PlaySound( "UI/buttonclickrelease.wav" ); BasePanel()->ShowMessageDialog( MD_SAVE_BEFORE_NEW_GAME, this ); } else { OnCommand( "StartNewGame" ); } } else { // This chapter isn't unlocked!
m_bMapStarting = false; vgui::surface()->PlaySound( "player/suit_denydevice.wav" );
if ( m_bCommentaryMode ) { BasePanel()->ShowMessageDialog( MD_COMMENTARY_CHAPTER_UNLOCK_EXPLANATION, this ); } } } else { StartGame(); } }
#ifdef _X360
else if ( !stricmp( command, "StartNewGame" ) ) { ConVarRef commentary( "commentary" );
if ( m_bCommentaryMode && !commentary.GetBool() ) { // Using the commentary menu, but not already in commentary mode, explain the rules
PostMessage( (vgui::Panel*)this, new KeyValues( "command", "command", "StartNewGameWithCommentaryExplanation" ), 0.2f ); } else { if ( XBX_GetStorageDeviceId() == XBX_INVALID_STORAGE_ID || XBX_GetStorageDeviceId() == XBX_STORAGE_DECLINED || !ModInfo().IsSinglePlayerOnly() ) { // Multiplayer or no storage device so don't bore them with autosave details
m_bMapStarting = true; OnCommand( "StartNewGameNoCommentaryExplanation" ); } else { // Don't allow other inputs
m_bMapStarting = true;
// Remind them how autosaves work
PostMessage( (vgui::Panel*)this, new KeyValues( "command", "command", "StartNewGameWithAutosaveExplanation" ), 0.2f ); } } } else if ( !stricmp( command, "StartNewGameWithAutosaveExplanation" ) ) { BasePanel()->ShowMessageDialog( MD_AUTOSAVE_EXPLANATION, this ); } else if ( !stricmp( command, "StartNewGameWithCommentaryExplanation" ) ) { if ( ModInfo().IsSinglePlayerOnly() ) { // Don't allow other inputs
m_bMapStarting = true; BasePanel()->ShowMessageDialog( MD_COMMENTARY_EXPLANATION, this ); } else { // Don't allow other inputs
m_bMapStarting = true; BasePanel()->ShowMessageDialog( MD_COMMENTARY_EXPLANATION_MULTI, this ); } } else if ( !stricmp( command, "StartNewGameNoCommentaryExplanation" ) ) { vgui::surface()->PlaySound( "UI/buttonclickrelease.wav" ); BasePanel()->RunAnimationWithCallback( this, "CloseNewGameDialog", new KeyValues( "StartGame" ) ); } #endif
else if ( !stricmp( command, "Next" ) ) { if ( m_bMapStarting ) return;
ScrollSelectionPanels( SCROLL_LEFT ); bReset = false; } else if ( !stricmp( command, "Prev" ) ) { if ( m_bMapStarting ) return;
ScrollSelectionPanels( SCROLL_RIGHT ); bReset = false; } else if ( !stricmp( command, "Mode_Next" ) ) { if ( m_bMapStarting ) return;
ScrollBonusSelection( SCROLL_LEFT ); bReset = false; } else if ( !stricmp( command, "Mode_Prev" ) ) { if ( m_bMapStarting ) return;
ScrollBonusSelection( SCROLL_RIGHT ); bReset = false; } else if ( !Q_stricmp( command, "ReleaseModalWindow" ) ) { vgui::surface()->RestrictPaintToSinglePanel(NULL); } else { BaseClass::OnCommand( command ); }
if ( bReset ) { m_KeyRepeat.Reset(); } }
void CNewGameDialog::PaintBackground() { if ( !GameUI().IsConsoleUI() ) { BaseClass::PaintBackground(); return; }
int wide, tall; GetSize( wide, tall );
Color col = GetBgColor(); DrawBox( 0, 0, wide, tall, col, 1.0f );
int y = 0; if ( m_pChapterTitleLabels[0] ) { // offset by title
int titleX, titleY, titleWide, titleTall; m_pChapterTitleLabels[0]->GetBounds( titleX, titleY, titleWide, titleTall ); y += titleY + titleTall; } else { y = 8; }
// draw an inset
Color darkColor; darkColor.SetColor( 0.70f * (float)col.r(), 0.70f * (float)col.g(), 0.70f * (float)col.b(), col.a() ); vgui::surface()->DrawSetColor( darkColor ); vgui::surface()->DrawFilledRect( 8, y, wide - 8, tall - 8 ); }
void CNewGameDialog::OnKeyCodePressed( KeyCode code ) { switch ( code ) { case KEY_XBUTTON_LEFT: case KEY_XSTICK1_LEFT: case KEY_XSTICK2_LEFT: case KEY_LEFT: case STEAMCONTROLLER_DPAD_LEFT: if ( !m_bScrolling ) { for ( int i = 0; i < m_ChapterPanels.Count(); ++i ) { if ( m_ChapterPanels[ i ]->IsSelected() ) { int nNewChapter = i - 1; if ( nNewChapter >= 0 ) { if ( nNewChapter < m_PanelIndex[ SLOT_LEFT ] && m_PanelIndex[ SLOT_LEFT ] != -1 ) { ScrollSelectionPanels( SCROLL_RIGHT ); } else if ( m_ChapterPanels[ nNewChapter ]->IsEnabled() ) { SetSelectedChapterIndex( nNewChapter ); } } break; } } } return;
case KEY_XBUTTON_RIGHT: case KEY_XSTICK1_RIGHT: case KEY_XSTICK2_RIGHT: case KEY_RIGHT: case STEAMCONTROLLER_DPAD_RIGHT: if ( !m_bScrolling ) { for ( int i = 0; i < m_ChapterPanels.Count(); ++i ) { if ( m_ChapterPanels[ i ]->IsSelected() ) { int nNewChapter = i + 1; if ( nNewChapter < m_ChapterPanels.Count() ) { if ( nNewChapter > m_PanelIndex[ SLOT_RIGHT ] && m_PanelIndex[ SLOT_RIGHT ] != -1 ) { ScrollSelectionPanels( SCROLL_LEFT ); } else if ( m_ChapterPanels[ nNewChapter ]->IsEnabled() ) { SetSelectedChapterIndex( nNewChapter ); } } break; } } } return;
case KEY_XBUTTON_B: case STEAMCONTROLLER_B: OnCommand( "Close" ); return;
case KEY_XBUTTON_A: case STEAMCONTROLLER_A: OnCommand( "Play" ); return; }
m_KeyRepeat.KeyDown( code );
BaseClass::OnKeyCodePressed( code ); }
void CNewGameDialog::OnKeyCodeReleased( vgui::KeyCode code ) { m_KeyRepeat.KeyUp( code );
BaseClass::OnKeyCodeReleased( code ); }
void CNewGameDialog::OnThink() { vgui::KeyCode code = m_KeyRepeat.KeyRepeated(); if ( code ) { OnKeyCodeTyped( code ); }
BaseClass::OnThink(); }
|