Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1006 lines
30 KiB

//========= 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);
}