ferret99gt@1440: /** ferret99gt@1440: * vim: set ts=4 : ferret99gt@1440: * ============================================================================= ferret99gt@1440: * SourceMod Mapchooser Plugin ferret99gt@1440: * Creates a map vote at appropriate times, setting sm_nextmap to the winning ferret99gt@1440: * vote ferret99gt@1440: * ferret99gt@1440: * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. ferret99gt@1440: * ============================================================================= ferret99gt@1440: * ferret99gt@1440: * This program is free software; you can redistribute it and/or modify it under ferret99gt@1440: * the terms of the GNU General Public License, version 3.0, as published by the ferret99gt@1440: * Free Software Foundation. ferret99gt@1440: * ferret99gt@1440: * This program is distributed in the hope that it will be useful, but WITHOUT ferret99gt@1440: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ferret99gt@1440: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ferret99gt@1440: * details. ferret99gt@1440: * ferret99gt@1440: * You should have received a copy of the GNU General Public License along with ferret99gt@1440: * this program. If not, see . ferret99gt@1440: * ferret99gt@1440: * As a special exception, AlliedModders LLC gives you permission to link the ferret99gt@1440: * code of this program (as well as its derivative works) to "Half-Life 2," the ferret99gt@1440: * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software ferret99gt@1440: * by the Valve Corporation. You must obey the GNU General Public License in ferret99gt@1440: * all respects for all other code used. Additionally, AlliedModders LLC grants ferret99gt@1440: * this exception to all derivative works. AlliedModders LLC defines further ferret99gt@1440: * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), ferret99gt@1440: * or . ferret99gt@1440: * ferret99gt@1440: * Version: $Id$ ferret99gt@1440: */ ferret99gt@1440: ferret99gt@1440: #pragma semicolon 1 ferret99gt@1440: #include ferret99gt@1440: ferret99gt@1479: public Plugin:myinfo = ferret99gt@1479: { ferret99gt@1479: name = "MapChooser", ferret99gt@1479: author = "AlliedModders LLC", ferret99gt@1479: description = "Automated Map Voting", ferret99gt@1479: version = SOURCEMOD_VERSION, ferret99gt@1479: url = "http://www.sourcemod.net/" ferret99gt@1479: }; ferret99gt@1440: ferret99gt@1440: new Handle:g_Cvar_Winlimit = INVALID_HANDLE; ferret99gt@1440: new Handle:g_Cvar_Maxrounds = INVALID_HANDLE; ferret99gt@1479: new Handle:g_Cvar_Fraglimit = INVALID_HANDLE; ferret99gt@1440: ferret99gt@1440: new Handle:g_Cvar_Nextmap = INVALID_HANDLE; ferret99gt@1479: ferret99gt@1440: new Handle:g_Cvar_StartTime = INVALID_HANDLE; ferret99gt@1479: new Handle:g_Cvar_StartRounds = INVALID_HANDLE; ferret99gt@1479: new Handle:g_Cvar_StartFrags = INVALID_HANDLE; ferret99gt@1440: new Handle:g_Cvar_ExtendTimeMax = INVALID_HANDLE; ferret99gt@1440: new Handle:g_Cvar_ExtendTimeStep = INVALID_HANDLE; ferret99gt@1445: new Handle:g_Cvar_ExtendRoundMax = INVALID_HANDLE; ferret99gt@1445: new Handle:g_Cvar_ExtendRoundStep = INVALID_HANDLE; ferret99gt@1479: new Handle:g_Cvar_ExtendFragMax = INVALID_HANDLE; ferret99gt@1479: new Handle:g_Cvar_ExtendFragStep = INVALID_HANDLE; ferret99gt@1440: new Handle:g_Cvar_Mapfile = INVALID_HANDLE; ferret99gt@1440: new Handle:g_Cvar_ExcludeMaps = INVALID_HANDLE; ferret99gt@1479: new Handle:g_Cvar_IncludeMaps = INVALID_HANDLE; ferret99gt@1440: ferret99gt@1440: new Handle:g_VoteTimer = INVALID_HANDLE; ferret99gt@1440: new Handle:g_RetryTimer = INVALID_HANDLE; ferret99gt@1440: ferret99gt@1440: new Handle:g_MapList = INVALID_HANDLE; ferret99gt@1440: new Handle:g_OldMapList = INVALID_HANDLE; ferret99gt@1440: new Handle:g_NextMapList = INVALID_HANDLE; ferret99gt@1440: new Handle:g_VoteMenu = INVALID_HANDLE; ferret99gt@1440: ferret99gt@1440: new bool:g_HasVoteStarted; ferret99gt@1440: new g_mapFileTime; ferret99gt@1440: ferret99gt@1440: public OnPluginStart() ferret99gt@1440: { ferret99gt@1440: LoadTranslations("mapchooser.phrases"); ferret99gt@1440: ferret99gt@1440: g_MapList = CreateArray(33); ferret99gt@1440: g_OldMapList = CreateArray(33); ferret99gt@1452: g_NextMapList = CreateArray(33); ferret99gt@1440: ferret99gt@1479: g_Cvar_StartTime = CreateConVar("sm_mapvote_start", "3.0", "Specifies when to start the vote based on time remaining.", _, true, 1.0); ferret99gt@1479: g_Cvar_StartRounds = CreateConVar("sm_mapvote_startround", "2.0", "Specifies when to start the vote based on rounds remaining.", _, true, 1.0); ferret99gt@1479: g_Cvar_StartFrags = CreateConVar("sm_mapvote_startfrags", "5.0", "Specifies when to start the vote base on frags remaining.", _, true, 1.0); ferret99gt@1479: g_Cvar_ExtendTimeMax = CreateConVar("sm_extendmap_maxtime", "90", "Specifies the maximum amount of time a map can be extended", _, true, 0.0); ferret99gt@1440: g_Cvar_ExtendTimeStep = CreateConVar("sm_extendmap_timestep", "15", "Specifies how much many more minutes each extension makes", _, true, 5.0); ferret99gt@1479: g_Cvar_ExtendRoundMax = CreateConVar("sm_extendmap_maxrounds", "30", "Specfies the maximum amount of rounds a map can be extended", _, true, 0.0); ferret99gt@1445: g_Cvar_ExtendRoundStep = CreateConVar("sm_extendmap_roundstep", "5", "Specifies how many more rounds each extension makes", _, true, 5.0); ferret99gt@1479: g_Cvar_ExtendFragMax = CreateConVar("sm_extendmap_maxfrags", "150", "Specfies the maximum frags allowed that a map can be extended.", _, true, 0.0); ferret99gt@1479: g_Cvar_ExtendFragStep = CreateConVar("sm_extendmap_fragstep", "10", "Specifies how many more frags are allowed when map is extended.", _, true, 5.0); ferret99gt@1440: g_Cvar_Mapfile = CreateConVar("sm_mapvote_file", "configs/maps.ini", "Map file to use. (Def sourcemod/configs/maps.ini)"); ferret99gt@1440: g_Cvar_ExcludeMaps = CreateConVar("sm_mapvote_exclude", "5", "Specifies how many past maps to exclude from the vote.", _, true, 0.0); ferret99gt@1479: g_Cvar_IncludeMaps = CreateConVar("sm_mapvote_include", "5", "Specifies how many maps to include in the vote.", _, true, 2.0, true, 6.0); ferret99gt@1440: ferret99gt@1479: RegAdminCmd("sm_mapvote", Command_Mapvote, ADMFLAG_CHANGEMAP, "sm_mapvote - Forces MapChooser to attempt to run a map vote now."); ferret99gt@1440: ferret99gt@1452: g_Cvar_Winlimit = FindConVar("mp_winlimit"); ferret99gt@1452: g_Cvar_Maxrounds = FindConVar("mp_maxrounds"); ferret99gt@1479: g_Cvar_Fraglimit = FindConVar("mp_fraglimit"); ferret99gt@1452: ferret99gt@1452: if (g_Cvar_Winlimit != INVALID_HANDLE || g_Cvar_Maxrounds != INVALID_HANDLE) ferret99gt@1440: { ferret99gt@1452: HookEvent("round_end", Event_RoundEnd); ferret99gt@1440: } ferret99gt@1467: ferret99gt@1479: if (g_Cvar_Fraglimit != INVALID_HANDLE) ferret99gt@1479: { ferret99gt@1479: HookEvent("player_death", Event_PlayerDeath); ferret99gt@1479: } ferret99gt@1479: ferret99gt@1467: AutoExecConfig(true, "mapchooser"); ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: public OnMapStart() ferret99gt@1440: { ferret99gt@1440: g_Cvar_Nextmap = FindConVar("sm_nextmap"); ferret99gt@1440: ferret99gt@1440: if (g_Cvar_Nextmap == INVALID_HANDLE) ferret99gt@1440: { ferret99gt@1440: LogError("FATAL: Cannot find sm_nextmap cvar. Mapchooser not loaded."); ferret99gt@1440: SetFailState("sm_nextmap not found"); ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: if (LoadMaps()) ferret99gt@1440: { ferret99gt@1440: CreateNextVote(); ferret99gt@1440: SetupTimeleftTimer(); ferret99gt@1440: } ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: public OnMapEnd() ferret99gt@1440: { ferret99gt@1440: g_HasVoteStarted = false; ferret99gt@1445: g_RetryTimer = INVALID_HANDLE; ferret99gt@1445: g_VoteTimer = INVALID_HANDLE; ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: public OnMapTimeLeftChanged() ferret99gt@1440: { ferret99gt@1467: if (GetArraySize(g_MapList)) ferret99gt@1467: { ferret99gt@1467: SetupTimeleftTimer(); ferret99gt@1467: } ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: SetupTimeleftTimer() ferret99gt@1440: { ferret99gt@1440: new time; ferret99gt@1440: if (GetMapTimeLeft(time) && time > 0) ferret99gt@1440: { ferret99gt@1440: new startTime = GetConVarInt(g_Cvar_StartTime); ferret99gt@1440: if (time - startTime < 0) ferret99gt@1440: { ferret99gt@1452: InitiateVote(); ferret99gt@1440: } ferret99gt@1440: else ferret99gt@1440: { ferret99gt@1440: if (g_VoteTimer != INVALID_HANDLE) ferret99gt@1440: { ferret99gt@1440: KillTimer(g_VoteTimer); ferret99gt@1440: g_VoteTimer = INVALID_HANDLE; ferret99gt@1452: } ferret99gt@1440: ferret99gt@1440: g_VoteTimer = CreateTimer(float(time - startTime), Timer_StartMapVote, TIMER_FLAG_NO_MAPCHANGE); ferret99gt@1440: } ferret99gt@1440: } ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: public Action:Timer_StartMapVote(Handle:timer) ferret99gt@1440: { ferret99gt@1452: if (!GetArraySize(g_MapList)) ferret99gt@1440: { ferret99gt@1440: return Plugin_Stop; ferret99gt@1479: } ferret99gt@1452: ferret99gt@1440: if (timer == g_RetryTimer) ferret99gt@1440: { ferret99gt@1440: g_RetryTimer = INVALID_HANDLE; ferret99gt@1440: } ferret99gt@1440: else ferret99gt@1440: { ferret99gt@1440: g_VoteTimer = INVALID_HANDLE; ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: InitiateVote(); ferret99gt@1440: ferret99gt@1440: return Plugin_Stop; ferret99gt@1440: } ferret99gt@1440: ferret99gt@1479: /* You ask, why don't you just use team_score event? And I answer... Because CSS doesn't. */ ferret99gt@1452: public Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast) ferret99gt@1440: { ferret99gt@1452: if (!GetArraySize(g_MapList)) ferret99gt@1440: { ferret99gt@1440: return; ferret99gt@1440: } ferret99gt@1440: ferret99gt@1479: new winner = GetEventInt(event, "winner"); ferret99gt@1479: ferret99gt@1479: if (winner == 0 || winner == 1) ferret99gt@1452: { ferret99gt@1452: return; ferret99gt@1452: } ferret99gt@1479: ferret99gt@1479: static total; ferret99gt@1479: static Handle:teamArray; ferret99gt@1479: if (teamArray == INVALID_HANDLE) ferret99gt@1479: { ferret99gt@1479: teamArray = CreateArray(2); ferret99gt@1479: } ferret99gt@1452: ferret99gt@1479: total++; ferret99gt@1479: ferret99gt@1479: new team[2], teamPos = -1; ferret99gt@1479: for (new i; i < GetArraySize(teamArray); i++) ferret99gt@1479: { ferret99gt@1479: GetArrayArray(teamArray, i, team); ferret99gt@1479: if (team[0] == winner) ferret99gt@1479: { ferret99gt@1479: teamPos = i; ferret99gt@1479: break; ferret99gt@1479: } ferret99gt@1479: } ferret99gt@1479: ferret99gt@1479: if (teamPos == -1) ferret99gt@1479: { ferret99gt@1479: team[0] = winner; ferret99gt@1479: team[1] = 1; ferret99gt@1479: PushArrayArray(teamArray, team); ferret99gt@1479: } ferret99gt@1479: else ferret99gt@1479: { ferret99gt@1479: team[1]++; ferret99gt@1479: SetArrayArray(teamArray, teamPos, team); ferret99gt@1479: } ferret99gt@1452: ferret99gt@1452: if (g_Cvar_Winlimit != INVALID_HANDLE) ferret99gt@1440: { ferret99gt@1452: new winlimit = GetConVarInt(g_Cvar_Winlimit); ferret99gt@1452: if (winlimit) ferret99gt@1440: { ferret99gt@1479: if (team[1] > winlimit - GetConVarInt(g_Cvar_StartRounds)) ferret99gt@1452: { ferret99gt@1452: InitiateVote(); ferret99gt@1452: } ferret99gt@1440: } ferret99gt@1440: } ferret99gt@1452: ferret99gt@1452: if (g_Cvar_Maxrounds != INVALID_HANDLE) ferret99gt@1440: { ferret99gt@1440: new maxrounds = GetConVarInt(g_Cvar_Maxrounds); ferret99gt@1440: if (maxrounds) ferret99gt@1440: { ferret99gt@1479: if (total > maxrounds - GetConVarInt(g_Cvar_StartRounds)) ferret99gt@1440: { ferret99gt@1440: InitiateVote(); ferret99gt@1440: } ferret99gt@1440: } ferret99gt@1440: } ferret99gt@1440: } ferret99gt@1440: ferret99gt@1479: public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast) ferret99gt@1479: { ferret99gt@1483: if (!GetArraySize(g_MapList) || g_Cvar_Fraglimit == INVALID_HANDLE) ferret99gt@1483: { ferret99gt@1483: return; ferret99gt@1483: } ferret99gt@1483: ferret99gt@1483: if (!GetConVarInt(g_Cvar_Fraglimit)) ferret99gt@1479: { ferret99gt@1479: return; ferret99gt@1479: } ferret99gt@1479: ferret99gt@1479: new fragger = GetClientOfUserId(GetEventInt(event, "attacker")); ferret99gt@1479: if (fragger && GetClientFrags(fragger) > (GetConVarInt(g_Cvar_Fraglimit) - GetConVarInt(g_Cvar_StartFrags))) ferret99gt@1479: { ferret99gt@1479: InitiateVote(); ferret99gt@1479: } ferret99gt@1479: } ferret99gt@1479: ferret99gt@1479: public Action:Command_Mapvote(client, args) ferret99gt@1479: { ferret99gt@1479: InitiateVote(); ferret99gt@1479: ferret99gt@1479: return Plugin_Handled; ferret99gt@1479: } ferret99gt@1479: ferret99gt@1440: InitiateVote() ferret99gt@1440: { ferret99gt@1440: if (g_HasVoteStarted || g_RetryTimer != INVALID_HANDLE) ferret99gt@1440: { ferret99gt@1440: return; ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: if (IsVoteInProgress()) ferret99gt@1440: { ferret99gt@1440: // Can't start a vote, try again in 5 seconds. ferret99gt@1440: g_RetryTimer = CreateTimer(5.0, Timer_StartMapVote, TIMER_FLAG_NO_MAPCHANGE); ferret99gt@1440: return; ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: g_HasVoteStarted = true; ferret99gt@1440: g_VoteMenu = CreateMenu(Handler_MapVoteMenu, MenuAction:MENU_ACTIONS_ALL); ferret99gt@1440: SetMenuTitle(g_VoteMenu, "Vote Nextmap"); ferret99gt@1440: ferret99gt@1440: decl String:map[32]; ferret99gt@1452: for (new i = 0; i < GetArraySize(g_NextMapList); i++) ferret99gt@1440: { ferret99gt@1452: GetArrayString(g_NextMapList, i, map, sizeof(map)); ferret99gt@1440: AddMenuItem(g_VoteMenu, map, map); ferret99gt@1440: } ferret99gt@1440: ferret99gt@1452: new bool:allowExtend, time; ferret99gt@1440: if (GetMapTimeLimit(time) && time > 0 && time < GetConVarInt(g_Cvar_ExtendTimeMax)) ferret99gt@1440: { ferret99gt@1452: allowExtend = true; ferret99gt@1440: } ferret99gt@1440: ferret99gt@1452: if (g_Cvar_Winlimit != INVALID_HANDLE && GetConVarInt(g_Cvar_Winlimit) < GetConVarInt(g_Cvar_ExtendRoundMax)) ferret99gt@1440: { ferret99gt@1452: allowExtend = true; ferret99gt@1440: } ferret99gt@1452: ferret99gt@1452: if (g_Cvar_Maxrounds != INVALID_HANDLE && GetConVarInt(g_Cvar_Maxrounds) < GetConVarInt(g_Cvar_ExtendRoundMax)) ferret99gt@1452: { ferret99gt@1452: allowExtend = true; ferret99gt@1452: } ferret99gt@1479: ferret99gt@1479: if (g_Cvar_Fraglimit != INVALID_HANDLE && GetConVarInt(g_Cvar_Fraglimit) < GetConVarInt(g_Cvar_ExtendFragMax)) ferret99gt@1479: { ferret99gt@1479: allowExtend = true; ferret99gt@1479: } ferret99gt@1440: ferret99gt@1452: if (allowExtend) ferret99gt@1440: { ferret99gt@1479: AddMenuItem(g_VoteMenu, "##extend##", "Extend Map"); ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: SetMenuExitButton(g_VoteMenu, false); ferret99gt@1440: VoteMenuToAll(g_VoteMenu, 20); ferret99gt@1440: ferret99gt@1440: LogMessage("Voting for next map has started."); ferret99gt@1440: PrintToChatAll("[SM] %t", "Nextmap Voting Started"); ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: public Handler_MapVoteMenu(Handle:menu, MenuAction:action, param1, param2) ferret99gt@1440: { ferret99gt@1440: switch (action) ferret99gt@1440: { ferret99gt@1440: case MenuAction_End: ferret99gt@1440: { ferret99gt@1440: g_VoteMenu = INVALID_HANDLE; ferret99gt@1440: CloseHandle(menu); ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: case MenuAction_Display: ferret99gt@1440: { ferret99gt@1440: decl String:buffer[255]; ferret99gt@1440: Format(buffer, sizeof(buffer), "%T", "Vote Nextmap", param1); ferret99gt@1440: ferret99gt@1440: new Handle:panel = Handle:param2; ferret99gt@1440: SetPanelTitle(panel, buffer); ferret99gt@1479: } ferret99gt@1479: ferret99gt@1479: case MenuAction_DisplayItem: ferret99gt@1479: { ferret99gt@1479: if (GetMenuItemCount(menu) - 1 == param2) ferret99gt@1479: { ferret99gt@1479: decl String:map[64], String:buffer[255]; ferret99gt@1479: GetMenuItem(menu, param2, map, sizeof(map)); ferret99gt@1479: if (strcmp(map, "##extend##", false)) ferret99gt@1479: { ferret99gt@1479: Format(buffer, sizeof(buffer), "%T", "Extend Map", param1); ferret99gt@1479: return RedrawMenuItem(buffer); ferret99gt@1479: } ferret99gt@1479: } ferret99gt@1479: } ferret99gt@1440: ferret99gt@1440: // Why am I commented out? Because BAIL hasn't decided yet if ferret99gt@1440: // vote notification will be built into the Vote API. ferret99gt@1440: /*case MenuAction_Select: ferret99gt@1440: { ferret99gt@1440: decl String:Name[32], String:Map[32]; ferret99gt@1440: GetClientName(param1, Name, sizeof(Name)); ferret99gt@1440: GetMenuItem(menu, param2, Map, sizeof(Map)); ferret99gt@1440: ferret99gt@1440: PrintToChatAll("[SM] %s has voted for map '%s'", Name, Map); ferret99gt@1440: }*/ ferret99gt@1440: ferret99gt@1440: case MenuAction_VoteCancel: ferret99gt@1440: { ferret99gt@1440: // If we receive 0 votes, pick at random. ferret99gt@1440: if (param1 == VoteCancel_NoVotes) ferret99gt@1440: { ferret99gt@1440: new count = GetMenuItemCount(menu); ferret99gt@1440: new item = GetRandomInt(0, count - 1); ferret99gt@1440: decl String:map[32]; ferret99gt@1440: GetMenuItem(menu, item, map, sizeof(map)); ferret99gt@1440: ferret99gt@1440: while (strcmp(map, "##extend##", false) == 0) ferret99gt@1440: { ferret99gt@1440: item = GetRandomInt(0, count - 1); ferret99gt@1440: GetMenuItem(menu, item, map, sizeof(map)); ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: SetNextMap(map); ferret99gt@1440: } ferret99gt@1440: else ferret99gt@1440: { ferret99gt@1440: // We were actually cancelled. What should we do? ferret99gt@1440: } ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: case MenuAction_VoteEnd: ferret99gt@1440: { ferret99gt@1440: decl String:map[32]; ferret99gt@1440: GetMenuItem(menu, param1, map, sizeof(map)); ferret99gt@1440: ferret99gt@1440: if (strcmp(map, "##extend##", false) == 0) ferret99gt@1440: { ferret99gt@1440: new time; ferret99gt@1440: if (GetMapTimeLimit(time)) ferret99gt@1440: { ferret99gt@1440: if (time > 0 && time < GetConVarInt(g_Cvar_ExtendTimeMax)) ferret99gt@1440: { ferret99gt@1482: ExtendMapTimeLimit(GetConVarInt(g_Cvar_ExtendTimeStep)*60); ferret99gt@1440: } ferret99gt@1440: } ferret99gt@1440: ferret99gt@1452: if (g_Cvar_Winlimit != INVALID_HANDLE) ferret99gt@1440: { ferret99gt@1440: new winlimit = GetConVarInt(g_Cvar_Winlimit); ferret99gt@1452: if (winlimit && winlimit < GetConVarInt(g_Cvar_ExtendRoundMax)) ferret99gt@1440: { ferret99gt@1452: SetConVarInt(g_Cvar_Winlimit, winlimit + GetConVarInt(g_Cvar_ExtendRoundStep)); ferret99gt@1452: } ferret99gt@1452: } ferret99gt@1452: ferret99gt@1452: if (g_Cvar_Maxrounds != INVALID_HANDLE) ferret99gt@1452: { ferret99gt@1452: new maxrounds = GetConVarInt(g_Cvar_Maxrounds); ferret99gt@1452: if (maxrounds && maxrounds < GetConVarInt(g_Cvar_ExtendRoundMax)) ferret99gt@1440: { ferret99gt@1452: SetConVarInt(g_Cvar_Maxrounds, maxrounds + GetConVarInt(g_Cvar_ExtendRoundStep)); ferret99gt@1440: } ferret99gt@1440: } ferret99gt@1479: ferret99gt@1479: if (g_Cvar_Fraglimit != INVALID_HANDLE) ferret99gt@1479: { ferret99gt@1479: new fraglimit = GetConVarInt(g_Cvar_Fraglimit); ferret99gt@1479: if (fraglimit && fraglimit < GetConVarInt(g_Cvar_ExtendFragMax)) ferret99gt@1479: { ferret99gt@1479: SetConVarInt(g_Cvar_Fraglimit, fraglimit + GetConVarInt(g_Cvar_ExtendFragStep)); ferret99gt@1479: } ferret99gt@1479: } ferret99gt@1440: ferret99gt@1440: PrintToChatAll("[SM] %t", "Current Map Extended"); ferret99gt@1440: LogMessage("Voting for next map has finished. The current map has been extended."); ferret99gt@1440: ferret99gt@1445: // We extended, so we'll have to vote again. ferret99gt@1440: g_HasVoteStarted = false; ferret99gt@1479: CreateNextVote(); ferret99gt@1445: SetupTimeleftTimer(); ferret99gt@1440: } ferret99gt@1440: else ferret99gt@1440: { ferret99gt@1440: SetNextMap(map); ferret99gt@1440: } ferret99gt@1440: } ferret99gt@1440: } ferret99gt@1479: ferret99gt@1479: return 0; ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: SetNextMap(const String:map[]) ferret99gt@1440: { ferret99gt@1440: SetConVarString(g_Cvar_Nextmap, map); ferret99gt@1440: PushArrayString(g_OldMapList, map); ferret99gt@1440: ferret99gt@1479: if (GetArraySize(g_OldMapList) > GetConVarInt(g_Cvar_ExcludeMaps)) ferret99gt@1440: { ferret99gt@1440: RemoveFromArray(g_OldMapList, 0); ferret99gt@1440: } ferret99gt@1440: ferret99gt@1452: PrintToChatAll("[SM] %t", "Nextmap Voting Finished", map); ferret99gt@1440: LogMessage("Voting for next map has finished. Nextmap: %s.", map); ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: CreateNextVote() ferret99gt@1440: { ferret99gt@1452: if(g_NextMapList != INVALID_HANDLE) ferret99gt@1445: { ferret99gt@1452: ClearArray(g_NextMapList); ferret99gt@1452: } ferret99gt@1445: ferret99gt@1452: decl String:map[32]; ferret99gt@1479: new limit = (GetConVarInt(g_Cvar_IncludeMaps) < GetArraySize(g_MapList) ? GetConVarInt(g_Cvar_IncludeMaps) : GetArraySize(g_MapList)); ferret99gt@1440: ferret99gt@1440: new bool:oldMaps = false; ferret99gt@1452: if (limit > GetConVarInt(g_Cvar_ExcludeMaps)) ferret99gt@1440: { ferret99gt@1452: limit -= GetArraySize(g_OldMapList); ferret99gt@1440: oldMaps = true; ferret99gt@1440: } ferret99gt@1440: ferret99gt@1452: for (new i = 0; i < limit; i++) ferret99gt@1440: { ferret99gt@1452: new b = GetRandomInt(0, limit - 1); ferret99gt@1440: GetArrayString(g_MapList, b, map, sizeof(map)); ferret99gt@1452: ferret99gt@1452: while (IsStringInArray(g_NextMapList, map) || (oldMaps && IsStringInArray(g_OldMapList, map))) ferret99gt@1440: { ferret99gt@1452: b = GetRandomInt(0, limit - 1); ferret99gt@1452: GetArrayString(g_MapList, b, map, sizeof(map)); ferret99gt@1440: } ferret99gt@1452: ferret99gt@1452: PushArrayString(g_NextMapList, map); ferret99gt@1440: } ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: LoadMaps() ferret99gt@1440: { ferret99gt@1440: new bool:fileFound; ferret99gt@1440: ferret99gt@1440: decl String:mapPath[256], String:mapFile[64]; ferret99gt@1440: GetConVarString(g_Cvar_Mapfile, mapFile, 64); ferret99gt@1440: BuildPath(Path_SM, mapPath, sizeof(mapFile), mapFile); ferret99gt@1440: fileFound = FileExists(mapPath); ferret99gt@1440: if (!fileFound) ferret99gt@1440: { ferret99gt@1440: new Handle:mapCycleFile = FindConVar("mapcyclefile"); ferret99gt@1440: GetConVarString(mapCycleFile, mapPath, sizeof(mapPath)); ferret99gt@1440: fileFound = FileExists(mapPath); ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: if (!fileFound) ferret99gt@1440: { ferret99gt@1479: LogError("Unable to locate sm_mapvote_file or mapcyclefile, no maps loaded."); ferret99gt@1440: ferret99gt@1440: if (g_MapList != INVALID_HANDLE) ferret99gt@1440: { ferret99gt@1440: ClearArray(g_MapList); ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: return 0; ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: // If the file hasn't changed, there's no reason to reload ferret99gt@1440: // all of the maps. ferret99gt@1440: new fileTime = GetFileTime(mapPath, FileTime_LastChange); ferret99gt@1440: if (g_mapFileTime == fileTime) ferret99gt@1440: { ferret99gt@1452: return GetArraySize(g_MapList); ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: g_mapFileTime = fileTime; ferret99gt@1440: ferret99gt@1440: // Reset the array ferret99gt@1440: if (g_MapList != INVALID_HANDLE) ferret99gt@1440: { ferret99gt@1440: ClearArray(g_MapList); ferret99gt@1440: } ferret99gt@1440: ferret99gt@1452: LogMessage("[SM] Loading mapchooser map file [%s]", mapPath); ferret99gt@1440: ferret99gt@1440: new Handle:file = OpenFile(mapPath, "rt"); ferret99gt@1440: if (file == INVALID_HANDLE) ferret99gt@1440: { ferret99gt@1440: LogError("[SM] Could not open file: %s", mapPath); ferret99gt@1440: return 0; ferret99gt@1440: } ferret99gt@1440: ferret99gt@1479: decl String:currentMap[32]; ferret99gt@1479: GetCurrentMap(currentMap, sizeof(currentMap)); ferret99gt@1479: ferret99gt@1440: decl String:buffer[64], len; ferret99gt@1440: while (!IsEndOfFile(file) && ReadFileLine(file, buffer, sizeof(buffer))) ferret99gt@1440: { ferret99gt@1440: TrimString(buffer); ferret99gt@1440: ferret99gt@1440: if ((len = StrContains(buffer, ".bsp", false)) != -1) ferret99gt@1440: { ferret99gt@1440: buffer[len] = '\0'; ferret99gt@1440: } ferret99gt@1440: ferret99gt@1479: if (buffer[0] == '\0' || !IsValidConVarChar(buffer[0]) || !IsMapValid(buffer) ferret99gt@1440: || strcmp(currentMap, buffer, false) == 0) ferret99gt@1440: { ferret99gt@1440: continue; ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: PushArrayString(g_MapList, buffer); ferret99gt@1440: } ferret99gt@1440: ferret99gt@1440: CloseHandle(file); ferret99gt@1452: return GetArraySize(g_MapList); ferret99gt@1440: }