plugins/nextmap.sp
author Michael McKoy <ferret99gt@gmail.com>
Fri Jul 27 00:24:04 2007 +0000 (2007-07-27)
changeset 1182 43d08badb860
parent 1180 90bfcf192ffd
child 1187 85c0934305bd
permissions -rw-r--r--
Import of basetriggers
     1 /**
     2  * nextmap.sp
     3  * Adds sm_nextmap Cvar for changing map, and nextmap chat trigger
     4  * This file is part of SourceMod, Copyright (C) 2004-2007 AlliedModders LLC
     5  *
     6  * This program is free software; you can redistribute it and/or
     7  * modify it under the terms of the GNU General Public License
     8  * as published by the Free Software Foundation; either version 2
     9  * of the License, or (at your option) any later version.
    10  *
    11  * This program is distributed in the hope that it will be useful,
    12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  * GNU General Public License for more details.
    15  * 
    16  * You should have received a copy of the GNU General Public License
    17  * along with this program; if not, write to the Free Software
    18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    19  *
    20  * Version: $Id$
    21  */
    22  
    23 #include <sourcemod>
    24  
    25 #pragma semicolon 1
    26  
    27 public Plugin:myinfo = 
    28 {
    29 	name = "Nextmap",
    30 	author = "AlliedModders LLC",
    31 	description = "Provides nextmap and sm_nextmap",
    32 	version = SOURCEMOD_VERSION,
    33 	url = "http://www.sourcemod.net/"
    34 };
    35 
    36 new bool:g_IntermissionCalled;
    37 new UserMsg:g_VGUIMenu;
    38  
    39 new Handle:g_Cvar_Chattime;
    40 new Handle:g_Cvar_Nextmap;
    41 new Handle:g_Cvar_Mapcycle;
    42 
    43 new g_MapPos = -1;
    44 new Handle:g_MapList = INVALID_HANDLE;
    45 
    46 #if 0
    47 new bool:g_INS = false;
    48 #endif
    49  
    50 public OnPluginStart()
    51 {
    52 	LoadTranslations("plugin.nextmap");
    53 	
    54 	g_VGUIMenu = GetUserMessageId("VGUIMenu");
    55 	if (g_VGUIMenu == INVALID_MESSAGE_ID)
    56 	{
    57 		LogMessage("FATAL: Cannot find VGUIMenu user message id. Nextmap not loaded.");
    58 		return;	
    59 	}
    60 	
    61 	g_Cvar_Chattime = FindConVar("mp_chattime");
    62 	g_Cvar_Mapcycle = FindConVar("mapcyclefile");
    63 	
    64 	g_MapList = CreateArray(32);
    65 	
    66 	decl String:mapCycle[64];
    67 	GetConVarString(g_Cvar_Mapcycle, mapCycle, 64);
    68 	if (LoadMaps(mapCycle) == 0)
    69 	{
    70 		LogMessage("FATAL: Cannot load map cycle. Nextmap not loaded.");
    71 		return;
    72 	}	
    73 	
    74 	HookUserMessage(g_VGUIMenu, UserMsg_VGUIMenu);
    75 	HookConVarChange(g_Cvar_Mapcycle, ConVarChange_Mapcyclefile);
    76 	
    77 	g_Cvar_Nextmap = CreateConVar("sm_nextmap", "", "Sets the Next Map", FCVAR_NOTIFY);
    78 	
    79 	RegConsoleCmd("say", Command_Say);
    80 	RegConsoleCmd("say_team", Command_Say);
    81 	
    82 	#if 0
    83 	decl String:modname[64];
    84 	GetGameFolderName(modname, sizeof(modname));
    85 	
    86 	if (strcmp(modname, "ins") == 0)
    87 	{
    88 		RegConsoleCmd("say2", Command_SayChat);
    89 		g_INS = true;
    90 	}
    91 	#endif
    92 
    93 	RegConsoleCmd("listmaps", Command_List);
    94 	
    95 	/* Set to the current map so OnMapStart() will know what to do */
    96 	decl String:currentMap[64];
    97 	GetCurrentMap(currentMap, 64);
    98 	SetConVarString(g_Cvar_Nextmap, currentMap);
    99 }
   100  
   101 public OnMapStart()
   102 {
   103 	decl String:lastMap[64], String:currentMap[64];
   104 	GetConVarString(g_Cvar_Nextmap, lastMap, 64);
   105 	GetCurrentMap(currentMap, 64);
   106 	
   107 	// 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
   108 	// some other plugin/command), we don't want to scramble the map cycle. Or for example, admin switches to a custom map
   109 	// not in mapcyclefile. So we keep it set to the last expected nextmap. - ferret
   110 	if (strcmp(lastMap, currentMap) == 0)
   111 	{
   112 		FindAndSetNextMap();
   113 	}
   114 }
   115  
   116 public OnMapEnd()
   117 {
   118 	g_IntermissionCalled = false;
   119 }
   120  
   121 public ConVarChange_Mapcyclefile(Handle:convar, const String:oldValue[], const String:newValue[])
   122 {
   123 	if (strcmp(oldValue, newValue, false) != 0)
   124 	{
   125 		LoadMaps(newValue);
   126 	}
   127 }
   128  
   129 public Action:Command_Say(client, args)
   130 {
   131 	decl String:text[192];
   132 	GetCmdArgString(text, sizeof(text));
   133 	
   134 	new startidx;
   135 	if (text[strlen(text)-1] == '"')
   136 	{
   137 		text[strlen(text)-1] = '\0';
   138 		startidx = 1;
   139 	}
   140 	
   141 	#if 0
   142 	if (g_INS)
   143 	{
   144 		startidx += 4;
   145 	}
   146 	#endif
   147 	
   148 	decl String:message[8];
   149 	BreakString(text[startidx], message, sizeof(message));
   150 	
   151 	if (strcmp(message, "nextmap", false) == 0)
   152 	{
   153 		decl String:map[32];
   154 		GetConVarString(g_Cvar_Nextmap, map, sizeof(map));
   155 		
   156 		PrintToChatAll("%t", "Next Map", map);
   157 	}
   158 	
   159 	return Plugin_Continue;	
   160 }
   161  
   162 public Action:UserMsg_VGUIMenu(UserMsg:msg_id, Handle:bf, const players[], playersNum, bool:reliable, bool:init)
   163 {
   164 	if (g_IntermissionCalled)
   165 	{
   166 		return Plugin_Handled;
   167 	}
   168 	
   169 	decl String:type[15];
   170 	BfReadString(bf, type, sizeof(type));
   171  
   172 	if (BfReadByte(bf) == 1 && BfReadByte(bf) == 0 && (strcmp(type, "scores", false) == 0))
   173 	{
   174 		g_IntermissionCalled = true;
   175 		
   176 		decl String:map[32];
   177 		new Float:fChatTime = GetConVarFloat(g_Cvar_Chattime);
   178 		
   179 		GetConVarString(g_Cvar_Nextmap, map, sizeof(map));
   180 		
   181 		if (fChatTime < 2.0)
   182 			SetConVarFloat(g_Cvar_Chattime, 2.0);
   183 		
   184 		new Handle:dp;
   185 		CreateDataTimer(fChatTime - 1.0, Timer_ChangeMap, dp);
   186 		WritePackString(dp, map);
   187 	}
   188 	
   189 	return Plugin_Handled;
   190 }
   191  
   192 public Action:Timer_ChangeMap(Handle:timer, Handle:dp)
   193 {
   194 	new String:map[32];
   195 	
   196 	ResetPack(dp);
   197 	ReadPackString(dp, map, sizeof(map));
   198  
   199 	InsertServerCommand("changelevel \"%s\"", map);
   200 	ServerExecute();
   201 	
   202 	LogMessage("Nextmap changed map to \"%s\"", map);
   203 	
   204 	return Plugin_Stop;
   205 }
   206  
   207 public Action:Command_List(client, args) 
   208 {
   209 	PrintToConsole(client, "Map Cycle:");
   210 	
   211 	new mapCount = GetArraySize(g_MapList);
   212 	decl String:mapName[32];
   213 	for (new i = 0; i < mapCount; i++)
   214 	{
   215 		GetArrayString(g_MapList, i, mapName, sizeof(mapName));
   216 		PrintToConsole(client, "%s", mapName);
   217 	}
   218  
   219 	return Plugin_Handled;
   220 }
   221  
   222 LoadMaps(const String:path[])
   223 {
   224 	if (!FileExists(path))
   225 	{
   226 		return 0;
   227 	}
   228  
   229 	new Handle:file = OpenFile(path, "r");
   230 	
   231 	if (file == INVALID_HANDLE)
   232 	{
   233 		LogError("[SM] Could not open file: %s", path);
   234 		return 0;
   235 	}
   236 	
   237 	ClearArray(g_MapList);
   238 	g_MapPos = -1;
   239 	
   240 	decl String:buffer[255];
   241 	while (!IsEndOfFile(file) && ReadFileLine(file, buffer, sizeof(buffer)))
   242 	{
   243 		TrimString(buffer);
   244 		if (buffer[0] == '\0' || buffer[0] == ';')
   245 		{
   246 			continue;
   247 		}
   248 		
   249 		if (IsMapValid(buffer))
   250 		{
   251 			PushArrayString(g_MapList, buffer);
   252 		}
   253 	}
   254 	
   255 	CloseHandle(file);
   256 
   257 	return GetArraySize(g_MapList);
   258 }
   259  
   260 FindAndSetNextMap()
   261 {
   262 	new mapCount = GetArraySize(g_MapList);
   263 	decl String:mapName[32];
   264 	
   265 	if (g_MapPos == -1)
   266 	{
   267 		decl String:current[64];
   268 		GetCurrentMap(current, 64);
   269 		
   270 
   271 		for (new i = 0; i < mapCount; i++)
   272 		{
   273 			GetArrayString(g_MapList, i, mapName, sizeof(mapName));
   274 			if (strcmp(current, mapName, false) == 0)
   275 			{
   276 				g_MapPos = i;
   277 				break;
   278 			}
   279 		}
   280 		
   281 		if (g_MapPos == -1)
   282 			g_MapPos = 0;
   283 	}
   284 	
   285 	g_MapPos++;
   286 	if (g_MapPos >= mapCount)
   287 		g_MapPos = 0;	
   288  
   289  	GetArrayString(g_MapList, g_MapPos, mapName, sizeof(mapName));
   290 	SetConVarString(g_Cvar_Nextmap, mapName);
   291 }