plugins/mapchooser.sp
author David Anderson <dvander@alliedmods.net>
Sat Dec 22 08:57:08 2007 +0000 (2007-12-22)
changeset 1813 372939c88bc7
parent 1719 c9d5e55f0899
child 1861 cc6c6ed7615d
permissions -rw-r--r--
fixed amb1305 by making OnClientPostAdminCheck() always occur after OnClientPutInServer(). this is now GUARANTEED. it was undefined before, however the usual case was opposite. if plugins were relying on this, they were written poorly and shouldn't have worked in the first place, especially with the threaded SQL plugin.
ferret99gt@1440
     1
/**
ferret99gt@1440
     2
 * vim: set ts=4 :
ferret99gt@1440
     3
 * =============================================================================
ferret99gt@1440
     4
 * SourceMod Mapchooser Plugin
ferret99gt@1440
     5
 * Creates a map vote at appropriate times, setting sm_nextmap to the winning
ferret99gt@1440
     6
 * vote
ferret99gt@1440
     7
 *
ferret99gt@1440
     8
 * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
ferret99gt@1440
     9
 * =============================================================================
ferret99gt@1440
    10
 *
ferret99gt@1440
    11
 * This program is free software; you can redistribute it and/or modify it under
ferret99gt@1440
    12
 * the terms of the GNU General Public License, version 3.0, as published by the
ferret99gt@1440
    13
 * Free Software Foundation.
ferret99gt@1440
    14
 * 
ferret99gt@1440
    15
 * This program is distributed in the hope that it will be useful, but WITHOUT
ferret99gt@1440
    16
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ferret99gt@1440
    17
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ferret99gt@1440
    18
 * details.
ferret99gt@1440
    19
 *
ferret99gt@1440
    20
 * You should have received a copy of the GNU General Public License along with
ferret99gt@1440
    21
 * this program.  If not, see <http://www.gnu.org/licenses/>.
ferret99gt@1440
    22
 *
ferret99gt@1440
    23
 * As a special exception, AlliedModders LLC gives you permission to link the
ferret99gt@1440
    24
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ferret99gt@1440
    25
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ferret99gt@1440
    26
 * by the Valve Corporation.  You must obey the GNU General Public License in
ferret99gt@1440
    27
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ferret99gt@1440
    28
 * this exception to all derivative works.  AlliedModders LLC defines further
ferret99gt@1440
    29
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ferret99gt@1440
    30
 * or <http://www.sourcemod.net/license.php>.
ferret99gt@1440
    31
 *
ferret99gt@1440
    32
 * Version: $Id$
ferret99gt@1440
    33
 */
ferret99gt@1440
    34
ferret99gt@1440
    35
#pragma semicolon 1
ferret99gt@1440
    36
#include <sourcemod>
ferret99gt@1440
    37
ferret99gt@1479
    38
public Plugin:myinfo =
ferret99gt@1479
    39
{
ferret99gt@1479
    40
	name = "MapChooser",
ferret99gt@1479
    41
	author = "AlliedModders LLC",
ferret99gt@1479
    42
	description = "Automated Map Voting",
ferret99gt@1479
    43
	version = SOURCEMOD_VERSION,
ferret99gt@1479
    44
	url = "http://www.sourcemod.net/"
ferret99gt@1479
    45
};
ferret99gt@1440
    46
ferret99gt@1440
    47
new Handle:g_Cvar_Winlimit = INVALID_HANDLE;
ferret99gt@1440
    48
new Handle:g_Cvar_Maxrounds = INVALID_HANDLE;
ferret99gt@1479
    49
new Handle:g_Cvar_Fraglimit = INVALID_HANDLE;
ferret99gt@1440
    50
ferret99gt@1440
    51
new Handle:g_Cvar_Nextmap = INVALID_HANDLE;
ferret99gt@1479
    52
ferret99gt@1440
    53
new Handle:g_Cvar_StartTime = INVALID_HANDLE;
ferret99gt@1479
    54
new Handle:g_Cvar_StartRounds = INVALID_HANDLE;
ferret99gt@1479
    55
new Handle:g_Cvar_StartFrags = INVALID_HANDLE;
ferret99gt@1440
    56
new Handle:g_Cvar_ExtendTimeMax = INVALID_HANDLE;
ferret99gt@1440
    57
new Handle:g_Cvar_ExtendTimeStep = INVALID_HANDLE;
ferret99gt@1445
    58
new Handle:g_Cvar_ExtendRoundMax = INVALID_HANDLE;
ferret99gt@1445
    59
new Handle:g_Cvar_ExtendRoundStep = INVALID_HANDLE;
ferret99gt@1479
    60
new Handle:g_Cvar_ExtendFragMax = INVALID_HANDLE;
ferret99gt@1479
    61
