plugins/nextmap.sp
author Matt Woodrow <pred@alliedmods.net>
Wed Aug 27 00:49:56 2008 +0000 (2008-08-27)
changeset 2239 9170d5518cba
parent 2215 bcbfee080d08
child 2289 44045ead61cd
permissions -rw-r--r--
Fixed amb1957 - Mapchooser now counts arena rounds correctly.
Fixed amb1925 - Mapchooser countly rounds incorrectly during an RTV
Fixed amb1920 - Cleared retry timer
Fixed amb1921 - Cancelling a vote now marks the vote as complete
     1 /**
     2  * vim: set ts=4 :
     3  * =============================================================================
     4  * SourceMod Nextmap Plugin
     5  * Adds sm_nextmap cvar for changing map and nextmap chat trigger.
     6  *
     7  * SourceMod (C)2004-2008 AlliedModders LLC.  All rights reserved.
     8  * =============================================================================
     9  *
    10  * This program is free software; you can redistribute it and/or modify it under
    11  * the terms of the GNU General Public License, version 3.0, as published by the
    12  * Free Software Foundation.
    13  * 
    14  * This program is distributed in the hope that it will be useful, but WITHOUT
    15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    16  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    17  * details.
    18  *
    19  * You should have received a copy of the GNU General Public License along with
    20  * this program.  If not, see <http://www.gnu.org/licenses/>.
    21  *
    22  * As a special exception, AlliedModders LLC gives you permission to link the
    23  * code of this program (as well as its derivative works) to "Half-Life 2," the
    24  * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    25  * by the Valve Corporation.  You must obey the GNU General Public License in
    26  * all respects for all other code used.  Additionally, AlliedModders LLC grants
    27  * this exception to all derivative works.  AlliedModders LLC defines further
    28  * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    29  * or <http://www.sourcemod.net/license.php>.
    30  *
    31  * Version: $Id$
    32  */
    33 
    34 #pragma semicolon 1
    35 
    36 #include <sourcemod>
    37 #include "include/nextmap.inc"
    38 
    39 public Plugin:myinfo = 
    40 {
    41 	name = "Nextmap",
    42 	author = "AlliedModders LLC",
    43 	description = "Provides nextmap and sm_nextmap",
    44 	version = SOURCEMOD_VERSION,
    45 	url = "http://www.sourcemod.net/"
    46 };
    47 
    48  
    49 new g_MapPos = -1;
    50 new Handle:g_MapList = INVALID_HANDLE;
    51 new g_MapListSerial = -1;
    52 
    53 new g_CurrentMapStartTime;
    54  
    55 public OnPluginStart()
    56 {
    57 	LoadTranslations("common.phrases");
    58 	LoadTranslations("nextmap.phrases");
    59 	
    60 	g_MapList = CreateArray(32);
    61 
    62 	RegAdminCmd("sm_maphistory", Command_MapHistory, ADMFLAG_CHANGEMAP, "Shows the most recent maps played");
    63 	RegConsoleCmd("listmaps", Command_List);
    64 
    65 	// Set to the current map so OnMapStart() will know what to do
    66 	decl String:currentMap[64];
    67 	GetCurrentMap(currentMap, 64);
    68 	SetNextMap(currentMap);
    69 }
    70 
    71 public OnMapStart()
    72 {
    73 	g_CurrentMapStartTime = GetTime();
    74 }
    75  
    76 public OnConfigsExecuted()
    77 {
    78 	decl String:lastMap[64], String:currentMap[64];
    79 	GetNextMap(lastMap, sizeof(lastMap));
    80 	GetCurrentMap(currentMap, 64);
    81 	
    82 	// Why am I doing this? If we switched to a new map, but it wasn't what we expected (Due to sm_map, sm_votemap, or
    83 	// some other plugin/command), we don't want to scramble the map cycle. Or for example, admin switches to a custom map
    84 	// not in mapcyclefile. So we keep it set to the last expected nextmap. - ferret
    85 	if (strcmp(lastMap, currentMap) == 0)
    86 	{
    87 		FindAndSetNextMap();
    88 	}
    89 }
    90 
    91 public Action:Command_List(client, args) 
    92 {
    93 	PrintToConsole(client, "Map Cycle:");
    94 	
    95 	new mapCount = GetArraySize(g_MapList);
    96 	decl String:mapName[32];
    97 	for (new i = 0; i < mapCount; i++)
    98 	{
    99 		GetArrayString(g_MapList, i, mapName, sizeof(mapName));
   100 		PrintToConsole(client, "%s", mapName);
   101 	}
   102  
   103 	return Plugin_Handled;
   104 }
   105   
   106 FindAndSetNextMap()
   107 {
   108 	if (ReadMapList(g_MapList, 
   109 			g_MapListSerial, 
   110 			"mapcyclefile", 
   111 			MAPLIST_FLAG_CLEARARRAY|MAPLIST_FLAG_NO_DEFAULT)
   112 		== INVALID_HANDLE)
   113 	{
   114 		if (g_MapListSerial == -1)
   115 		{
   116 			LogError("FATAL: Cannot load map cycle. Nextmap not loaded.");
   117 			SetFailState("Mapcycle Not Found");
   118 		}
   119 	}
   120 	
   121 	new mapCount = GetArraySize(g_MapList);
   122 	decl String:mapName[32];
   123 	
   124 	if (g_MapPos == -1)
   125 	{
   126 		decl String:current[64];
   127 		GetCurrentMap(current, 64);
   128 
   129 		for (new i = 0; i < mapCount; i++)
   130 		{
   131 			GetArrayString(g_MapList, i, mapName, sizeof(mapName));
   132 			if (strcmp(current, mapName, false) == 0)
   133 			{
   134 				g_MapPos = i;
   135 				break;
   136 			}
   137 		}
   138 		
   139 		if (g_MapPos == -1)
   140 			g_MapPos = 0;
   141 	}
   142 	
   143 	g_MapPos++;
   144 	if (g_MapPos >= mapCount)
   145 		g_MapPos = 0;	
   146  
   147  	GetArrayString(g_MapList, g_MapPos, mapName, sizeof(mapName));
   148 	SetNextMap(mapName);
   149 }
   150 
   151 public Action:Command_MapHistory(client, args)
   152 {
   153 	new mapCount = GetMapHistorySize();
   154 	
   155 	decl String:mapName[32];
   156 	decl String:changeReason[100];
   157 	decl String:timeString[100];
   158 	decl String:playedTime[100];
   159 	new startTime;
   160 	
   161 	new lastMapStartTime = g_CurrentMapStartTime;
   162 	
   163 	PrintToConsole(client, "Map History:\n");
   164 	PrintToConsole(client, "Map : Started : Played Time : Reason for ending");
   165 	
   166 	GetCurrentMap(mapName, sizeof(mapName));
   167 	PrintToConsole(client, "%02i. %s (Current Map)", 0, mapName);
   168 	
   169 	for (new i=0; i<mapCount; i++)
   170 	{
   171 		GetMapHistory(i, mapName, sizeof(mapName), changeReason, sizeof(changeReason), startTime);
   172 
   173 		FormatTimeDuration(timeString, sizeof(timeString), GetTime() - startTime);
   174 		FormatTimeDuration(playedTime, sizeof(playedTime), lastMapStartTime - startTime);
   175 		
   176 		PrintToConsole(client, "%02i. %s : %s ago : %s : %s", i+1, mapName, timeString, playedTime, changeReason);
   177 		
   178 		lastMapStartTime = startTime;
   179 	}
   180 }
   181 
   182 FormatTimeDuration(String:buffer[], maxlen, time)
   183 {
   184 	new	days = time / 86400;
   185 	new	hours = (time / 3600) % 24;
   186 	new	minutes = (time / 60) % 60;
   187 	new	seconds =  time % 60;
   188 	
   189 	if (days > 0)
   190 	{
   191 		return Format(buffer, maxlen, "%id %ih %im", days, hours, (seconds >= 30) ? minutes+1 : minutes);
   192 	}
   193 	else if (hours > 0)
   194 	{
   195 		return Format(buffer, maxlen, "%ih %im", hours, (seconds >= 30) ? minutes+1 : minutes);		
   196 	}
   197 	else if (minutes > 0)
   198 	{
   199 		return Format(buffer, maxlen, "%im", (seconds >= 30) ? minutes+1 : minutes);		
   200 	}
   201 	else
   202 	{
   203 		return Format(buffer, maxlen, "%is", seconds);		
   204 	}
   205 }