diff options
| author | Narendra Umate <[email protected]> | 2013-12-02 23:36:05 -0800 |
|---|---|---|
| committer | Narendra Umate <[email protected]> | 2013-12-02 23:36:05 -0800 |
| commit | 8737f191f3b59f001a77bf6c08091109211c1c9f (patch) | |
| tree | dbbf05c004d9b026f2c1f23f06600fe0add82c36 /mp/src/game/client/hud_vote.cpp | |
| parent | Update .gitignore. (diff) | |
| parent | Make .xcconfigs text files too. (diff) | |
| download | source-sdk-2013-8737f191f3b59f001a77bf6c08091109211c1c9f.tar.xz source-sdk-2013-8737f191f3b59f001a77bf6c08091109211c1c9f.zip | |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'mp/src/game/client/hud_vote.cpp')
| -rw-r--r-- | mp/src/game/client/hud_vote.cpp | 3442 |
1 files changed, 1721 insertions, 1721 deletions
diff --git a/mp/src/game/client/hud_vote.cpp b/mp/src/game/client/hud_vote.cpp index 17eb4f11..7a88bb22 100644 --- a/mp/src/game/client/hud_vote.cpp +++ b/mp/src/game/client/hud_vote.cpp @@ -1,1721 +1,1721 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-//===========================================================================//
-
-
-#include "cbase.h"
-#include "hud.h"
-#include "hudelement.h"
-#include "hud_macros.h"
-#include "hud_numericdisplay.h"
-#include "iclientmode.h"
-#include "clientmode_shared.h"
-#include "VGuiMatSurface/IMatSystemSurface.h"
-#include "materialsystem/imaterial.h"
-#include "materialsystem/imesh.h"
-#include "materialsystem/imaterialvar.h"
-#include "con_nprint.h"
-#include "hud_vote.h"
-#include "menu.h"
-
-#include <vgui/IScheme.h>
-#include <vgui/ISurface.h>
-#include <vgui/ILocalize.h>
-#include <KeyValues.h>
-#include <vgui_controls/AnimationController.h>
-#include <vgui_controls/EditablePanel.h>
-#include <vgui_controls/Label.h>
-#include <vgui_controls/ComboBox.h>
-#include <vgui_controls/ImageList.h>
-#include "vgui_avatarimage.h"
-
-#ifdef TF_CLIENT_DLL
-#include "ienginevgui.h"
-#include "tf_gcmessages.h"
-#include "c_tf_player.h"
-#include "econ_notifications.h"
-#include "confirm_dialog.h"
-#include "gc_clientsystem.h"
-#include "tf_gamerules.h"
-#include "c_playerresource.h"
-#include "c_tf_objective_resource.h"
-#endif
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-ConVar cl_vote_ui_active_after_voting( "cl_vote_ui_active_after_voting", "0" );
-ConVar cl_vote_ui_show_notification( "cl_vote_ui_show_notification", "0" );
-
-#ifdef TF_CLIENT_DLL
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-class CTFVoteNotification : public CEconNotification
-{
-public:
- CTFVoteNotification( const char *pPlayerName ) : CEconNotification()
- {
- g_pVGuiLocalize->ConvertANSIToUnicode( pPlayerName, m_wszPlayerName, sizeof(m_wszPlayerName) );
- SetLifetime( 7 );
- SetText( "#Vote_notification_text" );
- AddStringToken( "initiator", m_wszPlayerName );
- }
- virtual bool CanBeTriggered()
- {
- return true;
- }
- virtual void Trigger()
- {
- CTFGenericConfirmDialog *pDialog = ShowConfirmDialog( "#Vote_notification_title", "#Vote_notification_text", "#Vote_notification_view", "#cancel", &ConfirmShowVoteSetup );
- pDialog->SetContext( this );
- pDialog->AddStringToken( "initiator", m_wszPlayerName );
- // so we aren't deleted
- SetIsInUse( true );
- }
- virtual bool CanBeAcceptedOrDeclined()
- {
- return true;
- }
- virtual void Accept()
- {
- ConfirmShowVoteSetup( true, this );
- }
- virtual void Decline()
- {
- ConfirmShowVoteSetup( false, this );
- }
- static void ConfirmShowVoteSetup( bool bConfirmed, void *pContext )
- {
- CTFVoteNotification *pNotification = (CTFVoteNotification*)pContext;
- if ( bConfirmed )
- {
- // Show vote
- CHudVote *pHudVote = GET_HUDELEMENT( CHudVote );
- if ( pHudVote )
- {
- pHudVote->ShowVoteUI();
- }
- }
- pNotification->SetIsInUse( false );
- pNotification->MarkForDeletion();
- }
-
-public:
- wchar_t m_wszPlayerName[MAX_PLAYER_NAME_LENGTH];
-};
-#endif // TF_CLIENT_DLL
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-VoteBarPanel::VoteBarPanel( vgui::Panel *parent, const char *panelName ) : vgui::Panel( parent, panelName )
-{
- for( int index = 0; index < MAX_VOTE_OPTIONS; index++ )
- {
- m_nVoteOptionCount[index] = 0;
- }
- m_nPotentialVotes = 0;
-
- ListenForGameEvent( "vote_changed" );
-}
-
-void VoteBarPanel::Paint( void )
-{
- int wide, tall;
- GetSize( wide, tall );
-
- int x = 0;
-
- // driller: this shouldn't ship - temp UI solution for playtesting
- for ( int i = 0; i < 2; i++ )
- {
- // Draw an outlined box
- vgui::surface()->DrawSetColor( 128, 128, 128, 128 );
- vgui::surface()->DrawFilledRect( x, 0, x + m_iBoxSize, m_iBoxSize );
-
- vgui::surface()->DrawSetColor( 0, 0, 0, 255 );
- vgui::surface()->DrawFilledRect( x + m_iBoxInset, m_iBoxInset, x + m_iBoxSize - m_iBoxInset, m_iBoxSize - m_iBoxInset );
-
- vgui::surface()->DrawSetColor( Color(255, 255, 255, 255) );
-
- x += ( m_iBoxSize + 64 );
- }
-
- x = 0;
-
- int iImageInset = 2 * m_iBoxInset;
-
- // Yes image
- vgui::surface()->DrawSetTexture( m_nYesTextureId );
- vgui::surface()->DrawTexturedRect( x + iImageInset, iImageInset, x + m_iBoxSize - iImageInset, m_iBoxSize - iImageInset );
-
- x += ( m_iBoxSize + 64 );
-
- // No image
- vgui::surface()->DrawSetTexture( m_nNoTextureId );
- vgui::surface()->DrawTexturedRect( x + iImageInset, iImageInset, x + m_iBoxSize - iImageInset, m_iBoxSize - iImageInset );
-
-}
-
-void VoteBarPanel::FireGameEvent( IGameEvent *event )
-{
- const char *eventName = event->GetName();
- if ( !eventName )
- return;
-
- if( FStrEq( eventName, "vote_changed" ) )
- {
- for ( int index = 0; index < MAX_VOTE_OPTIONS; index++ )
- {
- char szOption[2];
- Q_snprintf( szOption, sizeof( szOption ), "%i", index + 1 );
-
- char szVoteOption[13] = "vote_option";
- Q_strncat( szVoteOption, szOption, sizeof( szVoteOption ), COPY_ALL_CHARACTERS );
-
- m_nVoteOptionCount[index] = event->GetInt( szVoteOption );
- }
- m_nPotentialVotes = event->GetInt( "potentialVotes" );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CVoteSetupDialog::CVoteSetupDialog( vgui::Panel *parent ) : BaseClass( parent, "VoteSetupDialog" )
-{
- SetMoveable( false );
- SetSizeable( false );
-
- m_pVoteSetupList = new SectionedListPanel( this, "VoteSetupList" );
- m_pVoteParameterList = new SectionedListPanel( this, "VoteParameterList" );
- m_pCallVoteButton = new Button( this, "CallVoteButton", "CallVote", this, "CallVote" );
- m_pComboBox = new ComboBox( this, "ComboBox", 5, false );
- m_pImageList = NULL;
-
-#ifdef TF_CLIENT_DLL
- vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme");
- SetScheme(scheme);
-#else
- SetScheme( "ClientScheme" );
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Destructor
-//-----------------------------------------------------------------------------
-CVoteSetupDialog::~CVoteSetupDialog()
-{
- if ( m_pImageList )
- {
- delete m_pImageList;
- m_pImageList = NULL;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CVoteSetupDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
-{
- BaseClass::ApplySchemeSettings( pScheme );
-
- SetProportional( true );
-
- LoadControlSettings( "Resource/UI/VoteHud.res" );
-
- m_pComboBox->GetComboButton()->SetFgColor( Color( 117,107,94,255 ) );
- m_pComboBox->GetComboButton()->SetDefaultColor( Color( 117,107,94,255), Color( 0,0,0,0) );
- m_pComboBox->GetComboButton()->SetArmedColor( Color( 117,107,94,255), Color( 0,0,0,0) );
- m_pComboBox->GetComboButton()->SetDepressedColor( Color( 117,107,94,255), Color( 0,0,0,0) );
-
- if ( m_pImageList )
- {
- delete m_pImageList;
- }
-
- m_pImageList = new ImageList( false );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Does dialog-specific customization after applying scheme settings.
-//-----------------------------------------------------------------------------
-void CVoteSetupDialog::PostApplySchemeSettings( vgui::IScheme *pScheme )
-{
- // resize the images to our resolution
- for ( int i = 0; i < m_pImageList->GetImageCount(); i++ )
- {
- int wide, tall;
- m_pImageList->GetImage( i )->GetSize( wide, tall );
- m_pImageList->GetImage( i )->SetSize(scheme()->GetProportionalScaledValueEx( GetScheme(), wide ), scheme()->GetProportionalScaledValueEx( GetScheme(), tall ) );
- }
-
- m_pVoteParameterList->SetImageList( m_pImageList, false );
- m_pVoteParameterList->SetVisible( true );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CVoteSetupDialog::ApplySettings(KeyValues *inResourceData)
-{
- BaseClass::ApplySettings( inResourceData );
-
- IScheme *pScheme = scheme()->GetIScheme( GetScheme() );
-
- m_hIssueFont = INVALID_FONT;
- const char *pszFont = inResourceData->GetString( "issue_font", NULL );
- if ( pszFont && pszFont[0] )
- {
- m_hIssueFont = pScheme->GetFont( pszFont, true );
- }
-
- m_hHeaderFont = INVALID_FONT;
- pszFont = inResourceData->GetString( "header_font", NULL );
- if ( pszFont && pszFont[0] )
- {
- m_hHeaderFont = pScheme->GetFont( pszFont, true );
- }
-
- const char *pszColor = inResourceData->GetString( "issue_fgcolor", "Label.TextColor" );
- m_IssueFGColor = pScheme->GetColor( pszColor, Color( 255, 255, 255, 255 ) );
-
- pszColor = inResourceData->GetString( "issue_fgcolor_disabled", "Label.TextColor" );
- m_IssueFGColorDisabled = pScheme->GetColor( pszColor, Color( 255, 255, 255, 255 ) );
-
- pszColor = inResourceData->GetString( "header_fgcolor", "Label.TextColor" );
- m_HeaderFGColor = pScheme->GetColor( pszColor, Color( 255, 255, 255, 255 ) );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Keep track of the current map
-//-----------------------------------------------------------------------------
-void CVoteSetupDialog::UpdateCurrentMap( void )
-{
- Q_FileBase( engine->GetLevelName(), m_szCurrentMap, sizeof(m_szCurrentMap) );
- Q_strlower( m_szCurrentMap );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Feeds Issues from the server to this Dialog
-//-----------------------------------------------------------------------------
-void CVoteSetupDialog::AddVoteIssues( CUtlStringList &m_VoteSetupIssues )
-{
- m_VoteIssues.RemoveAll();
- for ( int index = 0; index < m_VoteSetupIssues.Count(); index++ )
- {
- m_VoteIssues.AddToTail( m_VoteSetupIssues[index] );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Feeds the server's MapCycle to the parameters dialog
-//-----------------------------------------------------------------------------
-void CVoteSetupDialog::AddVoteIssueParams_MapCycle( CUtlStringList &m_VoteSetupMapCycle )
-{
- m_VoteIssuesMapCycle.RemoveAll();
- for ( int index = 0; index < m_VoteSetupMapCycle.Count(); index++ )
- {
- m_VoteIssuesMapCycle.AddToTail( m_VoteSetupMapCycle[index] );
- }
-}
-
-#ifdef TF_CLIENT_DLL
-//-----------------------------------------------------------------------------
-// Purpose: Feeds the server's PopFiles to the parameters dialog
-//-----------------------------------------------------------------------------
-void CVoteSetupDialog::AddVoteIssueParams_PopFiles( CUtlStringList &m_VoteSetupPopFiles )
-{
- m_VoteIssuesPopFiles.RemoveAll();
- for ( int index = 0; index < m_VoteSetupPopFiles.Count(); index++ )
- {
- m_VoteIssuesPopFiles.AddToTail( m_VoteSetupPopFiles[index] );
- }
-}
-#endif // TF_CLIENT_DLL
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CVoteSetupDialog::Activate()
-{
- InvalidateLayout( true, true );
-
- BaseClass::Activate();
-
- ResetData();
-
- m_pVoteSetupList->SetVerticalScrollbar( true );
- m_pVoteSetupList->RemoveAll();
- m_pVoteSetupList->RemoveAllSections();
- m_pVoteSetupList->AddSection( 0, "Issue" );
- m_pVoteSetupList->SetSectionAlwaysVisible( 0, true );
- m_pVoteSetupList->SetSectionFgColor( 0, Color( 255, 255, 255, 255 ) );
- m_pVoteSetupList->SetBgColor( Color( 0, 0, 0, 0 ) );
- m_pVoteSetupList->SetBorder( NULL );
- m_pVoteSetupList->AddColumnToSection( 0, "Issue", "#TF_Vote_Column_Issue", SectionedListPanel::COLUMN_CENTER, m_iIssueWidth );
-
- if ( m_hHeaderFont != INVALID_FONT )
- {
- m_pVoteSetupList->SetFontSection( 0, m_hHeaderFont );
- m_pVoteSetupList->SetSectionFgColor( 0, m_HeaderFGColor );
- }
-
- m_pVoteParameterList->SetVerticalScrollbar( true );
- m_pVoteParameterList->RemoveAll();
- m_pVoteParameterList->RemoveAllSections();
- m_pVoteParameterList->AddSection( 0, "Name" );
- m_pVoteParameterList->SetSectionAlwaysVisible( 0, true );
- m_pVoteParameterList->SetSectionFgColor( 0, Color( 255, 255, 255, 255 ) );
- m_pVoteParameterList->SetBgColor( Color( 0, 0, 0, 0 ) );
- m_pVoteParameterList->SetBorder( NULL );
- m_pVoteParameterList->AddColumnToSection( 0, "Avatar", "", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_RIGHT, 55 );
- m_pVoteParameterList->AddColumnToSection( 0, "", "", 0, 10 ); // Spacer
- m_pVoteParameterList->AddColumnToSection( 0, "Name", "#TF_Vote_Column_Name", 0, m_iParameterWidth * 0.6 );
- m_pVoteParameterList->AddColumnToSection( 0, "Properties", "#TF_Vote_Column_Properties", SectionedListPanel::COLUMN_CENTER, m_iParameterWidth * 0.3 );
-
- if ( m_hHeaderFont != INVALID_FONT )
- {
- m_pVoteParameterList->SetFontSection( 0, m_hHeaderFont );
- m_pVoteParameterList->SetSectionFgColor( 0, m_HeaderFGColor );
- m_pVoteParameterList->SetFontSection( 1, m_hHeaderFont );
- m_pVoteParameterList->SetSectionFgColor( 1, m_HeaderFGColor );
- }
-
- // Populate the Issue list
- for ( int index = 0; index < m_VoteIssues.Count(); index++ )
- {
- const char *pszIssue = m_VoteIssues[index];
- if ( !pszIssue || !pszIssue[0] )
- continue;
-
- KeyValues *pKeyValues = new KeyValues( "Issue" );
- pKeyValues->SetString( "Issue", pszIssue );
- int iId = m_pVoteSetupList->AddItem( 0, pKeyValues );
- pKeyValues->deleteThis();
-
- // Setup the list entry style
- if ( m_hIssueFont != INVALID_FONT )
- {
- m_pVoteSetupList->SetItemFont( iId, m_hIssueFont );
-
- bool bDisabled = V_stristr( pszIssue, "(Disabled on Server)" ); // driller: need to localize
- Color colFG = bDisabled ? m_IssueFGColorDisabled : m_IssueFGColor;
- m_pVoteSetupList->SetItemFgColor( iId, colFG );
- }
- }
-
- // Select the first item by default
- if ( m_pVoteSetupList->GetItemCount() > 0 )
- {
- m_pVoteSetupList->SetSelectedItem( 0 );
- }
-
- UpdateCurrentMap();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CVoteSetupDialog::OnClose()
-{
- ResetData();
- BaseClass::OnClose();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CVoteSetupDialog::OnCommand(const char *command)
-{
- // We should have enough data to issue a CallVote command
- if ( V_stricmp( command, "CallVote" ) == 0 )
- {
- int iSelectedItem = m_pVoteSetupList->GetSelectedItem();
- if ( iSelectedItem >= 0 )
- {
- char szVoteCommand[128];
- KeyValues *pIssueKeyValues = m_pVoteSetupList->GetItemData( iSelectedItem );
- const char *szIssue = pIssueKeyValues->GetString( "Issue" );
- if ( V_stricmp( "changelevel", szIssue ) == 0 || V_stricmp( "nextlevel", szIssue ) == 0 )
- {
- int nSelectedParam = m_pVoteParameterList->GetSelectedItem();
- if ( nSelectedParam >= 0 )
- {
- // Get selected Map
- int iSelectedParam = m_pVoteParameterList->GetSelectedItem();
- if ( iSelectedParam >= 0 )
- {
- KeyValues *pParameterKeyValues = m_pVoteParameterList->GetItemData( iSelectedParam );
- if ( pParameterKeyValues )
- {
- // Which Map?
- const char *szMapName = pParameterKeyValues->GetString( "Name" );
- Q_snprintf( szVoteCommand, sizeof( szVoteCommand ), "callvote %s %s\n;", szIssue, szMapName );
- engine->ClientCmd( szVoteCommand );
- }
- }
- }
- }
- else if ( V_stricmp( "kick", szIssue ) == 0 )
- {
- // Get selected Player
- int iSelectedParam = m_pVoteParameterList->GetSelectedItem();
- if ( iSelectedParam >= 0 )
- {
- KeyValues *pKeyValues = m_pVoteParameterList->GetItemData( iSelectedParam );
- if ( pKeyValues )
- {
- // Is Player valid?
- int playerIndex = pKeyValues->GetInt( "index" );
- const char *pReasonString = m_pComboBox->GetActiveItemUserData() ? m_pComboBox->GetActiveItemUserData()->GetName() : "other";
- player_info_t playerInfo;
- if ( engine->GetPlayerInfo( playerIndex, &playerInfo ) )
- {
- CBasePlayer *pPlayer = UTIL_PlayerByIndex( playerIndex );
- Q_snprintf( szVoteCommand, sizeof( szVoteCommand ), "callvote %s \"%d %s\"\n;", szIssue, pPlayer->GetUserID(), pReasonString );
- engine->ClientCmd( szVoteCommand );
-#ifdef TF_CLIENT_DLL
- CSteamID steamID;
- CTFPlayer* pSubject = ToTFPlayer( pPlayer );
- if ( pSubject && pSubject->GetSteamID( &steamID ) && steamID.GetAccountID() != 0 )
- {
- GCSDK::CProtoBufMsg<CMsgTFVoteKickBanPlayer> msg( k_EMsgGCVoteKickBanPlayer );
- uint32 reason = GetKickBanPlayerReason( pReasonString );
- msg.Body().set_account_id_subject( steamID.GetAccountID() );
- msg.Body().set_kick_reason( reason );
- GCClientSystem()->BSendMessage( msg );
- }
-#endif
- }
- }
- }
- }
-#ifdef TF_CLIENT_DLL
- else if ( V_stricmp( "ChangeMission", szIssue ) == 0 )
- {
- int nSelectedParam = m_pVoteParameterList->GetSelectedItem();
- if ( nSelectedParam >= 0 )
- {
- // Get selected Challenge
- int iSelectedParam = m_pVoteParameterList->GetSelectedItem();
- if ( iSelectedParam >= 0 )
- {
- KeyValues *pParameterKeyValues = m_pVoteParameterList->GetItemData( iSelectedParam );
- if ( pParameterKeyValues )
- {
- // Which Pop File?
- const char *szPopFile = pParameterKeyValues->GetString( "Name" );
- Q_snprintf( szVoteCommand, sizeof( szVoteCommand ), "callvote %s %s\n;", szIssue, szPopFile );
- engine->ClientCmd( szVoteCommand );
- }
- }
- }
- }
-#endif // TF_CLIENT_DLL
- else
- {
- // Non-parameter vote. i.e. callvote scrambleteams
- Q_snprintf( szVoteCommand, sizeof(szVoteCommand), "callvote %s\n;", szIssue );
- engine->ClientCmd( szVoteCommand );
- }
-
- Close();
- }
- }
- else
- {
- BaseClass::OnCommand( command );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CVoteSetupDialog::OnItemSelected( vgui::Panel *panel )
-{
- if ( panel == m_pVoteSetupList )
- {
- m_pComboBox->RemoveAll();
- m_pComboBox->SetVisible( false );
- SetDialogVariable( "combo_label", "" );
-
- // Which Issue did we select?
- int iSelectedItem = m_pVoteSetupList->GetSelectedItem();
- if ( iSelectedItem >= 0 )
- {
- KeyValues *pIssueKeyValues = m_pVoteSetupList->GetItemData( iSelectedItem );
- if ( !pIssueKeyValues )
- return;
-
- // We're rebuilding, so clear state
- m_bVoteButtonEnabled = false;
- m_pVoteParameterList->ClearSelection();
- m_pVoteParameterList->RemoveAll();
-
- const char *szName = pIssueKeyValues->GetString( "Issue" );
- if ( V_stricmp( "Voting disabled on this Server", szName ) == 0 )
- {
- m_bVoteButtonEnabled = false;
- }
- else if ( V_stristr( szName, "(Disabled on Server)" ) ) // driller: need to localize
- {
- m_bVoteButtonEnabled = false;
- }
- // CHANGELEVEL / NEXTLEVEL
- else if ( V_stricmp( "changelevel", szName ) == 0 || V_stricmp( "nextlevel", szName ) == 0 )
- {
- // Feed the mapcycle to the parameters list
- for ( int index = 0; index < m_VoteIssuesMapCycle.Count(); index++ )
- {
- // Don't show the current map
- if ( V_strncmp( m_VoteIssuesMapCycle[index], m_szCurrentMap, ( V_strlen( m_VoteIssuesMapCycle[index] ) - 1 ) ) == 0 )
- continue;
-
- KeyValues *pKeyValues = new KeyValues( "Name" );
- pKeyValues->SetString( "Name", m_VoteIssuesMapCycle[index] );
- pKeyValues->SetInt( "index", index );
- int iId = m_pVoteParameterList->AddItem( 0, pKeyValues );
- pKeyValues->deleteThis();
-
- if ( m_hIssueFont != INVALID_FONT )
- {
- m_pVoteParameterList->SetItemFont( iId, m_hIssueFont );
- m_pVoteParameterList->SetItemFgColor( iId, m_IssueFGColor );
- }
- }
-
- if ( m_pVoteParameterList->GetItemCount() == 0 )
- {
- KeyValues *pKeyValues = new KeyValues( "Name" );
- pKeyValues->SetString( "Name", "#TF_vote_no_maps" );
- pKeyValues->SetInt( "index", 1 );
- m_pVoteParameterList->AddItem( 0, pKeyValues );
- pKeyValues->deleteThis();
- }
- }
- // KICK
- else if ( V_stricmp( "kick", szName ) == 0 )
- {
- // Feed the player list to the parameters list
- int nMaxClients = engine->GetMaxClients();
- for ( int playerIndex = 1; playerIndex <= nMaxClients; playerIndex++ )
- {
- C_BasePlayer *pPlayer = UTIL_PlayerByIndex( playerIndex );
- if ( !pPlayer )
- continue;
-
- C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
- if ( !pLocalPlayer )
- continue;
-
- if ( pPlayer == pLocalPlayer )
- continue;
-
- bool bAllowKickUnassigned = false;
-#ifdef TF_CLIENT_DLL
- // Allow kicking team unassigned in MvM
- if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() && g_PR->IsConnected( playerIndex ) && pPlayer->GetTeamNumber() == TEAM_UNASSIGNED )
- {
- bAllowKickUnassigned = true;
- }
-#endif // TF_CLIENT_DLL
-
- // Can't kick people on the other team, so don't list them
- if ( pPlayer->GetTeam() != pLocalPlayer->GetTeam() && !bAllowKickUnassigned )
- continue;
-
- char szPlayerIndex[32];
- Q_snprintf( szPlayerIndex, sizeof( szPlayerIndex ), "%d", playerIndex );
-
- KeyValues *pKeyValues = new KeyValues( szPlayerIndex );
- pKeyValues->SetString( "Name", pPlayer->GetPlayerName() );
- pKeyValues->SetInt( "index", playerIndex );
- int iId = m_pVoteParameterList->AddItem( 0, pKeyValues );
- pKeyValues->deleteThis();
-
- if ( m_hIssueFont != INVALID_FONT )
- {
- m_pVoteParameterList->SetItemFont( iId, m_hIssueFont );
- m_pVoteParameterList->SetItemFgColor( iId, m_IssueFGColor );
- }
- }
-
-#ifdef TF_CLIENT_DLL
- SetDialogVariable( "combo_label", g_pVGuiLocalize->Find( "#TF_VoteKickReason" ) );
- m_pComboBox->AddItem( g_pVGuiLocalize->Find( "TF_VoteKickReason_Other" ), new KeyValues( "other" ) );
- m_pComboBox->AddItem( g_pVGuiLocalize->Find( "TF_VoteKickReason_Cheating" ), new KeyValues( "cheating" ) );
- m_pComboBox->AddItem( g_pVGuiLocalize->Find( "TF_VoteKickReason_Idle" ), new KeyValues( "idle" ) );
- m_pComboBox->AddItem( g_pVGuiLocalize->Find( "TF_VoteKickReason_Scamming" ), new KeyValues( "scamming" ) );
- m_pComboBox->SilentActivateItemByRow( 0 );
- m_pComboBox->SetVisible( true );
-#endif
- }
-#ifdef TF_CLIENT_DLL
- // CHANGE POP FILE
- else if ( V_stricmp( "ChangeMission", szName ) == 0 )
- {
- // Feed the popfiles to the parameters list
- for ( int index = 0; index < m_VoteIssuesPopFiles.Count(); index++ )
- {
- // Don't show the current pop file
- if ( TFObjectiveResource()->GetMvMPopFileName() == '\0' )
- {
- // Use the map name
- char szShortMapName[ MAX_MAP_NAME ];
- V_strncpy( szShortMapName, engine->GetLevelName(), sizeof( szShortMapName ) );
- V_StripExtension( szShortMapName, szShortMapName, sizeof( szShortMapName ) );
-
- if ( V_strncmp( m_VoteIssuesPopFiles[index], V_GetFileName( szShortMapName ), ( V_strlen( m_VoteIssuesPopFiles[index] ) - 1 ) ) == 0 )
- continue;
- }
- else
- {
- // Use the specified pop file
- if ( V_strncmp( m_VoteIssuesPopFiles[index], TFObjectiveResource()->GetMvMPopFileName(), ( V_strlen( m_VoteIssuesPopFiles[index] ) - 1 ) ) == 0 )
- continue;
- }
-
- KeyValues *pKeyValues = new KeyValues( "Name" );
- pKeyValues->SetString( "Name", m_VoteIssuesPopFiles[index] );
- pKeyValues->SetInt( "index", index );
- int iId = m_pVoteParameterList->AddItem( 0, pKeyValues );
- pKeyValues->deleteThis();
-
- if ( m_hIssueFont != INVALID_FONT )
- {
- m_pVoteParameterList->SetItemFont( iId, m_hIssueFont );
- m_pVoteParameterList->SetItemFgColor( iId, m_IssueFGColor );
- }
- }
-
- if ( m_pVoteParameterList->GetItemCount() == 0 )
- {
- KeyValues *pKeyValues = new KeyValues( "Name" );
- pKeyValues->SetString( "Name", "#TF_vote_no_challenges" );
- pKeyValues->SetInt( "index", 1 );
- m_pVoteParameterList->AddItem( 0, pKeyValues );
- pKeyValues->deleteThis();
- }
- }
-#endif // TF_CLIENT_DLL
- else
- {
- // User selected an issue that doesn't require a parameter - Scrambleteams, Restartgame, etc
- m_bVoteButtonEnabled = true;
- }
- }
- }
- else if ( panel == m_pVoteParameterList )
- {
- // If this issue requires a parameter, make sure we have one selected before enabling the CallVote button
- int iSelectedParam = m_pVoteParameterList->GetSelectedItem();
- if ( iSelectedParam >= 0 )
- {
- KeyValues *pParameterKeyValues = m_pVoteParameterList->GetItemData( iSelectedParam );
- if ( pParameterKeyValues )
- {
- const char *szParameterName = pParameterKeyValues->GetString( "Name" );
- if ( szParameterName )
- {
- m_bVoteButtonEnabled = true;
- }
- }
- }
- }
-
- m_pCallVoteButton->SetEnabled( m_bVoteButtonEnabled );
- RefreshIssueParameters();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Updates any additional data/info on Vote issue parameters
-//-----------------------------------------------------------------------------
-void CVoteSetupDialog::RefreshIssueParameters()
-{
- // In the case of the KICK issue, we list players and show additional properties (Bot, Disconnected)
- int iSelectedItem = m_pVoteSetupList->GetSelectedItem();
- if ( iSelectedItem >= 0 )
- {
- KeyValues *pIssueKeyValues = m_pVoteSetupList->GetItemData( iSelectedItem );
- const char *szName = pIssueKeyValues->GetString( "Issue" );
- if ( V_stricmp( "kick", szName ) == 0 )
- {
- if ( m_pVoteParameterList->GetItemCount() > 0 )
- {
- for ( int index = 0; index < m_pVoteParameterList->GetItemCount(); index++ )
- {
- KeyValues *pKeyValues = m_pVoteParameterList->GetItemData( index );
- if ( !pKeyValues )
- continue;
-
- int playerIndex = pKeyValues->GetInt( "index" );
- player_info_t playerInfo;
-
- if ( !engine->GetPlayerInfo( playerIndex, &playerInfo ) )
- {
- pKeyValues->SetString( "Properties", "Offline" );
- continue;
- }
-
- pKeyValues->SetString( "Name", playerInfo.name );
-
- if ( playerInfo.fakeplayer )
- {
- pKeyValues->SetString( "Properties", "Bot" );
- }
- else
- {
- pKeyValues->SetString( "Properties", "" );
- }
-
- CSteamID steamID;
- C_BasePlayer* pPlayer = UTIL_PlayerByIndex( playerIndex );
- if ( pPlayer && pPlayer->GetSteamID( &steamID ) && steamID.GetAccountID() != 0 )
- {
- CAvatarImage *pAvatar = new CAvatarImage();
- pAvatar->SetAvatarSteamID( steamID );
- pAvatar->SetAvatarSize( 32, 32 );
- int iImageIndex = m_pImageList->AddImage( pAvatar );
- pKeyValues->SetInt( "Avatar", iImageIndex );
- }
-
- m_pVoteParameterList->InvalidateItem( index );
- }
-
- m_pVoteParameterList->SetImageList( m_pImageList, false );
- }
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CVoteSetupDialog::ResetData()
-{
- m_bVoteButtonEnabled = false;
- m_pVoteSetupList->DeleteAllItems();
- m_pVoteParameterList->DeleteAllItems();
- m_pComboBox->DeleteAllItems();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-DECLARE_HUDELEMENT( CHudVote );
-DECLARE_HUD_MESSAGE( CHudVote, CallVoteFailed );
-DECLARE_HUD_MESSAGE( CHudVote, VoteStart );
-DECLARE_HUD_MESSAGE( CHudVote, VotePass );
-DECLARE_HUD_MESSAGE( CHudVote, VoteFailed );
-DECLARE_HUD_MESSAGE( CHudVote, VoteSetup );
-
-//-----------------------------------------------------------------------------
-// Purpose: Handles all UI for Voting
-//-----------------------------------------------------------------------------
-CHudVote::CHudVote( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "CHudVote" )
-{
- vgui::Panel *pParent = g_pClientMode->GetViewport();
- SetParent( pParent );
-
-#ifdef TF_CLIENT_DLL
- vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme");
- SetScheme(scheme);
-#endif
-
- SetHiddenBits( 0 );
- for( int index = 0; index < MAX_VOTE_OPTIONS; index++ )
- {
- m_nVoteOptionCount[index] = 0;
- }
- m_pVoteActive = new EditablePanel( this, "VoteActive" );
- m_voteBar = new VoteBarPanel( m_pVoteActive, "VoteBar" );
- m_pVoteFailed = new EditablePanel( this, "VoteFailed" );
- m_pVotePassed = new EditablePanel( this, "VotePassed" );
- m_pCallVoteFailed = new EditablePanel( this, "CallVoteFailed" );
- m_pVoteSetupDialog = new CVoteSetupDialog( pParent );
-
- RegisterForRenderGroup( "mid" );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudVote::ApplySchemeSettings( vgui::IScheme *pScheme )
-{
- BaseClass::ApplySchemeSettings( pScheme );
-
- SetProportional( true );
-
- LoadControlSettings( "Resource/UI/VoteHud.res" );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudVote::Init( void )
-{
- ListenForGameEvent( "vote_changed" );
- ListenForGameEvent( "vote_options" );
- ListenForGameEvent( "vote_cast" );
-
- SetVoteActive( false );
- m_flVoteResultCycleTime = -1;
- m_flHideTime = -1;
- m_bIsYesNoVote = true;
- m_bPlayerVoted = false;
- m_nVoteChoicesCount = 2; // Yes/No is the default
- m_bShowVoteActivePanel = false;
- m_iVoteCallerIdx = -1;
-
- HOOK_HUD_MESSAGE( CHudVote, CallVoteFailed );
- HOOK_HUD_MESSAGE( CHudVote, VoteStart );
- HOOK_HUD_MESSAGE( CHudVote, VotePass );
- HOOK_HUD_MESSAGE( CHudVote, VoteFailed );
- HOOK_HUD_MESSAGE( CHudVote, VoteSetup );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudVote::LevelInit( void )
-{
- SetVoteActive( false );
- m_flVoteResultCycleTime = -1;
- m_flHideTime = -1;
- m_flPostVotedHideTime = -1;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-int CHudVote::KeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding )
-{
- if ( !IsVisible() )
- return 1;
-
- if ( !down )
- return 1;
-
- if ( !m_bVoteActive )
- return 1;
-
- if ( m_bPlayerVoted )
- return 1;
-
- if ( !m_bShowVoteActivePanel )
- return 1;
-
- int nSlot = 999;
-
- if ( down && keynum == KEY_F1 )
- {
- nSlot = 1;
- }
- else if ( down && keynum == KEY_F2 )
- {
- nSlot = 2;
- }
- else if ( down && keynum == KEY_F3 )
- {
- nSlot = 3;
- }
- else if ( down && keynum == KEY_F4 )
- {
- nSlot = 4;
- }
- else if ( down && keynum == KEY_F5 )
- {
- nSlot = 5;
- }
- else
- {
- return 1;
- }
-
- // Limit key checking to the number of options
- if ( nSlot > m_nVoteChoicesCount )
- return 1;
-
- char szNumber[2];
- Q_snprintf( szNumber, sizeof( szNumber ), "%i", nSlot );
-
- char szOptionName[13] = "vote option";
- Q_strncat( szOptionName, szNumber, sizeof( szOptionName ), COPY_ALL_CHARACTERS );
-
- engine->ClientCmd( szOptionName );
-
- return 0;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Sent only to the caller
-//-----------------------------------------------------------------------------
-void CHudVote::MsgFunc_CallVoteFailed( bf_read &msg )
-{
- if ( IsPlayingDemo() )
- return;
-
- vote_create_failed_t nReason = (vote_create_failed_t)msg.ReadByte();
- int nTime = msg.ReadShort();
-
- // if we're already drawing a vote, do nothing
- if ( ShouldDraw() )
- return;
-
- C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
- if ( !pLocalPlayer )
- return;
-
- pLocalPlayer->EmitSound("Vote.Failed");
-
- m_pVoteActive->SetVisible( false );
- m_pVoteFailed->SetVisible( false );
- m_pVotePassed->SetVisible( false );
- m_pCallVoteFailed->SetVisible( true );
- m_pVoteSetupDialog->SetVisible( false );
-
- m_flHideTime = gpGlobals->curtime + 4.0;
-
- char szTime[256];
- wchar_t wszTime[256];
- Q_snprintf( szTime, sizeof ( szTime), "%i", nTime );
- g_pVGuiLocalize->ConvertANSIToUnicode( szTime, wszTime, sizeof( wszTime ) );
-
- wchar_t wszHeaderString[512];
- wchar_t *pwszHeaderString;
-
- switch( nReason )
- {
- case VOTE_FAILED_GENERIC:
- m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed" );
- break;
-
- case VOTE_FAILED_TRANSITIONING_PLAYERS:
- m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_transition_vote" );
- break;
-
- case VOTE_FAILED_RATE_EXCEEDED:
- g_pVGuiLocalize->ConstructString( wszHeaderString, sizeof(wszHeaderString), g_pVGuiLocalize->Find( "#GameUI_vote_failed_vote_spam" ), 1, wszTime );
- pwszHeaderString = wszHeaderString;
- m_pCallVoteFailed->SetDialogVariable( "FailedReason", pwszHeaderString );
- break;
-
- case VOTE_FAILED_ISSUE_DISABLED:
- m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_disabled_issue" );
- break;
-
- case VOTE_FAILED_MAP_NOT_FOUND:
- m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_map_not_found" );
- break;
-
- case VOTE_FAILED_MAP_NOT_VALID:
- m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_map_not_valid" );
- break;
-
- case VOTE_FAILED_MAP_NAME_REQUIRED:
- m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_map_name_required" );
- break;
-
- case VOTE_FAILED_FAILED_RECENTLY:
- g_pVGuiLocalize->ConstructString( wszHeaderString, sizeof(wszHeaderString), g_pVGuiLocalize->Find( "#GameUI_vote_failed_recently" ), 1, wszTime );
- pwszHeaderString = wszHeaderString;
- m_pCallVoteFailed->SetDialogVariable( "FailedReason", pwszHeaderString );
- break;
-
- case VOTE_FAILED_TEAM_CANT_CALL:
- m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_team_cant_call" );
- break;
-
- case VOTE_FAILED_WAITINGFORPLAYERS:
- m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_waitingforplayers" );
- break;
-
- case VOTE_FAILED_CANNOT_KICK_ADMIN:
- m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_cannot_kick_admin" );
- break;
-
- case VOTE_FAILED_SCRAMBLE_IN_PROGRESS:
- m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_scramble_in_prog" );
- break;
-
- case VOTE_FAILED_SPECTATOR:
- m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_spectator" );
- break;
-
- case VOTE_FAILED_NEXTLEVEL_SET:
- m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_nextlevel_set" );
- break;
-
- case VOTE_FAILED_CANNOT_KICK_FOR_TIME:
- g_pVGuiLocalize->ConstructString( wszHeaderString, sizeof(wszHeaderString), g_pVGuiLocalize->Find( "#GameUI_vote_failed_cannot_kick_for_time" ), 1, wszTime );
- pwszHeaderString = wszHeaderString;
- m_pCallVoteFailed->SetDialogVariable( "FailedReason", pwszHeaderString );
- break;
-
- case VOTE_FAILED_CANNOT_KICK_DURING_ROUND:
- m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_round_active" );
- break;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Sent to everyone
-//-----------------------------------------------------------------------------
-void CHudVote::MsgFunc_VoteFailed( bf_read &msg )
-{
- if ( IsPlayingDemo() )
- return;
-
- int iTeam = msg.ReadByte();
- vote_create_failed_t nReason = (vote_create_failed_t)msg.ReadByte();
-
- // Visibility of this error is handled by OnThink()
- SetVoteActive( false );
- m_bVotePassed = false;
- m_flVoteResultCycleTime = gpGlobals->curtime + 2;
- m_flHideTime = gpGlobals->curtime + 5;
-
- switch ( nReason )
- {
- case VOTE_FAILED_GENERIC:
- m_pVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed" );
- break;
-
- case VOTE_FAILED_YES_MUST_EXCEED_NO:
- m_pVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_yesno" );
- break;
-
- case VOTE_FAILED_QUORUM_FAILURE:
- m_pVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_quorum" );
- break;
- }
-
- // driller: this event has no listeners - will eventually hook into stats
- IGameEvent *event = gameeventmanager->CreateEvent( "vote_failed" );
- if ( event )
- {
- event->SetInt( "team", iTeam );
- gameeventmanager->FireEventClientSide( event );
- }
-
- C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
- if ( !pLocalPlayer )
- return;
-
- pLocalPlayer->EmitSound("Vote.Failed");
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudVote::MsgFunc_VoteStart( bf_read &msg )
-{
- if ( IsPlayingDemo() )
- return;
-
- C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
- if ( !pLocalPlayer )
- return;
-
- // Is this a team-only vote?
- int iTeam = msg.ReadByte();
- uint8 invalidTeam = (uint8)TEAM_INVALID;
- if ( iTeam != invalidTeam && iTeam != pLocalPlayer->GetTeamNumber() )
- return;
-
- // Entity calling the vote
- bool bShowNotif = cl_vote_ui_show_notification.GetBool();
- const char *pszCallerName = "Server";
- m_iVoteCallerIdx = msg.ReadByte();
- if ( m_iVoteCallerIdx != DEDICATED_SERVER )
- {
- C_BasePlayer *pVoteCaller = UTIL_PlayerByIndex( m_iVoteCallerIdx );
- if ( pVoteCaller )
- {
- pszCallerName = pVoteCaller->GetPlayerName();
-
- // Don't show a notification to the caller
- if ( pVoteCaller == pLocalPlayer )
- {
- bShowNotif = false;
- }
- }
- else
- {
- // Caller invalid for some reason
- pszCallerName = "Player";
- }
- }
-
- // DisplayString
- char szIssue[256];
- szIssue[0] = 0;
- msg.ReadString( szIssue, sizeof(szIssue) );
-
- // DetailString
- char szParam1[256];
- szParam1[0] = 0;
- msg.ReadString( szParam1, sizeof(szParam1) );
-
- m_bIsYesNoVote = msg.ReadByte();
-
- SetVoteActive( true );
- m_pVoteFailed->SetVisible( false );
- m_pVotePassed->SetVisible( false );
- m_pCallVoteFailed->SetVisible( false );
- m_pVoteSetupDialog->SetVisible( false );
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pVoteActive, "HideVoteBackgrounds" );
-
- m_voteBar->SetVisible( m_bIsYesNoVote );
-
- // There will always be at least two choices...
- m_pVoteActive->SetControlVisible( "LabelOption1", true );
- m_pVoteActive->SetControlVisible( "LabelOption2", true );
-
- // ...sometimes more
- m_pVoteActive->SetControlVisible( "LabelOption3", m_VoteSetupChoices.Count() > 2 ? true : false );
- m_pVoteActive->SetControlVisible( "Option3Background_Selected", m_VoteSetupChoices.Count() > 2 ? true : false );
- m_pVoteActive->SetControlVisible( "LabelOption4", m_VoteSetupChoices.Count() > 3 ? true : false );
- m_pVoteActive->SetControlVisible( "Option4Background_Selected", m_VoteSetupChoices.Count() > 3 ? true : false );
- m_pVoteActive->SetControlVisible( "LabelOption5", m_VoteSetupChoices.Count() > 4 ? true : false );
- m_pVoteActive->SetControlVisible( "Option5Background_Selected", m_VoteSetupChoices.Count() > 4 ? true : false );
-
- m_pVoteActive->SetControlVisible( "VoteCountLabel", m_bIsYesNoVote );
- m_pVoteActive->SetControlVisible( "Option1CountLabel", m_bIsYesNoVote );
- m_pVoteActive->SetControlVisible( "Option2CountLabel", m_bIsYesNoVote );
- m_pVoteActive->SetControlVisible( "Divider1", m_bIsYesNoVote );
- m_pVoteActive->SetControlVisible( "Divider2", m_bIsYesNoVote );
-
- // Display vote caller's name
- wchar_t wszCallerName[MAX_PLAYER_NAME_LENGTH];
-
- wchar_t wszHeaderString[512];
- wchar_t *pwszHeaderString;
-
- // Player
- g_pVGuiLocalize->ConvertANSIToUnicode( pszCallerName, wszCallerName, sizeof( wszCallerName ) );
-
- // String
- g_pVGuiLocalize->ConstructString( wszHeaderString, sizeof(wszHeaderString), g_pVGuiLocalize->Find( "#GameUI_vote_header" ), 1, wszCallerName );
- pwszHeaderString = wszHeaderString;
-
- // Final
- m_pVoteActive->SetDialogVariable( "header", pwszHeaderString );
-
- // Display the Issue
- wchar_t *pwcParam;
- wchar_t wcParam[128];
-
- wchar_t *pwcIssue;
- wchar_t wcIssue[512];
-
- if ( Q_strlen( szParam1 ) > 0 )
- {
- if ( szParam1[0] == '#' )
- {
- // localize it
- pwcParam = g_pVGuiLocalize->Find( szParam1 );
- }
- else
- {
- // convert to wchar
- g_pVGuiLocalize->ConvertANSIToUnicode( szParam1, wcParam, sizeof( wcParam ) );
- pwcParam = wcParam;
- }
-
- g_pVGuiLocalize->ConstructString( wcIssue, sizeof(wcIssue), g_pVGuiLocalize->Find( szIssue ), 1, pwcParam );
- pwcIssue = wcIssue;
- }
- else
- {
- // no param, just localize the issue
- pwcIssue = g_pVGuiLocalize->Find( szIssue );
- }
- m_pVoteActive->SetDialogVariable( "voteissue", pwcIssue );
-
- // Figure out which UI
- if ( m_bIsYesNoVote )
- {
- // YES / NO UI
- wchar_t wzFinal[512] = L"";
- wchar_t *pszText = g_pVGuiLocalize->Find( "#GameUI_vote_yes_pc_instruction" );
- if ( pszText )
- {
- UTIL_ReplaceKeyBindings( pszText, 0, wzFinal, sizeof( wzFinal ) );
- if ( m_pVoteActive )
- m_pVoteActive->SetControlString( "LabelOption1", wzFinal );
- }
-
- pszText = g_pVGuiLocalize->Find( "#GameUI_vote_no_pc_instruction" );
- if ( pszText )
- {
- UTIL_ReplaceKeyBindings( pszText, 0, wzFinal, sizeof( wzFinal ) );
- if ( m_pVoteActive )
- m_pVoteActive->SetControlString( "LabelOption2", wzFinal );
- }
- }
- else
- {
- // GENERAL UI
- if ( m_VoteSetupChoices.Count() )
- {
- // Clear the labels to prevent previous options from being displayed,
- // such as when there are fewer options this vote than the previous
- for ( int iIndex = 0; iIndex < MAX_VOTE_OPTIONS; iIndex++ )
- {
- // Construct Label name
- char szOptionNum[2];
- Q_snprintf( szOptionNum, sizeof( szOptionNum ), "%i", iIndex + 1 );
-
- char szVoteOptionCount[13] = "LabelOption";
- Q_strncat( szVoteOptionCount, szOptionNum, sizeof( szVoteOptionCount ), COPY_ALL_CHARACTERS );
-
- m_pVoteActive->SetControlString( szVoteOptionCount, "" );
- }
-
- // Set us up the vote
- for ( int iIndex = 0; iIndex < m_nVoteChoicesCount; iIndex++ )
- {
- // Construct Option name
- const char *pszChoiceName = m_VoteSetupChoices[iIndex];
-
- char szOptionName[256];
- Q_snprintf( szOptionName, sizeof( szOptionName ), "F%i. ", iIndex + 1 );
-
- Q_strncat( szOptionName, pszChoiceName, sizeof( szOptionName ), COPY_ALL_CHARACTERS );
-
- // Construct Label name
- char szOptionNum[2];
- Q_snprintf( szOptionNum, sizeof( szOptionNum ), "%i", iIndex + 1 );
-
- char szVoteOptionCount[13] = "LabelOption";
- Q_strncat( szVoteOptionCount, szOptionNum, sizeof( szVoteOptionCount ), COPY_ALL_CHARACTERS );
-
- // Set Label string
- if ( m_pVoteActive )
- {
- m_pVoteActive->SetControlString( szVoteOptionCount, szOptionName );
- }
- }
- }
- }
-
- IGameEvent *event = gameeventmanager->CreateEvent( "vote_started" );
- if ( event )
- {
- event->SetString( "issue", szIssue );
- event->SetString( "param1", szParam1 );
- event->SetInt( "team", iTeam );
- event->SetInt( "initiator", m_iVoteCallerIdx );
- gameeventmanager->FireEventClientSide( event );
- }
-
-#ifdef TF_CLIENT_DLL
- if ( bShowNotif )
- {
- NotificationQueue_Add( new CTFVoteNotification( pszCallerName ) );
- }
- else
- {
- ShowVoteUI();
- }
-#else
- ShowVoteUI();
-#endif // TF_CLIENT_DLL
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudVote::MsgFunc_VotePass( bf_read &msg )
-{
- if ( IsPlayingDemo() )
- return;
-
- int iTeam = msg.ReadByte();
-
- // Passed string
- char szResult[256];
- szResult[0] = 0;
- msg.ReadString( szResult, sizeof(szResult) );
-
- // Detail string
- char szParam1[256];
- szParam1[0] = 0;
- msg.ReadString( szParam1, sizeof(szParam1) );
-
- // Localize
- wchar_t *pwcParam;
- wchar_t wcParam[128];
-
- wchar_t *pwcIssue;
- wchar_t wcIssue[512];
-
- if ( Q_strlen( szParam1 ) > 0 )
- {
- if ( szParam1[0] == '#' )
- {
- pwcParam = g_pVGuiLocalize->Find( szParam1 );
- }
- else
- {
- // Convert to wchar
- g_pVGuiLocalize->ConvertANSIToUnicode( szParam1, wcParam, sizeof( wcParam ) );
- pwcParam = wcParam;
- }
-
- g_pVGuiLocalize->ConstructString( wcIssue, sizeof(wcIssue), g_pVGuiLocalize->Find( szResult ), 1, pwcParam );
- pwcIssue = wcIssue;
- }
- else
- {
- // No param, just localize the result
- pwcIssue = g_pVGuiLocalize->Find( szResult );
- }
-
- m_pVotePassed->SetDialogVariable( "passedresult", pwcIssue );
-
- SetVoteActive( false );
- m_bVotePassed = true;
- m_flVoteResultCycleTime = gpGlobals->curtime + 2;
- m_flHideTime = gpGlobals->curtime + 5;
-
- // driller: this event has no listeners - will eventually hook into stats
- IGameEvent *event = gameeventmanager->CreateEvent( "vote_passed" );
- if ( event )
- {
- event->SetString( "details", szResult );
- event->SetString( "param1", szParam1 );
- event->SetInt( "team", iTeam );
- gameeventmanager->FireEventClientSide( event );
- }
-
- C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
- if ( !pLocalPlayer )
- return;
-
- pLocalPlayer->EmitSound( "Vote.Passed" );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Creates a UI for Vote Issue selection
-//-----------------------------------------------------------------------------
-void CHudVote::MsgFunc_VoteSetup( bf_read &msg )
-{
- if ( IsPlayingDemo() )
- return;
-
- m_pVoteActive->SetVisible( false );
- m_pVoteFailed->SetVisible( false );
- m_pVotePassed->SetVisible( false );
- m_pCallVoteFailed->SetVisible( false );
-
- C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
- if ( !pLocalPlayer )
- return;
-
- // Load up the list of Vote Issues
- m_VoteSetupIssues.RemoveAll();
- int nIssueCount = msg.ReadByte();
- if ( nIssueCount )
- {
- for ( int index = 0; index < nIssueCount; index++ )
- {
- char szIssue[256];
- msg.ReadString( szIssue, sizeof(szIssue) );
- if ( !m_VoteSetupIssues.HasElement( szIssue ) )
- {
- // Send it over to the listpanel
- m_VoteSetupIssues.CopyAndAddToTail( szIssue );
- }
- }
- }
- else
- {
- m_VoteSetupIssues.CopyAndAddToTail( "Voting disabled on this Server" );
- }
- m_pVoteSetupDialog->AddVoteIssues( m_VoteSetupIssues );
-
- // Load up the list of Vote Issue Parameters
- m_VoteSetupMapCycle.RemoveAll();
-
- // Use the appropriate stringtable for maps based on gamemode
- bool bMvM = false;
- INetworkStringTable *pStringTable = g_pStringTableServerMapCycle;
-
-#ifdef TF_CLIENT_DLL
- if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
- {
- bMvM = true;
- pStringTable = g_pStringTableServerMapCycleMvM;
- }
-#endif // TF_CLIENT_DLL
-
- if ( pStringTable )
- {
- int index = bMvM ? pStringTable->FindStringIndex( "ServerMapCycleMvM" ) : pStringTable->FindStringIndex( "ServerMapCycle" );
- if ( index != ::INVALID_STRING_INDEX )
- {
- int nLength = 0;
- const char *pszMapCycle = (const char *)pStringTable->GetStringUserData( index, &nLength );
- if ( pszMapCycle && pszMapCycle[0] )
- {
- if ( pszMapCycle && nLength )
- {
- V_SplitString( pszMapCycle, "\n", m_VoteSetupMapCycle );
- }
-
- // Alphabetize
- if ( m_VoteSetupMapCycle.Count() )
- {
- m_VoteSetupMapCycle.Sort( m_VoteSetupMapCycle.SortFunc );
- }
- }
- }
- }
-
-#ifdef TF_CLIENT_DLL
- m_VoteSetupPopFiles.RemoveAll();
- if ( g_pStringTableServerPopFiles )
- {
- int index = g_pStringTableServerPopFiles->FindStringIndex( "ServerPopFiles" );
- if ( index != ::INVALID_STRING_INDEX )
- {
- int nLength = 0;
- const char *pszPopFiles = (const char *)g_pStringTableServerPopFiles->GetStringUserData( index, &nLength );
- if ( pszPopFiles && pszPopFiles[0] )
- {
- if ( pszPopFiles && nLength )
- {
- V_SplitString( pszPopFiles, "\n", m_VoteSetupPopFiles );
- }
-
- // Alphabetize
- if ( m_VoteSetupPopFiles.Count() )
- {
- m_VoteSetupPopFiles.Sort( m_VoteSetupPopFiles.SortFunc );
- }
- }
- }
- }
-#endif // TF_CLIENT_DLL
-
- // Now send any data we gathered over to the listpanel
- PropagateOptionParameters();
-
- m_pVoteSetupDialog->Activate();
- m_pVoteSetupDialog->SetVisible( true );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Propagate vote option parameters to the Issue Parameters list
-//-----------------------------------------------------------------------------
-void CHudVote::PropagateOptionParameters( void )
-{
- C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
- if ( !pLocalPlayer )
- return;
-
- m_pVoteSetupDialog->AddVoteIssueParams_MapCycle( m_VoteSetupMapCycle );
-
-#ifdef TF_CLIENT_DLL
- m_pVoteSetupDialog->AddVoteIssueParams_PopFiles( m_VoteSetupPopFiles );
-#endif // TF_CLIENT_DLL
-
- // Insert future issue param data containers here
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudVote::FireGameEvent( IGameEvent *event )
-{
- const char *eventName = event->GetName();
- if ( !eventName )
- return;
-
- C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
- if ( !pLocalPlayer )
- return;
-
- if( FStrEq( eventName, "vote_changed" ) )
- {
- for ( int index = 0; index < MAX_VOTE_OPTIONS; index++ )
- {
- char szOption[2];
- Q_snprintf( szOption, sizeof( szOption ), "%i", index + 1 );
-
- char szVoteOptionCount[13] = "vote_option";
- Q_strncat( szVoteOptionCount, szOption, sizeof( szVoteOptionCount ), COPY_ALL_CHARACTERS );
-
- m_nVoteOptionCount[index] = event->GetInt( szVoteOptionCount );
- }
- m_nPotentialVotes = event->GetInt( "potentialVotes" );
- }
- else if ( FStrEq( eventName, "vote_options" ) )
- {
- m_VoteSetupChoices.RemoveAll();
-
- m_nVoteChoicesCount = event->GetInt( "count" );
- for ( int iIndex = 0; iIndex < m_nVoteChoicesCount; iIndex++ )
- {
- char szNumber[2];
- Q_snprintf( szNumber, sizeof( szNumber ), "%i", iIndex + 1 );
-
- char szOptionName[8] = "option";
- Q_strncat( szOptionName, szNumber, sizeof( szOptionName ), COPY_ALL_CHARACTERS );
-
- const char *pszOptionName = event->GetString( szOptionName );
- m_VoteSetupChoices.CopyAndAddToTail( pszOptionName );
- }
- }
- else if ( FStrEq( eventName, "vote_cast" ) )
- {
- int iPlayer = event->GetInt( "entityid" );
- C_BasePlayer *pPlayer = UTIL_PlayerByIndex( iPlayer );
- if ( pPlayer != pLocalPlayer )
- return;
-
- int vote_option = event->GetInt( "vote_option", TEAM_UNASSIGNED );
- if( vote_option == VOTE_OPTION1 )
- {
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pVoteActive, "PulseOption1" );
- }
- else if( vote_option == VOTE_OPTION2 )
- {
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pVoteActive, "PulseOption2" );
- }
- else if( vote_option == VOTE_OPTION3 )
- {
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pVoteActive, "PulseOption3" );
- }
- else if( vote_option == VOTE_OPTION4 )
- {
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pVoteActive, "PulseOption4" );
- }
- else if( vote_option == VOTE_OPTION5 )
- {
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pVoteActive, "PulseOption5" );
- }
-
- m_bPlayerVoted = true;
-
- bool bForceActive = false;
-#ifdef TF_CLIENT_DLL
- if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
- {
- if ( m_iVoteCallerIdx == GetLocalPlayerIndex() )
- {
- bForceActive = true;
- }
- }
-#endif // TF_CLIENT_DLL
-
- if ( !cl_vote_ui_active_after_voting.GetBool() && !bForceActive )
- {
- m_flPostVotedHideTime = gpGlobals->curtime + 1.5f;
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudVote::OnThink()
-{
- // We delay hiding the menu after we cast a vote
- if ( m_bPlayerVoted && m_flPostVotedHideTime > 0 && m_flPostVotedHideTime < gpGlobals->curtime )
- {
- m_pVoteActive->SetVisible( false );
- m_bShowVoteActivePanel = false;
- m_flPostVotedHideTime = -1;
- }
-
- if ( m_flVoteResultCycleTime > 0 && m_flVoteResultCycleTime < gpGlobals->curtime )
- {
- m_pVoteActive->SetVisible( false );
- m_pVoteFailed->SetVisible( !m_bVotePassed );
- m_pVotePassed->SetVisible( m_bVotePassed );
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pVoteActive, "HideVoteBackgrounds" );
-
- m_flVoteResultCycleTime = -1;
- m_bPlayerVoted = false;
- m_bVoteActive = false;
- m_bShowVoteActivePanel = false;
- m_iVoteCallerIdx = -1;
- }
-
- if ( m_bVoteActive )
- {
- // driller: Need to rewrite this to handle all vote types (Yes/No and General)
- if ( m_bIsYesNoVote && m_pVoteActive )
- {
- char szYesCount[512] = "";
- Q_snprintf( szYesCount, 512, "%d", m_nVoteOptionCount[0] );
-
- char szNoCount[512] = "";
- Q_snprintf( szNoCount, 512, "%d", m_nVoteOptionCount[1] );
-
- m_pVoteActive->SetControlString( "Option1CountLabel", szYesCount );
- m_pVoteActive->SetControlString( "Option2CountLabel", szNoCount );
- }
-
- if ( !m_pVoteActive->IsVisible() && m_bShowVoteActivePanel )
- {
- m_pVoteActive->SetVisible( true );
-
- C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
- if ( pLocalPlayer )
- {
- pLocalPlayer->EmitSound("Vote.Created");
- }
- }
- }
-
- BaseClass::OnThink();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool CHudVote::ShouldDraw( void )
-{
- return ( m_bVoteActive || m_flHideTime > gpGlobals->curtime );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool CHudVote::IsPlayingDemo() const
-{
- return engine->IsPlayingDemo();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudVote::SetVoteActive( bool bActive )
-{
- m_bVoteActive = bActive;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CHudVote::ShowVoteUI( void )
-{
- m_bShowVoteActivePanel = true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool CHudVote::IsVoteUIActive( void )
-{
- return m_bShowVoteActivePanel;
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +//===========================================================================// + + +#include "cbase.h" +#include "hud.h" +#include "hudelement.h" +#include "hud_macros.h" +#include "hud_numericdisplay.h" +#include "iclientmode.h" +#include "clientmode_shared.h" +#include "VGuiMatSurface/IMatSystemSurface.h" +#include "materialsystem/imaterial.h" +#include "materialsystem/imesh.h" +#include "materialsystem/imaterialvar.h" +#include "con_nprint.h" +#include "hud_vote.h" +#include "menu.h" + +#include <vgui/IScheme.h> +#include <vgui/ISurface.h> +#include <vgui/ILocalize.h> +#include <KeyValues.h> +#include <vgui_controls/AnimationController.h> +#include <vgui_controls/EditablePanel.h> +#include <vgui_controls/Label.h> +#include <vgui_controls/ComboBox.h> +#include <vgui_controls/ImageList.h> +#include "vgui_avatarimage.h" + +#ifdef TF_CLIENT_DLL +#include "ienginevgui.h" +#include "tf_gcmessages.h" +#include "c_tf_player.h" +#include "econ_notifications.h" +#include "confirm_dialog.h" +#include "gc_clientsystem.h" +#include "tf_gamerules.h" +#include "c_playerresource.h" +#include "c_tf_objective_resource.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +ConVar cl_vote_ui_active_after_voting( "cl_vote_ui_active_after_voting", "0" ); +ConVar cl_vote_ui_show_notification( "cl_vote_ui_show_notification", "0" ); + +#ifdef TF_CLIENT_DLL + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CTFVoteNotification : public CEconNotification +{ +public: + CTFVoteNotification( const char *pPlayerName ) : CEconNotification() + { + g_pVGuiLocalize->ConvertANSIToUnicode( pPlayerName, m_wszPlayerName, sizeof(m_wszPlayerName) ); + SetLifetime( 7 ); + SetText( "#Vote_notification_text" ); + AddStringToken( "initiator", m_wszPlayerName ); + } + virtual bool CanBeTriggered() + { + return true; + } + virtual void Trigger() + { + CTFGenericConfirmDialog *pDialog = ShowConfirmDialog( "#Vote_notification_title", "#Vote_notification_text", "#Vote_notification_view", "#cancel", &ConfirmShowVoteSetup ); + pDialog->SetContext( this ); + pDialog->AddStringToken( "initiator", m_wszPlayerName ); + // so we aren't deleted + SetIsInUse( true ); + } + virtual bool CanBeAcceptedOrDeclined() + { + return true; + } + virtual void Accept() + { + ConfirmShowVoteSetup( true, this ); + } + virtual void Decline() + { + ConfirmShowVoteSetup( false, this ); + } + static void ConfirmShowVoteSetup( bool bConfirmed, void *pContext ) + { + CTFVoteNotification *pNotification = (CTFVoteNotification*)pContext; + if ( bConfirmed ) + { + // Show vote + CHudVote *pHudVote = GET_HUDELEMENT( CHudVote ); + if ( pHudVote ) + { + pHudVote->ShowVoteUI(); + } + } + pNotification->SetIsInUse( false ); + pNotification->MarkForDeletion(); + } + +public: + wchar_t m_wszPlayerName[MAX_PLAYER_NAME_LENGTH]; +}; +#endif // TF_CLIENT_DLL + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +VoteBarPanel::VoteBarPanel( vgui::Panel *parent, const char *panelName ) : vgui::Panel( parent, panelName ) +{ + for( int index = 0; index < MAX_VOTE_OPTIONS; index++ ) + { + m_nVoteOptionCount[index] = 0; + } + m_nPotentialVotes = 0; + + ListenForGameEvent( "vote_changed" ); +} + +void VoteBarPanel::Paint( void ) +{ + int wide, tall; + GetSize( wide, tall ); + + int x = 0; + + // driller: this shouldn't ship - temp UI solution for playtesting + for ( int i = 0; i < 2; i++ ) + { + // Draw an outlined box + vgui::surface()->DrawSetColor( 128, 128, 128, 128 ); + vgui::surface()->DrawFilledRect( x, 0, x + m_iBoxSize, m_iBoxSize ); + + vgui::surface()->DrawSetColor( 0, 0, 0, 255 ); + vgui::surface()->DrawFilledRect( x + m_iBoxInset, m_iBoxInset, x + m_iBoxSize - m_iBoxInset, m_iBoxSize - m_iBoxInset ); + + vgui::surface()->DrawSetColor( Color(255, 255, 255, 255) ); + + x += ( m_iBoxSize + 64 ); + } + + x = 0; + + int iImageInset = 2 * m_iBoxInset; + + // Yes image + vgui::surface()->DrawSetTexture( m_nYesTextureId ); + vgui::surface()->DrawTexturedRect( x + iImageInset, iImageInset, x + m_iBoxSize - iImageInset, m_iBoxSize - iImageInset ); + + x += ( m_iBoxSize + 64 ); + + // No image + vgui::surface()->DrawSetTexture( m_nNoTextureId ); + vgui::surface()->DrawTexturedRect( x + iImageInset, iImageInset, x + m_iBoxSize - iImageInset, m_iBoxSize - iImageInset ); + +} + +void VoteBarPanel::FireGameEvent( IGameEvent *event ) +{ + const char *eventName = event->GetName(); + if ( !eventName ) + return; + + if( FStrEq( eventName, "vote_changed" ) ) + { + for ( int index = 0; index < MAX_VOTE_OPTIONS; index++ ) + { + char szOption[2]; + Q_snprintf( szOption, sizeof( szOption ), "%i", index + 1 ); + + char szVoteOption[13] = "vote_option"; + Q_strncat( szVoteOption, szOption, sizeof( szVoteOption ), COPY_ALL_CHARACTERS ); + + m_nVoteOptionCount[index] = event->GetInt( szVoteOption ); + } + m_nPotentialVotes = event->GetInt( "potentialVotes" ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +CVoteSetupDialog::CVoteSetupDialog( vgui::Panel *parent ) : BaseClass( parent, "VoteSetupDialog" ) +{ + SetMoveable( false ); + SetSizeable( false ); + + m_pVoteSetupList = new SectionedListPanel( this, "VoteSetupList" ); + m_pVoteParameterList = new SectionedListPanel( this, "VoteParameterList" ); + m_pCallVoteButton = new Button( this, "CallVoteButton", "CallVote", this, "CallVote" ); + m_pComboBox = new ComboBox( this, "ComboBox", 5, false ); + m_pImageList = NULL; + +#ifdef TF_CLIENT_DLL + vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme"); + SetScheme(scheme); +#else + SetScheme( "ClientScheme" ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: Destructor +//----------------------------------------------------------------------------- +CVoteSetupDialog::~CVoteSetupDialog() +{ + if ( m_pImageList ) + { + delete m_pImageList; + m_pImageList = NULL; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CVoteSetupDialog::ApplySchemeSettings( vgui::IScheme *pScheme ) +{ + BaseClass::ApplySchemeSettings( pScheme ); + + SetProportional( true ); + + LoadControlSettings( "Resource/UI/VoteHud.res" ); + + m_pComboBox->GetComboButton()->SetFgColor( Color( 117,107,94,255 ) ); + m_pComboBox->GetComboButton()->SetDefaultColor( Color( 117,107,94,255), Color( 0,0,0,0) ); + m_pComboBox->GetComboButton()->SetArmedColor( Color( 117,107,94,255), Color( 0,0,0,0) ); + m_pComboBox->GetComboButton()->SetDepressedColor( Color( 117,107,94,255), Color( 0,0,0,0) ); + + if ( m_pImageList ) + { + delete m_pImageList; + } + + m_pImageList = new ImageList( false ); +} + +//----------------------------------------------------------------------------- +// Purpose: Does dialog-specific customization after applying scheme settings. +//----------------------------------------------------------------------------- +void CVoteSetupDialog::PostApplySchemeSettings( vgui::IScheme *pScheme ) +{ + // resize the images to our resolution + for ( int i = 0; i < m_pImageList->GetImageCount(); i++ ) + { + int wide, tall; + m_pImageList->GetImage( i )->GetSize( wide, tall ); + m_pImageList->GetImage( i )->SetSize(scheme()->GetProportionalScaledValueEx( GetScheme(), wide ), scheme()->GetProportionalScaledValueEx( GetScheme(), tall ) ); + } + + m_pVoteParameterList->SetImageList( m_pImageList, false ); + m_pVoteParameterList->SetVisible( true ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CVoteSetupDialog::ApplySettings(KeyValues *inResourceData) +{ + BaseClass::ApplySettings( inResourceData ); + + IScheme *pScheme = scheme()->GetIScheme( GetScheme() ); + + m_hIssueFont = INVALID_FONT; + const char *pszFont = inResourceData->GetString( "issue_font", NULL ); + if ( pszFont && pszFont[0] ) + { + m_hIssueFont = pScheme->GetFont( pszFont, true ); + } + + m_hHeaderFont = INVALID_FONT; + pszFont = inResourceData->GetString( "header_font", NULL ); + if ( pszFont && pszFont[0] ) + { + m_hHeaderFont = pScheme->GetFont( pszFont, true ); + } + + const char *pszColor = inResourceData->GetString( "issue_fgcolor", "Label.TextColor" ); + m_IssueFGColor = pScheme->GetColor( pszColor, Color( 255, 255, 255, 255 ) ); + + pszColor = inResourceData->GetString( "issue_fgcolor_disabled", "Label.TextColor" ); + m_IssueFGColorDisabled = pScheme->GetColor( pszColor, Color( 255, 255, 255, 255 ) ); + + pszColor = inResourceData->GetString( "header_fgcolor", "Label.TextColor" ); + m_HeaderFGColor = pScheme->GetColor( pszColor, Color( 255, 255, 255, 255 ) ); +} + +//----------------------------------------------------------------------------- +// Purpose: Keep track of the current map +//----------------------------------------------------------------------------- +void CVoteSetupDialog::UpdateCurrentMap( void ) +{ + Q_FileBase( engine->GetLevelName(), m_szCurrentMap, sizeof(m_szCurrentMap) ); + Q_strlower( m_szCurrentMap ); +} + +//----------------------------------------------------------------------------- +// Purpose: Feeds Issues from the server to this Dialog +//----------------------------------------------------------------------------- +void CVoteSetupDialog::AddVoteIssues( CUtlStringList &m_VoteSetupIssues ) +{ + m_VoteIssues.RemoveAll(); + for ( int index = 0; index < m_VoteSetupIssues.Count(); index++ ) + { + m_VoteIssues.AddToTail( m_VoteSetupIssues[index] ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Feeds the server's MapCycle to the parameters dialog +//----------------------------------------------------------------------------- +void CVoteSetupDialog::AddVoteIssueParams_MapCycle( CUtlStringList &m_VoteSetupMapCycle ) +{ + m_VoteIssuesMapCycle.RemoveAll(); + for ( int index = 0; index < m_VoteSetupMapCycle.Count(); index++ ) + { + m_VoteIssuesMapCycle.AddToTail( m_VoteSetupMapCycle[index] ); + } +} + +#ifdef TF_CLIENT_DLL +//----------------------------------------------------------------------------- +// Purpose: Feeds the server's PopFiles to the parameters dialog +//----------------------------------------------------------------------------- +void CVoteSetupDialog::AddVoteIssueParams_PopFiles( CUtlStringList &m_VoteSetupPopFiles ) +{ + m_VoteIssuesPopFiles.RemoveAll(); + for ( int index = 0; index < m_VoteSetupPopFiles.Count(); index++ ) + { + m_VoteIssuesPopFiles.AddToTail( m_VoteSetupPopFiles[index] ); + } +} +#endif // TF_CLIENT_DLL + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CVoteSetupDialog::Activate() +{ + InvalidateLayout( true, true ); + + BaseClass::Activate(); + + ResetData(); + + m_pVoteSetupList->SetVerticalScrollbar( true ); + m_pVoteSetupList->RemoveAll(); + m_pVoteSetupList->RemoveAllSections(); + m_pVoteSetupList->AddSection( 0, "Issue" ); + m_pVoteSetupList->SetSectionAlwaysVisible( 0, true ); + m_pVoteSetupList->SetSectionFgColor( 0, Color( 255, 255, 255, 255 ) ); + m_pVoteSetupList->SetBgColor( Color( 0, 0, 0, 0 ) ); + m_pVoteSetupList->SetBorder( NULL ); + m_pVoteSetupList->AddColumnToSection( 0, "Issue", "#TF_Vote_Column_Issue", SectionedListPanel::COLUMN_CENTER, m_iIssueWidth ); + + if ( m_hHeaderFont != INVALID_FONT ) + { + m_pVoteSetupList->SetFontSection( 0, m_hHeaderFont ); + m_pVoteSetupList->SetSectionFgColor( 0, m_HeaderFGColor ); + } + + m_pVoteParameterList->SetVerticalScrollbar( true ); + m_pVoteParameterList->RemoveAll(); + m_pVoteParameterList->RemoveAllSections(); + m_pVoteParameterList->AddSection( 0, "Name" ); + m_pVoteParameterList->SetSectionAlwaysVisible( 0, true ); + m_pVoteParameterList->SetSectionFgColor( 0, Color( 255, 255, 255, 255 ) ); + m_pVoteParameterList->SetBgColor( Color( 0, 0, 0, 0 ) ); + m_pVoteParameterList->SetBorder( NULL ); + m_pVoteParameterList->AddColumnToSection( 0, "Avatar", "", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_RIGHT, 55 ); + m_pVoteParameterList->AddColumnToSection( 0, "", "", 0, 10 ); // Spacer + m_pVoteParameterList->AddColumnToSection( 0, "Name", "#TF_Vote_Column_Name", 0, m_iParameterWidth * 0.6 ); + m_pVoteParameterList->AddColumnToSection( 0, "Properties", "#TF_Vote_Column_Properties", SectionedListPanel::COLUMN_CENTER, m_iParameterWidth * 0.3 ); + + if ( m_hHeaderFont != INVALID_FONT ) + { + m_pVoteParameterList->SetFontSection( 0, m_hHeaderFont ); + m_pVoteParameterList->SetSectionFgColor( 0, m_HeaderFGColor ); + m_pVoteParameterList->SetFontSection( 1, m_hHeaderFont ); + m_pVoteParameterList->SetSectionFgColor( 1, m_HeaderFGColor ); + } + + // Populate the Issue list + for ( int index = 0; index < m_VoteIssues.Count(); index++ ) + { + const char *pszIssue = m_VoteIssues[index]; + if ( !pszIssue || !pszIssue[0] ) + continue; + + KeyValues *pKeyValues = new KeyValues( "Issue" ); + pKeyValues->SetString( "Issue", pszIssue ); + int iId = m_pVoteSetupList->AddItem( 0, pKeyValues ); + pKeyValues->deleteThis(); + + // Setup the list entry style + if ( m_hIssueFont != INVALID_FONT ) + { + m_pVoteSetupList->SetItemFont( iId, m_hIssueFont ); + + bool bDisabled = V_stristr( pszIssue, "(Disabled on Server)" ); // driller: need to localize + Color colFG = bDisabled ? m_IssueFGColorDisabled : m_IssueFGColor; + m_pVoteSetupList->SetItemFgColor( iId, colFG ); + } + } + + // Select the first item by default + if ( m_pVoteSetupList->GetItemCount() > 0 ) + { + m_pVoteSetupList->SetSelectedItem( 0 ); + } + + UpdateCurrentMap(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CVoteSetupDialog::OnClose() +{ + ResetData(); + BaseClass::OnClose(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CVoteSetupDialog::OnCommand(const char *command) +{ + // We should have enough data to issue a CallVote command + if ( V_stricmp( command, "CallVote" ) == 0 ) + { + int iSelectedItem = m_pVoteSetupList->GetSelectedItem(); + if ( iSelectedItem >= 0 ) + { + char szVoteCommand[128]; + KeyValues *pIssueKeyValues = m_pVoteSetupList->GetItemData( iSelectedItem ); + const char *szIssue = pIssueKeyValues->GetString( "Issue" ); + if ( V_stricmp( "changelevel", szIssue ) == 0 || V_stricmp( "nextlevel", szIssue ) == 0 ) + { + int nSelectedParam = m_pVoteParameterList->GetSelectedItem(); + if ( nSelectedParam >= 0 ) + { + // Get selected Map + int iSelectedParam = m_pVoteParameterList->GetSelectedItem(); + if ( iSelectedParam >= 0 ) + { + KeyValues *pParameterKeyValues = m_pVoteParameterList->GetItemData( iSelectedParam ); + if ( pParameterKeyValues ) + { + // Which Map? + const char *szMapName = pParameterKeyValues->GetString( "Name" ); + Q_snprintf( szVoteCommand, sizeof( szVoteCommand ), "callvote %s %s\n;", szIssue, szMapName ); + engine->ClientCmd( szVoteCommand ); + } + } + } + } + else if ( V_stricmp( "kick", szIssue ) == 0 ) + { + // Get selected Player + int iSelectedParam = m_pVoteParameterList->GetSelectedItem(); + if ( iSelectedParam >= 0 ) + { + KeyValues *pKeyValues = m_pVoteParameterList->GetItemData( iSelectedParam ); + if ( pKeyValues ) + { + // Is Player valid? + int playerIndex = pKeyValues->GetInt( "index" ); + const char *pReasonString = m_pComboBox->GetActiveItemUserData() ? m_pComboBox->GetActiveItemUserData()->GetName() : "other"; + player_info_t playerInfo; + if ( engine->GetPlayerInfo( playerIndex, &playerInfo ) ) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex( playerIndex ); + Q_snprintf( szVoteCommand, sizeof( szVoteCommand ), "callvote %s \"%d %s\"\n;", szIssue, pPlayer->GetUserID(), pReasonString ); + engine->ClientCmd( szVoteCommand ); +#ifdef TF_CLIENT_DLL + CSteamID steamID; + CTFPlayer* pSubject = ToTFPlayer( pPlayer ); + if ( pSubject && pSubject->GetSteamID( &steamID ) && steamID.GetAccountID() != 0 ) + { + GCSDK::CProtoBufMsg<CMsgTFVoteKickBanPlayer> msg( k_EMsgGCVoteKickBanPlayer ); + uint32 reason = GetKickBanPlayerReason( pReasonString ); + msg.Body().set_account_id_subject( steamID.GetAccountID() ); + msg.Body().set_kick_reason( reason ); + GCClientSystem()->BSendMessage( msg ); + } +#endif + } + } + } + } +#ifdef TF_CLIENT_DLL + else if ( V_stricmp( "ChangeMission", szIssue ) == 0 ) + { + int nSelectedParam = m_pVoteParameterList->GetSelectedItem(); + if ( nSelectedParam >= 0 ) + { + // Get selected Challenge + int iSelectedParam = m_pVoteParameterList->GetSelectedItem(); + if ( iSelectedParam >= 0 ) + { + KeyValues *pParameterKeyValues = m_pVoteParameterList->GetItemData( iSelectedParam ); + if ( pParameterKeyValues ) + { + // Which Pop File? + const char *szPopFile = pParameterKeyValues->GetString( "Name" ); + Q_snprintf( szVoteCommand, sizeof( szVoteCommand ), "callvote %s %s\n;", szIssue, szPopFile ); + engine->ClientCmd( szVoteCommand ); + } + } + } + } +#endif // TF_CLIENT_DLL + else + { + // Non-parameter vote. i.e. callvote scrambleteams + Q_snprintf( szVoteCommand, sizeof(szVoteCommand), "callvote %s\n;", szIssue ); + engine->ClientCmd( szVoteCommand ); + } + + Close(); + } + } + else + { + BaseClass::OnCommand( command ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CVoteSetupDialog::OnItemSelected( vgui::Panel *panel ) +{ + if ( panel == m_pVoteSetupList ) + { + m_pComboBox->RemoveAll(); + m_pComboBox->SetVisible( false ); + SetDialogVariable( "combo_label", "" ); + + // Which Issue did we select? + int iSelectedItem = m_pVoteSetupList->GetSelectedItem(); + if ( iSelectedItem >= 0 ) + { + KeyValues *pIssueKeyValues = m_pVoteSetupList->GetItemData( iSelectedItem ); + if ( !pIssueKeyValues ) + return; + + // We're rebuilding, so clear state + m_bVoteButtonEnabled = false; + m_pVoteParameterList->ClearSelection(); + m_pVoteParameterList->RemoveAll(); + + const char *szName = pIssueKeyValues->GetString( "Issue" ); + if ( V_stricmp( "Voting disabled on this Server", szName ) == 0 ) + { + m_bVoteButtonEnabled = false; + } + else if ( V_stristr( szName, "(Disabled on Server)" ) ) // driller: need to localize + { + m_bVoteButtonEnabled = false; + } + // CHANGELEVEL / NEXTLEVEL + else if ( V_stricmp( "changelevel", szName ) == 0 || V_stricmp( "nextlevel", szName ) == 0 ) + { + // Feed the mapcycle to the parameters list + for ( int index = 0; index < m_VoteIssuesMapCycle.Count(); index++ ) + { + // Don't show the current map + if ( V_strncmp( m_VoteIssuesMapCycle[index], m_szCurrentMap, ( V_strlen( m_VoteIssuesMapCycle[index] ) - 1 ) ) == 0 ) + continue; + + KeyValues *pKeyValues = new KeyValues( "Name" ); + pKeyValues->SetString( "Name", m_VoteIssuesMapCycle[index] ); + pKeyValues->SetInt( "index", index ); + int iId = m_pVoteParameterList->AddItem( 0, pKeyValues ); + pKeyValues->deleteThis(); + + if ( m_hIssueFont != INVALID_FONT ) + { + m_pVoteParameterList->SetItemFont( iId, m_hIssueFont ); + m_pVoteParameterList->SetItemFgColor( iId, m_IssueFGColor ); + } + } + + if ( m_pVoteParameterList->GetItemCount() == 0 ) + { + KeyValues *pKeyValues = new KeyValues( "Name" ); + pKeyValues->SetString( "Name", "#TF_vote_no_maps" ); + pKeyValues->SetInt( "index", 1 ); + m_pVoteParameterList->AddItem( 0, pKeyValues ); + pKeyValues->deleteThis(); + } + } + // KICK + else if ( V_stricmp( "kick", szName ) == 0 ) + { + // Feed the player list to the parameters list + int nMaxClients = engine->GetMaxClients(); + for ( int playerIndex = 1; playerIndex <= nMaxClients; playerIndex++ ) + { + C_BasePlayer *pPlayer = UTIL_PlayerByIndex( playerIndex ); + if ( !pPlayer ) + continue; + + C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); + if ( !pLocalPlayer ) + continue; + + if ( pPlayer == pLocalPlayer ) + continue; + + bool bAllowKickUnassigned = false; +#ifdef TF_CLIENT_DLL + // Allow kicking team unassigned in MvM + if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() && g_PR->IsConnected( playerIndex ) && pPlayer->GetTeamNumber() == TEAM_UNASSIGNED ) + { + bAllowKickUnassigned = true; + } +#endif // TF_CLIENT_DLL + + // Can't kick people on the other team, so don't list them + if ( pPlayer->GetTeam() != pLocalPlayer->GetTeam() && !bAllowKickUnassigned ) + continue; + + char szPlayerIndex[32]; + Q_snprintf( szPlayerIndex, sizeof( szPlayerIndex ), "%d", playerIndex ); + + KeyValues *pKeyValues = new KeyValues( szPlayerIndex ); + pKeyValues->SetString( "Name", pPlayer->GetPlayerName() ); + pKeyValues->SetInt( "index", playerIndex ); + int iId = m_pVoteParameterList->AddItem( 0, pKeyValues ); + pKeyValues->deleteThis(); + + if ( m_hIssueFont != INVALID_FONT ) + { + m_pVoteParameterList->SetItemFont( iId, m_hIssueFont ); + m_pVoteParameterList->SetItemFgColor( iId, m_IssueFGColor ); + } + } + +#ifdef TF_CLIENT_DLL + SetDialogVariable( "combo_label", g_pVGuiLocalize->Find( "#TF_VoteKickReason" ) ); + m_pComboBox->AddItem( g_pVGuiLocalize->Find( "TF_VoteKickReason_Other" ), new KeyValues( "other" ) ); + m_pComboBox->AddItem( g_pVGuiLocalize->Find( "TF_VoteKickReason_Cheating" ), new KeyValues( "cheating" ) ); + m_pComboBox->AddItem( g_pVGuiLocalize->Find( "TF_VoteKickReason_Idle" ), new KeyValues( "idle" ) ); + m_pComboBox->AddItem( g_pVGuiLocalize->Find( "TF_VoteKickReason_Scamming" ), new KeyValues( "scamming" ) ); + m_pComboBox->SilentActivateItemByRow( 0 ); + m_pComboBox->SetVisible( true ); +#endif + } +#ifdef TF_CLIENT_DLL + // CHANGE POP FILE + else if ( V_stricmp( "ChangeMission", szName ) == 0 ) + { + // Feed the popfiles to the parameters list + for ( int index = 0; index < m_VoteIssuesPopFiles.Count(); index++ ) + { + // Don't show the current pop file + if ( TFObjectiveResource()->GetMvMPopFileName() == '\0' ) + { + // Use the map name + char szShortMapName[ MAX_MAP_NAME ]; + V_strncpy( szShortMapName, engine->GetLevelName(), sizeof( szShortMapName ) ); + V_StripExtension( szShortMapName, szShortMapName, sizeof( szShortMapName ) ); + + if ( V_strncmp( m_VoteIssuesPopFiles[index], V_GetFileName( szShortMapName ), ( V_strlen( m_VoteIssuesPopFiles[index] ) - 1 ) ) == 0 ) + continue; + } + else + { + // Use the specified pop file + if ( V_strncmp( m_VoteIssuesPopFiles[index], TFObjectiveResource()->GetMvMPopFileName(), ( V_strlen( m_VoteIssuesPopFiles[index] ) - 1 ) ) == 0 ) + continue; + } + + KeyValues *pKeyValues = new KeyValues( "Name" ); + pKeyValues->SetString( "Name", m_VoteIssuesPopFiles[index] ); + pKeyValues->SetInt( "index", index ); + int iId = m_pVoteParameterList->AddItem( 0, pKeyValues ); + pKeyValues->deleteThis(); + + if ( m_hIssueFont != INVALID_FONT ) + { + m_pVoteParameterList->SetItemFont( iId, m_hIssueFont ); + m_pVoteParameterList->SetItemFgColor( iId, m_IssueFGColor ); + } + } + + if ( m_pVoteParameterList->GetItemCount() == 0 ) + { + KeyValues *pKeyValues = new KeyValues( "Name" ); + pKeyValues->SetString( "Name", "#TF_vote_no_challenges" ); + pKeyValues->SetInt( "index", 1 ); + m_pVoteParameterList->AddItem( 0, pKeyValues ); + pKeyValues->deleteThis(); + } + } +#endif // TF_CLIENT_DLL + else + { + // User selected an issue that doesn't require a parameter - Scrambleteams, Restartgame, etc + m_bVoteButtonEnabled = true; + } + } + } + else if ( panel == m_pVoteParameterList ) + { + // If this issue requires a parameter, make sure we have one selected before enabling the CallVote button + int iSelectedParam = m_pVoteParameterList->GetSelectedItem(); + if ( iSelectedParam >= 0 ) + { + KeyValues *pParameterKeyValues = m_pVoteParameterList->GetItemData( iSelectedParam ); + if ( pParameterKeyValues ) + { + const char *szParameterName = pParameterKeyValues->GetString( "Name" ); + if ( szParameterName ) + { + m_bVoteButtonEnabled = true; + } + } + } + } + + m_pCallVoteButton->SetEnabled( m_bVoteButtonEnabled ); + RefreshIssueParameters(); +} + +//----------------------------------------------------------------------------- +// Purpose: Updates any additional data/info on Vote issue parameters +//----------------------------------------------------------------------------- +void CVoteSetupDialog::RefreshIssueParameters() +{ + // In the case of the KICK issue, we list players and show additional properties (Bot, Disconnected) + int iSelectedItem = m_pVoteSetupList->GetSelectedItem(); + if ( iSelectedItem >= 0 ) + { + KeyValues *pIssueKeyValues = m_pVoteSetupList->GetItemData( iSelectedItem ); + const char *szName = pIssueKeyValues->GetString( "Issue" ); + if ( V_stricmp( "kick", szName ) == 0 ) + { + if ( m_pVoteParameterList->GetItemCount() > 0 ) + { + for ( int index = 0; index < m_pVoteParameterList->GetItemCount(); index++ ) + { + KeyValues *pKeyValues = m_pVoteParameterList->GetItemData( index ); + if ( !pKeyValues ) + continue; + + int playerIndex = pKeyValues->GetInt( "index" ); + player_info_t playerInfo; + + if ( !engine->GetPlayerInfo( playerIndex, &playerInfo ) ) + { + pKeyValues->SetString( "Properties", "Offline" ); + continue; + } + + pKeyValues->SetString( "Name", playerInfo.name ); + + if ( playerInfo.fakeplayer ) + { + pKeyValues->SetString( "Properties", "Bot" ); + } + else + { + pKeyValues->SetString( "Properties", "" ); + } + + CSteamID steamID; + C_BasePlayer* pPlayer = UTIL_PlayerByIndex( playerIndex ); + if ( pPlayer && pPlayer->GetSteamID( &steamID ) && steamID.GetAccountID() != 0 ) + { + CAvatarImage *pAvatar = new CAvatarImage(); + pAvatar->SetAvatarSteamID( steamID ); + pAvatar->SetAvatarSize( 32, 32 ); + int iImageIndex = m_pImageList->AddImage( pAvatar ); + pKeyValues->SetInt( "Avatar", iImageIndex ); + } + + m_pVoteParameterList->InvalidateItem( index ); + } + + m_pVoteParameterList->SetImageList( m_pImageList, false ); + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CVoteSetupDialog::ResetData() +{ + m_bVoteButtonEnabled = false; + m_pVoteSetupList->DeleteAllItems(); + m_pVoteParameterList->DeleteAllItems(); + m_pComboBox->DeleteAllItems(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +DECLARE_HUDELEMENT( CHudVote ); +DECLARE_HUD_MESSAGE( CHudVote, CallVoteFailed ); +DECLARE_HUD_MESSAGE( CHudVote, VoteStart ); +DECLARE_HUD_MESSAGE( CHudVote, VotePass ); +DECLARE_HUD_MESSAGE( CHudVote, VoteFailed ); +DECLARE_HUD_MESSAGE( CHudVote, VoteSetup ); + +//----------------------------------------------------------------------------- +// Purpose: Handles all UI for Voting +//----------------------------------------------------------------------------- +CHudVote::CHudVote( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "CHudVote" ) +{ + vgui::Panel *pParent = g_pClientMode->GetViewport(); + SetParent( pParent ); + +#ifdef TF_CLIENT_DLL + vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme"); + SetScheme(scheme); +#endif + + SetHiddenBits( 0 ); + for( int index = 0; index < MAX_VOTE_OPTIONS; index++ ) + { + m_nVoteOptionCount[index] = 0; + } + m_pVoteActive = new EditablePanel( this, "VoteActive" ); + m_voteBar = new VoteBarPanel( m_pVoteActive, "VoteBar" ); + m_pVoteFailed = new EditablePanel( this, "VoteFailed" ); + m_pVotePassed = new EditablePanel( this, "VotePassed" ); + m_pCallVoteFailed = new EditablePanel( this, "CallVoteFailed" ); + m_pVoteSetupDialog = new CVoteSetupDialog( pParent ); + + RegisterForRenderGroup( "mid" ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudVote::ApplySchemeSettings( vgui::IScheme *pScheme ) +{ + BaseClass::ApplySchemeSettings( pScheme ); + + SetProportional( true ); + + LoadControlSettings( "Resource/UI/VoteHud.res" ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudVote::Init( void ) +{ + ListenForGameEvent( "vote_changed" ); + ListenForGameEvent( "vote_options" ); + ListenForGameEvent( "vote_cast" ); + + SetVoteActive( false ); + m_flVoteResultCycleTime = -1; + m_flHideTime = -1; + m_bIsYesNoVote = true; + m_bPlayerVoted = false; + m_nVoteChoicesCount = 2; // Yes/No is the default + m_bShowVoteActivePanel = false; + m_iVoteCallerIdx = -1; + + HOOK_HUD_MESSAGE( CHudVote, CallVoteFailed ); + HOOK_HUD_MESSAGE( CHudVote, VoteStart ); + HOOK_HUD_MESSAGE( CHudVote, VotePass ); + HOOK_HUD_MESSAGE( CHudVote, VoteFailed ); + HOOK_HUD_MESSAGE( CHudVote, VoteSetup ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudVote::LevelInit( void ) +{ + SetVoteActive( false ); + m_flVoteResultCycleTime = -1; + m_flHideTime = -1; + m_flPostVotedHideTime = -1; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CHudVote::KeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding ) +{ + if ( !IsVisible() ) + return 1; + + if ( !down ) + return 1; + + if ( !m_bVoteActive ) + return 1; + + if ( m_bPlayerVoted ) + return 1; + + if ( !m_bShowVoteActivePanel ) + return 1; + + int nSlot = 999; + + if ( down && keynum == KEY_F1 ) + { + nSlot = 1; + } + else if ( down && keynum == KEY_F2 ) + { + nSlot = 2; + } + else if ( down && keynum == KEY_F3 ) + { + nSlot = 3; + } + else if ( down && keynum == KEY_F4 ) + { + nSlot = 4; + } + else if ( down && keynum == KEY_F5 ) + { + nSlot = 5; + } + else + { + return 1; + } + + // Limit key checking to the number of options + if ( nSlot > m_nVoteChoicesCount ) + return 1; + + char szNumber[2]; + Q_snprintf( szNumber, sizeof( szNumber ), "%i", nSlot ); + + char szOptionName[13] = "vote option"; + Q_strncat( szOptionName, szNumber, sizeof( szOptionName ), COPY_ALL_CHARACTERS ); + + engine->ClientCmd( szOptionName ); + + return 0; +} + +//----------------------------------------------------------------------------- +// Purpose: Sent only to the caller +//----------------------------------------------------------------------------- +void CHudVote::MsgFunc_CallVoteFailed( bf_read &msg ) +{ + if ( IsPlayingDemo() ) + return; + + vote_create_failed_t nReason = (vote_create_failed_t)msg.ReadByte(); + int nTime = msg.ReadShort(); + + // if we're already drawing a vote, do nothing + if ( ShouldDraw() ) + return; + + C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); + if ( !pLocalPlayer ) + return; + + pLocalPlayer->EmitSound("Vote.Failed"); + + m_pVoteActive->SetVisible( false ); + m_pVoteFailed->SetVisible( false ); + m_pVotePassed->SetVisible( false ); + m_pCallVoteFailed->SetVisible( true ); + m_pVoteSetupDialog->SetVisible( false ); + + m_flHideTime = gpGlobals->curtime + 4.0; + + char szTime[256]; + wchar_t wszTime[256]; + Q_snprintf( szTime, sizeof ( szTime), "%i", nTime ); + g_pVGuiLocalize->ConvertANSIToUnicode( szTime, wszTime, sizeof( wszTime ) ); + + wchar_t wszHeaderString[512]; + wchar_t *pwszHeaderString; + + switch( nReason ) + { + case VOTE_FAILED_GENERIC: + m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed" ); + break; + + case VOTE_FAILED_TRANSITIONING_PLAYERS: + m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_transition_vote" ); + break; + + case VOTE_FAILED_RATE_EXCEEDED: + g_pVGuiLocalize->ConstructString( wszHeaderString, sizeof(wszHeaderString), g_pVGuiLocalize->Find( "#GameUI_vote_failed_vote_spam" ), 1, wszTime ); + pwszHeaderString = wszHeaderString; + m_pCallVoteFailed->SetDialogVariable( "FailedReason", pwszHeaderString ); + break; + + case VOTE_FAILED_ISSUE_DISABLED: + m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_disabled_issue" ); + break; + + case VOTE_FAILED_MAP_NOT_FOUND: + m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_map_not_found" ); + break; + + case VOTE_FAILED_MAP_NOT_VALID: + m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_map_not_valid" ); + break; + + case VOTE_FAILED_MAP_NAME_REQUIRED: + m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_map_name_required" ); + break; + + case VOTE_FAILED_FAILED_RECENTLY: + g_pVGuiLocalize->ConstructString( wszHeaderString, sizeof(wszHeaderString), g_pVGuiLocalize->Find( "#GameUI_vote_failed_recently" ), 1, wszTime ); + pwszHeaderString = wszHeaderString; + m_pCallVoteFailed->SetDialogVariable( "FailedReason", pwszHeaderString ); + break; + + case VOTE_FAILED_TEAM_CANT_CALL: + m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_team_cant_call" ); + break; + + case VOTE_FAILED_WAITINGFORPLAYERS: + m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_waitingforplayers" ); + break; + + case VOTE_FAILED_CANNOT_KICK_ADMIN: + m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_cannot_kick_admin" ); + break; + + case VOTE_FAILED_SCRAMBLE_IN_PROGRESS: + m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_scramble_in_prog" ); + break; + + case VOTE_FAILED_SPECTATOR: + m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_spectator" ); + break; + + case VOTE_FAILED_NEXTLEVEL_SET: + m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_nextlevel_set" ); + break; + + case VOTE_FAILED_CANNOT_KICK_FOR_TIME: + g_pVGuiLocalize->ConstructString( wszHeaderString, sizeof(wszHeaderString), g_pVGuiLocalize->Find( "#GameUI_vote_failed_cannot_kick_for_time" ), 1, wszTime ); + pwszHeaderString = wszHeaderString; + m_pCallVoteFailed->SetDialogVariable( "FailedReason", pwszHeaderString ); + break; + + case VOTE_FAILED_CANNOT_KICK_DURING_ROUND: + m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_round_active" ); + break; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Sent to everyone +//----------------------------------------------------------------------------- +void CHudVote::MsgFunc_VoteFailed( bf_read &msg ) +{ + if ( IsPlayingDemo() ) + return; + + int iTeam = msg.ReadByte(); + vote_create_failed_t nReason = (vote_create_failed_t)msg.ReadByte(); + + // Visibility of this error is handled by OnThink() + SetVoteActive( false ); + m_bVotePassed = false; + m_flVoteResultCycleTime = gpGlobals->curtime + 2; + m_flHideTime = gpGlobals->curtime + 5; + + switch ( nReason ) + { + case VOTE_FAILED_GENERIC: + m_pVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed" ); + break; + + case VOTE_FAILED_YES_MUST_EXCEED_NO: + m_pVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_yesno" ); + break; + + case VOTE_FAILED_QUORUM_FAILURE: + m_pVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_quorum" ); + break; + } + + // driller: this event has no listeners - will eventually hook into stats + IGameEvent *event = gameeventmanager->CreateEvent( "vote_failed" ); + if ( event ) + { + event->SetInt( "team", iTeam ); + gameeventmanager->FireEventClientSide( event ); + } + + C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); + if ( !pLocalPlayer ) + return; + + pLocalPlayer->EmitSound("Vote.Failed"); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudVote::MsgFunc_VoteStart( bf_read &msg ) +{ + if ( IsPlayingDemo() ) + return; + + C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); + if ( !pLocalPlayer ) + return; + + // Is this a team-only vote? + int iTeam = msg.ReadByte(); + uint8 invalidTeam = (uint8)TEAM_INVALID; + if ( iTeam != invalidTeam && iTeam != pLocalPlayer->GetTeamNumber() ) + return; + + // Entity calling the vote + bool bShowNotif = cl_vote_ui_show_notification.GetBool(); + const char *pszCallerName = "Server"; + m_iVoteCallerIdx = msg.ReadByte(); + if ( m_iVoteCallerIdx != DEDICATED_SERVER ) + { + C_BasePlayer *pVoteCaller = UTIL_PlayerByIndex( m_iVoteCallerIdx ); + if ( pVoteCaller ) + { + pszCallerName = pVoteCaller->GetPlayerName(); + + // Don't show a notification to the caller + if ( pVoteCaller == pLocalPlayer ) + { + bShowNotif = false; + } + } + else + { + // Caller invalid for some reason + pszCallerName = "Player"; + } + } + + // DisplayString + char szIssue[256]; + szIssue[0] = 0; + msg.ReadString( szIssue, sizeof(szIssue) ); + + // DetailString + char szParam1[256]; + szParam1[0] = 0; + msg.ReadString( szParam1, sizeof(szParam1) ); + + m_bIsYesNoVote = msg.ReadByte(); + + SetVoteActive( true ); + m_pVoteFailed->SetVisible( false ); + m_pVotePassed->SetVisible( false ); + m_pCallVoteFailed->SetVisible( false ); + m_pVoteSetupDialog->SetVisible( false ); + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pVoteActive, "HideVoteBackgrounds" ); + + m_voteBar->SetVisible( m_bIsYesNoVote ); + + // There will always be at least two choices... + m_pVoteActive->SetControlVisible( "LabelOption1", true ); + m_pVoteActive->SetControlVisible( "LabelOption2", true ); + + // ...sometimes more + m_pVoteActive->SetControlVisible( "LabelOption3", m_VoteSetupChoices.Count() > 2 ? true : false ); + m_pVoteActive->SetControlVisible( "Option3Background_Selected", m_VoteSetupChoices.Count() > 2 ? true : false ); + m_pVoteActive->SetControlVisible( "LabelOption4", m_VoteSetupChoices.Count() > 3 ? true : false ); + m_pVoteActive->SetControlVisible( "Option4Background_Selected", m_VoteSetupChoices.Count() > 3 ? true : false ); + m_pVoteActive->SetControlVisible( "LabelOption5", m_VoteSetupChoices.Count() > 4 ? true : false ); + m_pVoteActive->SetControlVisible( "Option5Background_Selected", m_VoteSetupChoices.Count() > 4 ? true : false ); + + m_pVoteActive->SetControlVisible( "VoteCountLabel", m_bIsYesNoVote ); + m_pVoteActive->SetControlVisible( "Option1CountLabel", m_bIsYesNoVote ); + m_pVoteActive->SetControlVisible( "Option2CountLabel", m_bIsYesNoVote ); + m_pVoteActive->SetControlVisible( "Divider1", m_bIsYesNoVote ); + m_pVoteActive->SetControlVisible( "Divider2", m_bIsYesNoVote ); + + // Display vote caller's name + wchar_t wszCallerName[MAX_PLAYER_NAME_LENGTH]; + + wchar_t wszHeaderString[512]; + wchar_t *pwszHeaderString; + + // Player + g_pVGuiLocalize->ConvertANSIToUnicode( pszCallerName, wszCallerName, sizeof( wszCallerName ) ); + + // String + g_pVGuiLocalize->ConstructString( wszHeaderString, sizeof(wszHeaderString), g_pVGuiLocalize->Find( "#GameUI_vote_header" ), 1, wszCallerName ); + pwszHeaderString = wszHeaderString; + + // Final + m_pVoteActive->SetDialogVariable( "header", pwszHeaderString ); + + // Display the Issue + wchar_t *pwcParam; + wchar_t wcParam[128]; + + wchar_t *pwcIssue; + wchar_t wcIssue[512]; + + if ( Q_strlen( szParam1 ) > 0 ) + { + if ( szParam1[0] == '#' ) + { + // localize it + pwcParam = g_pVGuiLocalize->Find( szParam1 ); + } + else + { + // convert to wchar + g_pVGuiLocalize->ConvertANSIToUnicode( szParam1, wcParam, sizeof( wcParam ) ); + pwcParam = wcParam; + } + + g_pVGuiLocalize->ConstructString( wcIssue, sizeof(wcIssue), g_pVGuiLocalize->Find( szIssue ), 1, pwcParam ); + pwcIssue = wcIssue; + } + else + { + // no param, just localize the issue + pwcIssue = g_pVGuiLocalize->Find( szIssue ); + } + m_pVoteActive->SetDialogVariable( "voteissue", pwcIssue ); + + // Figure out which UI + if ( m_bIsYesNoVote ) + { + // YES / NO UI + wchar_t wzFinal[512] = L""; + wchar_t *pszText = g_pVGuiLocalize->Find( "#GameUI_vote_yes_pc_instruction" ); + if ( pszText ) + { + UTIL_ReplaceKeyBindings( pszText, 0, wzFinal, sizeof( wzFinal ) ); + if ( m_pVoteActive ) + m_pVoteActive->SetControlString( "LabelOption1", wzFinal ); + } + + pszText = g_pVGuiLocalize->Find( "#GameUI_vote_no_pc_instruction" ); + if ( pszText ) + { + UTIL_ReplaceKeyBindings( pszText, 0, wzFinal, sizeof( wzFinal ) ); + if ( m_pVoteActive ) + m_pVoteActive->SetControlString( "LabelOption2", wzFinal ); + } + } + else + { + // GENERAL UI + if ( m_VoteSetupChoices.Count() ) + { + // Clear the labels to prevent previous options from being displayed, + // such as when there are fewer options this vote than the previous + for ( int iIndex = 0; iIndex < MAX_VOTE_OPTIONS; iIndex++ ) + { + // Construct Label name + char szOptionNum[2]; + Q_snprintf( szOptionNum, sizeof( szOptionNum ), "%i", iIndex + 1 ); + + char szVoteOptionCount[13] = "LabelOption"; + Q_strncat( szVoteOptionCount, szOptionNum, sizeof( szVoteOptionCount ), COPY_ALL_CHARACTERS ); + + m_pVoteActive->SetControlString( szVoteOptionCount, "" ); + } + + // Set us up the vote + for ( int iIndex = 0; iIndex < m_nVoteChoicesCount; iIndex++ ) + { + // Construct Option name + const char *pszChoiceName = m_VoteSetupChoices[iIndex]; + + char szOptionName[256]; + Q_snprintf( szOptionName, sizeof( szOptionName ), "F%i. ", iIndex + 1 ); + + Q_strncat( szOptionName, pszChoiceName, sizeof( szOptionName ), COPY_ALL_CHARACTERS ); + + // Construct Label name + char szOptionNum[2]; + Q_snprintf( szOptionNum, sizeof( szOptionNum ), "%i", iIndex + 1 ); + + char szVoteOptionCount[13] = "LabelOption"; + Q_strncat( szVoteOptionCount, szOptionNum, sizeof( szVoteOptionCount ), COPY_ALL_CHARACTERS ); + + // Set Label string + if ( m_pVoteActive ) + { + m_pVoteActive->SetControlString( szVoteOptionCount, szOptionName ); + } + } + } + } + + IGameEvent *event = gameeventmanager->CreateEvent( "vote_started" ); + if ( event ) + { + event->SetString( "issue", szIssue ); + event->SetString( "param1", szParam1 ); + event->SetInt( "team", iTeam ); + event->SetInt( "initiator", m_iVoteCallerIdx ); + gameeventmanager->FireEventClientSide( event ); + } + +#ifdef TF_CLIENT_DLL + if ( bShowNotif ) + { + NotificationQueue_Add( new CTFVoteNotification( pszCallerName ) ); + } + else + { + ShowVoteUI(); + } +#else + ShowVoteUI(); +#endif // TF_CLIENT_DLL +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudVote::MsgFunc_VotePass( bf_read &msg ) +{ + if ( IsPlayingDemo() ) + return; + + int iTeam = msg.ReadByte(); + + // Passed string + char szResult[256]; + szResult[0] = 0; + msg.ReadString( szResult, sizeof(szResult) ); + + // Detail string + char szParam1[256]; + szParam1[0] = 0; + msg.ReadString( szParam1, sizeof(szParam1) ); + + // Localize + wchar_t *pwcParam; + wchar_t wcParam[128]; + + wchar_t *pwcIssue; + wchar_t wcIssue[512]; + + if ( Q_strlen( szParam1 ) > 0 ) + { + if ( szParam1[0] == '#' ) + { + pwcParam = g_pVGuiLocalize->Find( szParam1 ); + } + else + { + // Convert to wchar + g_pVGuiLocalize->ConvertANSIToUnicode( szParam1, wcParam, sizeof( wcParam ) ); + pwcParam = wcParam; + } + + g_pVGuiLocalize->ConstructString( wcIssue, sizeof(wcIssue), g_pVGuiLocalize->Find( szResult ), 1, pwcParam ); + pwcIssue = wcIssue; + } + else + { + // No param, just localize the result + pwcIssue = g_pVGuiLocalize->Find( szResult ); + } + + m_pVotePassed->SetDialogVariable( "passedresult", pwcIssue ); + + SetVoteActive( false ); + m_bVotePassed = true; + m_flVoteResultCycleTime = gpGlobals->curtime + 2; + m_flHideTime = gpGlobals->curtime + 5; + + // driller: this event has no listeners - will eventually hook into stats + IGameEvent *event = gameeventmanager->CreateEvent( "vote_passed" ); + if ( event ) + { + event->SetString( "details", szResult ); + event->SetString( "param1", szParam1 ); + event->SetInt( "team", iTeam ); + gameeventmanager->FireEventClientSide( event ); + } + + C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); + if ( !pLocalPlayer ) + return; + + pLocalPlayer->EmitSound( "Vote.Passed" ); +} + +//----------------------------------------------------------------------------- +// Purpose: Creates a UI for Vote Issue selection +//----------------------------------------------------------------------------- +void CHudVote::MsgFunc_VoteSetup( bf_read &msg ) +{ + if ( IsPlayingDemo() ) + return; + + m_pVoteActive->SetVisible( false ); + m_pVoteFailed->SetVisible( false ); + m_pVotePassed->SetVisible( false ); + m_pCallVoteFailed->SetVisible( false ); + + C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); + if ( !pLocalPlayer ) + return; + + // Load up the list of Vote Issues + m_VoteSetupIssues.RemoveAll(); + int nIssueCount = msg.ReadByte(); + if ( nIssueCount ) + { + for ( int index = 0; index < nIssueCount; index++ ) + { + char szIssue[256]; + msg.ReadString( szIssue, sizeof(szIssue) ); + if ( !m_VoteSetupIssues.HasElement( szIssue ) ) + { + // Send it over to the listpanel + m_VoteSetupIssues.CopyAndAddToTail( szIssue ); + } + } + } + else + { + m_VoteSetupIssues.CopyAndAddToTail( "Voting disabled on this Server" ); + } + m_pVoteSetupDialog->AddVoteIssues( m_VoteSetupIssues ); + + // Load up the list of Vote Issue Parameters + m_VoteSetupMapCycle.RemoveAll(); + + // Use the appropriate stringtable for maps based on gamemode + bool bMvM = false; + INetworkStringTable *pStringTable = g_pStringTableServerMapCycle; + +#ifdef TF_CLIENT_DLL + if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() ) + { + bMvM = true; + pStringTable = g_pStringTableServerMapCycleMvM; + } +#endif // TF_CLIENT_DLL + + if ( pStringTable ) + { + int index = bMvM ? pStringTable->FindStringIndex( "ServerMapCycleMvM" ) : pStringTable->FindStringIndex( "ServerMapCycle" ); + if ( index != ::INVALID_STRING_INDEX ) + { + int nLength = 0; + const char *pszMapCycle = (const char *)pStringTable->GetStringUserData( index, &nLength ); + if ( pszMapCycle && pszMapCycle[0] ) + { + if ( pszMapCycle && nLength ) + { + V_SplitString( pszMapCycle, "\n", m_VoteSetupMapCycle ); + } + + // Alphabetize + if ( m_VoteSetupMapCycle.Count() ) + { + m_VoteSetupMapCycle.Sort( m_VoteSetupMapCycle.SortFunc ); + } + } + } + } + +#ifdef TF_CLIENT_DLL + m_VoteSetupPopFiles.RemoveAll(); + if ( g_pStringTableServerPopFiles ) + { + int index = g_pStringTableServerPopFiles->FindStringIndex( "ServerPopFiles" ); + if ( index != ::INVALID_STRING_INDEX ) + { + int nLength = 0; + const char *pszPopFiles = (const char *)g_pStringTableServerPopFiles->GetStringUserData( index, &nLength ); + if ( pszPopFiles && pszPopFiles[0] ) + { + if ( pszPopFiles && nLength ) + { + V_SplitString( pszPopFiles, "\n", m_VoteSetupPopFiles ); + } + + // Alphabetize + if ( m_VoteSetupPopFiles.Count() ) + { + m_VoteSetupPopFiles.Sort( m_VoteSetupPopFiles.SortFunc ); + } + } + } + } +#endif // TF_CLIENT_DLL + + // Now send any data we gathered over to the listpanel + PropagateOptionParameters(); + + m_pVoteSetupDialog->Activate(); + m_pVoteSetupDialog->SetVisible( true ); +} + +//----------------------------------------------------------------------------- +// Purpose: Propagate vote option parameters to the Issue Parameters list +//----------------------------------------------------------------------------- +void CHudVote::PropagateOptionParameters( void ) +{ + C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); + if ( !pLocalPlayer ) + return; + + m_pVoteSetupDialog->AddVoteIssueParams_MapCycle( m_VoteSetupMapCycle ); + +#ifdef TF_CLIENT_DLL + m_pVoteSetupDialog->AddVoteIssueParams_PopFiles( m_VoteSetupPopFiles ); +#endif // TF_CLIENT_DLL + + // Insert future issue param data containers here +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudVote::FireGameEvent( IGameEvent *event ) +{ + const char *eventName = event->GetName(); + if ( !eventName ) + return; + + C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); + if ( !pLocalPlayer ) + return; + + if( FStrEq( eventName, "vote_changed" ) ) + { + for ( int index = 0; index < MAX_VOTE_OPTIONS; index++ ) + { + char szOption[2]; + Q_snprintf( szOption, sizeof( szOption ), "%i", index + 1 ); + + char szVoteOptionCount[13] = "vote_option"; + Q_strncat( szVoteOptionCount, szOption, sizeof( szVoteOptionCount ), COPY_ALL_CHARACTERS ); + + m_nVoteOptionCount[index] = event->GetInt( szVoteOptionCount ); + } + m_nPotentialVotes = event->GetInt( "potentialVotes" ); + } + else if ( FStrEq( eventName, "vote_options" ) ) + { + m_VoteSetupChoices.RemoveAll(); + + m_nVoteChoicesCount = event->GetInt( "count" ); + for ( int iIndex = 0; iIndex < m_nVoteChoicesCount; iIndex++ ) + { + char szNumber[2]; + Q_snprintf( szNumber, sizeof( szNumber ), "%i", iIndex + 1 ); + + char szOptionName[8] = "option"; + Q_strncat( szOptionName, szNumber, sizeof( szOptionName ), COPY_ALL_CHARACTERS ); + + const char *pszOptionName = event->GetString( szOptionName ); + m_VoteSetupChoices.CopyAndAddToTail( pszOptionName ); + } + } + else if ( FStrEq( eventName, "vote_cast" ) ) + { + int iPlayer = event->GetInt( "entityid" ); + C_BasePlayer *pPlayer = UTIL_PlayerByIndex( iPlayer ); + if ( pPlayer != pLocalPlayer ) + return; + + int vote_option = event->GetInt( "vote_option", TEAM_UNASSIGNED ); + if( vote_option == VOTE_OPTION1 ) + { + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pVoteActive, "PulseOption1" ); + } + else if( vote_option == VOTE_OPTION2 ) + { + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pVoteActive, "PulseOption2" ); + } + else if( vote_option == VOTE_OPTION3 ) + { + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pVoteActive, "PulseOption3" ); + } + else if( vote_option == VOTE_OPTION4 ) + { + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pVoteActive, "PulseOption4" ); + } + else if( vote_option == VOTE_OPTION5 ) + { + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pVoteActive, "PulseOption5" ); + } + + m_bPlayerVoted = true; + + bool bForceActive = false; +#ifdef TF_CLIENT_DLL + if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() ) + { + if ( m_iVoteCallerIdx == GetLocalPlayerIndex() ) + { + bForceActive = true; + } + } +#endif // TF_CLIENT_DLL + + if ( !cl_vote_ui_active_after_voting.GetBool() && !bForceActive ) + { + m_flPostVotedHideTime = gpGlobals->curtime + 1.5f; + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudVote::OnThink() +{ + // We delay hiding the menu after we cast a vote + if ( m_bPlayerVoted && m_flPostVotedHideTime > 0 && m_flPostVotedHideTime < gpGlobals->curtime ) + { + m_pVoteActive->SetVisible( false ); + m_bShowVoteActivePanel = false; + m_flPostVotedHideTime = -1; + } + + if ( m_flVoteResultCycleTime > 0 && m_flVoteResultCycleTime < gpGlobals->curtime ) + { + m_pVoteActive->SetVisible( false ); + m_pVoteFailed->SetVisible( !m_bVotePassed ); + m_pVotePassed->SetVisible( m_bVotePassed ); + g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pVoteActive, "HideVoteBackgrounds" ); + + m_flVoteResultCycleTime = -1; + m_bPlayerVoted = false; + m_bVoteActive = false; + m_bShowVoteActivePanel = false; + m_iVoteCallerIdx = -1; + } + + if ( m_bVoteActive ) + { + // driller: Need to rewrite this to handle all vote types (Yes/No and General) + if ( m_bIsYesNoVote && m_pVoteActive ) + { + char szYesCount[512] = ""; + Q_snprintf( szYesCount, 512, "%d", m_nVoteOptionCount[0] ); + + char szNoCount[512] = ""; + Q_snprintf( szNoCount, 512, "%d", m_nVoteOptionCount[1] ); + + m_pVoteActive->SetControlString( "Option1CountLabel", szYesCount ); + m_pVoteActive->SetControlString( "Option2CountLabel", szNoCount ); + } + + if ( !m_pVoteActive->IsVisible() && m_bShowVoteActivePanel ) + { + m_pVoteActive->SetVisible( true ); + + C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); + if ( pLocalPlayer ) + { + pLocalPlayer->EmitSound("Vote.Created"); + } + } + } + + BaseClass::OnThink(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CHudVote::ShouldDraw( void ) +{ + return ( m_bVoteActive || m_flHideTime > gpGlobals->curtime ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CHudVote::IsPlayingDemo() const +{ + return engine->IsPlayingDemo(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudVote::SetVoteActive( bool bActive ) +{ + m_bVoteActive = bActive; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudVote::ShowVoteUI( void ) +{ + m_bShowVoteActivePanel = true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CHudVote::IsVoteUIActive( void ) +{ + return m_bShowVoteActivePanel; +} + |