new Handle:g_Cvar_ExtendFragStep = INVALID_HANDLE;
ferret99gt@1440
    62
new Handle:g_Cvar_Mapfile = INVALID_HANDLE;
ferret99gt@1440
    63
new Handle:g_Cvar_ExcludeMaps = INVALID_HANDLE;
ferret99gt@1479
    64
new Handle:g_Cvar_IncludeMaps = INVALID_HANDLE;
ferret99gt@1531
    65
new Handle:g_Cvar_NoVoteMode = INVALID_HANDLE;
ferret99gt@1531
    66
new Handle:g_Cvar_Extend = INVALID_HANDLE;
ferret99gt@1440
    67
ferret99gt@1440
    68
new Handle:g_VoteTimer = INVALID_HANDLE;
ferret99gt@1440
    69
new Handle:g_RetryTimer = INVALID_HANDLE;
ferret99gt@1440
    70
ferret99gt@1440
    71
new Handle:g_MapList = INVALID_HANDLE;
ferret99gt@1440
    72
new Handle:g_OldMapList = INVALID_HANDLE;
ferret99gt@1440
    73
new Handle:g_NextMapList = INVALID_HANDLE;
ferret99gt@1606
    74
new Handle:g_TeamScores = INVALID_HANDLE;
ferret99gt@1440
    75
new Handle:g_VoteMenu = INVALID_HANDLE;
ferret99gt@1440
    76
ferret99gt@1698
    77
new g_TotalRounds;
ferret99gt@1440
    78
new bool:g_HasVoteStarted;
ferret99gt@1440
    79
new g_mapFileTime;
ferret99gt@1440
    80
ferret99gt@1531
    81
#define VOTE_EXTEND "##extend##"
ferret99gt@1531
    82
ferret99gt@1440
    83
public OnPluginStart()
ferret99gt@1440
    84
{
ferret99gt@1440
    85
	LoadTranslations("mapchooser.phrases");
ferret99gt@1440
    86
	
ferret99gt@1664
    87
	new arraySize = ByteCountToCells(33);
ferret99gt@1664
    88
	g_MapList = CreateArray(arraySize);
ferret99gt@1664
    89
	g_OldMapList = CreateArray(arraySize);
ferret99gt@1664
    90
	g_NextMapList = CreateArray(arraySize);
ferret99gt@1440
    91
ferret99gt@1479
    92
	g_Cvar_StartTime = CreateConVar("sm_mapvote_start", "3.0", "Specifies when to start the vote based on time remaining.", _, true, 1.0);
ferret99gt@1479
    93
	g_Cvar_StartRounds = CreateConVar("sm_mapvote_startround", "2.0", "Specifies when to start the vote based on rounds remaining.", _, true, 1.0);
ferret99gt@1479
    94
	g_Cvar_StartFrags = CreateConVar("sm_mapvote_startfrags", "5.0", "Specifies when to start the vote base on frags remaining.", _, true, 1.0);
ferret99gt@1479
    95
	g_Cvar_ExtendTimeMax = CreateConVar("sm_extendmap_maxtime", "90", "Specifies the maximum amount of time a map can be extended", _, true, 0.0);
ferret99gt@1440
    96
	g_Cvar_ExtendTimeStep = CreateConVar("sm_extendmap_timestep", "15", "Specifies how much many more minutes each extension makes", _, true, 5.0);
ferret99gt@1479
    97
	g_Cvar_ExtendRoundMax = CreateConVar("sm_extendmap_maxrounds", "30", "Specfies the maximum amount of rounds a map can be extended", _, true, 0.0);
ferret99gt@1445
    98
	g_Cvar_ExtendRoundStep = CreateConVar("sm_extendmap_roundstep", "5", "Specifies how many more rounds each extension makes", _, true, 5.0);
ferret99gt@1479
    99
	g_Cvar_ExtendFragMax = CreateConVar("sm_extendmap_maxfrags", "150", "Specfies the maximum frags allowed that a map can be extended.", _, true, 0.0);
ferret99gt@1479
   100
	g_Cvar_ExtendFragStep = CreateConVar("sm_extendmap_fragstep", "10", "Specifies how many more frags are allowed when map is extended.", _, true, 5.0);	
ferret99gt@1440
   101
	g_Cvar_Mapfile = CreateConVar("sm_mapvote_file", "configs/maps.ini", "Map file to use. (Def sourcemod/configs/maps.ini)");
ferret99gt@1440
   102
	g_Cvar_ExcludeMaps = CreateConVar("sm_mapvote_exclude", "5", "Specifies how many past maps to exclude from the vote.", _, true, 0.0);
ferret99gt@1479
   103
	g_Cvar_IncludeMaps = CreateConVar("sm_mapvote_include", "5", "Specifies how many maps to include in the vote.", _, true, 2.0, true, 6.0);
ferret99gt@1531
   104
	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);
