PageRenderTime 28ms CodeModel.GetById 19ms app.highlight 7ms RepoModel.GetById 0ms app.codeStats 0ms

/addons/sourcemod/scripting/nextmap.sp

https://bitbucket.org/kimoto/sushi
Unknown | 228 lines | 188 code | 40 blank | 0 comment | 0 complexity | c688644a574573a1667434a632aa1e1e MD5 | raw file
  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
 39public 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 
 49new g_MapPos = -1;
 50new Handle:g_MapList = INVALID_HANDLE;
 51new g_MapListSerial = -1;
 52
 53new g_CurrentMapStartTime;
 54
 55public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
 56{
 57	decl String:game[128];
 58	GetGameFolderName(game, sizeof(game));
 59
 60	if (StrEqual(game, "left4dead", false)
 61			|| StrEqual(game, "dystopia", false)
 62			|| StrEqual(game, "synergy", false)
 63			|| StrEqual(game, "left4dead2", false)
 64			|| StrEqual(game, "garrysmod", false)
 65			|| StrEqual(game, "swarm", false))
 66	{
 67		strcopy(error, err_max, "Nextmap is incompatible with this game");
 68		return APLRes_SilentFailure;
 69	}
 70
 71	return APLRes_Success;
 72}
 73
 74
 75public OnPluginStart()
 76{
 77
 78	LoadTranslations("common.phrases");
 79	LoadTranslations("nextmap.phrases");
 80	
 81	g_MapList = CreateArray(32);
 82
 83	RegAdminCmd("sm_maphistory", Command_MapHistory, ADMFLAG_CHANGEMAP, "Shows the most recent maps played");
 84	RegConsoleCmd("listmaps", Command_List);
 85
 86	// Set to the current map so OnMapStart() will know what to do
 87	decl String:currentMap[64];
 88	GetCurrentMap(currentMap, 64);
 89	SetNextMap(currentMap);
 90}
 91
 92public OnMapStart()
 93{
 94	g_CurrentMapStartTime = GetTime();
 95}
 96 
 97public OnConfigsExecuted()
 98{
 99	decl String:lastMap[64], String:currentMap[64];
100	GetNextMap(lastMap, sizeof(lastMap));
101	GetCurrentMap(currentMap, 64);
102	
103	// 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
104	// some other plugin/command), we don't want to scramble the map cycle. Or for example, admin switches to a custom map
105	// not in mapcyclefile. So we keep it set to the last expected nextmap. - ferret
106	if (strcmp(lastMap, currentMap) == 0)
107	{
108		FindAndSetNextMap();
109	}
110}
111
112public Action:Command_List(client, args) 
113{
114	PrintToConsole(client, "Map Cycle:");
115	
116	new mapCount = GetArraySize(g_MapList);
117	decl String:mapName[32];
118	for (new i = 0; i < mapCount; i++)
119	{
120		GetArrayString(g_MapList, i, mapName, sizeof(mapName));
121		PrintToConsole(client, "%s", mapName);
122	}
123 
124	return Plugin_Handled;
125}
126  
127FindAndSetNextMap()
128{
129	if (ReadMapList(g_MapList, 
130			g_MapListSerial, 
131			"mapcyclefile", 
132			MAPLIST_FLAG_CLEARARRAY|MAPLIST_FLAG_NO_DEFAULT)
133		== INVALID_HANDLE)
134	{
135		if (g_MapListSerial == -1)
136		{
137			LogError("FATAL: Cannot load map cycle. Nextmap not loaded.");
138			SetFailState("Mapcycle Not Found");
139		}
140	}
141	
142	new mapCount = GetArraySize(g_MapList);
143	decl String:mapName[32];
144	
145	if (g_MapPos == -1)
146	{
147		decl String:current[64];
148		GetCurrentMap(current, 64);
149
150		for (new i = 0; i < mapCount; i++)
151		{
152			GetArrayString(g_MapList, i, mapName, sizeof(mapName));
153			if (strcmp(current, mapName, false) == 0)
154			{
155				g_MapPos = i;
156				break;
157			}
158		}
159		
160		if (g_MapPos == -1)
161			g_MapPos = 0;
162	}
163	
164	g_MapPos++;
165	if (g_MapPos >= mapCount)
166		g_MapPos = 0;	
167 
168 	GetArrayString(g_MapList, g_MapPos, mapName, sizeof(mapName));
169	SetNextMap(mapName);
170}
171
172public Action:Command_MapHistory(client, args)
173{
174	new mapCount = GetMapHistorySize();
175	
176	decl String:mapName[32];
177	decl String:changeReason[100];
178	decl String:timeString[100];
179	decl String:playedTime[100];
180	new startTime;
181	
182	new lastMapStartTime = g_CurrentMapStartTime;
183	
184	PrintToConsole(client, "Map History:\n");
185	PrintToConsole(client, "Map : Started : Played Time : Reason for ending");
186	
187	GetCurrentMap(mapName, sizeof(mapName));
188	PrintToConsole(client, "%02i. %s (Current Map)", 0, mapName);
189	
190	for (new i=0; i<mapCount; i++)
191	{
192		GetMapHistory(i, mapName, sizeof(mapName), changeReason, sizeof(changeReason), startTime);
193
194		FormatTimeDuration(timeString, sizeof(timeString), GetTime() - startTime);
195		FormatTimeDuration(playedTime, sizeof(playedTime), lastMapStartTime - startTime);
196		
197		PrintToConsole(client, "%02i. %s : %s ago : %s : %s", i+1, mapName, timeString, playedTime, changeReason);
198		
199		lastMapStartTime = startTime;
200	}
201
202	return Plugin_Handled;
203}
204
205FormatTimeDuration(String:buffer[], maxlen, time)
206{
207	new	days = time / 86400;
208	new	hours = (time / 3600) % 24;
209	new	minutes = (time / 60) % 60;
210	new	seconds =  time % 60;
211	
212	if (days > 0)
213	{
214		return Format(buffer, maxlen, "%id %ih %im", days, hours, (seconds >= 30) ? minutes+1 : minutes);
215	}
216	else if (hours > 0)
217	{
218		return Format(buffer, maxlen, "%ih %im", hours, (seconds >= 30) ? minutes+1 : minutes);		
219	}
220	else if (minutes > 0)
221	{
222		return Format(buffer, maxlen, "%im", (seconds >= 30) ? minutes+1 : minutes);		
223	}
224	else
225	{
226		return Format(buffer, maxlen, "%is", seconds);		
227	}
228}