plugins/rockthevote.sp
author Scott Ehlert <ds@alliedmods.net>
Sun Sep 14 03:01:05 2008 -0500 (2008-09-14)
changeset 2289 44045ead61cd
parent 2223 a912c065719f
parent 1947 e73a1e51833b
child 2361 2ff475ac117b
permissions -rw-r--r--
Eliminated head: da55a80522cf, a remnant of sourcemod-1.1.0 branch
     1 /**
     2  * vim: set ts=4 :
     3  * =============================================================================
     4  * SourceMod Rock The Vote Plugin
     5  * Creates a map vote when the required number of players have requested one.
     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 #include <sourcemod>
    35 #include <mapchooser>
    36 #include <nextmap>
    37 
    38 #pragma semicolon 1
    39 
    40 public Plugin:myinfo =
    41 {
    42 	name = "Rock The Vote",
    43 	author = "AlliedModders LLC",
    44 	description = "Provides RTV Map Voting",
    45 	version = SOURCEMOD_VERSION,
    46 	url = "http://www.sourcemod.net/"
    47 };
    48 
    49 new Handle:g_Cvar_Needed = INVALID_HANDLE;
    50 new Handle:g_Cvar_MinPlayers = INVALID_HANDLE;
    51 new Handle:g_Cvar_InitialDelay = INVALID_HANDLE;
    52 new Handle:g_Cvar_Interval = INVALID_HANDLE;
    53 new Handle:g_Cvar_ChangeTime = INVALID_HANDLE;
    54 new Handle:g_Cvar_RTVPostVoteAction = INVALID_HANDLE;
    55 
    56 new bool:g_CanRTV = false;		// True if RTV loaded maps and is active.
    57 new bool:g_RTVAllowed = false;	// True if RTV is available to players. Used to delay rtv votes.
    58 new g_Voters = 0;				// Total voters connected. Doesn't include fake clients.
    59 new g_Votes = 0;				// Total number of "say rtv" votes
    60 new g_VotesNeeded = 0;			// Necessary votes before map vote begins. (voters * percent_needed)
    61 new bool:g_Voted[MAXPLAYERS+1] = {false, ...};
    62 
    63 new bool:g_InChange = false;
    64 
    65 public OnPluginStart()
    66 {
    67 	LoadTranslations("common.phrases");
    68 	LoadTranslations("rockthevote.phrases");
    69 	
    70 	g_Cvar_Needed = CreateConVar("sm_rtv_needed", "0.60", "Percentage of players needed to rockthevote (Def 60%)", 0, true, 0.05, true, 1.0);
    71 	g_Cvar_MinPlayers = CreateConVar("sm_rtv_minplayers", "0", "Number of players required before RTV will be enabled.", 0, true, 0.0, true, float(MAXPLAYERS));
    72 	g_Cvar_InitialDelay = CreateConVar("sm_rtv_initialdelay", "30.0", "Time (in seconds) before first RTV can be held", 0, true, 0.00);
    73 	g_Cvar_Interval = CreateConVar("sm_rtv_interval", "240.0", "Time (in seconds) after a failed RTV before another can be held", 0, true, 0.00);
    74 	g_Cvar_ChangeTime = CreateConVar("sm_rtv_changetime", "0", "When to change the map after a succesful RTV: 0 - Instant, 1 - RoundEnd, 2 - MapEnd", _, true, 0.0, true, 2.0);
    75 	g_Cvar_RTVPostVoteAction = CreateConVar("sm_rtv_postvoteaction", "0", "What to do with RTV's after a mapvote has completed. 0 - Allow, success = instant change, 1 - Deny", _, true, 0.0, true, 1.0);
    76 	
    77 	RegConsoleCmd("say", Command_Say);
    78 	RegConsoleCmd("say_team", Command_Say);
    79 	
    80 	RegConsoleCmd("sm_rtv", Command_RTV);
    81 	
    82 	AutoExecConfig(true, "rtv");
    83 }
    84 
    85 public OnMapStart()
    86 {
    87 	g_Voters = 0;
    88 	g_Votes = 0;
    89 	g_VotesNeeded = 0;
    90 	g_InChange = false;
    91 	
    92 	/* Handle late load */
    93 	new maxclients = GetMaxClients();
    94 	for (new i=1; i<=maxclients; i++)
    95 	{
    96 		if (IsClientConnected(i))
    97 		{
    98 			OnClientConnect(i, "", 0);	
    99 		}	
   100 	}
   101 }
   102 
   103 public OnMapEnd()
   104 {
   105 	g_CanRTV = false;	
   106 	g_RTVAllowed = false;
   107 }
   108 
   109 public OnConfigsExecuted()
   110 {	
   111 	g_CanRTV = true;
   112 	g_RTVAllowed = false;
   113 	CreateTimer(GetConVarFloat(g_Cvar_InitialDelay), Timer_DelayRTV, _, TIMER_FLAG_NO_MAPCHANGE);
   114 }
   115 
   116 public bool:OnClientConnect(client, String:rejectmsg[], maxlen)
   117 {
   118 	if(IsFakeClient(client))
   119 		return true;
   120 	
   121 	g_Voted[client] = false;
   122 
   123 	g_Voters++;
   124 	g_VotesNeeded = RoundToFloor(float(g_Voters) * GetConVarFloat(g_Cvar_Needed));
   125 	
   126 	return true;
   127 }
   128 
   129 public OnClientDisconnect(client)
   130 {
   131 	if(!g_CanRTV || IsFakeClient(client))
   132 		return;
   133 	
   134 	if(g_Voted[client])
   135 	{
   136 		g_Votes--;
   137 	}
   138 	
   139 	g_Voters--;
   140 	
   141 	g_VotesNeeded = RoundToFloor(float(g_Voters) * GetConVarFloat(g_Cvar_Needed));
   142 	
   143 	if (g_Votes && 
   144 		g_Voters && 
   145 		g_Votes >= g_VotesNeeded && 
   146 		g_RTVAllowed ) 
   147 	{
   148 		if (GetConVarInt(g_Cvar_RTVPostVoteAction) == 1 && HasEndOfMapVoteFinished())
   149 		{
   150 			return;
   151 		}
   152 		
   153 		StartRTV();
   154 	}	
   155 }
   156 
   157 public Action:Command_RTV(client, args)
   158 {
   159 	if (!g_CanRTV || !client)
   160 	{
   161 		return Plugin_Continue;
   162 	}
   163 	
   164 	AttemptRTV(client);
   165 	
   166 	return Plugin_Continue;
   167 }
   168 
   169 public Action:Command_Say(client, args)
   170 {
   171 	if (!g_CanRTV || !client)
   172 	{
   173 		return Plugin_Continue;
   174 	}
   175 	
   176 	decl String:text[192];
   177 	if (!GetCmdArgString(text, sizeof(text)))
   178 	{
   179 		return Plugin_Continue;
   180 	}
   181 	
   182 	new startidx = 0;
   183 	if(text[strlen(text)-1] == '"')
   184 	{
   185 		text[strlen(text)-1] = '\0';
   186 		startidx = 1;
   187 	}
   188 	
   189 	new ReplySource:old = SetCmdReplySource(SM_REPLY_TO_CHAT);
   190 	
   191 	if (strcmp(text[startidx], "rtv", false) == 0 || strcmp(text[startidx], "rockthevote", false) == 0)
   192 	{
   193 		AttemptRTV(client);
   194 	}
   195 	
   196 	SetCmdReplySource(old);
   197 	
   198 	return Plugin_Continue;	
   199 }
   200 
   201 AttemptRTV(client)
   202 {
   203 	if (!g_RTVAllowed  || (GetConVarInt(g_Cvar_RTVPostVoteAction) == 1 && HasEndOfMapVoteFinished()))
   204 	{
   205 		ReplyToCommand(client, "[SM] %t", "RTV Not Allowed");
   206 		return;
   207 	}
   208 		
   209 	if (!CanMapChooserStartVote())
   210 	{
   211 		ReplyToCommand(client, "[SM] %t", "RTV Started");
   212 		return;
   213 	}
   214 	
   215 	if (GetClientCount(true) < GetConVarInt(g_Cvar_MinPlayers))
   216 	{
   217 		ReplyToCommand(client, "[SM] %t", "Minimal Players Not Met");
   218 		return;			
   219 	}
   220 	
   221 	if (g_Voted[client])
   222 	{
   223 		ReplyToCommand(client, "[SM] %t", "Already Voted");
   224 		return;
   225 	}	
   226 	
   227 	new String:name[64];
   228 	GetClientName(client, name, sizeof(name));
   229 	
   230 	g_Votes++;
   231 	g_Voted[client] = true;
   232 	
   233 	PrintToChatAll("[SM] %t", "RTV Requested", name, g_Votes, g_VotesNeeded);
   234 	
   235 	if (g_Votes >= g_VotesNeeded)
   236 	{
   237 		StartRTV();
   238 	}	
   239 }
   240 
   241 public Action:Timer_DelayRTV(Handle:timer)
   242 {
   243 	g_RTVAllowed = true;
   244 }
   245 
   246 StartRTV()
   247 {
   248 	if (g_InChange)
   249 	{
   250 		return;	
   251 	}
   252 	
   253 	if (EndOfMapVoteEnabled() && HasEndOfMapVoteFinished())
   254 	{
   255 		/* Change right now then */
   256 		new String:map[65];
   257 		if (GetNextMap(map, sizeof(map)))
   258 		{
   259 			PrintToChatAll("[SM] %t", "Changing Maps", map);
   260 			CreateTimer(5.0, Timer_ChangeMap, _, TIMER_FLAG_NO_MAPCHANGE);
   261 			g_InChange = true;
   262 			
   263 			ResetRTV();
   264 			
   265 			g_RTVAllowed = false;
   266 		}
   267 		return;	
   268 	}
   269 	
   270 	if (CanMapChooserStartVote())
   271 	{
   272 		new MapChange:when = MapChange:GetConVarInt(g_Cvar_ChangeTime);
   273 		InitiateMapChooserVote(when);
   274 		
   275 		ResetRTV();
   276 		
   277 		g_RTVAllowed = false;
   278 		CreateTimer(GetConVarFloat(g_Cvar_Interval), Timer_DelayRTV, _, TIMER_FLAG_NO_MAPCHANGE);
   279 	}
   280 }
   281 
   282 ResetRTV()
   283 {
   284 	g_Votes = 0;
   285 			
   286 	for (new i=1; i<=MAXPLAYERS; i++)
   287 	{
   288 		g_Voted[i] = false;
   289 	}
   290 }
   291 
   292 public Action:Timer_ChangeMap(Handle:hTimer)
   293 {
   294 	g_InChange = false;
   295 	
   296 	LogMessage("RTV changing map manually");
   297 	
   298 	new String:map[65];
   299 	if (GetNextMap(map, sizeof(map)))
   300 	{	
   301 		ForceChangeLevel(map, "RTV after mapvote");
   302 	}
   303 	
   304 	return Plugin_Stop;
   305 }