ferret99gt@1531
   105
	g_Cvar_Extend = CreateConVar("sm_mapvote_extend", "1", "Specifies whether or not MapChooser will allow the map to be extended.", _, true, 0.0, true, 1.0);
ferret99gt@1440
   106
ferret99gt@1479
   107
	RegAdminCmd("sm_mapvote", Command_Mapvote, ADMFLAG_CHANGEMAP, "sm_mapvote - Forces MapChooser to attempt to run a map vote now.");
ferret99gt@1440
   108
ferret99gt@1452
   109
	g_Cvar_Winlimit = FindConVar("mp_winlimit");
ferret99gt@1452
   110
	g_Cvar_Maxrounds = FindConVar("mp_maxrounds");
ferret99gt@1479
   111
	g_Cvar_Fraglimit = FindConVar("mp_fraglimit");
ferret99gt@1452
   112
	
ferret99gt@1452
   113
	if (g_Cvar_Winlimit != INVALID_HANDLE || g_Cvar_Maxrounds != INVALID_HANDLE)
ferret99gt@1440
   114
	{
ferret99gt@1452
   115
		HookEvent("round_end", Event_RoundEnd);
ferret99gt@1440
   116
	}
ferret99gt@1467
   117
	
ferret99gt@1479
   118
	if (g_Cvar_Fraglimit != INVALID_HANDLE)
ferret99gt@1479
   119
	{
ferret99gt@1479
   120
		HookEvent("player_death", Event_PlayerDeath);		
ferret99gt@1479
   121
	}
ferret99gt@1479
   122
	
ferret99gt@1467
   123
	AutoExecConfig(true, "mapchooser");
ferret99gt@1440
   124
}
ferret99gt@1440
   125
ferret99gt@1606
   126
public OnConfigsExecuted()
ferret99gt@1440
   127
{
ferret99gt@1440
   128
	g_Cvar_Nextmap = FindConVar("sm_nextmap");
ferret99gt@1440
   129
ferret99gt@1440
   130
	if (g_Cvar_Nextmap == INVALID_HANDLE)
ferret99gt@1440
   131
	{
ferret99gt@1440
   132
		LogError("FATAL: Cannot find sm_nextmap cvar. Mapchooser not loaded.");
ferret99gt@1440
   133
		SetFailState("sm_nextmap not found");
ferret99gt@1440
   134
	}
ferret99gt@1440
   135
	
ferret99gt@1606
   136
	if (LoadMaps(g_MapList, g_mapFileTime, g_Cvar_Mapfile))
ferret99gt@1440
   137
	{
ferret99gt@1440
   138
		CreateNextVote();
ferret99gt@1440
   139
		SetupTimeleftTimer();
ferret99gt@1531
   140
		SetConVarString(g_Cvar_Nextmap, "Pending Vote");
ferret99gt@1440
   141
	}
ferret99gt@1698
   142
	
ferret99gt@1698
   143
	if (g_TeamScores != INVALID_HANDLE)
ferret99gt@1698
   144
	{
ferret99gt@1698
   145
		CloseHandle(g_TeamScores);
ferret99gt@1698
   146
	}
ferret99gt@1698
   147
	
ferret99gt@1698
   148
	g_TeamScores = CreateArray(2);
ferret99gt@1698
   149
	g_TotalRounds = 0;
ferret99gt@1440
   150
}
ferret99gt@1440
   151
ferret99gt@1440
   152
public OnMapEnd()
ferret99gt@1440
   153
{
ferret99gt@1440
   154
	g_HasVoteStarted = false;
ferret99gt@1606
   155
	
ferret99gt@1606
   156
	if (g_VoteTimer != INVALID_HANDLE)
ferret99gt@1606
   157
	{
ferret99gt@1606
   158
		KillTimer(g_VoteTimer);
ferret99gt@1606
   159
		g_VoteTimer = INVALID_HANDLE;
ferret99gt@1606
   160
	}
ferret99gt@1606
   161
	
ferret99gt@1606
   162
	if (g_RetryTimer != INVALID_HANDLE)
ferret99gt@1606
   163
	{
ferret99gt@1606
   164
		KillTimer(g_RetryTimer);
ferret99gt@1606
   165
		g_RetryTimer = INVALID_HANDLE;
ferret99gt@1606
   166
	}
ferret99gt@1440
   167
}
ferret99gt@1440
   168
ferret99gt@1440
   169
public OnMapTimeLeftChanged()
ferret99gt@1440
   170
{
ferret99gt@1467
   171
	if (GetArraySize(g_MapList))
ferret99gt@1467
   172
	{
ferret99gt@1467
   173
		SetupTimeleftTimer();
ferret99gt@1467
   174
	}
ferret99gt@1440
   175
}
ferret99gt@1440
   176
ferret99gt@1440
   177
