//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #include "BonusMapsDialog.h" #include "EngineInterface.h" #include "vgui/ISystem.h" #include "vgui/ISurface.h" #include "vgui/IVGui.h" #include #include "filesystem.h" #include "vgui_controls/Button.h" #include "vgui_controls/ComboBox.h" #include "vgui_controls/PanelListPanel.h" #include "vgui_controls/QueryBox.h" #include "vgui_controls/ImagePanel.h" #include "vgui_controls/BitmapImagePanel.h" #include "vgui_controls/FileOpenDialog.h" #include "TGAImagePanel.h" #include "MouseMessageForwardingPanel.h" #include "BasePanel.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" using namespace vgui; #define MAX_LISTED_BONUS_MAPS 128 extern const char *COM_GetModDirectory( void ); bool ConstructFullImagePath( const char *pCurrentPath, const char *pchImageName, char *pchImageFileName ) { char *ext = Q_strstr( pchImageName , ".tga" ); if ( ext ) { // Use the specified image if ( pchImageName[ 0 ] != '.' ) Q_snprintf( pchImageFileName, _MAX_PATH, "%s", pchImageName ); else Q_snprintf( pchImageFileName, _MAX_PATH, "%s/%s", pCurrentPath, pchImageName ); return true; } Q_strcpy( pchImageFileName, pchImageName ); return false; } //----------------------------------------------------------------------------- // Purpose: Describes the layout of a same game pic //----------------------------------------------------------------------------- class CBonusMapPanel : public vgui::EditablePanel { DECLARE_CLASS_SIMPLE( CBonusMapPanel, vgui::EditablePanel ); public: CBonusMapPanel( PanelListPanel *parent, const char *name, int bonusMapListItemID ) : BaseClass( parent, name ) { m_iBonusMapListItemID = bonusMapListItemID; m_pParent = parent; m_pBonusMapTGAImage = new CTGAImagePanel( this, "BonusMapTGAImage" ); m_pBonusMapImage = SETUP_PANEL( new ImagePanel( this, "BonusMapImage" ) ); m_pBonusMapScreenshotBackground = SETUP_PANEL( new ImagePanel( this, "BonusMapScreenshotBackground" ) ); m_pMapNameLabel = new Label( this, "MapNameLabel", "" ); m_pLockIcon = new ImagePanel( this, "LockIcon" ); m_pCompleteIcon = new ImagePanel( this, "CompleteIcon" ); CMouseMessageForwardingPanel *panel = new CMouseMessageForwardingPanel(this, NULL); panel->SetZPos(2); SetSize( 200, 140 ); LoadControlSettings( "resource/BonusMapPanel.res" ); m_FillColor = m_pBonusMapScreenshotBackground->GetFillColor(); } void SetBonusMapInfo( const char *pCurrentPath, BonusMapDescription_t &map ) { // set the image to display char szImageFileName[_MAX_PATH]; bool bIsTGA = false; if ( map.bIsFolder ) { if ( map.szImageName[ 0 ] == '\0' ) { // use associate bonus folder icon Q_snprintf( szImageFileName, sizeof(szImageFileName), "%s/foldericon.tga", map.szFileName ); bIsTGA = true; // use default folder icon if( !g_pFullFileSystem->FileExists( szImageFileName, "MOD" ) ) { V_strcpy_safe( szImageFileName, "bonusmaps/icon_bonus_map_folder" ); bIsTGA = false; } } else { // Use the specified image bIsTGA = ConstructFullImagePath( pCurrentPath, map.szImageName, szImageFileName ); } } else { if ( map.szImageName[ 0 ] == '\0' ) { // Didn't specify an image name, so pair it with the name of this file char szImpliedTgaName[_MAX_PATH]; Q_snprintf( szImpliedTgaName, sizeof( szImpliedTgaName ), "%s.tga", map.szMapFileName ); bIsTGA = ConstructFullImagePath( pCurrentPath, szImpliedTgaName, szImageFileName ); // if it doesn't exist use default bonus map icon if( !g_pFullFileSystem->FileExists( szImageFileName, "MOD" ) ) { V_strcpy_safe( szImageFileName, "bonusmaps/icon_bonus_map_default" ); bIsTGA = false; } } else { // Use the specified image bIsTGA = ConstructFullImagePath( pCurrentPath, map.szImageName, szImageFileName ); } } if ( bIsTGA ) { m_pBonusMapTGAImage->SetTGANonMod( szImageFileName ); m_pBonusMapTGAImage->SetSize( 180, 100 ); m_pBonusMapTGAImage->SetVisible( true ); m_pBonusMapImage->SetVisible( false ); } else { m_pBonusMapImage->SetImage( szImageFileName ); m_pBonusMapImage->SetSize( 180, 100 ); m_pBonusMapImage->SetVisible( true ); m_pBonusMapTGAImage->SetVisible( false ); } m_pLockIcon->SetVisible( map.bLocked ); m_pCompleteIcon->SetVisible( map.bComplete ); // set the title text m_pMapNameLabel->SetText( map.szMapName ); } MESSAGE_FUNC_INT( OnPanelSelected, "PanelSelected", state ) { if ( state ) { // set the text color to be orange, and the pic border to be orange m_pBonusMapScreenshotBackground->SetFillColor( m_SelectedColor ); m_pMapNameLabel->SetFgColor( Color( 0, 0, 0, 255 ) ); } else { m_pBonusMapScreenshotBackground->SetFillColor( m_FillColor ); m_pMapNameLabel->SetFgColor( m_TextColor ); } PostMessage( m_pParent->GetVParent(), new KeyValues("PanelSelected") ); } virtual void OnMousePressed( vgui::MouseCode code ) { m_pParent->SetSelectedPanel( this ); } virtual void ApplySchemeSettings( IScheme *pScheme ) { m_TextColor = pScheme->GetColor( "NewGame.TextColor", Color(255, 255, 255, 255) ); m_SelectedColor = pScheme->GetColor( "NewGame.SelectionColor", Color(255, 255, 255, 255) ); BaseClass::ApplySchemeSettings( pScheme ); } virtual void OnMouseDoublePressed( vgui::MouseCode code ) { // call the panel OnMousePressed( code ); PostMessage( m_pParent->GetParent(), new KeyValues("Command", "command", "loadbonusmap") ); } int GetBonusMapListItemID() { return m_iBonusMapListItemID; } private: vgui::PanelListPanel *m_pParent; vgui::Label *m_pMapNameLabel; ImagePanel *m_pBonusMapImage; CTGAImagePanel *m_pBonusMapTGAImage; ImagePanel *m_pLockIcon; ImagePanel *m_pCompleteIcon; // things to change color when the selection changes ImagePanel *m_pBonusMapScreenshotBackground; Color m_TextColor, m_FillColor, m_SelectedColor; int m_iBonusMapListItemID; }; CBonusMapsDialog *g_pBonusMapsDialog = NULL; //----------------------------------------------------------------------------- // Purpose:Constructor //----------------------------------------------------------------------------- CBonusMapsDialog::CBonusMapsDialog(vgui::Panel *parent) : BaseClass(parent, "BonusMapsDialog") { g_pBonusMapsDialog = this; m_hImportBonusMapsDialog = NULL; BonusMapsDatabase()->RootPath(); CreateBonusMapsList(); BuildMapsList(); new vgui::Button( this, "loadbonusmap", "" ); SetControlEnabled( "loadbonusmap", false ); SetDeleteSelfOnClose(true); //SetBounds(0, 0, 512, 384); //SetMinimumSize( 256, 300 ); SetSizeable( false ); SetTitle("#GameUI_BonusMaps", true); vgui::Button *cancel = new vgui::Button( this, "Cancel", "#GameUI_Cancel" ); cancel->SetCommand( "Close" ); m_pPercentageBarBackground = SETUP_PANEL( new ImagePanel( this, "PercentageBarBackground" ) ); m_pPercentageBar = SETUP_PANEL( new ImagePanel( this, "PercentageBar" ) ); LoadControlSettings("resource/BonusMapsDialog.res"); // Stop blinking the bonus maps menu item CBasePanel *pBasePanel = BasePanel(); if ( pBasePanel ) pBasePanel->SetMenuItemBlinkingState( "OpenBonusMapsDialog", false ); BonusMapsDatabase()->SetBlink( false ); } //----------------------------------------------------------------------------- // Purpose: Destructor //----------------------------------------------------------------------------- CBonusMapsDialog::~CBonusMapsDialog() { BonusMapsDatabase()->WriteSaveData(); // Closing this dialog is a good time to save g_pBonusMapsDialog = NULL; } bool CBonusMapsDialog::ImportZippedBonusMaps( const char *pchZippedFileName ) { // Get the zip file's name with dir info char *pchShortFileName = Q_strrchr( pchZippedFileName, CORRECT_PATH_SEPARATOR ); if ( !pchShortFileName ) return false; // It's going to go in the maps folder char szOutFilename[ 512 ]; Q_snprintf( szOutFilename, sizeof( szOutFilename ), "maps%s", pchShortFileName ); Q_StripExtension( szOutFilename, szOutFilename, sizeof( szOutFilename ) ); // If there's already a folder by the same name we're going to tack a number onto the end int iOutFilenameLength = Q_strlen( szOutFilename ); int iSameFolderCount = 1; while ( g_pFullFileSystem->FileExists( szOutFilename, "MOD" ) ) { ++iSameFolderCount; if ( iSameFolderCount > 99 ) { return false; } szOutFilename[ iOutFilenameLength ] = '\0'; Q_snprintf( szOutFilename, sizeof( szOutFilename ), "%s%02i", szOutFilename, iSameFolderCount ); } // Pull the files out of the zip if ( g_pFullFileSystem->UnzipFile( pchZippedFileName, "MOD", szOutFilename ) ) { // New maps have been imported, so refresh the list BuildMapsList(); } return false; } //----------------------------------------------------------------------------- // Purpose: builds bonus map list from directory //----------------------------------------------------------------------------- void CBonusMapsDialog::BuildMapsList( void ) { // clear the current list m_pGameList->DeleteAllItems(); BonusMapsDatabase()->ClearBonusMapsList(); BonusMapsDatabase()->ScanBonusMaps(); // Enable back button if we're in a sub folder bool bIsRoot = ( Q_strcmp( BonusMapsDatabase()->GetPath(), "." ) == 0 ); SetControlEnabled( "Back", !bIsRoot ); SetControlVisible( "Back", !bIsRoot ); SetControlEnabled( "ImportBonusMaps", bIsRoot ); SetControlVisible( "ImportBonusMaps", bIsRoot ); char szDisplayPath[_MAX_PATH]; Q_snprintf( szDisplayPath, _MAX_PATH, "%s/", BonusMapsDatabase()->GetPath() ); SetControlString( "FileName", szDisplayPath ); SetControlString( "CommentLabel", "" ); int iMapCount = BonusMapsDatabase()->BonusCount(); // add to the list for ( int iMapIndex = 0; iMapIndex < iMapCount && iMapIndex < MAX_LISTED_BONUS_MAPS; ++iMapIndex ) { CBonusMapPanel *bonusMapPanel = new CBonusMapPanel( m_pGameList, "BonusMapPanel", iMapIndex ); bonusMapPanel->SetBonusMapInfo( BonusMapsDatabase()->GetPath(), *(BonusMapsDatabase()->GetBonusData( iMapIndex )) ); m_pGameList->AddItem( NULL, bonusMapPanel ); } // display a message if there are no save games if ( iMapCount <= 0 ) { vgui::Label *pNoSavesLabel = SETUP_PANEL(new Label(m_pGameList, "NoBonusMapsLabel", "#GameUI_NoBonusMapsToDisplay")); pNoSavesLabel->SetTextColorState(vgui::Label::CS_DULL); m_pGameList->AddItem( NULL, pNoSavesLabel ); m_pGameList->SetNumColumns( 1 ); } else { m_pGameList->SetNumColumns( 3 ); } RefreshCompletionPercentage(); // Disable load button SetControlEnabled( "loadbonusmap", false ); // Make challenge selection invisible m_pChallengeSelection->SetEnabled( false ); m_pChallengeSelection->SetVisible( false ); } //----------------------------------------------------------------------------- // Purpose: Creates the load game display list //----------------------------------------------------------------------------- void CBonusMapsDialog::CreateBonusMapsList() { m_pGameList = new vgui::PanelListPanel( this, "listpanel_bonusmaps" ); m_pGameList->SetFirstColumnWidth( 0 ); new Label( this, "FileName", "./" ); new Label( this, "CommentLabel", "" ); m_pChallengeSelection = new vgui::ComboBox( this, "ChallengeSelection", 0, false ); } //----------------------------------------------------------------------------- // Purpose: returns the save file name of the selected item //----------------------------------------------------------------------------- int CBonusMapsDialog::GetSelectedItemBonusMapIndex() { CBonusMapPanel *panel = dynamic_cast(m_pGameList->GetSelectedPanel()); if ( panel && panel->GetBonusMapListItemID() < BonusMapsDatabase()->BonusCount() ) return panel->GetBonusMapListItemID(); return BonusMapsDatabase()->InvalidIndex(); } void CBonusMapsDialog::SetSelectedBooleanStatus( const char *pchName, bool bValue ) { CBonusMapPanel *pSelectedBonusMapPanel = (CBonusMapPanel *)m_pGameList->GetSelectedPanel(); if ( !pSelectedBonusMapPanel ) return; BonusMapsDatabase()->SetBooleanStatus( pchName, pSelectedBonusMapPanel->GetBonusMapListItemID(), bValue ); // Change the status in the dialog BonusMapDescription_t *pMap = BonusMapsDatabase()->GetBonusData( pSelectedBonusMapPanel->GetBonusMapListItemID() ); pSelectedBonusMapPanel->SetBonusMapInfo( BonusMapsDatabase()->GetPath(), *pMap ); RefreshCompletionPercentage(); RefreshDialog( pMap ); } void CBonusMapsDialog::RefreshData( void ) { for ( int iMap = 0; iMap < m_pGameList->GetItemCount(); ++iMap ) { CBonusMapPanel *pBonusMapPanel = (CBonusMapPanel *)m_pGameList->GetItemPanel( iMap ); if ( pBonusMapPanel ) pBonusMapPanel->SetBonusMapInfo( BonusMapsDatabase()->GetPath(), *(BonusMapsDatabase()->GetBonusData( pBonusMapPanel->GetBonusMapListItemID() ) ) ); } CBonusMapPanel *pSelectedBonusMapPanel = (CBonusMapPanel *)m_pGameList->GetSelectedPanel(); if ( !pSelectedBonusMapPanel ) return; BonusMapDescription_t *pMap = BonusMapsDatabase()->GetBonusData( pSelectedBonusMapPanel->GetBonusMapListItemID() ); RefreshCompletionPercentage(); RefreshDialog( pMap ); } int CBonusMapsDialog::GetSelectedChallenge( void ) { if ( !m_pChallengeSelection->IsEnabled() ) return -1; KeyValues *pUserDataKey = m_pChallengeSelection->GetActiveItemUserData(); return pUserDataKey->GetInt( "challenge" ); } void CBonusMapsDialog::RefreshDialog( BonusMapDescription_t *pMap ) { if ( !pMap || pMap->bLocked || ( m_pChallengeSelection->IsEnabled() && GetSelectedChallenge() == -1 ) ) { // It's locked or no challenge is selected, so disable the load button SetControlEnabled( "loadbonusmap", false ); } else { // Enable the load button SetControlEnabled( "loadbonusmap", true ); } RefreshMedalDisplay( pMap ); if ( pMap ) SetControlString( "CommentLabel", pMap->szComment ); else SetControlString( "CommentLabel", "" ); } void CBonusMapsDialog::RefreshMedalDisplay( BonusMapDescription_t *pMap ) { { int iFirstChildIndex = FindChildIndexByName( "ChallengeMedalOverview00" ); for ( int iMedal = 0; iMedal < 5; ++iMedal ) { Panel *pMedalImage = GetChild( iFirstChildIndex + iMedal ); pMedalImage->SetVisible( false ); } } if ( !pMap || !pMap->m_pChallenges ) { SetControlVisible( "ChallengeCommentLabel", false ); SetControlVisible( "ChallengeEarnedMedal", false ); SetControlVisible( "ChallengeBestLabel", false ); SetControlVisible( "ChallengeNextMedal", false ); SetControlVisible( "ChallengeNextLabel", false ); return; } char szBuff[ 512 ]; int iChallenge = GetSelectedChallenge(); if ( iChallenge < 0 ) { SetControlVisible( "ChallengeCommentLabel", false ); SetControlVisible( "ChallengeEarnedMedal", false ); SetControlVisible( "ChallengeBestLabel", false ); SetControlVisible( "ChallengeNextMedal", false ); SetControlVisible( "ChallengeNextLabel", false ); int iFirstChildIndex = FindChildIndexByName( "ChallengeMedalOverview00" ); for ( int iChallengeIndex = 0; iChallengeIndex < m_pChallengeSelection->GetItemCount(); ++iChallengeIndex ) { KeyValues *pUserDataKey = m_pChallengeSelection->GetItemUserData( iChallengeIndex ); int iChallengeNum = pUserDataKey->GetInt( "challenge" ); if ( iChallengeNum >= 0 ) { ChallengeDescription_t *pChallengeDescription = NULL; for ( int i = 0 ; i < pMap->m_pChallenges->Count(); ++i ) { int iType = ((*pMap->m_pChallenges)[ i ]).iType; if ( iType == -1 ) { iType = i; } if ( iType == iChallengeNum ) pChallengeDescription = &((*pMap->m_pChallenges)[ i ]); } if ( pChallengeDescription ) { int iBest, iEarnedMedal, iNext, iNextMedal; GetChallengeMedals( pChallengeDescription, iBest, iEarnedMedal, iNext, iNextMedal ); if ( iChallengeNum < 10 ) Q_snprintf( szBuff, 256, "medals/medal_0%i_%s", iChallengeNum, g_pszMedalNames[ iEarnedMedal ] ); else Q_snprintf( szBuff, 256, "medals/medal_%i_%s", iChallengeNum, g_pszMedalNames[ iEarnedMedal ] ); } CBitmapImagePanel *pBitmap = dynamic_cast( GetChild( iFirstChildIndex + iChallengeNum ) ); pBitmap->SetVisible( true ); pBitmap->setTexture( szBuff ); } } return; } ChallengeDescription_t *pChallengeDescription = NULL; for ( int i = 0 ; i < pMap->m_pChallenges->Count(); ++i ) { int iType = ((*pMap->m_pChallenges)[ i ]).iType; if ( iType == -1 ) { iType = i; } if ( iType == iChallenge ) pChallengeDescription = &((*pMap->m_pChallenges)[ i ]); } if ( !pChallengeDescription ) return; const char *pchChallengeComment = pChallengeDescription->szComment; int iBest, iEarnedMedal, iNext, iNextMedal; GetChallengeMedals( pChallengeDescription, iBest, iEarnedMedal, iNext, iNextMedal ); // Set comment label SetControlString( "ChallengeCommentLabel", pchChallengeComment ); SetControlVisible( "ChallengeCommentLabel", true ); // Set earned medal if ( iEarnedMedal > -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( FindChildByName( "ChallengeEarnedMedal" ) ); pBitmap->SetVisible( true ); pBitmap->setTexture( szBuff ); } // 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( 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 ); } void CBonusMapsDialog::RefreshCompletionPercentage( void ) { float fPercentage = BonusMapsDatabase()->GetCompletionPercentage(); if ( fPercentage > 0.0f ) { char szBuff[ 256 ]; if ( fPercentage * 100.0f < 1.0f ) Q_snprintf( szBuff, 256, "%.2f%%", fPercentage * 100.0f ); // Show decimal places if less than 1% else Q_snprintf( szBuff, 256, "%.0f%%", fPercentage * 100.0f ); SetControlString( "PercentageText", szBuff ); SetControlVisible( "PercentageText", true ); SetControlVisible( "CompletionText", true ); // Blend the color from backround color 0% to selected color 100% Color cProgressBar = Color( static_cast( m_PercentageBarBackgroundColor.r() ) * ( 1.0f - fPercentage ) + static_cast( m_PercentageBarColor.r() ) * fPercentage, static_cast( m_PercentageBarBackgroundColor.g() ) * ( 1.0f - fPercentage ) + static_cast( m_PercentageBarColor.g() ) * fPercentage, static_cast( m_PercentageBarBackgroundColor.b() ) * ( 1.0f - fPercentage ) + static_cast( m_PercentageBarColor.b() ) * fPercentage, static_cast( m_PercentageBarBackgroundColor.a() ) * ( 1.0f - fPercentage ) + static_cast( m_PercentageBarColor.a() ) * fPercentage ); m_pPercentageBar->SetFillColor( cProgressBar ); m_pPercentageBar->SetWide( m_pPercentageBarBackground->GetWide() * fPercentage ); SetControlVisible( "PercentageBarBackground", true ); SetControlVisible( "PercentageBar", true ); } else { // 0% complete so don't display SetControlVisible( "PercentageText", false ); SetControlVisible( "CompletionText", false ); SetControlVisible( "PercentageBarBackground", false ); SetControlVisible( "PercentageBar", false ); } } void CBonusMapsDialog::ApplySchemeSettings( IScheme *pScheme ) { m_PercentageBarBackgroundColor = Color( 0, 0, 0, 64 ); m_PercentageBarColor = pScheme->GetColor( "NewGame.SelectionColor", Color(255, 255, 255, 255) ); BaseClass::ApplySchemeSettings( pScheme ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CBonusMapsDialog::OnCommand( const char *command ) { if ( !stricmp( command, "loadbonusmap" ) ) { int mapIndex = GetSelectedItemBonusMapIndex(); if ( BonusMapsDatabase()->IsValidIndex( mapIndex ) ) { BonusMapDescription_t *pBonusMap = BonusMapsDatabase()->GetBonusData( mapIndex ); // Don't do anything with locked items if ( pBonusMap->bLocked || ( m_pChallengeSelection->IsEnabled() && GetSelectedChallenge() == -1 ) ) return; const char *shortName = pBonusMap->szShortName; if ( shortName && shortName[ 0 ] ) { if ( pBonusMap->bIsFolder ) { BonusMapsDatabase()->AppendPath( shortName ); // repopulate list with current directory BuildMapsList(); m_pGameList->MoveScrollBarToTop(); } else { // Load the game, return to top and switch to engine char sz[ 256 ]; // Set the challenge mode if one is selected int iChallenge = GetSelectedChallenge() + 1; if ( iChallenge > 0 ) { Q_snprintf( sz, sizeof( sz ), "sv_bonus_challenge %i\n", iChallenge ); engine->ClientCmd_Unrestricted( sz ); ChallengeDescription_t *pChallengeDescription = &((*pBonusMap->m_pChallenges)[ iChallenge - 1 ]); // Set up medal goals BonusMapsDatabase()->SetCurrentChallengeObjectives( pChallengeDescription->iBronze, pChallengeDescription->iSilver, pChallengeDescription->iGold ); BonusMapsDatabase()->SetCurrentChallengeNames( pBonusMap->szFileName, pBonusMap->szMapName, pChallengeDescription->szName ); } if ( pBonusMap->szMapFileName[ 0 ] != '.' ) { Q_snprintf( sz, sizeof( sz ), "map %s\n", pBonusMap->szMapFileName ); } else { const char *pchSubDir = Q_strnchr( BonusMapsDatabase()->GetPath(), '/', Q_strlen( BonusMapsDatabase()->GetPath() ) ); if ( pchSubDir ) { pchSubDir = Q_strnchr( pchSubDir + 1, '/', Q_strlen( pchSubDir ) ); if ( pchSubDir ) { ++pchSubDir; const char *pchMapFileName = pBonusMap->szMapFileName + 2; Q_snprintf( sz, sizeof( sz ), "map %s/%s\n", pchSubDir, pchMapFileName ); } } } engine->ClientCmd_Unrestricted( sz ); // Close this dialog //OnClose(); } } } } else if ( !stricmp( command, "back" ) ) { BonusMapsDatabase()->BackPath(); // repopulate list with current directory BuildMapsList(); m_pChallengeSelection->RemoveAll(); m_pChallengeSelection->AddItem( "", new KeyValues( "ChallengeSelection", "challenge", -1 ) ); int iFoundSimilar = 0; for ( iNumChallenges; iNumChallenges < pMap->m_pChallenges->Count(); ++iNumChallenges ) { ChallengeDescription_t *pChallenge = &(*pMap->m_pChallenges)[ iNumChallenges ]; int iType = iNumChallenges; // If the challenge type was specified then use that instead of (legacy) the order the challenges were listed if ( pChallenge->iType != -1 ) iType = pChallenge->iType; m_pChallengeSelection->AddItem( pChallenge->szName, new KeyValues( "ChallengeSelection", "challenge", iType ) ); if ( iSelectedChallenge == iNumChallenges ) iFoundSimilar = iNumChallenges + 1; } m_pChallengeSelection->ActivateItemByRow( iFoundSimilar ); } if ( iNumChallenges > 0 ) { m_pChallengeSelection->SetEnabled( true ); m_pChallengeSelection->SetVisible( true ); m_pChallengeSelection->SetNumberOfEditLines( iNumChallenges + 1 ); } else { m_pChallengeSelection->SetEnabled( false ); m_pChallengeSelection->SetVisible( false ); } RefreshDialog( pMap ); } void CBonusMapsDialog::OnControlModified() { CBonusMapPanel *pSelectedBonusMapPanel = (CBonusMapPanel *)m_pGameList->GetSelectedPanel(); if ( !pSelectedBonusMapPanel ) return; BonusMapDescription_t *pMap = BonusMapsDatabase()->GetBonusData( pSelectedBonusMapPanel->GetBonusMapListItemID() ); if ( !pMap ) return; RefreshDialog( pMap ); } // file selected. This can only happen when someone selects an image to be imported as a spray logo. void CBonusMapsDialog::OnFileSelected( const char *fullpath ) { if ( fullpath == NULL || fullpath[ 0 ] == '\0' ) return; // this can take a while, put up a waiting cursor surface()->SetCursor(dc_hourglass); ImportZippedBonusMaps( fullpath ); // change the cursor back to normal surface()->SetCursor(dc_user); }