diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /gameui/BonusMapsDialog.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'gameui/BonusMapsDialog.cpp')
| -rw-r--r-- | gameui/BonusMapsDialog.cpp | 1006 |
1 files changed, 1006 insertions, 0 deletions
diff --git a/gameui/BonusMapsDialog.cpp b/gameui/BonusMapsDialog.cpp new file mode 100644 index 0000000..f5243a7 --- /dev/null +++ b/gameui/BonusMapsDialog.cpp @@ -0,0 +1,1006 @@ +//========= 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 <vgui/ILocalize.h> +#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<CBonusMapPanel *>(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<CBitmapImagePanel*>( 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<CBitmapImagePanel*>( 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<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 ); +} + +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<float>( m_PercentageBarBackgroundColor.r() ) * ( 1.0f - fPercentage ) + static_cast<float>( m_PercentageBarColor.r() ) * fPercentage, + static_cast<float>( m_PercentageBarBackgroundColor.g() ) * ( 1.0f - fPercentage ) + static_cast<float>( m_PercentageBarColor.g() ) * fPercentage, + static_cast<float>( m_PercentageBarBackgroundColor.b() ) * ( 1.0f - fPercentage ) + static_cast<float>( m_PercentageBarColor.b() ) * fPercentage, + static_cast<float>( m_PercentageBarBackgroundColor.a() ) * ( 1.0f - fPercentage ) + static_cast<float>( 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( "<Select A Challenge>", new KeyValues( "ChallengeSelection", "challenge", -1 ) ); + + RefreshDialog( NULL ); + + m_pGameList->MoveScrollBarToTop(); + } + else if ( !stricmp( command, "ImportBonusMaps" ) ) + { + if ( m_hImportBonusMapsDialog == NULL ) + { + m_hImportBonusMapsDialog = new FileOpenDialog( NULL, "#GameUI_ImportBonusMaps", true ); + m_hImportBonusMapsDialog->AddFilter( "*.bmz", "#GameUI_BMZ_Files", true ); + m_hImportBonusMapsDialog->AddActionSignalTarget( this ); + } + m_hImportBonusMapsDialog->DoModal(false); + m_hImportBonusMapsDialog->Activate(); + } + else + { + BaseClass::OnCommand( command ); + } +} + +void CBonusMapsDialog::OnKeyCodeTyped( vgui::KeyCode code ) +{ + if ( code == KEY_ESCAPE ) + { + OnCommand( "Close" ); + return; + } + + BaseClass::OnKeyCodeTyped( code ); +} + +void CBonusMapsDialog::OnKeyCodePressed( vgui::KeyCode code ) +{ + if ( code == KEY_XBUTTON_B ) + { + OnCommand( "Close" ); + return; + } + else if ( code == KEY_XSTICK1_RIGHT || + code == KEY_XSTICK2_RIGHT || + code == KEY_XBUTTON_RIGHT || + code == KEY_RIGHT ) + { + if ( m_pGameList->GetItemCount() ) + { + Panel *pSelectedPanel = m_pGameList->GetSelectedPanel(); + if ( !pSelectedPanel ) + { + m_pGameList->SetSelectedPanel( m_pGameList->GetItemPanel( m_pGameList->FirstItem() ) ); + m_pGameList->ScrollToItem( m_pGameList->FirstItem() ); + return; + } + else + { + int nNextPanelID = m_pGameList->FirstItem(); + while ( nNextPanelID != m_pGameList->InvalidItemID() ) + { + if ( m_pGameList->GetItemPanel( nNextPanelID ) == pSelectedPanel ) + { + nNextPanelID = m_pGameList->NextItem( nNextPanelID ); + if ( nNextPanelID != m_pGameList->InvalidItemID() ) + { + m_pGameList->SetSelectedPanel( m_pGameList->GetItemPanel( nNextPanelID ) ); + m_pGameList->ScrollToItem( nNextPanelID ); + return; + } + + break; + } + + nNextPanelID = m_pGameList->NextItem( nNextPanelID ); + } + } + } + } + else if ( code == KEY_XSTICK1_LEFT || + code == KEY_XSTICK2_LEFT || + code == KEY_XBUTTON_LEFT || + code == KEY_LEFT ) + { + if ( m_pGameList->GetItemCount() ) + { + Panel *pSelectedPanel = m_pGameList->GetSelectedPanel(); + if ( !pSelectedPanel ) + { + m_pGameList->SetSelectedPanel( m_pGameList->GetItemPanel( m_pGameList->FirstItem() ) ); + m_pGameList->ScrollToItem( m_pGameList->FirstItem() ); + return; + } + else + { + int nNextPanelID = m_pGameList->FirstItem(); + if ( m_pGameList->GetItemPanel( nNextPanelID ) != pSelectedPanel ) + { + while ( nNextPanelID != m_pGameList->InvalidItemID() ) + { + int nOldPanelID = nNextPanelID; + nNextPanelID = m_pGameList->NextItem( nNextPanelID ); + + if ( nNextPanelID != m_pGameList->InvalidItemID() ) + { + if ( m_pGameList->GetItemPanel( nNextPanelID ) == pSelectedPanel ) + { + m_pGameList->SetSelectedPanel( m_pGameList->GetItemPanel( nOldPanelID ) ); + m_pGameList->ScrollToItem( nOldPanelID ); + return; + } + } + } + } + } + } + } + else if ( code == KEY_XSTICK1_DOWN || + code == KEY_XSTICK2_DOWN || + code == KEY_XBUTTON_DOWN || + code == KEY_DOWN ) + { + int nOldActiveItem = m_pChallengeSelection->GetActiveItem(); + int nActiveItem = min( nOldActiveItem + 1, m_pChallengeSelection->GetItemCount() - 1 ); + + if ( nOldActiveItem != nActiveItem ) + { + m_pChallengeSelection->ActivateItem( nActiveItem ); + return; + } + } + else if ( code == KEY_XSTICK1_UP || + code == KEY_XSTICK2_UP || + code == KEY_XBUTTON_UP || + code == KEY_UP ) + { + int nOldActiveItem = m_pChallengeSelection->GetActiveItem(); + int nActiveItem = max( nOldActiveItem - 1, 0 ); + + if ( nOldActiveItem != nActiveItem ) + { + m_pChallengeSelection->ActivateItem( nActiveItem ); + return; + } + } + else if ( code == KEY_ENTER || code == KEY_XBUTTON_A || code == STEAMCONTROLLER_A ) + { + Panel *pSelectedPanel = m_pGameList->GetSelectedPanel(); + if ( pSelectedPanel ) + { + OnCommand( "loadbonusmap" ); + return; + } + } + + BaseClass::OnKeyCodePressed( code ); +} + +//----------------------------------------------------------------------------- +// Purpose: One item has been selected +//----------------------------------------------------------------------------- +void CBonusMapsDialog::OnPanelSelected() +{ + CBonusMapPanel *pSelectedBonusMapPanel = (CBonusMapPanel *)m_pGameList->GetSelectedPanel(); + if ( !pSelectedBonusMapPanel ) + return; + + BonusMapDescription_t *pMap = BonusMapsDatabase()->GetBonusData( pSelectedBonusMapPanel->GetBonusMapListItemID() ); + if ( !pMap ) + return; + + SetControlString( "CommentLabel", pMap->szComment ); + + // Handle challenge selection box + int iNumChallenges = 0; + + if ( pMap->m_pChallenges ) + { + // Get the name of the previously selected challenge so that we can select a matching challenge (if one exists) + int iSelectedChallenge = GetSelectedChallenge(); + + m_pChallengeSelection->RemoveAll(); + + m_pChallengeSelection->AddItem( "<Select A Challenge>", 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); +} |