SetupTimeleftTimer()
ferret99gt@1440
   178
{
ferret99gt@1440
   179
	new time;
ferret99gt@1440
   180
	if (GetMapTimeLeft(time) && time > 0)
ferret99gt@1440
   181
	{
ferret99gt@1506
   182
		new startTime = GetConVarInt(g_Cvar_StartTime) * 60;
ferret99gt@1440
   183
		if (time - startTime < 0)
ferret99gt@1440
   184
		{
ferret99gt@1452
   185
			InitiateVote();		
ferret99gt@1440
   186
		}
ferret99gt@1440
   187
		else
ferret99gt@1440
   188
		{
ferret99gt@1440
   189
			if (g_VoteTimer != INVALID_HANDLE)
ferret99gt@1440
   190
			{
ferret99gt@1440
   191
				KillTimer(g_VoteTimer);
ferret99gt@1440
   192
				g_VoteTimer = INVALID_HANDLE;
ferret99gt@1452
   193
			}	
ferret99gt@1440
   194
			
ferret99gt@1606
   195
			g_VoteTimer = CreateTimer(float(time - startTime), Timer_StartMapVote);
ferret99gt@1440
   196
		}		
ferret99gt@1440
   197
	}
ferret99gt@1440
   198
}
ferret99gt@1440
   199
ferret99gt@1440
   200
public Action:Timer_StartMapVote(Handle:timer)
ferret99gt@1440
   201
{
ferret99gt@1452
   202
	if (!GetArraySize(g_MapList))
ferret99gt@1440
   203
	{
ferret99gt@1440
   204
		return Plugin_Stop;
ferret99gt@1479
   205
	}		
ferret99gt@1452
   206
	
ferret99gt@1440
   207
	if (timer == g_RetryTimer)
ferret99gt@1440
   208
	{
ferret99gt@1440
   209
		g_RetryTimer = INVALID_HANDLE;
ferret99gt@1440
   210
	}
ferret99gt@1440
   211
	else
ferret99gt@1440
   212
	{
ferret99gt@1440
   213
		g_VoteTimer = INVALID_HANDLE;
ferret99gt@1440
   214
	}
ferret99gt@1440
   215
ferret99gt@1440
   216
	InitiateVote();
ferret99gt@1440
   217
ferret99gt@1440
   218
	return Plugin_Stop;
ferret99gt@1440
   219
}
ferret99gt@1440
   220
ferret99gt@1479
   221
/* You ask, why don't you just use team_score event? And I answer... Because CSS doesn't. */
ferret99gt@1452
   222
public Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
ferret99gt@1440
   223
{
ferret99gt@1528
   224
	if (!GetArraySize(g_MapList) || g_HasVoteStarted)
ferret99gt@1440
   225
	{
ferret99gt@1440
   226
		return;
ferret99gt@1440
   227
	}
ferret99gt@1440
   228
ferret99gt@1479
   229
	new winner = GetEventInt(event, "winner");
ferret99gt@1479
   230
	
ferret99gt@1479
   231
	if (winner == 0 || winner == 1)
ferret99gt@1452
   232
	{
ferret99gt@1452
   233
		return;
ferret99gt@1452
   234
	}
ferret99gt@1479
   235
ferret99gt@1698
   236
	g_TotalRounds++;
ferret99gt@1479
   237
	
ferret99gt@1479
   238
	new team[2], teamPos = -1;
ferret99gt@1528
   239
	for (new i; i < GetArraySize(g_TeamScores); i++)
ferret99gt@1479
   240
	{
ferret99gt@1528
   241
		GetArrayArray(g_TeamScores, i, team);
ferret99gt@1479
   242
		if (team[0] == winner)
ferret99gt@1479
   243
		{
ferret99gt@1479
   244
			teamPos = i;
ferret99gt@1479
   245
			break;
ferret99gt@1479
   246
		}		
ferret99gt@1479
   247
	}
ferret99gt@1479
   248
	
ferret99gt@1479
   249
	if (teamPos == -1)
ferret99gt@1479
   250
	{
ferret99gt@1479
   251
		team[0] = winner;
ferret99gt@1479
   252
		team[1] = 1;
ferret99gt@1528
   253
		PushArrayArray(g_TeamScores, team);
ferret99gt@1479
   254
	}
ferret99gt@1479
   255
	else
ferret99gt@1479
   256
	{
ferret99gt@1479
   257
		team[1]++;
ferret99gt@1528
   258
		SetArrayArray(g_TeamScores, teamPos, team);
ferret99gt@1479
   259
	}	
ferret99gt@1452
   260
	
ferret99gt@1452
   261
	if (g_Cvar_Winlimit != INVALID_HANDLE)
ferret99gt@1440
   262
	{
ferret99gt@1452
   263
		new winlimit = GetConVarInt(g_Cvar_Winlimit);
ferret99gt@1452
   264
		if (winlimit)
ferret99gt@1440
   265
		{
ferret99gt@1528
   266
			if (team[1] >= (winlimit - GetConVarInt(g_Cvar_StartRounds)))
ferret99gt@1452
   267
			{
ferret99gt@1452
   268
				InitiateVote();
ferret99gt@1452
   269
			}
ferret99gt@1440
   270
		}
ferret99gt@1440
   271
	}
ferret99gt@1452
   272
	
ferret99gt@1452
   273
	if (g_Cvar_Maxrounds != INVALID_HANDLE)
ferret99gt@1440
   274
	{
ferret99gt@1440
   275
		new maxrounds = GetConVarInt(g_Cvar_Maxrounds);
ferret99gt@1440
   276
		if (maxrounds)
ferret99gt@1440
   277
		{
ferret99gt@1698
   278
			if (g_TotalRounds >= (maxrounds - GetConVarInt(g_Cvar_StartRounds)))
ferret99gt@1440
   279
			{
ferret99gt@1440
   280
				InitiateVote();
ferret99gt@1440
   281
			}			
ferret99gt@1440
   282
		}
ferret99gt@1440
   283
	}
ferret99gt@1440
   284
}
ferret99gt@1440
   285
