# HG changeset patch # User Adam Kaminski # Date 1616964206 14400 # Sun Mar 28 16:43:26 2021 -0400 # Node ID 007e8c0421bdfb6ddfa37b0a8d64adc56929cf02 # Parent 094aa59c017e54539df931a5bd1ba78bce36b89d Added a new vote type for changing gameplay or compatibility flags by doing "callvote [reason]", which can also be disabled by the server using the "sv_noflagvote" CVar. Also added the missing checkbox for changemap votes in the server console window. diff -r 094aa59c017e -r 007e8c0421bd src/callvote.cpp --- a/src/callvote.cpp Sun Mar 21 22:28:45 2021 +0100 +++ b/src/callvote.cpp Sun Mar 28 16:43:26 2021 -0400 @@ -65,6 +65,7 @@ #include "sv_main.h" #include "v_video.h" #include "maprotation.h" +#include "gamemode.h" #include //***************************************************************************** @@ -94,6 +95,7 @@ static bool callvote_CheckValidity( FString &Command, FString &Parameters ); static ULONG callvote_GetVoteType( const char *pszCommand ); static bool callvote_IsKickVote( const ULONG ulVoteType ); +static bool callvote_IsFlagValid( const char *pszName ); //***************************************************************************** // FUNCTIONS @@ -122,11 +124,45 @@ if ( g_ulVoteCountdownTicks ) { g_ulVoteCountdownTicks--; - if (( NETWORK_InClientMode() == false ) && - ( g_ulVoteCountdownTicks == 0 )) + if ( NETWORK_InClientMode() == false ) { + // [AK] If the current vote is for changing a flag, we must constantly check if it's still valid to change the given flag. + if ( g_PreviousVotes.back().ulVoteType == VOTECMD_FLAG ) + { + const char *flagName = g_VoteCommand.Left( g_VoteCommand.IndexOf( ' ' )); + FFlagCVar *flag = static_cast( FindCVar( flagName, NULL )); + bool bCancelVote = false; + + // [AK] It's possible the game mode could change in the middle of a game and the flag is then locked in the new game + // mode, so cancel when vote if that happens. + if ( flag->GetBitVal() & GAMEMODE_GetCurrentFlagsetMask( flag->GetValueVar(), true )) + { + SERVER_Printf( "%s cannot be changed in the current game mode so the vote has been cancelled.\n", flag->GetName() ); + bCancelVote = true; + } + + bool bEnable = !!g_VoteCommand.Right( g_VoteCommand.Len() - ( strlen( flagName ) + 1 )).CompareNoCase( "false" ); + + // [AK] Also cancel the vote if the flag has already been changed to the desired value. + if ( flag->GetGenericRep( CVAR_Bool ).Bool == bEnable ) + { + SERVER_Printf( "%s has been changed so the vote has been cancelled.\n", flag->GetName() ); + bCancelVote = true; + } + + if ( bCancelVote ) + { + g_PreviousVotes.back().ulVoteType = NUM_VOTECMDS; + g_bVoteCancelled = true; + g_bVotePassed = false; + callvote_EndVote(); + return; + } + } + // [RK] Perform the final tally of votes. - CALLVOTE_TallyVotes(); + if ( g_ulVoteCountdownTicks == 0 ) + CALLVOTE_TallyVotes(); } } break; @@ -878,6 +914,42 @@ } Parameters.Format( "%d", parameterInt ); break; + case VOTECMD_FLAG: + { + // [AK] Any valid input could be either a number or simply "true" or "false". + if (( parameterInt == 0 ) && (( Parameters.GetChars()[0] != '0' ) || ( Parameters.Len() != 1 ))) + { + if ( Parameters.CompareNoCase( "true" ) == 0 ) + { + parameterInt = 1; + } + else if ( Parameters.CompareNoCase( "false" ) != 0 ) + { + if ( NETWORK_GetState( ) == NETSTATE_SERVER ) + SERVER_PrintfPlayer( SERVER_GetCurrentClient( ), "%s is an invalid parameter.\n", Parameters.GetChars() ); + return ( false ); + } + } + + FFlagCVar *flag = static_cast( FindCVar( Command, NULL)); + + // [AK] Don't call the vote if this flag is supposed to be locked in the current game mode. + if ( flag->GetBitVal() & GAMEMODE_GetCurrentFlagsetMask( flag->GetValueVar(), true )) + { + SERVER_PrintfPlayer( SERVER_GetCurrentClient( ), "%s cannot be changed in this game mode.\n", flag->GetName() ); + return ( false ); + } + + // [AK] Don't call the vote if this flag is already set to the parameter's value. + if ( flag->GetGenericRep( CVAR_Int ).Int == parameterInt ) + { + SERVER_PrintfPlayer( SERVER_GetCurrentClient( ), "%s is already set to %s.\n", flag->GetName(), Parameters.GetChars() ); + return ( false ); + } + + Parameters.Format( "%s", parameterInt ? "true" : "false" ); + } + break; default: return ( false ); @@ -909,6 +981,8 @@ return VOTECMD_DUELLIMIT; else if ( stricmp( "pointlimit", pszCommand ) == 0 ) return VOTECMD_POINTLIMIT; + else if ( callvote_IsFlagValid( pszCommand )) + return VOTECMD_FLAG; return NUM_VOTECMDS; } @@ -921,6 +995,41 @@ } //***************************************************************************** +// +static bool callvote_IsFlagValid( const char *pszName ) +{ + // [AK] Check to make sure the CVar the client sent by name actually exists. + FBaseCVar *cvar = FindCVar( pszName, NULL ); + if ( cvar == NULL ) + { + if ( NETWORK_GetState( ) == NETSTATE_SERVER ) + SERVER_PrintfPlayer( SERVER_GetCurrentClient( ), "That cvar does not exist.\n" ); + return ( false ); + } + + // [AK] Also check to make sure this is a flag-type CVar. + if ( cvar->IsFlagCVar( ) == false ) + { + if ( NETWORK_GetState( ) == NETSTATE_SERVER ) + SERVER_PrintfPlayer( SERVER_GetCurrentClient( ), "That cvar is not a flag.\n" ); + return ( false ); + } + + // [AK] This flag must belong to a gameplay or compatibility flagset in order to be valid. + FIntCVar* flagset = static_cast( cvar )->GetValueVar( ); + if (( flagset != &dmflags && flagset != &dmflags2 ) && + ( flagset != &compatflags && flagset != &compatflags ) && + ( flagset != &zadmflags && flagset != &zacompatflags )) + { + if ( NETWORK_GetState( ) == NETSTATE_SERVER ) + SERVER_PrintfPlayer( SERVER_GetCurrentClient( ), "That cvar is not a valid gameplay or compatibility flag.\n" ); + return ( false ); + } + + return ( true ); +} + +//***************************************************************************** // CONSOLE COMMANDS/VARIABLES CUSTOM_CVAR( Int, sv_minvoters, 1, CVAR_ARCHIVE ) @@ -939,6 +1048,7 @@ CVAR( Bool, sv_nowinlimitvote, false, CVAR_ARCHIVE | CVAR_SERVERINFO ); CVAR( Bool, sv_noduellimitvote, false, CVAR_ARCHIVE | CVAR_SERVERINFO ); CVAR( Bool, sv_nopointlimitvote, false, CVAR_ARCHIVE | CVAR_SERVERINFO ); +CVAR( Bool, sv_noflagvote, false, CVAR_ARCHIVE | CVAR_SERVERINFO ); CVAR( Int, sv_votecooldown, 5, CVAR_ARCHIVE | CVAR_SERVERINFO ); CVAR( Int, sv_voteconnectwait, 0, CVAR_ARCHIVE | CVAR_SERVERINFO ); // [RK] The amount of seconds after client connect to wait before voting CVAR( Bool, cl_showfullscreenvote, false, CVAR_ARCHIVE ); @@ -947,6 +1057,7 @@ CCMD( callvote ) { ULONG ulVoteCmd; + char szArgument[128]; // Don't allow a vote unless the player is a client. if ( NETWORK_GetState( ) != NETSTATE_CLIENT ) @@ -978,10 +1089,16 @@ return; } + // [AK] If we're calling a flag vote, put the CVar's name and the parameter together. + if ( ulVoteCmd == VOTECMD_FLAG ) + sprintf( szArgument, "%s %s", argv[1], argv[2] ); + else + sprintf( szArgument, "%s", argv[2] ); + if ( argv.argc( ) >= 4 ) - CLIENTCOMMANDS_CallVote( ulVoteCmd, argv[2], argv[3] ); + CLIENTCOMMANDS_CallVote( ulVoteCmd, szArgument, argv[3] ); else - CLIENTCOMMANDS_CallVote( ulVoteCmd, argv[2], "" ); + CLIENTCOMMANDS_CallVote( ulVoteCmd, szArgument, "" ); /* g_lBytesSent += g_LocalBuffer.cursize; if ( g_lBytesSent > g_lMaxBytesSent ) diff -r 094aa59c017e -r 007e8c0421bd src/callvote.h --- a/src/callvote.h Sun Mar 21 22:28:45 2021 +0100 +++ b/src/callvote.h Sun Mar 28 16:43:26 2021 -0400 @@ -72,6 +72,7 @@ VOTECMD_WINLIMIT, VOTECMD_DUELLIMIT, VOTECMD_POINTLIMIT, + VOTECMD_FLAG, NUM_VOTECMDS }; @@ -148,6 +149,7 @@ EXTERN_CVAR( Bool, sv_nowinlimitvote ); EXTERN_CVAR( Bool, sv_noduellimitvote ); EXTERN_CVAR( Bool, sv_nopointlimitvote ); +EXTERN_CVAR( Bool, sv_noflagvote ); EXTERN_CVAR( Int, sv_votecooldown ); EXTERN_CVAR( Int, sv_voteconnectwait ); EXTERN_CVAR( Bool, cl_showfullscreenvote ) diff -r 094aa59c017e -r 007e8c0421bd src/menu/multiplayermenu.cpp --- a/src/menu/multiplayermenu.cpp Sun Mar 21 22:28:45 2021 +0100 +++ b/src/menu/multiplayermenu.cpp Sun Mar 28 16:43:26 2021 -0400 @@ -128,6 +128,7 @@ CVAR ( Int, menu_callvotemap, 0, 0 ) CVAR ( Bool, menu_callvoteintermission, true, 0 ) CVAR ( String, menu_callvotereason, "", 0 ) +CVAR ( String, menu_callvoteflag, "", 0 ) CVAR ( Int, menu_callvotelimit, 0, 0 ) CVAR ( Float, menu_callvotevalue, 0, 0 ) CVAR ( Int, menu_callvoteplayer, 0, 0 ) @@ -678,6 +679,30 @@ } } +// ================================================================================================= +// +// +// +// +// +// ================================================================================================= + +static void M_CallFlagVote() +{ + const char *flagName = menu_callvoteflag.GetGenericRep( CVAR_String ).String; + + if ( strlen( flagName ) > 0 ) + { + FString command; + command.Format( "callvote %s %s \"%s\"", + flagName, + menu_callvotevalue.GetGenericRep( CVAR_String ).String, + *menu_callvotereason ); + C_DoCommand( command ); + M_ClearMenus(); + } +} + //================================================================================================= // // [TP] M_ExecuteIgnore @@ -909,6 +934,11 @@ M_CallLimitVote(); } +CCMD ( menu_callflagvote ) +{ + M_CallFlagVote(); +} + CCMD ( menu_autoselect ) { M_AutoSelect(); diff -r 094aa59c017e -r 007e8c0421bd src/sv_main.cpp --- a/src/sv_main.cpp Sun Mar 21 22:28:45 2021 +0100 +++ b/src/sv_main.cpp Sun Mar 28 16:43:26 2021 -0400 @@ -6643,6 +6643,11 @@ bVoteAllowed = !sv_nopointlimitvote; sprintf( szCommand, "pointlimit" ); break; + case VOTECMD_FLAG: + + bVoteAllowed = !sv_noflagvote; + sprintf( szCommand, "flag" ); + break; default: return ( false ); @@ -6650,7 +6655,17 @@ // Begin the vote, if that type is allowed. if ( bVoteAllowed ) + { + // [AK] If we're changing a flag, first separate the CVar name + // and the parameter from each other. + if ( ulVoteCmd == VOTECMD_FLAG ) + { + sprintf( szCommand, Parameters.Left( Parameters.IndexOf( ' '))); + Parameters = Parameters.Right( Parameters.Len() - ( strlen( szCommand ) + 1 )); + } + CALLVOTE_BeginVote( szCommand, Parameters, Reason, g_lCurrentClient ); + } else SERVER_PrintfPlayer( g_lCurrentClient, "%s votes are disabled on this server.\n", szCommand ); diff -r 094aa59c017e -r 007e8c0421bd src/win32/serverconsole/resource.h --- a/src/win32/serverconsole/resource.h Sun Mar 21 22:28:45 2021 +0100 +++ b/src/win32/serverconsole/resource.h Sun Mar 28 16:43:26 2021 -0400 @@ -226,9 +226,11 @@ #define IDC_ALLOWVOTE_TIMELIMIT 4066 #define IDC_ALLOWVOTE_WINLIMIT 4067 #define IDC_ALLOWVOTE_MAP 4068 -#define IDC_MARKCHATLINES 4069 -#define IDC_ALLOWRCON 4070 -#define IDC_LOGFILENAME_TIMESTAMP 4072 +#define IDC_ALLOWVOTE_CHANGEMAP 4069 +#define IDC_ALLOWVOTE_FLAG 4070 +#define IDC_MARKCHATLINES 4071 +#define IDC_ALLOWRCON 4072 +#define IDC_LOGFILENAME_TIMESTAMP 4073 #define IDC_VIEWLOGFILE 4082 #define ID_ADMIN_ADDREMOVEBOT 40000 #define IDC_LMSWEAPONS_VALUE 40001 diff -r 094aa59c017e -r 007e8c0421bd src/win32/serverconsole/serverconsole.rc --- a/src/win32/serverconsole/serverconsole.rc Sun Mar 21 22:28:45 2021 +0100 +++ b/src/win32/serverconsole/serverconsole.rc Sun Mar 28 16:43:26 2021 -0400 @@ -447,23 +447,25 @@ EDITTEXT IDC_PASSWORD, 48, 38, 72, 12, ES_AUTOHSCROLL, WS_EX_LEFT AUTOCHECKBOX "Require a password to play", IDC_REQUIREJOINPW, 27, 53, 106, 10, 0, WS_EX_LEFT EDITTEXT IDC_JOINPASSWORD, 48, 65, 72, 12, ES_AUTOHSCROLL, WS_EX_LEFT - RTEXT "people can connect", IDC_STATIC, 73, 95, 63, 8, SS_RIGHT, WS_EX_LEFT - EDITTEXT IDC_MAXCLIENTS, 34, 93, 32, 14, ES_AUTOHSCROLL | ES_NUMBER, WS_EX_LEFT - CONTROL "", IDC_SPIN1, UPDOWN_CLASS, UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_AUTOBUDDY | UDS_SETBUDDYINT, 54, 93, 12, 14, WS_EX_LEFT - RTEXT "people can play", IDC_STATIC, 73, 111, 51, 8, SS_RIGHT, WS_EX_LEFT - EDITTEXT IDC_MAXPLAYERS, 34, 109, 32, 14, ES_AUTOHSCROLL | ES_NUMBER, WS_EX_LEFT - CONTROL "", IDC_SPIN6, UPDOWN_CLASS, UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_AUTOBUDDY | UDS_SETBUDDYINT, 54, 109, 12, 14, WS_EX_LEFT + RTEXT "people can connect", IDC_STATIC, 73, 100, 63, 8, SS_RIGHT, WS_EX_LEFT + EDITTEXT IDC_MAXCLIENTS, 34, 98, 32, 14, ES_AUTOHSCROLL | ES_NUMBER, WS_EX_LEFT + CONTROL "", IDC_SPIN1, UPDOWN_CLASS, UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_AUTOBUDDY | UDS_SETBUDDYINT, 54, 98, 12, 14, WS_EX_LEFT + RTEXT "people can play", IDC_STATIC, 73, 116, 51, 8, SS_RIGHT, WS_EX_LEFT + EDITTEXT IDC_MAXPLAYERS, 34, 114, 32, 14, ES_AUTOHSCROLL | ES_NUMBER, WS_EX_LEFT + CONTROL "", IDC_SPIN6, UPDOWN_CLASS, UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_AUTOBUDDY | UDS_SETBUDDYINT, 54, 114, 12, 14, WS_EX_LEFT GROUPBOX "Passwords", IDC_STATIC, 15, 9, 136, 77, 0, WS_EX_LEFT - GROUPBOX "Voting", IDC_STATIC, 166, 9, 131, 117, 0, WS_EX_LEFT + GROUPBOX "Voting", IDC_STATIC, 166, 9, 131, 132, 0, WS_EX_LEFT AUTOCHECKBOX "Allow users to call votes", IDC_ALLOW_CALLVOTE, 180, 23, 93, 10, 0, WS_EX_LEFT AUTOCHECKBOX "Allow kicks", IDC_ALLOWVOTE_KICKLIMIT, 194, 34, 50, 9, 0, WS_EX_LEFT - AUTOCHECKBOX "Allow map changes", IDC_ALLOWVOTE_MAP, 194, 44, 77, 10, 0, WS_EX_LEFT - AUTOCHECKBOX "Allow frag limit changes", IDC_ALLOWVOTE_FRAGLIMIT, 194, 54, 91, 10, 0, WS_EX_LEFT - AUTOCHECKBOX "Allow time limit changes", IDC_ALLOWVOTE_TIMELIMIT, 194, 64, 91, 10, 0, WS_EX_LEFT - AUTOCHECKBOX "Allow win limit changes", IDC_ALLOWVOTE_WINLIMIT, 194, 74, 89, 10, 0, WS_EX_LEFT - AUTOCHECKBOX "Allow duel limit changes", IDC_ALLOWVOTE_DUELLIMIT, 194, 84, 91, 10, 0, WS_EX_LEFT - AUTOCHECKBOX "Allow point limit changes", IDC_ALLOWVOTE_POINTLIMIT, 194, 94, 93, 10, 0, WS_EX_LEFT - AUTOCHECKBOX "Allow spectators to vote", IDC_ALLOWVOTE_SPECTATOR, 194, 104, 94, 10, 0, WS_EX_LEFT + AUTOCHECKBOX "Allow map votes", IDC_ALLOWVOTE_MAP, 194, 44, 77, 10, 0, WS_EX_LEFT + AUTOCHECKBOX "Allow changemap votes", IDC_ALLOWVOTE_CHANGEMAP, 194, 54, 92, 10, 0, WS_EX_LEFT + AUTOCHECKBOX "Allow frag limit changes", IDC_ALLOWVOTE_FRAGLIMIT, 194, 64, 91, 10, 0, WS_EX_LEFT + AUTOCHECKBOX "Allow time limit changes", IDC_ALLOWVOTE_TIMELIMIT, 194, 74, 91, 10, 0, WS_EX_LEFT + AUTOCHECKBOX "Allow win limit changes", IDC_ALLOWVOTE_WINLIMIT, 194, 84, 89, 10, 0, WS_EX_LEFT + AUTOCHECKBOX "Allow duel limit changes", IDC_ALLOWVOTE_DUELLIMIT, 194, 94, 91, 10, 0, WS_EX_LEFT + AUTOCHECKBOX "Allow point limit changes", IDC_ALLOWVOTE_POINTLIMIT, 194, 104, 93, 10, 0, WS_EX_LEFT + AUTOCHECKBOX "Allow flag changes", IDC_ALLOWVOTE_FLAG, 194, 114, 90, 10, 0, WS_EX_LEFT + AUTOCHECKBOX "Allow spectators to vote", IDC_ALLOWVOTE_SPECTATOR, 194, 124, 94, 10, 0, WS_EX_LEFT } diff -r 094aa59c017e -r 007e8c0421bd src/win32/serverconsole/serverconsole_settings.cpp --- a/src/win32/serverconsole/serverconsole_settings.cpp Sun Mar 21 22:28:45 2021 +0100 +++ b/src/win32/serverconsole/serverconsole_settings.cpp Sun Mar 28 16:43:26 2021 -0400 @@ -363,6 +363,8 @@ sv_notimelimitvote = !SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_TIMELIMIT, BM_GETCHECK, 0, 0 ); sv_nowinlimitvote = !SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_WINLIMIT, BM_GETCHECK, 0, 0 ); sv_nomapvote = !SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_MAP, BM_GETCHECK, 0, 0 ); + sv_nochangemapvote = !SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_CHANGEMAP, BM_GETCHECK, 0, 0 ); + sv_noflagvote = !SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_FLAG, BM_GETCHECK, 0, 0 ); GetDlgItemText( hDlg, IDC_PASSWORD, szBuffer, 1024 ); sv_password = szBuffer; @@ -863,10 +865,12 @@ EnableWindow( GetDlgItem( hDlg, IDC_ALLOWVOTE_FRAGLIMIT ), bVotesEnabled ); EnableWindow( GetDlgItem( hDlg, IDC_ALLOWVOTE_KICKLIMIT ), bVotesEnabled ); EnableWindow( GetDlgItem( hDlg, IDC_ALLOWVOTE_MAP ), bVotesEnabled ); + EnableWindow( GetDlgItem( hDlg, IDC_ALLOWVOTE_CHANGEMAP ), bVotesEnabled ); EnableWindow( GetDlgItem( hDlg, IDC_ALLOWVOTE_POINTLIMIT ), bVotesEnabled ); EnableWindow( GetDlgItem( hDlg, IDC_ALLOWVOTE_DUELLIMIT ), bVotesEnabled ); EnableWindow( GetDlgItem( hDlg, IDC_ALLOWVOTE_TIMELIMIT ), bVotesEnabled ); EnableWindow( GetDlgItem( hDlg, IDC_ALLOWVOTE_WINLIMIT ), bVotesEnabled ); + EnableWindow( GetDlgItem( hDlg, IDC_ALLOWVOTE_FLAG ), bVotesEnabled ); EnableWindow( GetDlgItem( hDlg, IDC_ALLOWVOTE_SPECTATOR ), bVotesEnabled ); } @@ -919,6 +923,8 @@ SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_TIMELIMIT, BM_SETCHECK, ( !sv_notimelimitvote ? BST_CHECKED : BST_UNCHECKED ), 0 ); SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_WINLIMIT, BM_SETCHECK, ( !sv_nowinlimitvote ? BST_CHECKED : BST_UNCHECKED ), 0 ); SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_MAP, BM_SETCHECK, ( !sv_nomapvote ? BST_CHECKED : BST_UNCHECKED ), 0 ); + SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_CHANGEMAP, BM_SETCHECK, ( !sv_nochangemapvote ? BST_CHECKED : BST_UNCHECKED ), 0 ); + SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_FLAG, BM_SETCHECK, ( !sv_noflagvote ? BST_CHECKED : BST_UNCHECKED ), 0 ); SendDlgItemMessage( hDlg, IDC_ALLOWVOTE_SPECTATOR, BM_SETCHECK, ( sv_nocallvote != 2 ? BST_CHECKED : BST_UNCHECKED ), 0 ); settings_AccessTab_ShowOrHideItems( hDlg ); diff -r 094aa59c017e -r 007e8c0421bd wadsrc/static/menudef.za --- a/wadsrc/static/menudef.za Sun Mar 21 22:28:45 2021 +0100 +++ b/wadsrc/static/menudef.za Sun Mar 28 16:43:26 2021 -0400 @@ -279,6 +279,7 @@ SubMenu "Kick a player", "ZA_CallKickVote" SubMenu "Change the map", "ZA_CallMapVote" SubMenu "Change a limit", "ZA_CallLimitVote" + SubMenu "Change a flag", "ZA_CallFlagVote" } OptionMenu ZA_CallKickVote @@ -314,6 +315,17 @@ Command "Vote!", "menu_calllimitvote" } +OptionMenu ZA_CallFlagVote +{ + Title "CHANGE FLAG" + + TextField "Flag", "menu_callvoteflag" + Option "New value", "menu_callvotevalue", "OnOff" + StaticText " " + TextField "Reason for change", "menu_callvotereason" + Command "Vote!", "menu_callflagvote" +} + // ================================================================================================= // // IGNORE A PLAYER MENU @@ -537,6 +549,7 @@ Option "Win limit votes", "sv_nowinlimitvote", "NoYes" Option "Duel limit votes", "sv_noduellimitvote", "NoYes" Option "Point limit votes", "sv_nopointlimitvote", "NoYes" + Option "Flag votes", "sv_noflagvote", "NoYes" Class VotingSetupMenu }