You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1834 lines
58 KiB
1834 lines
58 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
//===========================================================================// |
|
|
|
|
|
#include "cbase.h" |
|
#include "inputsystem/iinputsystem.h" |
|
#include "input.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( "#GameUI_Vote_Notification_Text" ); |
|
AddStringToken( "initiator", m_wszPlayerName ); |
|
} |
|
|
|
virtual EType NotificationType() { return eType_AcceptDecline; } |
|
|
|
virtual void Trigger() |
|
{ |
|
CTFGenericConfirmDialog *pDialog = ShowConfirmDialog( "#GameUI_Vote_Notification_Title", |
|
"#GameUI_Vote_Notification_Text", |
|
"#GameUI_Vote_Notification_View", |
|
"#cancel", &ConfirmShowVoteSetup ); |
|
pDialog->SetContext( this ); |
|
pDialog->AddStringToken( "initiator", m_wszPlayerName ); |
|
// so we aren't deleted |
|
SetIsInUse( 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( true ); |
|
} |
|
} |
|
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: |
|
//----------------------------------------------------------------------------- |
|
void CVoteSetupDialog::InitializeIssueList( void ) |
|
{ |
|
m_pComboBox->RemoveAll(); |
|
m_pComboBox->SetVisible( false ); |
|
SetDialogVariable( "combo_label", "" ); |
|
|
|
for ( int index = 0; index < m_VoteIssues.Count(); index++ ) |
|
{ |
|
if ( !m_VoteIssues[index].szName || !m_VoteIssues[index].szName[0] ) |
|
continue; |
|
|
|
bool bActive = m_VoteIssues[index].bIsActive; |
|
|
|
char szIssueLocalized[k_MAX_VOTE_NAME_LENGTH] = { 0 }; |
|
g_pVGuiLocalize->ConvertUnicodeToANSI( g_pVGuiLocalize->Find( m_VoteIssues[index].szNameString ), szIssueLocalized, sizeof( szIssueLocalized ) ); |
|
|
|
if ( !bActive ) |
|
{ |
|
char szDisabled[k_MAX_VOTE_NAME_LENGTH] = { 0 }; |
|
g_pVGuiLocalize->ConvertUnicodeToANSI( g_pVGuiLocalize->Find( "#GameUI_Vote_Disabled" ), szDisabled, sizeof( szDisabled ) ); |
|
V_strcat_safe( szIssueLocalized, szDisabled ); |
|
} |
|
|
|
KeyValues *pKeyValues = new KeyValues( "Issue" ); |
|
pKeyValues->SetString( "Issue", szIssueLocalized ); |
|
pKeyValues->SetString( "IssueRaw", m_VoteIssues[index].szName ); |
|
pKeyValues->SetBool( "Active", m_VoteIssues[index].bIsActive ); |
|
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 ); |
|
Color colFG = bActive ? m_IssueFGColor : m_IssueFGColorDisabled; |
|
m_pVoteSetupList->SetItemFgColor( iId, colFG ); |
|
} |
|
} |
|
|
|
// Select the first item by default |
|
if ( m_pVoteSetupList->GetItemCount() > 0 ) |
|
{ |
|
m_pVoteSetupList->SetSelectedItem( 0 ); |
|
} |
|
else |
|
{ |
|
// No active issues |
|
char szIssueLocalized[k_MAX_VOTE_NAME_LENGTH] = { 0 }; |
|
g_pVGuiLocalize->ConvertUnicodeToANSI( g_pVGuiLocalize->Find( "#GameUI_Vote_System_Disabled" ), szIssueLocalized, sizeof( szIssueLocalized ) ); |
|
|
|
KeyValues *pKeyValues = new KeyValues( "Issue" ); |
|
pKeyValues->SetString( "Issue", szIssueLocalized ); |
|
pKeyValues->SetString( "IssueRaw", "Disabled" ); |
|
pKeyValues->SetBool( "Active", false ); |
|
int iId = m_pVoteSetupList->AddItem( 0, pKeyValues ); |
|
pKeyValues->deleteThis(); |
|
|
|
if ( m_hIssueFont != INVALID_FONT ) |
|
{ |
|
m_pVoteSetupList->SetItemFont( iId, m_hIssueFont ); |
|
m_pVoteSetupList->SetItemFgColor( iId, m_IssueFGColor ); |
|
} |
|
} |
|
|
|
UpdateCurrentMap(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// 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( CUtlVector< VoteIssue_t > &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 ); |
|
} |
|
|
|
InitializeIssueList(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// 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" ) ) |
|
{ |
|
int iSelectedItem = m_pVoteSetupList->GetSelectedItem(); |
|
if ( iSelectedItem >= 0 ) |
|
{ |
|
char szVoteCommand[k_MAX_VOTE_NAME_LENGTH]; |
|
KeyValues *pIssueKeyValues = m_pVoteSetupList->GetItemData( iSelectedItem ); |
|
const char *szIssueRaw = pIssueKeyValues->GetString( "IssueRaw" ); |
|
if ( !V_stricmp( "ChangeLevel", szIssueRaw ) || !V_stricmp( "NextLevel", szIssueRaw ) ) |
|
{ |
|
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;", szIssueRaw, szMapName ); |
|
engine->ClientCmd( szVoteCommand ); |
|
} |
|
} |
|
} |
|
} |
|
else if ( !V_stricmp( "Kick", szIssueRaw ) ) |
|
{ |
|
// 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;", szIssueRaw, 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", szIssueRaw ) ) |
|
{ |
|
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;", szIssueRaw, szPopFile ); |
|
engine->ClientCmd( szVoteCommand ); |
|
} |
|
} |
|
} |
|
} |
|
#endif // TF_CLIENT_DLL |
|
else |
|
{ |
|
// Non-parameter vote. i.e. callvote scrambleteams |
|
Q_snprintf( szVoteCommand, sizeof(szVoteCommand), "callvote %s\n;", szIssueRaw ); |
|
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; |
|
|
|
CHudVote *pHudVote = GET_HUDELEMENT( CHudVote ); |
|
if ( !pHudVote ) |
|
return; |
|
|
|
// We're rebuilding, so clear state |
|
m_bVoteButtonEnabled = false; |
|
m_pVoteParameterList->ClearSelection(); |
|
m_pVoteParameterList->RemoveAll(); |
|
|
|
const char *pszIssueRaw = pIssueKeyValues->GetString( "IssueRaw" ); |
|
bool bActive = pIssueKeyValues->GetBool( "Active" ); |
|
if ( !pHudVote->IsVoteSystemActive() || !bActive ) |
|
{ |
|
m_bVoteButtonEnabled = false; |
|
} |
|
// CHANGELEVEL / NEXTLEVEL |
|
else if ( !V_stricmp( "ChangeLevel", pszIssueRaw ) || !V_stricmp( "NextLevel", pszIssueRaw ) ) |
|
{ |
|
// 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", pszIssueRaw ) ) |
|
{ |
|
// 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", pszIssueRaw ) ) |
|
{ |
|
// Feed the popfiles to the parameters list |
|
for ( int index = 0; index < m_VoteIssuesPopFiles.Count(); index++ ) |
|
{ |
|
// Don't show the current pop file |
|
const char *pszPopFileName = TFObjectiveResource()->GetMvMPopFileName(); |
|
if ( !pszPopFileName || !pszPopFileName[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 *pszIssueRaw = pIssueKeyValues->GetString( "IssueRaw" ); |
|
if ( !V_stricmp( "Kick", pszIssueRaw ) ) |
|
{ |
|
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->RemoveAll(); |
|
m_pVoteParameterList->RemoveAll(); |
|
m_pComboBox->RemoveAll(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// 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_pVoteActiveIssueLabel = new vgui::Label( m_pVoteActive, "Issue", "" ); |
|
m_pVoteActiveTargetAvatar = new CAvatarImagePanel( m_pVoteActive, "TargetAvatarImage" ); |
|
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" ); |
|
|
|
m_pVoteActiveIssueLabel->GetPos( m_nVoteActiveIssueLabelX, m_nVoteActiveIssueLabelY ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CHudVote::Init( void ) |
|
{ |
|
ListenForGameEvent( "vote_changed" ); |
|
ListenForGameEvent( "vote_options" ); |
|
ListenForGameEvent( "vote_cast" ); |
|
|
|
m_bVotingActive = 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; |
|
m_bVoteSystemActive = false; |
|
m_nVoteTeamIndex = 0; |
|
|
|
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 ) |
|
{ |
|
m_bVotingActive = false; |
|
m_flVoteResultCycleTime = -1; |
|
m_flHideTime = -1; |
|
m_flPostVotedHideTime = -1; |
|
m_bPlayerVoted = false; |
|
m_bShowVoteActivePanel = false; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
int CHudVote::KeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding ) |
|
{ |
|
if ( !IsVisible() ) |
|
return 1; |
|
|
|
if ( !down ) |
|
return 1; |
|
|
|
if ( !m_bVotingActive ) |
|
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.f; |
|
|
|
char szTime[k_MAX_VOTE_NAME_LENGTH]; |
|
wchar_t wszTime[k_MAX_VOTE_NAME_LENGTH]; |
|
bool bMinutes = ( nTime > 65 ); |
|
if ( bMinutes ) |
|
{ |
|
nTime /= 60; |
|
} |
|
Q_snprintf( szTime, sizeof ( szTime), "%i", nTime ); |
|
g_pVGuiLocalize->ConvertANSIToUnicode( szTime, wszTime, sizeof( wszTime ) ); |
|
|
|
wchar_t wszHeaderString[k_MAX_VOTE_NAME_LENGTH]; |
|
|
|
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: |
|
{ |
|
const char *pszTimeString = ( bMinutes ) ? ( ( nTime < 2 ) ? "#GameUI_vote_failed_vote_spam_min" : "#GameUI_vote_failed_vote_spam_mins" ) : "#GameUI_vote_failed_vote_spam"; |
|
g_pVGuiLocalize->ConstructString_safe( wszHeaderString, g_pVGuiLocalize->Find( pszTimeString ), 1, wszTime ); |
|
m_pCallVoteFailed->SetDialogVariable( "FailedReason", wszHeaderString ); |
|
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_ON_COOLDOWN: |
|
{ |
|
const char *pszTimeString = ( bMinutes ) ? ( ( nTime < 2 ) ? "#GameUI_vote_failed_recently_min" : "#GameUI_vote_failed_recently_mins" ) : "#GameUI_vote_failed_recently"; |
|
g_pVGuiLocalize->ConstructString_safe( wszHeaderString, g_pVGuiLocalize->Find( pszTimeString ), 1, wszTime ); |
|
m_pCallVoteFailed->SetDialogVariable( "FailedReason", wszHeaderString ); |
|
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: |
|
{ |
|
const char *pszTimeString = ( bMinutes ) ? ( ( nTime < 2 ) ? "#GameUI_vote_failed_cannot_kick_min" : "#GameUI_vote_failed_cannot_kick_mins" ) : "#GameUI_vote_failed_cannot_kick"; |
|
g_pVGuiLocalize->ConstructString_safe( wszHeaderString, g_pVGuiLocalize->Find( pszTimeString ), 1, wszTime ); |
|
m_pCallVoteFailed->SetDialogVariable( "FailedReason", wszHeaderString ); |
|
break; |
|
} |
|
|
|
case VOTE_FAILED_CANNOT_KICK_DURING_ROUND: |
|
m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_round_active" ); |
|
break; |
|
|
|
case VOTE_FAILED_MODIFICATION_ALREADY_ACTIVE: |
|
m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_event_already_active" ); |
|
break; |
|
|
|
case VOTE_FAILED_VOTE_IN_PROGRESS: |
|
m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_vote_in_progress" ); |
|
break; |
|
|
|
case VOTE_FAILED_KICK_LIMIT_REACHED: |
|
m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_kick_limit" ); |
|
break; |
|
|
|
case VOTE_FAILED_KICK_DENIED_BY_GC: |
|
m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_kick_limit_gc" ); |
|
break; |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Sent to everyone |
|
//----------------------------------------------------------------------------- |
|
void CHudVote::MsgFunc_VoteFailed( bf_read &msg ) |
|
{ |
|
if ( IsPlayingDemo() ) |
|
return; |
|
|
|
m_nVoteTeamIndex = msg.ReadByte(); |
|
vote_create_failed_t nReason = (vote_create_failed_t)msg.ReadByte(); |
|
|
|
// Visibility of this error is handled by OnThink() |
|
m_bVotingActive = false; |
|
m_bVotePassed = false; |
|
m_flVoteResultCycleTime = gpGlobals->curtime + 2.f; |
|
m_flHideTime = gpGlobals->curtime + 5.f; |
|
|
|
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; |
|
} |
|
|
|
IGameEvent *event = gameeventmanager->CreateEvent( "vote_failed" ); |
|
if ( event ) |
|
{ |
|
event->SetInt( "team", m_nVoteTeamIndex ); |
|
gameeventmanager->FireEventClientSide( event ); |
|
} |
|
|
|
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); |
|
if ( !pLocalPlayer ) |
|
return; |
|
|
|
bool bShowToPlayer = ( !m_nVoteTeamIndex || pLocalPlayer->GetTeamNumber() == m_nVoteTeamIndex ); |
|
if ( bShowToPlayer ) |
|
{ |
|
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? |
|
m_nVoteTeamIndex = msg.ReadByte(); |
|
if ( m_nVoteTeamIndex >= FIRST_GAME_TEAM && m_nVoteTeamIndex != 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[k_MAX_VOTE_NAME_LENGTH] = { 0 }; |
|
msg.ReadString( szIssue, sizeof(szIssue) ); |
|
|
|
// DetailString |
|
char szParam1[k_MAX_VOTE_NAME_LENGTH] = { 0 }; |
|
msg.ReadString( szParam1, sizeof(szParam1) ); |
|
|
|
m_bIsYesNoVote = msg.ReadByte(); |
|
int iTargetEntIndex = msg.ReadByte(); |
|
|
|
m_flVoteResultCycleTime = -1.f; |
|
m_bVotingActive = 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[k_MAX_VOTE_NAME_LENGTH]; |
|
|
|
// Player |
|
g_pVGuiLocalize->ConvertANSIToUnicode( pszCallerName, wszCallerName, sizeof( wszCallerName ) ); |
|
|
|
// String |
|
g_pVGuiLocalize->ConstructString_safe( wszHeaderString, g_pVGuiLocalize->Find( "#GameUI_vote_header" ), 1, wszCallerName ); |
|
|
|
// Final |
|
m_pVoteActive->SetDialogVariable( "header", wszHeaderString ); |
|
|
|
// Display the Issue |
|
wchar_t *pwcParam; |
|
wchar_t wcParam[k_MAX_VOTE_NAME_LENGTH]; |
|
|
|
wchar_t *pwcIssue; |
|
wchar_t wcIssue[k_MAX_VOTE_NAME_LENGTH]; |
|
|
|
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_safe( 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[k_MAX_VOTE_NAME_LENGTH] = L""; |
|
wchar_t *pszText = g_pVGuiLocalize->Find( ::input->IsSteamControllerActive() ? "#GameUI_vote_yes_sc_instruction" : "#GameUI_vote_yes_pc_instruction" ); |
|
if ( pszText ) |
|
{ |
|
UTIL_ReplaceKeyBindings( pszText, 0, wzFinal, sizeof( wzFinal ), GAME_ACTION_SET_FPSCONTROLS ); |
|
if ( m_pVoteActive ) |
|
m_pVoteActive->SetControlString( "LabelOption1", wzFinal ); |
|
} |
|
|
|
pszText = g_pVGuiLocalize->Find( ::input->IsSteamControllerActive() ? "#GameUI_vote_no_sc_instruction" : "#GameUI_vote_no_pc_instruction" ); |
|
if ( pszText ) |
|
{ |
|
UTIL_ReplaceKeyBindings( pszText, 0, wzFinal, sizeof( wzFinal ), GAME_ACTION_SET_FPSCONTROLS ); |
|
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[k_MAX_VOTE_NAME_LENGTH]; |
|
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 ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
// Is the target a player? |
|
int nTargetLabelX = m_nVoteActiveIssueLabelX; |
|
C_BasePlayer *pTargetPlayer = NULL; |
|
if ( iTargetEntIndex ) |
|
{ |
|
pTargetPlayer = UTIL_PlayerByIndex( iTargetEntIndex ); |
|
if ( pTargetPlayer ) |
|
{ |
|
m_pVoteActiveTargetAvatar->SetPlayer( pTargetPlayer ); |
|
m_pVoteActiveTargetAvatar->SetShouldDrawFriendIcon( false ); |
|
nTargetLabelX += ( m_pVoteActiveTargetAvatar->GetWide() + XRES( 3 ) ); |
|
} |
|
} |
|
m_pVoteActiveIssueLabel->SetPos( nTargetLabelX, m_nVoteActiveIssueLabelY ); |
|
m_pVoteActiveTargetAvatar->SetVisible( pTargetPlayer ? true : false ); |
|
|
|
IGameEvent *event = gameeventmanager->CreateEvent( "vote_started" ); |
|
if ( event ) |
|
{ |
|
event->SetString( "issue", szIssue ); |
|
event->SetString( "param1", szParam1 ); |
|
event->SetInt( "team", m_nVoteTeamIndex ); |
|
event->SetInt( "initiator", m_iVoteCallerIdx ); |
|
gameeventmanager->FireEventClientSide( event ); |
|
} |
|
|
|
#ifdef TF_CLIENT_DLL |
|
if ( bShowNotif ) |
|
{ |
|
NotificationQueue_Add( new CTFVoteNotification( pszCallerName ) ); |
|
} |
|
else |
|
{ |
|
m_bShowVoteActivePanel = true; |
|
} |
|
#else |
|
m_bShowVoteActivePanel = true; |
|
#endif // TF_CLIENT_DLL |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CHudVote::MsgFunc_VotePass( bf_read &msg ) |
|
{ |
|
if ( IsPlayingDemo() ) |
|
return; |
|
|
|
m_nVoteTeamIndex = msg.ReadByte(); |
|
|
|
// Passed string |
|
char szResult[k_MAX_VOTE_NAME_LENGTH]; |
|
szResult[0] = 0; |
|
msg.ReadString( szResult, sizeof(szResult) ); |
|
|
|
// Detail string |
|
char szParam1[k_MAX_VOTE_NAME_LENGTH]; |
|
szParam1[0] = 0; |
|
msg.ReadString( szParam1, sizeof(szParam1) ); |
|
|
|
// Localize |
|
wchar_t *pwcParam; |
|
wchar_t wcParam[k_MAX_VOTE_NAME_LENGTH]; |
|
|
|
wchar_t *pwcIssue; |
|
wchar_t wcIssue[k_MAX_VOTE_NAME_LENGTH]; |
|
|
|
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_safe( 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 ); |
|
|
|
m_bVotingActive = false; |
|
m_bVotePassed = true; |
|
m_flVoteResultCycleTime = gpGlobals->curtime + 2.f; |
|
m_flHideTime = gpGlobals->curtime + 5.f; |
|
|
|
// 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", m_nVoteTeamIndex ); |
|
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 i = 0; i < nIssueCount; i++ ) |
|
{ |
|
char szIssue[k_MAX_VOTE_NAME_LENGTH]; |
|
char szIssueString[k_MAX_VOTE_NAME_LENGTH]; |
|
msg.ReadString( szIssue, sizeof( szIssue ) ); |
|
msg.ReadString( szIssueString, sizeof( szIssueString ) ); |
|
bool bIsActive = (bool)msg.ReadByte(); |
|
|
|
m_bVoteSystemActive |= bIsActive; |
|
|
|
bool bAdd = true; |
|
FOR_EACH_VEC( m_VoteSetupIssues, j ) |
|
{ |
|
if ( !V_strcmp( szIssue, m_VoteSetupIssues[j].szName ) ) |
|
{ |
|
bAdd = false; |
|
break; |
|
} |
|
} |
|
|
|
if ( bAdd ) |
|
{ |
|
// When empty, assume that we just pre-pend #Vote_ to szIssue (reduces msg size) |
|
if ( !szIssueString[0] ) |
|
{ |
|
V_sprintf_safe( szIssueString, "#Vote_%s", szIssue ); |
|
} |
|
|
|
VoteIssue_t issue; |
|
V_strcpy_safe( issue.szName, szIssue ); |
|
V_strcpy_safe( issue.szNameString, szIssueString ); |
|
issue.bIsActive = bIsActive; |
|
|
|
// Send it over to the listpanel |
|
m_VoteSetupIssues.AddToTail( issue ); |
|
} |
|
} |
|
} |
|
|
|
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() |
|
{ |
|
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); |
|
if ( pLocalPlayer ) |
|
{ |
|
bool bShowToPlayer = ( !m_nVoteTeamIndex || pLocalPlayer->GetTeamNumber() == m_nVoteTeamIndex ); |
|
|
|
// We delay hiding the menu after we cast a vote |
|
if ( m_bPlayerVoted && m_flPostVotedHideTime > 0 && gpGlobals->curtime > m_flPostVotedHideTime ) |
|
{ |
|
m_pVoteActive->SetVisible( false ); |
|
m_bShowVoteActivePanel = false; |
|
m_flPostVotedHideTime = -1; |
|
} |
|
|
|
if ( m_flVoteResultCycleTime > 0 && gpGlobals->curtime > m_flVoteResultCycleTime ) |
|
{ |
|
m_pVoteActive->SetVisible( false ); |
|
m_pVoteFailed->SetVisible( !m_bVotePassed && bShowToPlayer ); |
|
m_pVotePassed->SetVisible( m_bVotePassed && bShowToPlayer ); |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( m_pVoteActive, "HideVoteBackgrounds" ); |
|
|
|
m_flVoteResultCycleTime = -1; |
|
m_bPlayerVoted = false; |
|
m_bVotingActive = false; |
|
m_bShowVoteActivePanel = false; |
|
m_iVoteCallerIdx = -1; |
|
} |
|
|
|
if ( m_bVotingActive && m_bShowVoteActivePanel ) |
|
{ |
|
// driller: Need to rewrite this to handle all vote types (Yes/No and General) |
|
if ( m_bIsYesNoVote && m_pVoteActive ) |
|
{ |
|
char szYesCount[k_MAX_VOTE_NAME_LENGTH] = ""; |
|
Q_snprintf( szYesCount, sizeof( szYesCount ), "%d", m_nVoteOptionCount[0] ); |
|
|
|
char szNoCount[k_MAX_VOTE_NAME_LENGTH] = ""; |
|
Q_snprintf( szNoCount, sizeof( szNoCount ), "%d", m_nVoteOptionCount[1] ); |
|
|
|
m_pVoteActive->SetControlString( "Option1CountLabel", szYesCount ); |
|
m_pVoteActive->SetControlString( "Option2CountLabel", szNoCount ); |
|
} |
|
|
|
if ( !m_pVoteActive->IsVisible() && bShowToPlayer ) |
|
{ |
|
m_pVoteActive->SetVisible( true ); |
|
pLocalPlayer->EmitSound("Vote.Created"); |
|
} |
|
} |
|
} |
|
|
|
BaseClass::OnThink(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
bool CHudVote::ShouldDraw( void ) |
|
{ |
|
return ( m_bVotingActive || gpGlobals->curtime < m_flHideTime ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
bool CHudVote::IsPlayingDemo() const |
|
{ |
|
return engine->IsPlayingDemo(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
bool CHudVote::IsVoteUIActive( void ) |
|
{ |
|
return m_bShowVoteActivePanel; |
|
} |
|
|
|
bool CHudVote::IsShowingVoteSetupDialog() |
|
{ |
|
return m_pVoteSetupDialog && m_pVoteSetupDialog->IsEnabled() && m_pVoteSetupDialog->IsVisible(); |
|
} |
|
|
|
bool CHudVote::IsShowingVotingUI() |
|
{ |
|
return m_pVoteActive && m_pVoteActive->IsEnabled() && m_pVoteActive->IsVisible(); |
|
} |
|
|
|
|