ferret99gt@1479
   286
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
ferret99gt@1479
   287
{
ferret99gt@1528
   288
	if (!GetArraySize(g_MapList) || g_Cvar_Fraglimit == INVALID_HANDLE || g_HasVoteStarted)
ferret99gt@1483
   289
	{
ferret99gt@1483
   290
		return;
ferret99gt@1483
   291
	}
ferret99gt@1483
   292
	
ferret99gt@1483
   293
	if (!GetConVarInt(g_Cvar_Fraglimit))
ferret99gt@1479
   294
	{
ferret99gt@1479
   295
		return;
ferret99gt@1479
   296
	}
ferret99gt@1479
   297
ferret99gt@1479
   298
	new fragger = GetClientOfUserId(GetEventInt(event, "attacker"));
ferret99gt@1528
   299
	if (fragger && GetClientFrags(fragger) >= (GetConVarInt(g_Cvar_Fraglimit) - GetConVarInt(g_Cvar_StartFrags)))
ferret99gt@1479
   300
	{
ferret99gt@1479
   301
		InitiateVote();
ferret99gt@1479
   302
	}
ferret99gt@1479
   303
}
ferret99gt@1479
   304
ferret99gt@1479
   305
public Action:Command_Mapvote(client, args)
ferret99gt@1517
   306
{
ferret99gt@1479
   307
	InitiateVote();
ferret99gt@1479
   308
ferret99gt@1479
   309
	return Plugin_Handled;	
ferret99gt@1479
   310
}
ferret99gt@1479
   311
ferret99gt@1440
   312
