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