2008-03-30 09:00:22 +02:00
/ * *
* vim : set ts = 4 :
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* SourceMod Mapchooser Plugin
* Creates a map vote at appropriate times , setting sm_nextmap to the winning
* vote
*
2014-12-17 17:53:02 +01:00
* SourceMod ( C ) 2004 - 2014 AlliedModders LLC . All rights reserved .
2008-03-30 09:00:22 +02:00
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*
* This program is free software ; you can redistribute it and / or modify it under
* the terms of the GNU General Public License , version 3.0 , as published by the
* Free Software Foundation .
*
* This program is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE . See the GNU General Public License for more
* details .
*
* You should have received a copy of the GNU General Public License along with
* this program . If not , see < http : //www.gnu.org/licenses/>.
*
* As a special exception , AlliedModders LLC gives you permission to link the
* code of this program ( as well as its derivative works ) to " Half-Life 2, " the
* " Source Engine, " the " SourcePawn JIT, " and any Game MODs that run on software
* by the Valve Corporation . You must obey the GNU General Public License in
* all respects for all other code used . Additionally , AlliedModders LLC grants
* this exception to all derivative works . AlliedModders LLC defines further
* exceptions , found in LICENSE . txt ( as of this writing , version JULY - 31 - 2007 ) ,
* or < http : //www.sourcemod.net/license.php>.
*
* Version : $ Id $
* /
2011-11-06 01:36:20 +01:00
2008-03-30 09:00:22 +02:00
# pragma semicolon 1
# include <sourcemod>
2008-07-01 03:18:52 +02:00
# include <mapchooser>
# include <nextmap>
2008-03-30 09:00:22 +02:00
2014-12-16 19:38:43 +01:00
# pragma newdecls required
public Plugin myinfo =
2008-03-30 09:00:22 +02:00
{
name = " MapChooser " ,
author = " AlliedModders LLC " ,
description = " Automated Map Voting " ,
version = SOURCEMOD_VERSION ,
url = " http://www.sourcemod.net/ "
} ;
2008-07-01 03:18:52 +02:00
/* Valve ConVars */
2014-11-10 01:22:58 +01:00
ConVar g_Cvar_Winlimit ;
ConVar g_Cvar_Maxrounds ;
ConVar g_Cvar_Fraglimit ;
ConVar g_Cvar_Bonusroundtime ;
2008-03-30 09:00:22 +02:00
2008-07-01 03:18:52 +02:00
/* Plugin ConVars */
2014-11-10 01:22:58 +01:00
ConVar g_Cvar_StartTime ;
ConVar g_Cvar_StartRounds ;
ConVar g_Cvar_StartFrags ;
ConVar g_Cvar_ExtendTimeStep ;
ConVar g_Cvar_ExtendRoundStep ;
ConVar g_Cvar_ExtendFragStep ;
ConVar g_Cvar_ExcludeMaps ;
ConVar g_Cvar_IncludeMaps ;
ConVar g_Cvar_NoVoteMode ;
ConVar g_Cvar_Extend ;
ConVar g_Cvar_DontChange ;
ConVar g_Cvar_EndOfMapVote ;
ConVar g_Cvar_VoteDuration ;
ConVar g_Cvar_RunOff ;
ConVar g_Cvar_RunOffPercent ;
2008-07-08 00:17:55 +02:00
2014-12-16 19:38:43 +01:00
Handle g_VoteTimer = null ;
Handle g_RetryTimer = null ;
2008-03-30 09:00:22 +02:00
2015-09-14 17:21:26 +02:00
// g_MapList stores unresolved names so we can resolve them after every map change in the workshop updates.
// g_OldMapList and g_NextMapList are resolved. g_NominateList depends on the nominations implementation.
2008-07-01 03:18:52 +02:00
/* Data Handles */
2014-12-16 19:38:43 +01:00
ArrayList g_MapList ;
ArrayList g_NominateList ;
ArrayList g_NominateOwners ;
ArrayList g_OldMapList ;
ArrayList g_NextMapList ;
2014-11-16 01:30:45 +01:00
Menu g_VoteMenu ;
2008-03-30 09:00:22 +02:00
2014-12-16 19:38:43 +01:00
int g_Extends ;
int g_TotalRounds ;
bool g_HasVoteStarted ;
bool g_WaitingForVote ;
bool g_MapVoteCompleted ;
bool g_ChangeMapAtRoundEnd ;
bool g_ChangeMapInProgress ;
int g_mapFileSerial = - 1 ;
2008-03-30 09:00:22 +02:00
2014-12-16 19:38:43 +01:00
MapChange g_ChangeTime ;
2008-07-01 03:18:52 +02:00
2014-12-16 19:38:43 +01:00
Handle g_NominationsResetForward = null ;
Handle g_MapVoteStartedForward = null ;
2008-07-01 03:18:52 +02:00
/* Upper bound of how many team there could be */
# define MAXTEAMS 10
2014-12-16 19:38:43 +01:00
int g_winCount [ MAXTEAMS ] ;
2008-07-01 03:18:52 +02:00
2008-03-30 09:00:22 +02:00
# define VOTE_EXTEND "##extend##"
2008-07-01 03:18:52 +02:00
# define VOTE_DONTCHANGE "##dontchange##"
2008-03-30 09:00:22 +02:00
2014-12-16 19:38:43 +01:00
public void OnPluginStart ( )
2008-03-30 09:00:22 +02:00
{
LoadTranslations ( " mapchooser.phrases " ) ;
2008-07-28 09:47:28 +02:00
LoadTranslations ( " common.phrases " ) ;
2008-03-30 09:00:22 +02:00
2014-12-16 19:38:43 +01:00
int arraySize = ByteCountToCells ( PLATFORM_MAX_PATH ) ;
g_MapList = new ArrayList ( arraySize ) ;
g_NominateList = new ArrayList ( arraySize ) ;
g_NominateOwners = new ArrayList ( ) ;
g_OldMapList = new ArrayList ( arraySize ) ;
g_NextMapList = new ArrayList ( arraySize ) ;
2008-07-01 03:18:52 +02:00
g_Cvar_EndOfMapVote = CreateConVar ( " sm_mapvote_endvote " , " 1 " , " Specifies if MapChooser should run an end of map vote " , _ , true , 0.0 , true , 1.0 ) ;
2008-03-30 09:00:22 +02:00
g_Cvar_StartTime = CreateConVar ( " sm_mapvote_start " , " 3.0 " , " Specifies when to start the vote based on time remaining. " , _ , true , 1.0 ) ;
2008-07-01 03:18:52 +02:00
g_Cvar_StartRounds = CreateConVar ( " sm_mapvote_startround " , " 2.0 " , " Specifies when to start the vote based on rounds remaining. Use 0 on TF2 to start vote during bonus round time " , _ , true , 0.0 ) ;
2008-03-30 09:00:22 +02:00
g_Cvar_StartFrags = CreateConVar ( " sm_mapvote_startfrags " , " 5.0 " , " Specifies when to start the vote base on frags remaining. " , _ , true , 1.0 ) ;
g_Cvar_ExtendTimeStep = CreateConVar ( " sm_extendmap_timestep " , " 15 " , " Specifies how much many more minutes each extension makes " , _ , true , 5.0 ) ;
2008-07-01 03:18:52 +02:00
g_Cvar_ExtendRoundStep = CreateConVar ( " sm_extendmap_roundstep " , " 5 " , " Specifies how many more rounds each extension makes " , _ , true , 1.0 ) ;
2008-03-30 09:00:22 +02:00
g_Cvar_ExtendFragStep = CreateConVar ( " sm_extendmap_fragstep " , " 10 " , " Specifies how many more frags are allowed when map is extended. " , _ , true , 5.0 ) ;
g_Cvar_ExcludeMaps = CreateConVar ( " sm_mapvote_exclude " , " 5 " , " Specifies how many past maps to exclude from the vote. " , _ , true , 0.0 ) ;
g_Cvar_IncludeMaps = CreateConVar ( " sm_mapvote_include " , " 5 " , " Specifies how many maps to include in the vote. " , _ , true , 2.0 , true , 6.0 ) ;
g_Cvar_NoVoteMode = CreateConVar ( " sm_mapvote_novote " , " 1 " , " Specifies whether or not MapChooser should pick a map if no votes are received. " , _ , true , 0.0 , true , 1.0 ) ;
g_Cvar_Extend = CreateConVar ( " sm_mapvote_extend " , " 0 " , " Number of extensions allowed each map. " , _ , true , 0.0 ) ;
2008-07-01 03:18:52 +02:00
g_Cvar_DontChange = CreateConVar ( " sm_mapvote_dontchange " , " 1 " , " Specifies if a 'Don't Change' option should be added to early votes " , _ , true , 0.0 ) ;
2008-08-27 03:45:10 +02:00
g_Cvar_VoteDuration = CreateConVar ( " sm_mapvote_voteduration " , " 20 " , " Specifies how long the mapvote should be available for. " , _ , true , 5.0 ) ;
2011-11-06 01:36:20 +01:00
g_Cvar_RunOff = CreateConVar ( " sm_mapvote_runoff " , " 0 " , " Hold run of votes if winning choice is less than a certain margin " , _ , true , 0.0 , true , 1.0 ) ;
g_Cvar_RunOffPercent = CreateConVar ( " sm_mapvote_runoffpercent " , " 50 " , " If winning choice has less than this percent of votes, hold a runoff " , _ , true , 0.0 , true , 100.0 ) ;
2008-07-28 09:47:28 +02:00
2008-03-30 09:00:22 +02:00
RegAdminCmd ( " sm_mapvote " , Command_Mapvote , ADMFLAG_CHANGEMAP , " sm_mapvote - Forces MapChooser to attempt to run a map vote now. " ) ;
2008-07-28 09:47:28 +02:00
RegAdminCmd ( " sm_setnextmap " , Command_SetNextmap , ADMFLAG_CHANGEMAP , " sm_setnextmap <map> " ) ;
2008-03-30 09:00:22 +02:00
g_Cvar_Winlimit = FindConVar ( " mp_winlimit " ) ;
g_Cvar_Maxrounds = FindConVar ( " mp_maxrounds " ) ;
g_Cvar_Fraglimit = FindConVar ( " mp_fraglimit " ) ;
2008-07-01 03:18:52 +02:00
g_Cvar_Bonusroundtime = FindConVar ( " mp_bonusroundtime " ) ;
2008-03-30 09:00:22 +02:00
2014-11-10 01:22:58 +01:00
if ( g_Cvar_Winlimit | | g_Cvar_Maxrounds )
2008-03-30 09:00:22 +02:00
{
2014-11-10 01:22:58 +01:00
char folder [ 64 ] ;
2011-10-12 01:47:20 +02:00
GetGameFolderName ( folder , sizeof ( folder ) ) ;
if ( strcmp ( folder , " tf " ) = = 0 )
{
HookEvent ( " teamplay_win_panel " , Event_TeamPlayWinPanel ) ;
HookEvent ( " teamplay_restart_round " , Event_TFRestartRound ) ;
HookEvent ( " arena_win_panel " , Event_TeamPlayWinPanel ) ;
}
else if ( strcmp ( folder , " nucleardawn " ) = = 0 )
{
HookEvent ( " round_win " , Event_RoundEnd ) ;
}
2016-02-22 22:10:34 +01:00
else if ( strcmp ( folder , " empires " ) = = 0 ) {
HookEvent ( " game_end " , Event_RoundEnd ) ;
}
2011-10-12 01:47:20 +02:00
else
{
HookEvent ( " round_end " , Event_RoundEnd ) ;
}
2008-03-30 09:00:22 +02:00
}
2014-11-10 01:22:58 +01:00
if ( g_Cvar_Fraglimit )
2008-03-30 09:00:22 +02:00
{
HookEvent ( " player_death " , Event_PlayerDeath ) ;
}
AutoExecConfig ( true , " mapchooser " ) ;
2008-07-01 03:18:52 +02:00
//Change the mp_bonusroundtime max so that we have time to display the vote
//If you display a vote during bonus time good defaults are 17 vote duration and 19 mp_bonustime
2014-11-10 01:22:58 +01:00
if ( g_Cvar_Bonusroundtime )
2008-07-01 03:18:52 +02:00
{
2014-11-10 01:22:58 +01:00
g_Cvar_Bonusroundtime . SetBounds ( ConVarBound_Upper , true , 30.0 ) ;
2008-07-01 03:18:52 +02:00
}
g_NominationsResetForward = CreateGlobalForward ( " OnNominationRemoved " , ET_Ignore , Param_String , Param_Cell ) ;
2010-11-19 05:39:53 +01:00
g_MapVoteStartedForward = CreateGlobalForward ( " OnMapVoteStarted " , ET_Ignore ) ;
2008-03-30 09:00:22 +02:00
}
2014-12-16 19:38:43 +01:00
public APLRes AskPluginLoad2 ( Handle myself , bool late , char [ ] error , int err_max )
2008-03-30 09:00:22 +02:00
{
2008-07-06 05:30:06 +02:00
RegPluginLibrary ( " mapchooser " ) ;
2008-07-01 03:18:52 +02:00
CreateNative ( " NominateMap " , Native_NominateMap ) ;
2010-11-19 05:39:53 +01:00
CreateNative ( " RemoveNominationByMap " , Native_RemoveNominationByMap ) ;
CreateNative ( " RemoveNominationByOwner " , Native_RemoveNominationByOwner ) ;
2008-07-01 03:18:52 +02:00
CreateNative ( " InitiateMapChooserVote " , Native_InitiateVote ) ;
CreateNative ( " CanMapChooserStartVote " , Native_CanVoteStart ) ;
CreateNative ( " HasEndOfMapVoteFinished " , Native_CheckVoteDone ) ;
CreateNative ( " GetExcludeMapList " , Native_GetExcludeMapList ) ;
2010-11-19 05:39:53 +01:00
CreateNative ( " GetNominatedMapList " , Native_GetNominatedMapList ) ;
2008-08-08 02:06:14 +02:00
CreateNative ( " EndOfMapVoteEnabled " , Native_EndOfMapVoteEnabled ) ;
2008-03-30 09:00:22 +02:00
2009-03-19 06:10:39 +01:00
return APLRes_Success ;
2008-07-01 03:18:52 +02:00
}
2014-12-16 19:38:43 +01:00
public void OnConfigsExecuted ( )
2008-07-01 03:18:52 +02:00
{
2008-03-30 09:00:22 +02:00
if ( ReadMapList ( g_MapList ,
g_mapFileSerial ,
" mapchooser " ,
MAPLIST_FLAG_CLEARARRAY | MAPLIST_FLAG_MAPSFOLDER )
2014-11-16 01:30:45 +01:00
! = null )
2008-03-30 09:00:22 +02:00
{
if ( g_mapFileSerial = = - 1 )
{
LogError ( " Unable to create a valid map list. " ) ;
}
}
CreateNextVote ( ) ;
SetupTimeleftTimer ( ) ;
g_TotalRounds = 0 ;
g_Extends = 0 ;
2008-07-01 03:18:52 +02:00
g_MapVoteCompleted = false ;
2015-01-06 16:07:15 +01:00
g_NominateList . Clear ( ) ;
g_NominateOwners . Clear ( ) ;
2008-07-01 03:18:52 +02:00
2014-12-16 19:38:43 +01:00
for ( int i = 0 ; i < MAXTEAMS ; i + + )
2008-07-01 03:18:52 +02:00
{
g_winCount [ i ] = 0 ;
}
/* Check if mapchooser will attempt to start mapvote during bonus round time - TF2 Only */
2014-11-10 01:22:58 +01:00
if ( g_Cvar_Bonusroundtime & & ! g_Cvar_StartRounds . IntValue )
2008-07-01 03:18:52 +02:00
{
2014-11-10 01:22:58 +01:00
if ( g_Cvar_Bonusroundtime . FloatValue < = g_Cvar_VoteDuration . FloatValue )
2008-07-01 03:18:52 +02:00
{
LogError ( " Warning - Bonus Round Time shorter than Vote Time. Votes during bonus round may not have time to complete " ) ;
}
}
2008-03-30 09:00:22 +02:00
}
2014-12-16 19:38:43 +01:00
public void OnMapEnd ( )
2008-03-30 09:00:22 +02:00
{
g_HasVoteStarted = false ;
2008-07-01 03:18:52 +02:00
g_WaitingForVote = false ;
2008-08-08 02:06:14 +02:00
g_ChangeMapAtRoundEnd = false ;
2008-09-28 06:46:07 +02:00
g_ChangeMapInProgress = false ;
2008-03-30 09:00:22 +02:00
2014-11-16 01:30:45 +01:00
g_VoteTimer = null ;
g_RetryTimer = null ;
2008-07-01 03:18:52 +02:00
2014-12-16 19:38:43 +01:00
char map [ PLATFORM_MAX_PATH ] ;
2008-07-01 03:18:52 +02:00
GetCurrentMap ( map , sizeof ( map ) ) ;
2014-12-16 19:38:43 +01:00
g_OldMapList . PushString ( map ) ;
2008-07-01 03:18:52 +02:00
2014-12-16 19:38:43 +01:00
if ( g_OldMapList . Length > g_Cvar_ExcludeMaps . IntValue )
2008-07-01 03:18:52 +02:00
{
2014-12-16 19:38:43 +01:00
g_OldMapList . Erase ( 0 ) ;
2008-07-01 03:18:52 +02:00
}
}
2014-12-16 19:38:43 +01:00
public void OnClientDisconnect ( int client )
2008-07-01 03:18:52 +02:00
{
2014-12-16 19:38:43 +01:00
int index = g_NominateOwners . FindValue ( client ) ;
2008-07-01 03:18:52 +02:00
if ( index = = - 1 )
{
return ;
}
2014-12-16 19:38:43 +01:00
char oldmap [ PLATFORM_MAX_PATH ] ;
g_NominateList . GetString ( index , oldmap , sizeof ( oldmap ) ) ;
2008-07-01 03:18:52 +02:00
Call_StartForward ( g_NominationsResetForward ) ;
Call_PushString ( oldmap ) ;
2014-12-16 23:00:00 +01:00
Call_PushCell ( g_NominateOwners . Get ( index ) ) ;
2008-07-01 03:18:52 +02:00
Call_Finish ( ) ;
2014-12-16 19:38:43 +01:00
g_NominateOwners . Erase ( index ) ;
g_NominateList . Erase ( index ) ;
2008-07-01 03:18:52 +02:00
}
2014-12-16 19:38:43 +01:00
public Action Command_SetNextmap ( int client , int args )
2008-07-01 03:18:52 +02:00
{
2008-07-28 09:47:28 +02:00
if ( args < 1 )
2008-07-01 03:18:52 +02:00
{
2008-07-28 09:47:28 +02:00
ReplyToCommand ( client , " [SM] Usage: sm_setnextmap <map> " ) ;
return Plugin_Handled ;
2008-07-01 03:18:52 +02:00
}
2008-07-28 09:47:28 +02:00
2014-12-16 19:38:43 +01:00
char map [ PLATFORM_MAX_PATH ] ;
2015-09-14 17:21:26 +02:00
char displayName [ PLATFORM_MAX_PATH ] ;
2008-07-28 09:47:28 +02:00
GetCmdArg ( 1 , map , sizeof ( map ) ) ;
2015-09-14 17:21:26 +02:00
if ( FindMap ( map , displayName , sizeof ( displayName ) ) = = FindMap_NotFound )
2008-07-01 03:18:52 +02:00
{
2008-07-28 09:47:28 +02:00
ReplyToCommand ( client , " [SM] %t " , " Map was not found " , map ) ;
return Plugin_Handled ;
2008-07-01 03:18:52 +02:00
}
2015-09-14 17:21:26 +02:00
GetMapDisplayName ( displayName , displayName , sizeof ( displayName ) ) ;
ShowActivity ( client , " %t " , " Changed Next Map " , displayName ) ;
2011-03-21 00:37:25 +01:00
LogAction ( client , - 1 , " \" %L \" changed nextmap to \" %s \" " , client , map ) ;
2008-07-28 09:47:28 +02:00
SetNextMap ( map ) ;
g_MapVoteCompleted = true ;
return Plugin_Handled ;
2008-03-30 09:00:22 +02:00
}
2014-12-16 19:38:43 +01:00
public void OnMapTimeLeftChanged ( )
2008-03-30 09:00:22 +02:00
{
2014-12-16 19:38:43 +01:00
if ( g_MapList . Length )
2008-03-30 09:00:22 +02:00
{
SetupTimeleftTimer ( ) ;
}
}
2014-12-16 19:38:43 +01:00
void SetupTimeleftTimer ( )
2008-03-30 09:00:22 +02:00
{
2014-12-16 19:38:43 +01:00
int time ;
2008-03-30 09:00:22 +02:00
if ( GetMapTimeLeft ( time ) & & time > 0 )
{
2014-12-16 19:38:43 +01:00
int startTime = g_Cvar_StartTime . IntValue * 60 ;
2014-11-10 01:22:58 +01:00
if ( time - startTime < 0 & & g_Cvar_EndOfMapVote . BoolValue & & ! g_MapVoteCompleted & & ! g_HasVoteStarted )
2008-03-30 09:00:22 +02:00
{
2015-09-14 17:21:26 +02:00
InitiateVote ( MapChange_MapEnd , null ) ;
2008-03-30 09:00:22 +02:00
}
else
{
2014-11-16 01:30:45 +01:00
if ( g_VoteTimer ! = null )
2008-03-30 09:00:22 +02:00
{
KillTimer ( g_VoteTimer ) ;
2014-11-16 01:30:45 +01:00
g_VoteTimer = null ;
2008-03-30 09:00:22 +02:00
}
2008-09-28 06:46:07 +02:00
//g_VoteTimer = CreateTimer(float(time - startTime), Timer_StartMapVote, _, TIMER_FLAG_NO_MAPCHANGE);
2014-12-16 19:38:43 +01:00
DataPack data ;
2008-09-28 06:46:07 +02:00
g_VoteTimer = CreateDataTimer ( float ( time - startTime ) , Timer_StartMapVote , data , TIMER_FLAG_NO_MAPCHANGE ) ;
2014-12-16 19:38:43 +01:00
data . WriteCell ( MapChange_MapEnd ) ;
2014-12-17 17:07:51 +01:00
data . WriteCell ( INVALID_HANDLE ) ;
2014-12-16 19:38:43 +01:00
data . Reset ( ) ;
2008-03-30 09:00:22 +02:00
}
}
}
2014-12-16 19:38:43 +01:00
public Action Timer_StartMapVote ( Handle timer , DataPack data )
2008-03-30 09:00:22 +02:00
{
if ( timer = = g_RetryTimer )
{
2008-08-27 02:49:56 +02:00
g_WaitingForVote = false ;
2014-11-16 01:30:45 +01:00
g_RetryTimer = null ;
2008-03-30 09:00:22 +02:00
}
else
{
2014-11-16 01:30:45 +01:00
g_VoteTimer = null ;
2008-03-30 09:00:22 +02:00
}
2008-07-01 03:18:52 +02:00
2014-12-16 19:38:43 +01:00
if ( ! g_MapList . Length | | ! g_Cvar_EndOfMapVote . BoolValue | | g_MapVoteCompleted | | g_HasVoteStarted )
2008-08-08 02:06:14 +02:00
{
return Plugin_Stop ;
2008-09-28 06:46:07 +02:00
}
2008-10-01 07:45:26 +02:00
2014-12-16 19:38:43 +01:00
MapChange mapChange = view_as < MapChange > ( data . ReadCell ( ) ) ;
ArrayList hndl = view_as < ArrayList > ( data . ReadCell ( ) ) ;
2008-08-08 02:06:14 +02:00
2008-10-01 07:45:26 +02:00
InitiateVote ( mapChange , hndl ) ;
2008-03-30 09:00:22 +02:00
return Plugin_Stop ;
}
2014-12-16 19:38:43 +01:00
public void Event_TFRestartRound ( Event event , const char [ ] name , bool dontBroadcast )
2008-05-01 04:39:35 +02:00
{
2008-07-01 03:18:52 +02:00
/* Game got restarted - reset our round count tracking */
g_TotalRounds = 0 ;
}
2014-12-16 19:38:43 +01:00
public void Event_TeamPlayWinPanel ( Event event , const char [ ] name , bool dontBroadcast )
2008-07-01 03:18:52 +02:00
{
if ( g_ChangeMapAtRoundEnd )
{
g_ChangeMapAtRoundEnd = false ;
2008-07-08 01:12:21 +02:00
CreateTimer ( 2.0 , Timer_ChangeMap , INVALID_HANDLE , TIMER_FLAG_NO_MAPCHANGE ) ;
2008-09-28 06:46:07 +02:00
g_ChangeMapInProgress = true ;
2008-07-01 03:18:52 +02:00
}
2008-05-01 04:39:35 +02:00
2014-12-16 19:38:43 +01:00
int bluescore = event . GetInt ( " blue_score " ) ;
int redscore = event . GetInt ( " red_score " ) ;
2008-08-27 03:00:01 +02:00
2014-11-09 23:39:09 +01:00
if ( event . GetInt ( " round_complete " ) = = 1 | | StrEqual ( name , " arena_win_panel " ) )
2008-08-27 02:49:56 +02:00
{
g_TotalRounds + + ;
2014-12-16 19:38:43 +01:00
if ( ! g_MapList . Length | | g_HasVoteStarted | | g_MapVoteCompleted | | ! g_Cvar_EndOfMapVote . BoolValue )
2008-08-27 02:49:56 +02:00
{
return ;
}
2008-08-27 03:45:10 +02:00
CheckMaxRounds ( g_TotalRounds ) ;
2014-11-09 23:39:09 +01:00
switch ( event . GetInt ( " winning_team " ) )
2008-07-01 03:18:52 +02:00
{
2008-07-28 09:47:28 +02:00
case 3 :
2008-07-01 03:18:52 +02:00
{
CheckWinLimit ( bluescore ) ;
}
2008-07-28 09:47:28 +02:00
case 2 :
2008-07-01 03:18:52 +02:00
{
CheckWinLimit ( redscore ) ;
}
//We need to do nothing on winning_team == 0 this indicates stalemate.
default :
{
return ;
}
}
2008-05-01 04:39:35 +02:00
}
}
2008-03-30 09:00:22 +02:00
/* You ask, why don't you just use team_score event? And I answer... Because CSS doesn't. */
2014-12-16 19:38:43 +01:00
public void Event_RoundEnd ( Event event , const char [ ] name , bool dontBroadcast )
2008-03-30 09:00:22 +02:00
{
2008-07-01 03:18:52 +02:00
if ( g_ChangeMapAtRoundEnd )
2008-03-30 09:00:22 +02:00
{
2008-07-01 03:18:52 +02:00
g_ChangeMapAtRoundEnd = false ;
2008-07-08 01:12:21 +02:00
CreateTimer ( 2.0 , Timer_ChangeMap , INVALID_HANDLE , TIMER_FLAG_NO_MAPCHANGE ) ;
2008-09-28 06:46:07 +02:00
g_ChangeMapInProgress = true ;
2008-03-30 09:00:22 +02:00
}
2014-12-16 19:38:43 +01:00
int winner ;
2011-10-12 01:47:20 +02:00
if ( strcmp ( name , " round_win " ) = = 0 )
{
// Nuclear Dawn
2014-11-09 23:39:09 +01:00
winner = event . GetInt ( " team " ) ;
2011-10-12 01:47:20 +02:00
}
else
{
2014-11-09 23:39:09 +01:00
winner = event . GetInt ( " winner " ) ;
2011-10-12 01:47:20 +02:00
}
2008-03-30 09:00:22 +02:00
2014-11-10 01:22:58 +01:00
if ( winner = = 0 | | winner = = 1 | | ! g_Cvar_EndOfMapVote . BoolValue )
2008-03-30 09:00:22 +02:00
{
2008-07-01 03:18:52 +02:00
return ;
2008-03-30 09:00:22 +02:00
}
2008-07-01 03:18:52 +02:00
if ( winner > = MAXTEAMS )
2008-03-30 09:00:22 +02:00
{
2008-07-01 03:18:52 +02:00
SetFailState ( " Mod exceed maximum team count - Please file a bug report. " ) ;
2008-03-30 09:00:22 +02:00
}
2008-07-01 03:18:52 +02:00
g_TotalRounds + + ;
g_winCount [ winner ] + + ;
2008-03-30 09:00:22 +02:00
2014-12-16 19:38:43 +01:00
if ( ! g_MapList . Length | | g_HasVoteStarted | | g_MapVoteCompleted )
2008-08-27 02:49:56 +02:00
{
return ;
}
2008-07-01 03:18:52 +02:00
CheckWinLimit ( g_winCount [ winner ] ) ;
CheckMaxRounds ( g_TotalRounds ) ;
}
2014-12-16 19:38:43 +01:00
public void CheckWinLimit ( int winner_score )
2008-07-01 03:18:52 +02:00
{
2014-11-10 01:22:58 +01:00
if ( g_Cvar_Winlimit )
2008-03-30 09:00:22 +02:00
{
2014-11-10 01:22:58 +01:00
int winlimit = g_Cvar_Winlimit . IntValue ;
2008-03-30 09:00:22 +02:00
if ( winlimit )
2008-07-01 03:18:52 +02:00
{
2014-11-10 01:22:58 +01:00
if ( winner_score > = ( winlimit - g_Cvar_StartRounds . IntValue ) )
2008-03-30 09:00:22 +02:00
{
2014-11-16 01:30:45 +01:00
InitiateVote ( MapChange_MapEnd , null ) ;
2008-03-30 09:00:22 +02:00
}
}
}
2008-07-01 03:18:52 +02:00
}
2014-12-16 19:38:43 +01:00
public void CheckMaxRounds ( int roundcount )
2008-07-01 03:18:52 +02:00
{
2014-11-10 01:22:58 +01:00
if ( g_Cvar_Maxrounds )
2008-03-30 09:00:22 +02:00
{
2014-11-10 01:22:58 +01:00
int maxrounds = g_Cvar_Maxrounds . IntValue ;
2008-03-30 09:00:22 +02:00
if ( maxrounds )
{
2014-11-10 01:22:58 +01:00
if ( roundcount > = ( maxrounds - g_Cvar_StartRounds . IntValue ) )
2008-03-30 09:00:22 +02:00
{
2014-11-16 01:30:45 +01:00
InitiateVote ( MapChange_MapEnd , null ) ;
2008-03-30 09:00:22 +02:00
}
}
}
}
2014-12-16 19:38:43 +01:00
public void Event_PlayerDeath ( Event event , const char [ ] name , bool dontBroadcast )
2008-03-30 09:00:22 +02:00
{
2014-12-16 19:38:43 +01:00
if ( ! g_MapList . Length | | ! g_Cvar_Fraglimit | | g_HasVoteStarted )
2008-03-30 09:00:22 +02:00
{
return ;
}
2014-11-10 01:22:58 +01:00
if ( ! g_Cvar_Fraglimit . IntValue | | ! g_Cvar_EndOfMapVote . BoolValue )
2008-03-30 09:00:22 +02:00
{
return ;
}
2009-02-19 08:35:41 +01:00
if ( g_MapVoteCompleted )
{
return ;
}
2014-12-16 19:38:43 +01:00
int fragger = GetClientOfUserId ( event . GetInt ( " attacker " ) ) ;
2009-02-19 08:35:41 +01:00
if ( ! fragger )
{
return ;
}
2014-11-10 01:22:58 +01:00
if ( GetClientFrags ( fragger ) > = ( g_Cvar_Fraglimit . IntValue - g_Cvar_StartFrags . IntValue ) )
2008-03-30 09:00:22 +02:00
{
2014-11-16 01:30:45 +01:00
InitiateVote ( MapChange_MapEnd , null ) ;
2008-03-30 09:00:22 +02:00
}
}
2014-12-16 19:38:43 +01:00
public Action Command_Mapvote ( int client , int args )
2008-03-30 09:00:22 +02:00
{
2014-11-16 01:30:45 +01:00
InitiateVote ( MapChange_MapEnd , null ) ;
2008-03-30 09:00:22 +02:00
return Plugin_Handled ;
}
2008-09-28 06:46:07 +02:00
/ * *
* Starts a new map vote
*
* @ param when When the resulting map change should occur .
* @ param inputlist Optional list of maps to use for the vote , otherwise an internal list of nominations + random maps will be used .
2011-11-06 01:36:20 +01:00
* @ param noSpecials Block special vote options like extend / nochange ( upgrade this to bitflags instead ? )
2008-09-28 06:46:07 +02:00
* /
2014-12-16 19:38:43 +01:00
void InitiateVote ( MapChange when , ArrayList inputlist = null )
2008-03-30 09:00:22 +02:00
{
2008-07-01 03:18:52 +02:00
g_WaitingForVote = true ;
2008-03-30 09:00:22 +02:00
if ( IsVoteInProgress ( ) )
{
// Can't start a vote, try again in 5 seconds.
2008-09-28 06:46:07 +02:00
//g_RetryTimer = CreateTimer(5.0, Timer_StartMapVote, _, TIMER_FLAG_NO_MAPCHANGE);
2014-12-16 19:38:43 +01:00
DataPack data ;
2008-09-28 06:46:07 +02:00
g_RetryTimer = CreateDataTimer ( 5.0 , Timer_StartMapVote , data , TIMER_FLAG_NO_MAPCHANGE ) ;
2014-12-16 19:38:43 +01:00
data . WriteCell ( when ) ;
data . WriteCell ( inputlist ) ;
data . Reset ( ) ;
2008-09-28 06:46:07 +02:00
return ;
}
/* If the main map vote has completed (and chosen result) and its currently changing (not a delayed change) we block further attempts */
if ( g_MapVoteCompleted & & g_ChangeMapInProgress )
{
2008-03-30 09:00:22 +02:00
return ;
2008-07-01 03:18:52 +02:00
}
g_ChangeTime = when ;
2008-03-30 09:00:22 +02:00
2008-07-01 03:18:52 +02:00
g_WaitingForVote = false ;
2008-03-30 09:00:22 +02:00
g_HasVoteStarted = true ;
2014-12-16 19:38:43 +01:00
g_VoteMenu = new Menu ( Handler_MapVoteMenu , MENU_ACTIONS_ALL ) ;
2014-11-16 01:30:45 +01:00
g_VoteMenu . SetTitle ( " Vote Nextmap " ) ;
g_VoteMenu . VoteResultCallback = Handler_MapVoteFinished ;
2010-11-19 05:39:53 +01:00
/* Call OnMapVoteStarted() Forward */
Call_StartForward ( g_MapVoteStartedForward ) ;
Call_Finish ( ) ;
2008-07-01 03:18:52 +02:00
/ * *
* TODO : Make a proper decision on when to clear the nominations list .
* Currently it clears when used , and stays if an external list is provided .
* Is this the right thing to do ? External lists will probably come from places
* like sm_mapvote from the adminmenu in the future .
* /
2014-11-10 01:22:58 +01:00
char map [ PLATFORM_MAX_PATH ] ;
2008-07-01 03:18:52 +02:00
/* No input given - User our internal nominations and maplist */
2014-11-16 01:30:45 +01:00
if ( inputlist = = null )
2008-03-30 09:00:22 +02:00
{
2014-12-16 19:38:43 +01:00
int nominateCount = g_NominateList . Length ;
2014-11-10 01:22:58 +01:00
int voteSize = g_Cvar_IncludeMaps . IntValue ;
2008-07-01 03:18:52 +02:00
/* Smaller of the two - It should be impossible for nominations to exceed the size though (cvar changed mid-map?) */
2014-11-10 01:22:58 +01:00
int nominationsToAdd = nominateCount > = voteSize ? voteSize : nominateCount ;
2008-07-01 03:18:52 +02:00
2014-12-16 19:38:43 +01:00
for ( int i = 0 ; i < nominationsToAdd ; i + + )
2008-07-01 03:18:52 +02:00
{
2015-09-14 17:21:26 +02:00
char displayName [ PLATFORM_MAX_PATH ] ;
2014-12-16 19:38:43 +01:00
g_NominateList . GetString ( i , map , sizeof ( map ) ) ;
2015-09-14 17:21:26 +02:00
GetMapDisplayName ( map , displayName , sizeof ( displayName ) ) ;
g_VoteMenu . AddItem ( map , displayName ) ;
2011-11-06 01:36:20 +01:00
RemoveStringFromArray ( g_NextMapList , map ) ;
2008-07-01 03:18:52 +02:00
/* Notify Nominations that this map is now free */
Call_StartForward ( g_NominationsResetForward ) ;
Call_PushString ( map ) ;
2014-12-16 19:38:43 +01:00
Call_PushCell ( g_NominateOwners . Get ( i ) ) ;
2008-07-01 03:18:52 +02:00
Call_Finish ( ) ;
}
/* Clear out the rest of the nominations array */
2014-12-16 19:38:43 +01:00
for ( int i = nominationsToAdd ; i < nominateCount ; i + + )
2008-07-01 03:18:52 +02:00
{
2014-12-16 19:38:43 +01:00
g_NominateList . GetString ( i , map , sizeof ( map ) ) ;
2011-11-06 01:36:20 +01:00
/* These maps shouldn't be excluded from the vote as they weren't really nominated at all */
2008-07-01 03:18:52 +02:00
/* Notify Nominations that this map is now free */
Call_StartForward ( g_NominationsResetForward ) ;
Call_PushString ( map ) ;
2014-12-16 19:38:43 +01:00
Call_PushCell ( g_NominateOwners . Get ( i ) ) ;
2008-07-01 03:18:52 +02:00
Call_Finish ( ) ;
}
/* There should currently be 'nominationsToAdd' unique maps in the vote */
2014-12-16 19:38:43 +01:00
int i = nominationsToAdd ;
int count = 0 ;
int availableMaps = g_NextMapList . Length ;
2008-07-01 03:18:52 +02:00
while ( i < voteSize )
{
2014-05-13 22:44:14 +02:00
if ( count > = availableMaps )
{
//Run out of maps, this will have to do.
break ;
}
2014-12-16 19:38:43 +01:00
g_NextMapList . GetString ( count , map , sizeof ( map ) ) ;
2008-07-01 03:18:52 +02:00
count + + ;
2011-11-06 01:36:20 +01:00
/* Insert the map and increment our count */
2015-09-14 17:21:26 +02:00
char displayName [ PLATFORM_MAX_PATH ] ;
GetMapDisplayName ( map , displayName , sizeof ( displayName ) ) ;
g_VoteMenu . AddItem ( map , displayName ) ;
2011-11-06 01:36:20 +01:00
i + + ;
2008-07-01 03:18:52 +02:00
}
/* Wipe out our nominations list - Nominations have already been informed of this */
2015-01-06 16:07:15 +01:00
g_NominateOwners . Clear ( ) ;
g_NominateList . Clear ( ) ;
2008-03-30 09:00:22 +02:00
}
2008-07-01 03:18:52 +02:00
else //We were given a list of maps to start the vote with
{
2014-12-16 19:38:43 +01:00
int size = inputlist . Length ;
2008-07-01 03:18:52 +02:00
2014-12-16 19:38:43 +01:00
for ( int i = 0 ; i < size ; i + + )
2008-07-01 03:18:52 +02:00
{
2014-12-16 19:38:43 +01:00
inputlist . GetString ( i , map , sizeof ( map ) ) ;
2008-07-01 03:18:52 +02:00
if ( IsMapValid ( map ) )
{
2015-09-14 17:21:26 +02:00
char displayName [ PLATFORM_MAX_PATH ] ;
GetMapDisplayName ( map , displayName , sizeof ( displayName ) ) ;
g_VoteMenu . AddItem ( map , displayName ) ;
2008-07-01 03:18:52 +02:00
}
}
}
/* Do we add any special items? */
2014-11-10 01:22:58 +01:00
if ( ( when = = MapChange_Instant | | when = = MapChange_RoundEnd ) & & g_Cvar_DontChange . BoolValue )
2008-07-01 03:18:52 +02:00
{
2014-11-16 01:30:45 +01:00
g_VoteMenu . AddItem ( VOTE_DONTCHANGE , " Don't Change " ) ;
2008-07-01 03:18:52 +02:00
}
2014-11-10 01:22:58 +01:00
else if ( g_Cvar_Extend . BoolValue & & g_Extends < g_Cvar_Extend . IntValue )
2008-03-30 09:00:22 +02:00
{
2014-11-16 01:30:45 +01:00
g_VoteMenu . AddItem ( VOTE_EXTEND , " Extend Map " ) ;
2008-03-30 09:00:22 +02:00
}
2008-07-01 03:18:52 +02:00
2014-05-13 22:44:14 +02:00
/* There are no maps we could vote for. Don't show anything. */
2014-11-16 01:30:45 +01:00
if ( g_VoteMenu . ItemCount = = 0 )
2014-05-13 22:44:14 +02:00
{
g_HasVoteStarted = false ;
2014-11-16 01:30:45 +01:00
delete g_VoteMenu ;
g_VoteMenu = null ;
2014-05-13 22:44:14 +02:00
return ;
}
2014-11-10 01:22:58 +01:00
int voteDuration = g_Cvar_VoteDuration . IntValue ;
2008-03-30 09:00:22 +02:00
2014-11-16 01:30:45 +01:00
g_VoteMenu . ExitButton = false ;
g_VoteMenu . DisplayVoteToAll ( voteDuration ) ;
2008-03-30 09:00:22 +02:00
2011-03-21 00:37:25 +01:00
LogAction ( - 1 , - 1 , " Voting for next map has started. " ) ;
2008-03-30 09:00:22 +02:00
PrintToChatAll ( " [SM] %t " , " Nextmap Voting Started " ) ;
}
2014-12-16 19:38:43 +01:00
public void Handler_VoteFinishedGeneric ( Menu menu ,
2014-12-16 22:20:03 +01:00
int num_votes ,
2014-12-16 19:38:43 +01:00
int num_clients ,
2014-12-16 22:20:03 +01:00
const int [ ] [ ] client_info ,
2014-12-16 19:38:43 +01:00
int num_items ,
2014-12-16 22:20:03 +01:00
const int [ ] [ ] item_info )
2008-07-01 03:18:52 +02:00
{
2014-11-10 01:22:58 +01:00
char map [ PLATFORM_MAX_PATH ] ;
2015-09-14 17:21:26 +02:00
char displayName [ PLATFORM_MAX_PATH ] ;
menu . GetItem ( item_info [ 0 ] [ VOTEINFO_ITEM_INDEX ] , map , sizeof ( map ) , _ , displayName , sizeof ( displayName ) ) ;
2008-07-01 03:18:52 +02:00
if ( strcmp ( map , VOTE_EXTEND , false ) = = 0 )
{
g_Extends + + ;
2014-11-10 01:22:58 +01:00
int time ;
2008-07-01 03:18:52 +02:00
if ( GetMapTimeLimit ( time ) )
{
if ( time > 0 )
{
2014-11-10 01:22:58 +01:00
ExtendMapTimeLimit ( g_Cvar_ExtendTimeStep . IntValue * 60 ) ;
2008-07-01 03:18:52 +02:00
}
}
2014-11-10 01:22:58 +01:00
if ( g_Cvar_Winlimit )
2008-07-01 03:18:52 +02:00
{
2014-11-10 01:22:58 +01:00
int winlimit = g_Cvar_Winlimit . IntValue ;
2008-07-01 03:18:52 +02:00
if ( winlimit )
{
2014-11-10 01:22:58 +01:00
g_Cvar_Winlimit . IntValue = winlimit + g_Cvar_ExtendRoundStep . IntValue ;
2008-07-01 03:18:52 +02:00
}
}
2014-11-10 01:22:58 +01:00
if ( g_Cvar_Maxrounds )
2008-07-01 03:18:52 +02:00
{
2014-12-16 19:38:43 +01:00
int maxrounds = g_Cvar_Maxrounds . IntValue ;
2008-07-01 03:18:52 +02:00
if ( maxrounds )
{
2014-11-10 01:22:58 +01:00
g_Cvar_Maxrounds . IntValue = maxrounds + g_Cvar_ExtendRoundStep . IntValue ;
2008-07-01 03:18:52 +02:00
}
}
2014-11-10 01:22:58 +01:00
if ( g_Cvar_Fraglimit )
2008-07-01 03:18:52 +02:00
{
2014-11-10 01:22:58 +01:00
int fraglimit = g_Cvar_Fraglimit . IntValue ;
2008-07-01 03:18:52 +02:00
if ( fraglimit )
{
2014-11-10 01:22:58 +01:00
g_Cvar_Fraglimit . IntValue = fraglimit + g_Cvar_ExtendFragStep . IntValue ;
2008-07-01 03:18:52 +02:00
}
}
PrintToChatAll ( " [SM] %t " , " Current Map Extended " , RoundToFloor ( float ( item_info [ 0 ] [ VOTEINFO_ITEM_VOTES ] ) / float ( num_votes ) * 100 ) , num_votes ) ;
2011-03-21 00:37:25 +01:00
LogAction ( - 1 , - 1 , " Voting for next map has finished. The current map has been extended. " ) ;
2008-07-01 03:18:52 +02:00
// We extended, so we'll have to vote again.
g_HasVoteStarted = false ;
CreateNextVote ( ) ;
SetupTimeleftTimer ( ) ;
}
else if ( strcmp ( map , VOTE_DONTCHANGE , false ) = = 0 )
{
PrintToChatAll ( " [SM] %t " , " Current Map Stays " , RoundToFloor ( float ( item_info [ 0 ] [ VOTEINFO_ITEM_VOTES ] ) / float ( num_votes ) * 100 ) , num_votes ) ;
2011-03-21 00:37:25 +01:00
LogAction ( - 1 , - 1 , " Voting for next map has finished. 'No Change' was the winner " ) ;
2008-07-01 03:18:52 +02:00
g_HasVoteStarted = false ;
CreateNextVote ( ) ;
SetupTimeleftTimer ( ) ;
}
else
{
if ( g_ChangeTime = = MapChange_MapEnd )
{
SetNextMap ( map ) ;
}
else if ( g_ChangeTime = = MapChange_Instant )
{
2014-12-16 19:38:43 +01:00
DataPack data ;
2008-07-01 03:18:52 +02:00
CreateDataTimer ( 2.0 , Timer_ChangeMap , data ) ;
2014-12-16 19:38:43 +01:00
data . WriteString ( map ) ;
2008-09-28 06:46:07 +02:00
g_ChangeMapInProgress = false ;
2008-07-01 03:18:52 +02:00
}
else // MapChange_RoundEnd
{
SetNextMap ( map ) ;
g_ChangeMapAtRoundEnd = true ;
}
g_HasVoteStarted = false ;
g_MapVoteCompleted = true ;
2015-09-14 17:21:26 +02:00
PrintToChatAll ( " [SM] %t " , " Nextmap Voting Finished " , displayName , RoundToFloor ( float ( item_info [ 0 ] [ VOTEINFO_ITEM_VOTES ] ) / float ( num_votes ) * 100 ) , num_votes ) ;
2011-03-21 00:37:25 +01:00
LogAction ( - 1 , - 1 , " Voting for next map has finished. Nextmap: %s. " , map ) ;
2008-07-01 03:18:52 +02:00
}
}
2014-12-16 19:38:43 +01:00
public void Handler_MapVoteFinished ( Menu menu ,
2014-12-16 22:20:03 +01:00
int num_votes ,
2014-11-16 01:30:45 +01:00
int num_clients ,
2014-12-16 22:20:03 +01:00
const int [ ] [ ] client_info ,
2014-11-16 01:30:45 +01:00
int num_items ,
2014-12-16 22:20:03 +01:00
const int [ ] [ ] item_info )
2011-11-06 01:36:20 +01:00
{
2014-11-10 01:22:58 +01:00
if ( g_Cvar_RunOff . BoolValue & & num_items > 1 )
2011-11-06 01:36:20 +01:00
{
2014-11-10 01:22:58 +01:00
float winningvotes = float ( item_info [ 0 ] [ VOTEINFO_ITEM_VOTES ] ) ;
float required = num_votes * ( g_Cvar_RunOffPercent . FloatValue / 100.0 ) ;
2011-11-06 01:36:20 +01:00
2013-08-30 20:14:59 +02:00
if ( winningvotes < required )
2011-11-06 01:36:20 +01:00
{
/* Insufficient Winning margin - Lets do a runoff */
2014-12-17 22:05:14 +01:00
g_VoteMenu = new Menu ( Handler_MapVoteMenu , MENU_ACTIONS_ALL ) ;
2014-11-16 01:30:45 +01:00
g_VoteMenu . SetTitle ( " Runoff Vote Nextmap " ) ;
2014-12-17 22:05:14 +01:00
g_VoteMenu . VoteResultCallback = Handler_VoteFinishedGeneric ;
2011-11-06 01:36:20 +01:00
2014-11-10 01:22:58 +01:00
char map [ PLATFORM_MAX_PATH ] ;
char info1 [ PLATFORM_MAX_PATH ] ;
char info2 [ PLATFORM_MAX_PATH ] ;
2011-11-06 01:36:20 +01:00
2014-11-16 01:30:45 +01:00
menu . GetItem ( item_info [ 0 ] [ VOTEINFO_ITEM_INDEX ] , map , sizeof ( map ) , _ , info1 , sizeof ( info1 ) ) ;
g_VoteMenu . AddItem ( map , info1 ) ;
menu . GetItem ( item_info [ 1 ] [ VOTEINFO_ITEM_INDEX ] , map , sizeof ( map ) , _ , info2 , sizeof ( info2 ) ) ;
g_VoteMenu . AddItem ( map , info2 ) ;
2011-11-06 01:36:20 +01:00
2014-11-10 01:22:58 +01:00
int voteDuration = g_Cvar_VoteDuration . IntValue ;
2014-11-16 01:30:45 +01:00
g_VoteMenu . ExitButton = false ;
g_VoteMenu . DisplayVoteToAll ( voteDuration ) ;
2011-11-06 01:36:20 +01:00
/* Notify */
2014-11-16 01:30:45 +01:00
float map1percent = float ( item_info [ 0 ] [ VOTEINFO_ITEM_VOTES ] ) / float ( num_votes ) * 100 ;
float map2percent = float ( item_info [ 1 ] [ VOTEINFO_ITEM_VOTES ] ) / float ( num_votes ) * 100 ;
2011-11-06 01:36:20 +01:00
2014-11-10 01:22:58 +01:00
PrintToChatAll ( " [SM] %t " , " Starting Runoff " , g_Cvar_RunOffPercent . FloatValue , info1 , map1percent , info2 , map2percent ) ;
2011-11-06 01:36:20 +01:00
LogMessage ( " Voting for next map was indecisive, beginning runoff vote " ) ;
return ;
}
}
Handler_VoteFinishedGeneric ( menu , num_votes , num_clients , client_info , num_items , item_info ) ;
}
2014-12-16 19:38:43 +01:00
public int Handler_MapVoteMenu ( Menu menu , MenuAction action , int param1 , int param2 )
2008-03-30 09:00:22 +02:00
{
switch ( action )
{
case MenuAction_End :
{
2014-11-16 01:30:45 +01:00
g_VoteMenu = null ;
delete menu ;
2008-03-30 09:00:22 +02:00
}
case MenuAction_Display :
{
2014-12-16 19:38:43 +01:00
char buffer [ 255 ] ;
2008-03-30 09:00:22 +02:00
Format ( buffer , sizeof ( buffer ) , " %T " , " Vote Nextmap " , param1 ) ;
2014-12-16 19:38:43 +01:00
Panel panel = view_as < Panel > ( param2 ) ;
2014-11-16 01:30:45 +01:00
panel . SetTitle ( buffer ) ;
2008-03-30 09:00:22 +02:00
}
case MenuAction_DisplayItem :
{
2014-11-16 01:30:45 +01:00
if ( menu . ItemCount - 1 = = param2 )
2008-03-30 09:00:22 +02:00
{
2014-11-16 01:30:45 +01:00
char map [ PLATFORM_MAX_PATH ] , buffer [ 255 ] ;
menu . GetItem ( param2 , map , sizeof ( map ) ) ;
2008-03-30 09:00:22 +02:00
if ( strcmp ( map , VOTE_EXTEND , false ) = = 0 )
{
Format ( buffer , sizeof ( buffer ) , " %T " , " Extend Map " , param1 ) ;
return RedrawMenuItem ( buffer ) ;
}
2008-07-01 03:18:52 +02:00
else if ( strcmp ( map , VOTE_DONTCHANGE , false ) = = 0 )
{
Format ( buffer , sizeof ( buffer ) , " %T " , " Dont Change " , param1 ) ;
return RedrawMenuItem ( buffer ) ;
}
2008-03-30 09:00:22 +02:00
}
}
2008-07-01 03:18:52 +02:00
2008-03-30 09:00:22 +02:00
case MenuAction_VoteCancel :
{
// If we receive 0 votes, pick at random.
2014-11-10 01:22:58 +01:00
if ( param1 = = VoteCancel_NoVotes & & g_Cvar_NoVoteMode . BoolValue )
2008-03-30 09:00:22 +02:00
{
2014-12-16 19:38:43 +01:00
int count = menu . ItemCount ;
char map [ PLATFORM_MAX_PATH ] ;
2014-11-16 01:30:45 +01:00
menu . GetItem ( 0 , map , sizeof ( map ) ) ;
2008-03-30 09:00:22 +02:00
2014-05-13 22:44:14 +02:00
// Make sure the first map in the menu isn't one of the special items.
// This would mean there are no real maps in the menu, because the special items are added after all maps. Don't do anything if that's the case.
if ( strcmp ( map , VOTE_EXTEND , false ) ! = 0 & & strcmp ( map , VOTE_DONTCHANGE , false ) ! = 0 )
2008-03-30 09:00:22 +02:00
{
2014-05-13 22:44:14 +02:00
// Get a random map from the list.
2014-12-16 19:38:43 +01:00
int item = GetRandomInt ( 0 , count - 1 ) ;
2014-11-16 01:30:45 +01:00
menu . GetItem ( item , map , sizeof ( map ) ) ;
2014-05-13 22:44:14 +02:00
// Make sure it's not one of the special items.
while ( strcmp ( map , VOTE_EXTEND , false ) = = 0 | | strcmp ( map , VOTE_DONTCHANGE , false ) = = 0 )
{
item = GetRandomInt ( 0 , count - 1 ) ;
2014-11-16 01:30:45 +01:00
menu . GetItem ( item , map , sizeof ( map ) ) ;
2014-05-13 22:44:14 +02:00
}
SetNextMap ( map ) ;
g_MapVoteCompleted = true ;
2008-03-30 09:00:22 +02:00
}
}
else
{
2008-07-10 03:11:51 +02:00
// We were actually cancelled. I guess we do nothing.
2008-03-30 09:00:22 +02:00
}
2008-08-27 02:49:56 +02:00
g_HasVoteStarted = false ;
2008-03-30 09:00:22 +02:00
}
}
return 0 ;
}
2014-12-16 19:38:43 +01:00
public Action Timer_ChangeMap ( Handle hTimer , DataPack dp )
2008-03-30 09:00:22 +02:00
{
2008-09-28 06:46:07 +02:00
g_ChangeMapInProgress = false ;
2014-12-16 19:38:43 +01:00
char map [ PLATFORM_MAX_PATH ] ;
2008-07-01 03:18:52 +02:00
2014-11-16 01:30:45 +01:00
if ( dp = = null )
2008-03-30 09:00:22 +02:00
{
2008-07-01 03:18:52 +02:00
if ( ! GetNextMap ( map , sizeof ( map ) ) )
{
//No passed map and no set nextmap. fail!
return Plugin_Stop ;
}
2008-03-30 09:00:22 +02:00
}
2008-07-01 03:18:52 +02:00
else
{
2014-12-16 19:38:43 +01:00
dp . Reset ( ) ;
dp . ReadString ( map , sizeof ( map ) ) ;
2008-07-01 03:18:52 +02:00
}
2008-07-13 07:13:37 +02:00
ForceChangeLevel ( map , " Map Vote " ) ;
2008-07-01 03:18:52 +02:00
return Plugin_Stop ;
2008-03-30 09:00:22 +02:00
}
2014-12-16 19:38:43 +01:00
bool RemoveStringFromArray ( ArrayList array , char [ ] str )
2008-03-30 09:00:22 +02:00
{
2014-12-16 19:38:43 +01:00
int index = array . FindString ( str ) ;
2011-11-06 01:36:20 +01:00
if ( index ! = - 1 )
2008-03-30 09:00:22 +02:00
{
2014-12-16 19:38:43 +01:00
array . Erase ( index ) ;
2011-11-06 01:36:20 +01:00
return true ;
2008-03-30 09:00:22 +02:00
}
2011-11-06 01:36:20 +01:00
return false ;
}
2014-12-16 19:38:43 +01:00
void CreateNextVote ( )
2011-11-06 01:36:20 +01:00
{
2015-09-14 17:21:26 +02:00
g_NextMapList . Clear ( ) ;
2011-11-06 01:36:20 +01:00
2014-11-10 01:22:58 +01:00
char map [ PLATFORM_MAX_PATH ] ;
2015-09-14 17:21:26 +02:00
// tempMaps is a resolved map list
ArrayList tempMaps = new ArrayList ( ByteCountToCells ( PLATFORM_MAX_PATH ) ) ;
2008-03-30 09:00:22 +02:00
2015-09-14 17:21:26 +02:00
for ( int i = 0 ; i < g_MapList . Length ; i + + )
{
g_MapList . GetString ( i , map , sizeof ( map ) ) ;
if ( FindMap ( map , map , sizeof ( map ) ) ! = FindMap_NotFound )
{
tempMaps . PushString ( map ) ;
}
}
//GetCurrentMap always returns a resolved map
2008-03-30 09:00:22 +02:00
GetCurrentMap ( map , sizeof ( map ) ) ;
2011-11-06 01:36:20 +01:00
RemoveStringFromArray ( tempMaps , map ) ;
2008-03-30 09:00:22 +02:00
2014-12-16 19:38:43 +01:00
if ( g_Cvar_ExcludeMaps . IntValue & & tempMaps . Length > g_Cvar_ExcludeMaps . IntValue )
2008-03-30 09:00:22 +02:00
{
2014-12-16 19:38:43 +01:00
for ( int i = 0 ; i < g_OldMapList . Length ; i + + )
2008-03-30 09:00:22 +02:00
{
2014-12-16 19:38:43 +01:00
g_OldMapList . GetString ( i , map , sizeof ( map ) ) ;
2011-11-06 01:36:20 +01:00
RemoveStringFromArray ( tempMaps , map ) ;
2015-09-14 17:21:26 +02:00
}
2008-03-30 09:00:22 +02:00
}
2014-12-16 19:38:43 +01:00
int limit = ( g_Cvar_IncludeMaps . IntValue < tempMaps . Length ? g_Cvar_IncludeMaps . IntValue : tempMaps . Length ) ;
2014-11-10 01:22:58 +01:00
for ( int i = 0 ; i < limit ; i + + )
2008-03-30 09:00:22 +02:00
{
2014-12-16 23:00:00 +01:00
int b = GetRandomInt ( 0 , tempMaps . Length - 1 ) ;
2014-12-16 19:38:43 +01:00
tempMaps . GetString ( b , map , sizeof ( map ) ) ;
g_NextMapList . PushString ( map ) ;
tempMaps . Erase ( b ) ;
2008-03-30 09:00:22 +02:00
}
2014-11-16 01:30:45 +01:00
delete tempMaps ;
2008-07-01 03:18:52 +02:00
}
2014-12-16 19:38:43 +01:00
bool CanVoteStart ( )
2008-07-01 03:18:52 +02:00
{
if ( g_WaitingForVote | | g_HasVoteStarted )
{
return false ;
}
return true ;
}
2014-12-16 19:38:43 +01:00
NominateResult InternalNominateMap ( char [ ] map , bool force , int owner )
2008-07-01 03:18:52 +02:00
{
if ( ! IsMapValid ( map ) )
{
return Nominate_InvalidMap ;
}
2014-01-18 05:21:16 +01:00
/* Map already in the vote */
2014-12-16 19:38:43 +01:00
if ( g_NominateList . FindString ( map ) ! = - 1 )
2014-01-18 05:21:16 +01:00
{
return Nominate_AlreadyInVote ;
}
2014-12-16 19:38:43 +01:00
int index ;
2008-07-01 03:18:52 +02:00
2008-10-08 10:02:01 +02:00
/* Look to replace an existing nomination by this client - Nominations made with owner = 0 aren't replaced */
2014-12-16 19:38:43 +01:00
if ( owner & & ( ( index = g_NominateOwners . FindValue ( owner ) ) ! = - 1 ) )
2008-07-01 03:18:52 +02:00
{
2014-12-16 19:38:43 +01:00
char oldmap [ PLATFORM_MAX_PATH ] ;
g_NominateList . GetString ( index , oldmap , sizeof ( oldmap ) ) ;
2008-07-01 03:18:52 +02:00
Call_StartForward ( g_NominationsResetForward ) ;
Call_PushString ( oldmap ) ;
Call_PushCell ( owner ) ;
Call_Finish ( ) ;
2014-12-16 19:38:43 +01:00
g_NominateList . SetString ( index , map ) ;
2008-07-01 03:18:52 +02:00
return Nominate_Replaced ;
}
/* Too many nominated maps. */
2014-12-16 19:38:43 +01:00
if ( g_NominateList . Length > = g_Cvar_IncludeMaps . IntValue & & ! force )
2008-07-01 03:18:52 +02:00
{
return Nominate_VoteFull ;
}
2014-12-16 19:38:43 +01:00
g_NominateList . PushString ( map ) ;
g_NominateOwners . Push ( owner ) ;
2008-07-01 03:18:52 +02:00
2014-12-16 19:38:43 +01:00
while ( g_NominateList . Length > g_Cvar_IncludeMaps . IntValue )
2008-07-01 03:18:52 +02:00
{
2014-11-10 01:22:58 +01:00
char oldmap [ PLATFORM_MAX_PATH ] ;
2014-12-16 19:38:43 +01:00
g_NominateList . GetString ( 0 , oldmap , sizeof ( oldmap ) ) ;
2008-07-01 03:18:52 +02:00
Call_StartForward ( g_NominationsResetForward ) ;
Call_PushString ( oldmap ) ;
2014-12-16 23:00:00 +01:00
Call_PushCell ( g_NominateOwners . Get ( 0 ) ) ;
2008-07-01 03:18:52 +02:00
Call_Finish ( ) ;
2014-12-16 19:38:43 +01:00
g_NominateList . Erase ( 0 ) ;
g_NominateOwners . Erase ( 0 ) ;
2008-07-01 03:18:52 +02:00
}
return Nominate_Added ;
}
/* Add natives to allow nominate and initiate vote to be call */
2014-12-16 19:53:54 +01:00
/* native NominateResult NominateMap(const char[] map, bool force, int owner); */
2014-12-16 19:38:43 +01:00
public int Native_NominateMap ( Handle plugin , int numParams )
2008-07-01 03:18:52 +02:00
{
2014-12-16 19:38:43 +01:00
int len ;
2008-07-01 03:18:52 +02:00
GetNativeStringLength ( 1 , len ) ;
if ( len < = 0 )
{
return false ;
}
2014-12-16 19:38:43 +01:00
char [ ] map = new char [ len + 1 ] ;
2008-07-01 03:18:52 +02:00
GetNativeString ( 1 , map , len + 1 ) ;
2014-12-16 19:38:43 +01:00
return view_as < int > ( InternalNominateMap ( map , GetNativeCell ( 2 ) , GetNativeCell ( 3 ) ) ) ;
2008-07-01 03:18:52 +02:00
}
2014-12-16 19:38:43 +01:00
bool InternalRemoveNominationByMap ( char [ ] map )
2010-11-19 05:39:53 +01:00
{
2014-12-16 23:00:00 +01:00
for ( int i = 0 ; i < g_NominateList . Length ; i + + )
2010-11-19 05:39:53 +01:00
{
2014-12-16 19:38:43 +01:00
char oldmap [ PLATFORM_MAX_PATH ] ;
g_NominateList . GetString ( i , oldmap , sizeof ( oldmap ) ) ;
2010-11-19 05:39:53 +01:00
if ( strcmp ( map , oldmap , false ) = = 0 )
{
Call_StartForward ( g_NominationsResetForward ) ;
Call_PushString ( oldmap ) ;
2014-12-16 23:00:00 +01:00
Call_PushCell ( g_NominateOwners . Get ( i ) ) ;
2010-11-19 05:39:53 +01:00
Call_Finish ( ) ;
2014-12-16 19:38:43 +01:00
g_NominateList . Erase ( i ) ;
g_NominateOwners . Erase ( i ) ;
2010-11-19 05:39:53 +01:00
return true ;
}
}
return false ;
}
2014-12-16 19:53:54 +01:00
/* native bool RemoveNominationByMap(const char[] map); */
2014-12-16 19:38:43 +01:00
public int Native_RemoveNominationByMap ( Handle plugin , int numParams )
2010-11-19 05:39:53 +01:00
{
2014-12-16 19:38:43 +01:00
int len ;
2010-11-19 05:39:53 +01:00
GetNativeStringLength ( 1 , len ) ;
if ( len < = 0 )
{
return false ;
}
2014-12-16 19:38:43 +01:00
char [ ] map = new char [ len + 1 ] ;
2010-11-19 05:39:53 +01:00
GetNativeString ( 1 , map , len + 1 ) ;
2014-12-16 19:53:54 +01:00
return InternalRemoveNominationByMap ( map ) ;
2010-11-19 05:39:53 +01:00
}
2014-12-16 19:38:43 +01:00
bool InternalRemoveNominationByOwner ( int owner )
2010-11-19 05:39:53 +01:00
{
2014-12-16 19:38:43 +01:00
int index ;
2010-11-19 05:39:53 +01:00
2014-12-16 19:38:43 +01:00
if ( owner & & ( ( index = g_NominateOwners . FindValue ( owner ) ) ! = - 1 ) )
2010-11-19 05:39:53 +01:00
{
2014-12-16 19:38:43 +01:00
char oldmap [ PLATFORM_MAX_PATH ] ;
g_NominateList . GetString ( index , oldmap , sizeof ( oldmap ) ) ;
2010-11-19 05:39:53 +01:00
Call_StartForward ( g_NominationsResetForward ) ;
Call_PushString ( oldmap ) ;
Call_PushCell ( owner ) ;
Call_Finish ( ) ;
2014-12-16 19:38:43 +01:00
g_NominateList . Erase ( index ) ;
g_NominateOwners . Erase ( index ) ;
2010-11-19 05:39:53 +01:00
return true ;
}
return false ;
}
2014-12-16 19:53:54 +01:00
/* native bool RemoveNominationByOwner(int owner); */
2014-12-16 19:38:43 +01:00
public int Native_RemoveNominationByOwner ( Handle plugin , int numParams )
2010-11-19 05:39:53 +01:00
{
2014-12-16 19:53:54 +01:00
return InternalRemoveNominationByOwner ( GetNativeCell ( 1 ) ) ;
2010-11-19 05:39:53 +01:00
}
2014-12-26 18:36:12 +01:00
/* native void InitiateMapChooserVote(MapChange when, ArrayList inputarray=null); */
2014-12-16 19:38:43 +01:00
public int Native_InitiateVote ( Handle plugin , int numParams )
2008-07-01 03:18:52 +02:00
{
2014-12-16 19:38:43 +01:00
MapChange when = view_as < MapChange > ( GetNativeCell ( 1 ) ) ;
ArrayList inputarray = view_as < ArrayList > ( GetNativeCell ( 2 ) ) ;
2008-07-01 03:18:52 +02:00
2011-03-21 00:37:25 +01:00
LogAction ( - 1 , - 1 , " Starting map vote because outside request " ) ;
2008-07-01 03:18:52 +02:00
InitiateVote ( when , inputarray ) ;
}
2014-12-16 19:53:54 +01:00
/* native bool CanMapChooserStartVote(); */
2014-12-16 19:38:43 +01:00
public int Native_CanVoteStart ( Handle plugin , int numParams )
2008-07-01 03:18:52 +02:00
{
return CanVoteStart ( ) ;
}
2014-12-16 19:53:54 +01:00
/* native bool HasEndOfMapVoteFinished(); */
2014-12-16 19:38:43 +01:00
public int Native_CheckVoteDone ( Handle plugin , int numParams )
2008-07-01 03:18:52 +02:00
{
return g_MapVoteCompleted ;
}
2014-12-16 19:53:54 +01:00
/* native bool EndOfMapVoteEnabled(); */
2014-12-16 19:38:43 +01:00
public int Native_EndOfMapVoteEnabled ( Handle plugin , int numParams )
2008-08-08 02:06:14 +02:00
{
2014-11-10 01:22:58 +01:00
return g_Cvar_EndOfMapVote . BoolValue ;
2008-08-08 02:06:14 +02:00
}
2014-12-26 18:36:12 +01:00
/* native void GetExcludeMapList(ArrayList array); */
2014-12-16 19:38:43 +01:00
public int Native_GetExcludeMapList ( Handle plugin , int numParams )
2008-07-01 03:18:52 +02:00
{
2014-12-16 19:38:43 +01:00
ArrayList array = view_as < ArrayList > ( GetNativeCell ( 1 ) ) ;
2008-07-01 03:18:52 +02:00
2014-11-16 01:30:45 +01:00
if ( array = = null )
2008-07-01 03:18:52 +02:00
{
return ;
}
2014-12-16 19:38:43 +01:00
int size = g_OldMapList . Length ;
char map [ PLATFORM_MAX_PATH ] ;
2008-07-01 03:18:52 +02:00
2014-12-16 19:38:43 +01:00
for ( int i = 0 ; i < size ; i + + )
2008-07-01 03:18:52 +02:00
{
2014-12-16 19:38:43 +01:00
g_OldMapList . GetString ( i , map , sizeof ( map ) ) ;
array . PushString ( map ) ;
2008-07-01 03:18:52 +02:00
}
return ;
2008-09-28 06:46:07 +02:00
}
2010-11-19 05:39:53 +01:00
2014-12-26 18:36:12 +01:00
/* native void GetNominatedMapList(ArrayList maparray, ArrayList ownerarray = null); */
2014-12-16 19:38:43 +01:00
public int Native_GetNominatedMapList ( Handle plugin , int numParams )
2010-11-19 05:39:53 +01:00
{
2014-12-16 19:38:43 +01:00
ArrayList maparray = view_as < ArrayList > ( GetNativeCell ( 1 ) ) ;
ArrayList ownerarray = view_as < ArrayList > ( GetNativeCell ( 2 ) ) ;
2010-11-19 05:39:53 +01:00
2014-11-16 01:30:45 +01:00
if ( maparray = = null )
2010-11-19 05:39:53 +01:00
return ;
2014-12-16 19:38:43 +01:00
char map [ PLATFORM_MAX_PATH ] ;
2010-11-19 05:39:53 +01:00
2014-12-16 19:38:43 +01:00
for ( int i = 0 ; i < g_NominateList . Length ; i + + )
2010-11-19 05:39:53 +01:00
{
2014-12-16 19:38:43 +01:00
g_NominateList . GetString ( i , map , sizeof ( map ) ) ;
maparray . PushString ( map ) ;
2010-11-19 05:39:53 +01:00
// If the optional parameter for an owner list was passed, then we need to fill that out as well
2014-11-16 01:30:45 +01:00
if ( ownerarray ! = null )
2010-11-19 05:39:53 +01:00
{
2014-12-16 19:38:43 +01:00
int index = g_NominateOwners . Get ( i ) ;
ownerarray . Push ( index ) ;
2010-11-19 05:39:53 +01:00
}
}
return ;
2014-07-04 23:31:56 +02:00
}