InitiateVote()
ferret99gt@1440
   313
{
ferret99gt@1440
   314
	if (g_HasVoteStarted || g_RetryTimer != INVALID_HANDLE)
ferret99gt@1440
   315
	{
ferret99gt@1440
   316
		return;
ferret99gt@1440
   317
	}
ferret99gt@1440
   318
	
ferret99gt@1440
   319
	if (IsVoteInProgress())
ferret99gt@1440
   320
	{
ferret99gt@1440
   321
		// Can't start a vote, try again in 5 seconds.
ferret99gt@1606
   322
		g_RetryTimer = CreateTimer(5.0, Timer_StartMapVote);
ferret99gt@1440
   323
		return;
ferret99gt@1440
   324
	}		
ferret99gt@1440
   325
	
ferret99gt@1440
   326
	g_HasVoteStarted = true;
ferret99gt@1440
   327
	g_VoteMenu = CreateMenu(Handler_MapVoteMenu, MenuAction:MENU_ACTIONS_ALL);
ferret99gt@1440
   328
	SetMenuTitle(g_VoteMenu, "Vote Nextmap");
ferret99gt@1440
   329
ferret99gt@1440
   330
	decl String:map[32];
ferret99gt@1452
   331
	for (new i = 0; i < GetArraySize(g_NextMapList); i++)
ferret99gt@1440
   332
	{
ferret99gt@1452
   333
		GetArrayString(g_NextMapList, i, map, sizeof(map));
ferret99gt@1440
   334
		AddMenuItem(g_VoteMenu, map, map);
ferret99gt@1440
   335
	}
ferret99gt@1440
   336
ferret99gt@1531
   337
	if (GetConVarBool(g_Cvar_Extend))
ferret99gt@1440
   338
	{
ferret99gt@1531
   339
		new bool:allowExtend, time;
ferret99gt@1531
   340
		if (GetMapTimeLimit(time) && time > 0 && time < GetConVarInt(g_Cvar_ExtendTimeMax))
ferret99gt@1531
   341
		{
ferret99gt@1531
   342
			allowExtend = true;
ferret99gt@1531
   343
		}
ferret99gt@1531
   344
ferret99gt@1531
   345
		if (g_Cvar_Winlimit != INVALID_HANDLE && GetConVarInt(g_Cvar_Winlimit) < GetConVarInt(g_Cvar_ExtendRoundMax))
ferret99gt@1531
   346
		{
ferret99gt@1531
   347
			allowExtend = true;
ferret99gt@1531
   348
		}	
ferret99gt@1452
   349
	
ferret99gt@1531
   350
		if (g_Cvar_Maxrounds != INVALID_HANDLE && GetConVarInt(g_Cvar_Maxrounds) < GetConVarInt(g_Cvar_ExtendRoundMax))
ferret99gt@1531
   351
		{
ferret99gt@1531
   352
			allowExtend = true;
ferret99gt@1531
   353
		}
ferret99gt@1479
   354
	
ferret99gt@1531
   355
		if (g_Cvar_Fraglimit != INVALID_HANDLE && GetConVarInt(g_Cvar_Fraglimit) < GetConVarInt(g_Cvar_ExtendFragMax))
ferret99gt@1531
   356
		{
ferret99gt@1531
   357
			allowExtend = true;
ferret99gt@1531
   358
		}
ferret99gt@1440
   359
ferret99gt@1531
   360
		if (allowExtend)
ferret99gt@1531
   361
		{
ferret99gt@1531
   362
			AddMenuItem(g_VoteMenu, VOTE_EXTEND, "Extend Map");
ferret99gt@1531
   363
		}
ferret99gt@1440
   364
	}
ferret99gt@1440
   365
ferret99gt@1440
   366
	SetMenuExitButton(g_VoteMenu, false);
ferret99gt@1440
   367
	VoteMenuToAll(g_VoteMenu, 20);
ferret99gt@1440
   368
ferret99gt@1440
   369
	LogMessage("Voting for next map has started.");
ferret99gt@1440
   370
	PrintToChatAll("[SM] %t", "Nextmap Voting Started");
ferret99gt@1440
   371
}
ferret99gt@1440
   372
ferret99gt@1440
   373
