1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/plugins/nextmap.sp Thu Jul 26 22:41:13 2007 +0000
1.3 @@ -0,0 +1,299 @@
1.4 +/**
1.5 + * nextmap.sp
1.6 + * Adds sm_nextmap Cvar for changing map, and nextmap chat trigger
1.7 + * This file is part of SourceMod, Copyright (C) 2004-2007 AlliedModders LLC
1.8 + *
1.9 + * This program is free software; you can redistribute it and/or
1.10 + * modify it under the terms of the GNU General Public License
1.11 + * as published by the Free Software Foundation; either version 2
1.12 + * of the License, or (at your option) any later version.
1.13 + *
1.14 + * This program is distributed in the hope that it will be useful,
1.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.17 + * GNU General Public License for more details.
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License
1.20 + * along with this program; if not, write to the Free Software
1.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1.22 + *
1.23 + * Version: $Id$
1.24 + */
1.25 +
1.26 +#include <sourcemod>
1.27 +
1.28 +#pragma semicolon 1
1.29 +
1.30 +public Plugin:myinfo =
1.31 +{
1.32 + name = "Nextmap",
1.33 + author = "AlliedModders LLC",
1.34 + description = "Provides nextmap and sm_nextmap",
1.35 + version = SOURCEMOD_VERSION,
1.36 + url = "http://www.sourcemod.net/"
1.37 +};
1.38 +
1.39 +new bool:g_IntermissionCalled;
1.40 +new UserMsg:g_VGUIMenu;
1.41 +
1.42 +new Handle:g_Cvar_Chattime;
1.43 +new Handle:g_Cvar_Nextmap;
1.44 +new Handle:g_Cvar_Mapcycle;
1.45 +
1.46 +new g_MapPos = -1;
1.47 +new Handle:g_MapList = INVALID_HANDLE;
1.48 +
1.49 +#if 0
1.50 +new bool:g_INS = false;
1.51 +#endif
1.52 +
1.53 +public OnPluginStart()
1.54 +{
1.55 + LoadTranslations("plugin.nextmap");
1.56 +
1.57 + g_VGUIMenu = GetUserMessageId("VGUIMenu");
1.58 + if (g_VGUIMenu == INVALID_MESSAGE_ID)
1.59 + {
1.60 + LogMessage("FATAL: Cannot find VGUIMenu user message id. Nextmap not loaded.");
1.61 + return;
1.62 + }
1.63 +
1.64 + g_Cvar_Chattime = FindConVar("mp_chattime");
1.65 + g_Cvar_Mapcycle = FindConVar("mapcyclefile");
1.66 +
1.67 + g_MapList = CreateArray(32);
1.68 +
1.69 + decl String:mapCycle[64];
1.70 + GetConVarString(g_Cvar_Mapcycle, mapCycle, 64);
1.71 + if (LoadMaps(mapCycle) == 0)
1.72 + {
1.73 + LogMessage("FATAL: Cannot load map cycle. Nextmap not loaded.");
1.74 + return;
1.75 + }
1.76 +
1.77 + HookUserMessage(g_VGUIMenu, UserMsg_VGUIMenu);
1.78 + HookConVarChange(g_Cvar_Mapcycle, ConVarChange_Mapcyclefile);
1.79 +
1.80 + g_Cvar_Nextmap = CreateConVar("sm_nextmap", "", "Sets the Next Map", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_UNLOGGED|FCVAR_DONTRECORD|FCVAR_REPLICATED|FCVAR_NOTIFY);
1.81 +
1.82 + RegConsoleCmd("say", Command_Say);
1.83 + RegConsoleCmd("say_team", Command_Say);
1.84 +
1.85 + #if 0
1.86 + decl String:modname[64];
1.87 + GetGameFolderName(modname, sizeof(modname));
1.88 +
1.89 + if (strcmp(modname, "ins") == 0)
1.90 + {
1.91 + RegConsoleCmd("say2", Command_SayChat);
1.92 + g_INS = true;
1.93 + }
1.94 + #endif
1.95 +
1.96 + RegConsoleCmd("nextmap", Command_Nextmap);
1.97 + RegConsoleCmd("listmaps", Command_List);
1.98 +
1.99 + /* Set to the current map so OnMapStart() will know what to do */
1.100 + decl String:currentMap[64];
1.101 + GetCurrentMap(currentMap, 64);
1.102 + SetConVarString(g_Cvar_Nextmap, currentMap);
1.103 +}
1.104 +
1.105 +public OnMapStart()
1.106 +{
1.107 + decl String:lastMap[64], String:currentMap[64];
1.108 + GetConVarString(g_Cvar_Nextmap, lastMap, 64);
1.109 + GetCurrentMap(currentMap, 64);
1.110 +
1.111 + // 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
1.112 + // some other plugin/command), we don't want to scramble the map cycle. Or for example, admin switches to a custom map
1.113 + // not in mapcyclefile. So we keep it set to the last expected nextmap. - ferret
1.114 + if (strcmp(lastMap, currentMap) == 0)
1.115 + {
1.116 + FindAndSetNextMap();
1.117 + }
1.118 +}
1.119 +
1.120 +public OnMapEnd()
1.121 +{
1.122 + g_IntermissionCalled = false;
1.123 +}
1.124 +
1.125 +public ConVarChange_Mapcyclefile(Handle:convar, const String:oldValue[], const String:newValue[])
1.126 +{
1.127 + if (strcmp(oldValue, newValue, false) != 0)
1.128 + {
1.129 + LoadMaps(newValue);
1.130 + }
1.131 +}
1.132 +
1.133 +public Action:Command_Say(client, args)
1.134 +{
1.135 + decl String:text[192];
1.136 + GetCmdArgString(text, sizeof(text));
1.137 +
1.138 + new startidx;
1.139 + if (text[strlen(text)-1] == '"')
1.140 + {
1.141 + text[strlen(text)-1] = '\0';
1.142 + startidx = 1;
1.143 + }
1.144 +
1.145 + #if 0
1.146 + if (g_INS)
1.147 + {
1.148 + startidx += 4;
1.149 + }
1.150 + #endif
1.151 +
1.152 + decl String:message[8];
1.153 + BreakString(text[startidx], message, sizeof(message));
1.154 +
1.155 + if (strcmp(message, "nextmap", false) == 0)
1.156 + {
1.157 + return Command_Nextmap(client, args);
1.158 + }
1.159 +
1.160 + return Plugin_Continue;
1.161 +}
1.162 +
1.163 +public Action:Command_Nextmap(client, args)
1.164 +{
1.165 + decl String:map[32];
1.166 + GetConVarString(g_Cvar_Nextmap, map, sizeof(map));
1.167 +
1.168 + PrintToChatAll("%t", "Next Map", map);
1.169 +
1.170 + return Plugin_Continue;
1.171 +}
1.172 +
1.173 +public Action:UserMsg_VGUIMenu(UserMsg:msg_id, Handle:bf, const players[], playersNum, bool:reliable, bool:init)
1.174 +{
1.175 + if (g_IntermissionCalled)
1.176 + {
1.177 + return Plugin_Handled;
1.178 + }
1.179 +
1.180 + decl String:type[15];
1.181 + BfReadString(bf, type, sizeof(type));
1.182 +
1.183 + if (BfReadByte(bf) == 1 && BfReadByte(bf) == 0 && (strcmp(type, "scores", false) == 0))
1.184 + {
1.185 + g_IntermissionCalled = true;
1.186 +
1.187 + decl String:map[32];
1.188 + new Float:fChatTime = GetConVarFloat(g_Cvar_Chattime);
1.189 +
1.190 + GetConVarString(g_Cvar_Nextmap, map, sizeof(map));
1.191 +
1.192 + if (fChatTime < 2.0)
1.193 + SetConVarFloat(g_Cvar_Chattime, 2.0);
1.194 +
1.195 + new Handle:dp;
1.196 + CreateDataTimer(fChatTime - 1.0, Timer_ChangeMap, dp);
1.197 + WritePackString(dp, map);
1.198 + }
1.199 +
1.200 + return Plugin_Handled;
1.201 +}
1.202 +
1.203 +public Action:Timer_ChangeMap(Handle:timer, Handle:dp)
1.204 +{
1.205 + new String:map[32];
1.206 +
1.207 + ResetPack(dp);
1.208 + ReadPackString(dp, map, sizeof(map));
1.209 +
1.210 + InsertServerCommand("changelevel \"%s\"", map);
1.211 + ServerExecute();
1.212 +
1.213 + LogMessage("Nextmap changed map to \"%s\"", map);
1.214 +
1.215 + return Plugin_Stop;
1.216 +}
1.217 +
1.218 +public Action:Command_List(client, args)
1.219 +{
1.220 + PrintToConsole(client, "Map Cycle:");
1.221 +
1.222 + new mapCount = GetArraySize(g_MapList);
1.223 + decl String:mapName[32];
1.224 + for (new i = 0; i < mapCount; i++)
1.225 + {
1.226 + GetArrayString(g_MapList, i, mapName, sizeof(mapName));
1.227 + PrintToConsole(client, "%s", mapName);
1.228 + }
1.229 +
1.230 + return Plugin_Handled;
1.231 +}
1.232 +
1.233 +LoadMaps(const String:path[])
1.234 +{
1.235 + if (!FileExists(path))
1.236 + {
1.237 + return 0;
1.238 + }
1.239 +
1.240 + new Handle:file = OpenFile(path, "r");
1.241 +
1.242 + if (file == INVALID_HANDLE)
1.243 + {
1.244 + LogError("[SM] Could not open file: %s", path);
1.245 + return 0;
1.246 + }
1.247 +
1.248 + ClearArray(g_MapList);
1.249 + g_MapPos = -1;
1.250 +
1.251 + decl String:buffer[255];
1.252 + while (!IsEndOfFile(file) && ReadFileLine(file, buffer, sizeof(buffer)))
1.253 + {
1.254 + TrimString(buffer);
1.255 + if (buffer[0] == '\0' || buffer[0] == ';')
1.256 + {
1.257 + continue;
1.258 + }
1.259 +
1.260 + if (IsMapValid(buffer))
1.261 + {
1.262 + PushArrayString(g_MapList, buffer);
1.263 + }
1.264 + }
1.265 +
1.266 + CloseHandle(file);
1.267 +
1.268 + return GetArraySize(g_MapList);
1.269 +}
1.270 +
1.271 +FindAndSetNextMap()
1.272 +{
1.273 + new mapCount = GetArraySize(g_MapList);
1.274 + decl String:mapName[32];
1.275 +
1.276 + if (g_MapPos == -1)
1.277 + {
1.278 + decl String:current[64];
1.279 + GetCurrentMap(current, 64);
1.280 +
1.281 +
1.282 + for (new i = 0; i < mapCount; i++)
1.283 + {
1.284 + GetArrayString(g_MapList, i, mapName, sizeof(mapName));
1.285 + if (strcmp(current, mapName, false) == 0)
1.286 + {
1.287 + g_MapPos = i;
1.288 + break;
1.289 + }
1.290 + }
1.291 +
1.292 + if (g_MapPos == -1)
1.293 + g_MapPos = 0;
1.294 + }
1.295 +
1.296 + g_MapPos++;
1.297 + if (g_MapPos >= mapCount)
1.298 + g_MapPos = 0;
1.299 +
1.300 + GetArrayString(g_MapList, g_MapPos, mapName, sizeof(mapName));
1.301 + SetConVarString(g_Cvar_Nextmap, mapName);
1.302 +}
1.303 \ No newline at end of file