public Handler_MapVoteMenu(Handle:menu, MenuAction:action, param1, param2)
ferret99gt@1440
   374
{
ferret99gt@1440
   375
	switch (action)
ferret99gt@1440
   376
	{
ferret99gt@1440
   377
		case MenuAction_End:
ferret99gt@1440
   378
		{
ferret99gt@1440
   379
			g_VoteMenu = INVALID_HANDLE;
ferret99gt@1440
   380
			CloseHandle(menu);
ferret99gt@1440
   381
		}
ferret99gt@1440
   382
		
ferret99gt@1440
   383
		case MenuAction_Display:
ferret99gt@1440
   384
		{
ferret99gt@1440
   385
	 		decl String:buffer[255];
ferret99gt@1440
   386
			Format(buffer, sizeof(buffer), "%T", "Vote Nextmap", param1);
ferret99gt@1440
   387
ferret99gt@1440
   388
			new Handle:panel = Handle:param2;
ferret99gt@1440
   389
			SetPanelTitle(panel, buffer);
ferret99gt@1479
   390
		}		
ferret99gt@1479
   391
		
ferret99gt@1479
   392
		case MenuAction_DisplayItem:
ferret99gt@1479
   393
		{
ferret99gt@1479
   394
			if (GetMenuItemCount(menu) - 1 == param2)
ferret99gt@1479
   395
			{
ferret99gt@1479
   396
				decl String:map[64], String:buffer[255];
ferret99gt@1479
   397
				GetMenuItem(menu, param2, map, sizeof(map));
ferret99gt@1531
   398
				if (strcmp(map, VOTE_EXTEND, false) == 0)
ferret99gt@1479
   399
				{
ferret99gt@1479
   400
					Format(buffer, sizeof(buffer), "%T", "Extend Map", param1);
ferret99gt@1479
   401
					return RedrawMenuItem(buffer);
ferret99gt@1479
   402
				}
ferret99gt@1479
   403
			}
ferret99gt@1479
   404
		}		
ferret99gt@1440
   405
ferret99gt@1440
   406
		// Why am I commented out? Because BAIL hasn't decided yet if
ferret99gt@1440
   407
		// vote notification will be built into the Vote API.
ferret99gt@1440
   408
		/*case MenuAction_Select:
ferret99gt@1440
   409
		{
ferret99gt@1440
   410
			decl String:Name[32], String:Map[32];
ferret99gt@1440
   411
			GetClientName(param1, Name, sizeof(Name));
ferret99gt@1440
   412
			GetMenuItem(menu, param2, Map, sizeof(Map));
ferret99gt@1440
   413
ferret99gt@1440
   414
			PrintToChatAll("[SM] %s has voted for map '%s'", Name, Map);
ferret99gt@1440
   415
		}*/
ferret99gt@1440
   416
		
ferret99gt@1440
   417
		case MenuAction_VoteCancel:
ferret99gt@1440
   418
		{
ferret99gt@1440
   419
			// If we receive 0 votes, pick at random.
ferret99gt@1531
   420
			if (param1 == VoteCancel_NoVotes && GetConVarBool(g_Cvar_NoVoteMode))
ferret99gt@1440
   421
			{
ferret99gt@1440
   422
				new count = GetMenuItemCount(menu);
ferret99gt@1440
   423
				new item = GetRandomInt(0, count - 1);
ferret99gt@1440
   424
				decl String:map[32];
ferret99gt@1440
   425
				GetMenuItem(menu, item, map, sizeof(map));
ferret99gt@1440
   426
				
ferret99gt@1531
   427
				while (strcmp(map, VOTE_EXTEND, false) == 0)
ferret99gt@1440
   428
				{
ferret99gt@1440
   429
					item = GetRandomInt(0, count - 1);
ferret99gt@1440
   430
					GetMenuItem(menu, item, map, sizeof(map));
ferret99gt@1440
   431
				}
ferret99gt@1440
   432
				
ferret99gt@1440
   433
				SetNextMap(map);			
ferret99gt@1440
   434
			}
ferret99gt@1440
   435
			else
ferret99gt@1440
   436
			{
ferret99gt@1440
   437
				// We were actually cancelled. What should we do?
ferret99gt@1440
   438
			}
ferret99gt@1440
   439
		}
ferret99gt@1440
   440
ferret99gt@1440
   441
		case MenuAction_VoteEnd:
ferret99gt@1440
   442
		{
ferret99gt@1440
   443
			decl String:map[32];
ferret99gt@1440
   444
			GetMenuItem(menu, param1, map, sizeof(map));
ferret99gt@1440
   445
ferret99gt@1531
   446
			if (strcmp(map, VOTE_EXTEND, false) == 0)
ferret99gt@1440
   447
			{
ferret99gt@1440
   448
				new time;
ferret99gt@1440
   449
				if (GetMapTimeLimit(time))
ferret99gt@1440
   450
				{
ferret99gt@1440
   451
					if (time > 0 && time < GetConVarInt(g_Cvar_ExtendTimeMax))
ferret99gt@1440
   452
					{
ferret99gt@1482
   453
						ExtendMapTimeLimit(GetConVarInt(g_Cvar_ExtendTimeStep)*60);						
ferret99gt@1440
   454
					}
ferret99gt@1440
   455
				}
ferret99gt@1440
   456
				
ferret99gt@1452
   457
				if (g_Cvar_Winlimit != INVALID_HANDLE)
ferret99gt@1440
   458
				{
ferret99gt@1440
   459
					new winlimit = GetConVarInt(g_Cvar_Winlimit);
ferret99gt@1452
   460
					if (winlimit && winlimit < GetConVarInt(g_Cvar_ExtendRoundMax))
ferret99gt@1440
   461
					{
ferret99gt@1452
   462
						SetConVarInt(g_Cvar_Winlimit, winlimit + GetConVarInt(g_Cvar_ExtendRoundStep));
ferret99gt@1452
   463
					}					
ferret99gt@1452
   464
				}
ferret99gt@1452
   465
				
ferret99gt@1452
   466
				if (g_Cvar_Maxrounds != INVALID_HANDLE)
ferret99gt@1452
   467
				{
ferret99gt@1452
   468
					new maxrounds = GetConVarInt(g_Cvar_Maxrounds);
ferret99gt@1452
   469
					if (maxrounds && maxrounds < GetConVarInt(g_Cvar_ExtendRoundMax))
ferret99gt@1440
   470
					{
ferret99gt@1452
   471
						SetConVarInt(g_Cvar_Maxrounds, maxrounds + GetConVarInt(g_Cvar_ExtendRoundStep));
ferret99gt@1440
   472
					}
ferret99gt@1440
   473
				}
ferret99gt@1479
   474
				
ferret99gt@1479
   475
				if (g_Cvar_Fraglimit != INVALID_HANDLE)
ferret99gt@1479
   476
				{
ferret99gt@1479
   477
					new fraglimit = GetConVarInt(g_Cvar_Fraglimit);
ferret99gt@1479
   478
					if (fraglimit && fraglimit < GetConVarInt(g_Cvar_ExtendFragMax))
ferret99gt@1479
   479
					{
ferret99gt@1479
   480
						SetConVarInt(g_Cvar_Fraglimit, fraglimit + GetConVarInt(g_Cvar_ExtendFragStep));						
ferret99gt@1479
   481
					}
ferret99gt@1479
   482
				}
ferret99gt@1440
   483
ferret99gt@1440
   484
				PrintToChatAll("[SM] %t", "Current Map Extended");
ferret99gt@1440
   485
				LogMessage("Voting for next map has finished. The current map has been extended.");
ferret99gt@1440
   486
				
ferret99gt@1445
   487
				// We extended, so we'll have to vote again.
ferret99gt@1440
   488
				g_HasVoteStarted = false;
ferret99gt@1479
   489
				CreateNextVote();
ferret99gt@1445
   490
				SetupTimeleftTimer();
ferret99gt@1440
   491
			}
ferret99gt@1440
   492
			else
ferret99gt@1440
   493
			{
ferret99gt@1440
   494
				SetNextMap(map);
ferret99gt@1440
   495
			}
ferret99gt@1440
   496
		}
ferret99gt@1440
   497
	}
ferret99gt@1479
   498
	
ferret99gt@1479
   499
	return 0;
ferret99gt@1440
   500
}
ferret99gt@1440
   501
ferret99gt@1440
   502
SetNextMap(const String:map[])
ferret99gt@1440
   503
{
ferret99gt@1440
   504
	SetConVarString(g_Cvar_Nextmap, map);
ferret99gt@1440
   505
	PushArrayString(g_OldMapList, map);
ferret99gt@1440
   506
				
ferret99gt@1479
   507
	if (GetArraySize(g_OldMapList) > GetConVarInt(g_Cvar_ExcludeMaps))
ferret99gt@1440
   508
	{
ferret99gt@1440
   509
		RemoveFromArray(g_OldMapList, 0);
ferret99gt@1440
   510
	}
ferret99gt@1440
   511
		
ferret99gt@1452
   512
	PrintToChatAll("[SM] %t", "Nextmap Voting Finished", map);
ferret99gt@1440
   513
	LogMessage("Voting for next map has finished. Nextmap: %s.", map);	
ferret99gt@1440
   514
}
ferret99gt@1440
   515
ferret99gt@1440
   516
CreateNextVote()
ferret99gt@1440
   517
{
ferret99gt@1452
   518
	if(g_NextMapList != INVALID_HANDLE)
ferret99gt@1445
   519
	{
ferret99gt@1452
   520
		ClearArray(g_NextMapList);
ferret99gt@1533
   521
	}
ferret99gt@1440
   522
	
ferret99gt@1533
   523
	decl String:map[32];
ferret99gt@1719
   524
	new index, Handle:tempMaps  = CloneArray(g_MapList);
ferret99gt@1719
   525
	
ferret99gt@1719
   526
	GetCurrentMap(map, sizeof(map));
ferret99gt@1719
   527
	index = FindStringInArray(tempMaps, map);
ferret99gt@1719
   528
	if (index != -1)
ferret99gt@1719
   529
	{
ferret99gt@1719
   530
		RemoveFromArray(tempMaps, index);
ferret99gt@1719
   531
	}	
ferret99gt@1440
   532
	
ferret99gt@1664
   533
	if (GetConVarInt(g_Cvar_ExcludeMaps) && GetArraySize(tempMaps) > GetConVarInt(g_Cvar_ExcludeMaps))
ferret99gt@1533
   534
	{
ferret99gt@1533
   535
		for (new i = 0; i < GetArraySize(g_OldMapList); i++)
ferret99gt@1533
   536
		{
ferret99gt@1533
   537
			GetArrayString(g_OldMapList, i, map, sizeof(map));
ferret99gt@1719
   538
			index = FindStringInArray(tempMaps, map);
ferret99gt@1664
   539
			if (index != -1)
ferret99gt@1533
   540
			{
ferret99gt@1664
   541
				RemoveFromArray(tempMaps, index);
ferret99gt@1533
   542
			}
ferret99gt@1533
   543
		}	
ferret99gt@1533
   544
	}
ferret99gt@1533
   545
ferret99gt@1533
   546
	new limit = (GetConVarInt(g_Cvar_IncludeMaps) < GetArraySize(tempMaps) ? GetConVarInt(g_Cvar_IncludeMaps) : GetArraySize(tempMaps));
ferret99gt@1452
   547
	for (new i = 0; i < limit; i++)
ferret99gt@1440
   548
	{
ferret99gt@1533
   549
		new b = GetRandomInt(0, GetArraySize(tempMaps) - 1);
ferret99gt@1533
   550
		GetArrayString(tempMaps, b, map, sizeof(map));		
ferret99gt@1533
   551
		PushArrayString(g_NextMapList, map);
ferret99gt@1533
   552
		RemoveFromArray(tempMaps, b);
ferret99gt@1440
   553
	}
ferret99gt@1642
   554
	
ferret99gt@1642
   555
	CloseHandle(tempMaps);
ferret99gt@1440
   556
}