plugins/basefunvotes.sp
author Michael McKoy <ferret99gt@gmail.com>
Wed Aug 22 01:18:17 2007 +0000 (2007-08-22)
changeset 1365 cff0aaa4d571
parent 1364 99405d7da69d
child 1375 b7acfca8070d
permissions -rw-r--r--
Fixed amb822. Fixed tag mismatches in vote plugins. Fixed "No votes casts"
     1 /**
     2  * vim: set ts=4 :
     3  * =============================================================================
     4  * SourceMod Fun Votes Plugin
     5  * Implements extra fun vote commands.
     6  *
     7  * SourceMod (C)2004-2007 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 <sdktools>
    38 
    39 public Plugin:myinfo =
    40 {
    41 	name = "Fun Votes",
    42 	author = "AlliedModders LLC",
    43 	description = "Fun Vote Commands",
    44 	version = SOURCEMOD_VERSION,
    45 	url = "http://www.sourcemod.net/"
    46 };
    47 
    48 #define VOTE_NO "###no###"
    49 #define VOTE_YES "###yes###"
    50 
    51 new Handle:g_hVoteMenu = INVALID_HANDLE;
    52 
    53 new Handle:g_Cvar_Limits[5] = {INVALID_HANDLE, ...};
    54 new Handle:g_Cvar_Gravity = INVALID_HANDLE;
    55 new Handle:g_Cvar_Alltalk = INVALID_HANDLE;
    56 new Handle:g_Cvar_FF = INVALID_HANDLE;
    57 
    58 // new Handle:g_Cvar_Show = INVALID_HANDLE;
    59 
    60 enum voteType
    61 {
    62 	gravity = 0,
    63 	burn,
    64 	slay,
    65 	alltalk,
    66 	ff
    67 }
    68 
    69 new voteType:g_voteType = voteType:gravity;
    70 
    71 // Menu API does not provide us with a way to pass multiple peices of data with a single
    72 // choice, so some globals are used to hold stuff.
    73 //
    74 #define VOTE_CLIENTID	0
    75 #define VOTE_USERID	1
    76 new g_voteClient[2];		/* Holds the target's client id and user id */
    77 
    78 #define VOTE_NAME	0
    79 #define VOTE_AUTHID	1
    80 #define	VOTE_IP		2
    81 new String:g_voteInfo[3][65];	/* Holds the target's name, authid, and IP */
    82 
    83 public OnPluginStart()
    84 {
    85 	LoadTranslations("common.phrases");
    86 	LoadTranslations("basevotes.phrases");
    87 	LoadTranslations("basefunvotes.phrases");
    88 	
    89 	RegAdminCmd("sm_votegravity", Command_VoteGravity, ADMFLAG_VOTE, "sm_votegravity <amount> [amount2] ... [amount5]");
    90 	RegAdminCmd("sm_voteburn", Command_VoteBurn, ADMFLAG_VOTE|ADMFLAG_SLAY, "sm_voteburn <player>");
    91 	RegAdminCmd("sm_voteslay", Command_VoteSlay, ADMFLAG_VOTE|ADMFLAG_SLAY, "sm_voteslay <player>");
    92 	RegAdminCmd("sm_votealltalk", Command_VoteAlltalk, ADMFLAG_VOTE, "sm_votealltalk");
    93 	RegAdminCmd("sm_voteff", Command_VoteFF, ADMFLAG_VOTE, "sm_voteff");
    94 
    95 	g_Cvar_Limits[0] = CreateConVar("sm_vote_gravity", "0.60", "percent required for successful gravity vote.", 0, true, 0.05, true, 1.0);
    96 	g_Cvar_Limits[1] = CreateConVar("sm_vote_burn", "0.60", "percent required for successful burn vote.", 0, true, 0.05, true, 1.0);
    97 	g_Cvar_Limits[2] = CreateConVar("sm_vote_slay", "0.60", "percent required for successful slay vote.", 0, true, 0.05, true, 1.0);
    98 	g_Cvar_Limits[3] = CreateConVar("sm_vote_alltalk", "0.60", "percent required for successful alltalk vote.", 0, true, 0.05, true, 1.0);
    99 	g_Cvar_Limits[4] = CreateConVar("sm_vote_ff", "0.60", "percent required for successful friendly fire vote.", 0, true, 0.05, true, 1.0);
   100 	
   101 	g_Cvar_Gravity = FindConVar("sv_gravity");
   102 	g_Cvar_Alltalk = FindConVar("sv_alltalk");
   103 	g_Cvar_FF = FindConVar("mp_friendlyfire");
   104 	
   105 	/*
   106 	g_Cvar_Show = FindConVar("sm_vote_show");
   107 	if (g_Cvar_Show == INVALID_HANDLE)
   108 	{
   109 		g_Cvar_Show = CreateConVar("sm_vote_show", "1", "Show player's votes? Default on.", 0, true, 0.0, true, 1.0);
   110 	}
   111 	*/
   112 }
   113 
   114 public Action:Command_VoteGravity(client, args)
   115 {
   116 	if (args < 1)
   117 	{
   118 		ReplyToCommand(client, "[SM] Usage: sm_votegravity <amount> [amount2] ... [amount5]");
   119 		return Plugin_Handled;	
   120 	}
   121 	
   122 	if (IsVoteInProgress())
   123 	{
   124 		ReplyToCommand(client, "[SM] %t", "Vote in Progress");
   125 		return Plugin_Handled;
   126 	}
   127 	
   128 	if (!TestVoteDelay(client))
   129 	{
   130 		return Plugin_Handled;
   131 	}
   132 	
   133 	decl String:text[256];
   134 	GetCmdArgString(text, sizeof(text));
   135 
   136 	decl String:items[5][64];
   137 	new count;	
   138 	new len, pos;
   139 	
   140 	while (pos != -1 && count < 5)
   141 	{	
   142 		pos = BreakString(text[len], items[count], sizeof(items[]));
   143 		
   144 		decl Float:temp;
   145 		if (StringToFloatEx(items[count], temp) == 0)
   146 		{
   147 			ReplyToCommand(client, "[SM] %t", "Invalid Amount");
   148 			return Plugin_Handled;
   149 		}		
   150 
   151 		count++;
   152 		
   153 		if (pos != -1)
   154 		{
   155 			len += pos;
   156 		}	
   157 	}
   158 
   159 	ShowActivity(client, "%t", "Initiated Vote Gravity");
   160 	
   161 	g_voteType = voteType:gravity;
   162 	
   163 	g_hVoteMenu = CreateMenu(Handler_VoteCallback, MenuAction:MENU_ACTIONS_ALL);
   164 	
   165 	if (count == 1)
   166 	{
   167 		strcopy(g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[]), items[0]);
   168 			
   169 		SetMenuTitle(g_hVoteMenu, "Change Gravity To");
   170 		AddMenuItem(g_hVoteMenu, items[0], "Yes");
   171 		AddMenuItem(g_hVoteMenu, VOTE_NO, "No");
   172 	}
   173 	else
   174 	{
   175 		g_voteInfo[VOTE_NAME][0] = '\0';
   176 		
   177 		SetMenuTitle(g_hVoteMenu, "Gravity Vote");
   178 		for (new i = 0; i < count; i++)
   179 		{
   180 			AddMenuItem(g_hVoteMenu, items[i], items[i]);
   181 		}	
   182 	}
   183 	
   184 	SetMenuExitButton(g_hVoteMenu, false);
   185 	VoteMenuToAll(g_hVoteMenu, 20);		
   186 	
   187 	return Plugin_Handled;	
   188 }
   189 
   190 public Action:Command_VoteBurn(client, args)
   191 {
   192 	if (args < 1)
   193 	{
   194 		ReplyToCommand(client, "[SM] Usage: sm_voteburn <player>");
   195 		return Plugin_Handled;	
   196 	}
   197 	
   198 	if (IsVoteInProgress())
   199 	{
   200 		ReplyToCommand(client, "[SM] %t", "Vote in Progress");
   201 		return Plugin_Handled;
   202 	}	
   203 	
   204 	if (!TestVoteDelay(client))
   205 	{
   206 		return Plugin_Handled;
   207 	}
   208 	
   209 	decl String:text[256], String:arg[64];
   210 	GetCmdArgString(text, sizeof(text));
   211 	
   212 	BreakString(text, arg, sizeof(arg));
   213 	
   214 	new target = FindTarget(client, arg);
   215 	if (target == -1)
   216 	{
   217 		return Plugin_Handled;
   218 	}
   219 
   220 	if (!IsPlayerAlive(target))
   221 	{
   222 		ReplyToCommand(client, "[SM] %t", "Cannot performed on dead", arg);
   223 		return Plugin_Handled;
   224 	}
   225 	
   226 	g_voteClient[VOTE_CLIENTID] = target;
   227 	GetClientName(target, g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[]));
   228 
   229 	ShowActivity(client, "%t", "Initiated Vote Burn", g_voteInfo[VOTE_NAME]);
   230 	
   231 	g_voteType = voteType:burn;
   232 	
   233 	g_hVoteMenu = CreateMenu(Handler_VoteCallback, MenuAction:MENU_ACTIONS_ALL);
   234 	SetMenuTitle(g_hVoteMenu, "Voteburn Player");
   235 	AddMenuItem(g_hVoteMenu, VOTE_YES, "Yes");
   236 	AddMenuItem(g_hVoteMenu, VOTE_NO, "No");
   237 	SetMenuExitButton(g_hVoteMenu, false);
   238 	VoteMenuToAll(g_hVoteMenu, 20);
   239 	
   240 	return Plugin_Handled;
   241 }
   242 
   243 public Action:Command_VoteSlay(client, args)
   244 {
   245 	if (args < 1)
   246 	{
   247 		ReplyToCommand(client, "[SM] Usage: sm_voteslay <player>");
   248 		return Plugin_Handled;	
   249 	}
   250 	
   251 	if (IsVoteInProgress())
   252 	{
   253 		ReplyToCommand(client, "[SM] %t", "Vote in Progress");
   254 		return Plugin_Handled;
   255 	}	
   256 	
   257 	if (!TestVoteDelay(client))
   258 	{
   259 		return Plugin_Handled;
   260 	}
   261 	
   262 	decl String:text[256], String:arg[64];
   263 	GetCmdArgString(text, sizeof(text));
   264 	
   265 	BreakString(text, arg, sizeof(arg));
   266 	
   267 	new target = FindTarget(client, arg);
   268 	if (target == -1)
   269 	{
   270 		return Plugin_Handled;
   271 	}
   272 
   273 	if (!IsPlayerAlive(target))
   274 	{
   275 		ReplyToCommand(client, "[SM] %t", "Cannot performed on dead", arg);
   276 		return Plugin_Handled;
   277 	}
   278 	
   279 	g_voteClient[VOTE_CLIENTID] = target;
   280 	GetClientName(target, g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[]));
   281 
   282 	ShowActivity(client, "%t", "Initiated Vote Slay", g_voteInfo[VOTE_NAME]);
   283 	
   284 	g_voteType = voteType:slay;
   285 	
   286 	g_hVoteMenu = CreateMenu(Handler_VoteCallback, MenuAction:MENU_ACTIONS_ALL);
   287 	SetMenuTitle(g_hVoteMenu, "Voteslay Player");
   288 	AddMenuItem(g_hVoteMenu, VOTE_YES, "Yes");
   289 	AddMenuItem(g_hVoteMenu, VOTE_NO, "No");
   290 	SetMenuExitButton(g_hVoteMenu, false);
   291 	VoteMenuToAll(g_hVoteMenu, 20);
   292 	
   293 	return Plugin_Handled;
   294 }
   295 
   296 public Action:Command_VoteAlltalk(client, args)
   297 {
   298 	if (args > 0)
   299 	{
   300 		ReplyToCommand(client, "[SM] Usage: sm_votealltalk");
   301 		return Plugin_Handled;	
   302 	}
   303 	
   304 	if (IsVoteInProgress())
   305 	{
   306 		ReplyToCommand(client, "[SM] %t", "Vote in Progress");
   307 		return Plugin_Handled;
   308 	}	
   309 	
   310 	if (!TestVoteDelay(client))
   311 	{
   312 		return Plugin_Handled;
   313 	}
   314 	
   315 	ShowActivity(client, "%t", "Initiated Vote Alltalk");
   316 	
   317 	g_voteType = voteType:alltalk;
   318 	g_voteInfo[VOTE_NAME][0] = '\0';
   319 
   320 	g_hVoteMenu = CreateMenu(Handler_VoteCallback, MenuAction:MENU_ACTIONS_ALL);
   321 	
   322 	if (GetConVarBool(g_Cvar_Alltalk))
   323 	{
   324 		SetMenuTitle(g_hVoteMenu, "Votealltalk Off");
   325 	}
   326 	else
   327 	{
   328 		SetMenuTitle(g_hVoteMenu, "Votealltalk On");
   329 	}
   330 	
   331 	AddMenuItem(g_hVoteMenu, VOTE_YES, "Yes");
   332 	AddMenuItem(g_hVoteMenu, VOTE_NO, "No");
   333 	SetMenuExitButton(g_hVoteMenu, false);
   334 	VoteMenuToAll(g_hVoteMenu, 20);
   335 	
   336 	return Plugin_Handled;
   337 }
   338 
   339 public Action:Command_VoteFF(client, args)
   340 {
   341 	if (args > 0)
   342 	{
   343 		ReplyToCommand(client, "[SM] Usage: sm_voteff");
   344 		return Plugin_Handled;	
   345 	}
   346 	
   347 	if (IsVoteInProgress())
   348 	{
   349 		ReplyToCommand(client, "[SM] %t", "Vote in Progress");
   350 		return Plugin_Handled;
   351 	}	
   352 	
   353 	if (!TestVoteDelay(client))
   354 	{
   355 		return Plugin_Handled;
   356 	}
   357 	
   358 	ShowActivity(client, "%t", "Initiated Vote FF");
   359 	
   360 	g_voteType = voteType:ff;
   361 	g_voteInfo[VOTE_NAME][0] = '\0';
   362 	
   363 	g_hVoteMenu = CreateMenu(Handler_VoteCallback, MenuAction:MENU_ACTIONS_ALL);
   364 	
   365 	if (GetConVarBool(g_Cvar_Alltalk))
   366 	{
   367 		SetMenuTitle(g_hVoteMenu, "Voteff Off");
   368 	}
   369 	else
   370 	{
   371 		SetMenuTitle(g_hVoteMenu, "Voteff On");
   372 	}
   373 	
   374 	AddMenuItem(g_hVoteMenu, VOTE_YES, "Yes");
   375 	AddMenuItem(g_hVoteMenu, VOTE_NO, "No");
   376 	SetMenuExitButton(g_hVoteMenu, false);
   377 	VoteMenuToAll(g_hVoteMenu, 20);
   378 	
   379 	return Plugin_Handled;
   380 }
   381 
   382 public Handler_VoteCallback(Handle:menu, MenuAction:action, param1, param2)
   383 {
   384 	if (action == MenuAction_End)
   385 	{
   386 		VoteMenuClose();
   387 	}
   388 	else if (action == MenuAction_Display)
   389 	{
   390 	 	decl String:title[64];
   391 		GetMenuTitle(menu, title, sizeof(title));
   392 
   393 	 	decl String:buffer[255];
   394 		Format(buffer, sizeof(buffer), "%T", title, param1, g_voteInfo[VOTE_NAME]);
   395 
   396 		new Handle:panel = Handle:param2;
   397 		SetPanelTitle(panel, buffer);
   398 	}
   399 	else if (action == MenuAction_DisplayItem)
   400 	{
   401 		decl String:display[64];
   402 		GetMenuItem(menu, param2, "", 0, _, display, sizeof(display));
   403 	 
   404 	 	if (strcmp(display, VOTE_NO) == 0 || strcmp(display, VOTE_YES) == 0)
   405 	 	{
   406 			decl String:buffer[255];
   407 			Format(buffer, sizeof(buffer), "%T", display, param1);
   408 
   409 			return RedrawMenuItem(buffer);
   410 		}
   411 	}
   412 	/* else if (action == MenuAction_Select)
   413 	{
   414 		VoteSelect(menu, param1, param2);
   415 	}*/
   416 	else if (action == MenuAction_VoteCancel && param1 == VoteCancel_NoVotes)
   417 	{
   418 		PrintToChatAll("[SM] %t", "No Votes Cast");
   419 	}
   420 	else if (action == MenuAction_VoteEnd)
   421 	{
   422 		decl String:item[64];
   423 		new Float:percent, Float:limit, votes, totalVotes;
   424 
   425 		GetMenuVoteInfo(param2, votes, totalVotes);
   426 		GetMenuItem(menu, param1, item, sizeof(item));
   427 		
   428 		if (strcmp(item, VOTE_NO) == 0 && param1 == 1)
   429 		{
   430 			votes = totalVotes - votes; // Reverse the votes to be in relation to the Yes option.
   431 		}
   432 		
   433 		percent = GetVotePercent(votes, totalVotes);
   434 		
   435 		limit = GetConVarFloat(g_Cvar_Limits[g_voteType]);
   436 
   437 		// A multi-argument vote is "always successful", but have to check if its a Yes/No vote.
   438 		if ((strcmp(item, VOTE_YES) == 0 && FloatCompare(percent,limit) < 0 && param1 == 0) || (strcmp(item, VOTE_NO) == 0 && param1 == 1))
   439 		{
   440 			LogMessage("Vote failed.");
   441 			PrintToChatAll("[SM] %t", "Vote Failed", RoundToNearest(100.0*limit), RoundToNearest(100.0*percent), totalVotes);
   442 		}
   443 		else
   444 		{
   445 			PrintToChatAll("[SM] %t", "Vote Successful", RoundToNearest(100.0*percent), totalVotes);
   446 			
   447 			switch (g_voteType)
   448 			{
   449 				case (voteType:gravity):
   450 				{
   451 					PrintToChatAll("[SM] %t", "Cvar changed", "sv_gravity", item);					
   452 					LogMessage("Changing gravity to %s due to vote.", item);
   453 					SetConVarInt(g_Cvar_Gravity, StringToInt(item));
   454 				}
   455 				
   456 				case (voteType:burn):
   457 				{
   458 					PrintToChatAll("[SM] %t", "Ignited player", g_voteInfo[VOTE_NAME]);					
   459 					LogMessage("Vote burn successful, igniting \"%L\"", g_voteClient[VOTE_CLIENTID]);
   460 					
   461 					IgniteEntity(g_voteClient[VOTE_CLIENTID], 19.8);	
   462 				}
   463 				
   464 				case (voteType:slay):
   465 				{
   466 					PrintToChatAll("[SM] %t", "Slayed player", g_voteInfo[VOTE_NAME]);					
   467 					LogMessage("Vote slay successful, slaying \"%L\"", g_voteClient[VOTE_CLIENTID]);
   468 					
   469 					ExtinguishEntity(g_voteClient[VOTE_CLIENTID]);
   470 					ForcePlayerSuicide(g_voteClient[VOTE_CLIENTID]);
   471 				}
   472 				
   473 				case (voteType:alltalk):
   474 				{
   475 					PrintToChatAll("[SM] %t", "Cvar changed", "sv_alltalk", (GetConVarBool(g_Cvar_Alltalk) ? "0" : "1"));
   476 					LogMessage("Changing alltalk to %s due to vote.", (GetConVarBool(g_Cvar_Alltalk) ? "0" : "1"));
   477 					SetConVarBool(g_Cvar_Alltalk, !GetConVarBool(g_Cvar_Alltalk));
   478 				}
   479 				
   480 				case (voteType:ff):
   481 				{
   482 					PrintToChatAll("[SM] %t", "Cvar changed", "mp_friendlyfire", (GetConVarBool(g_Cvar_FF) ? "0" : "1"));
   483 					LogMessage("Changing friendly fire to %s due to vote.", (GetConVarBool(g_Cvar_FF) ? "0" : "1"));
   484 					SetConVarBool(g_Cvar_FF, !GetConVarBool(g_Cvar_FF));
   485 				}				
   486 			}
   487 		}
   488 	}
   489 	
   490 	return 0;
   491 }
   492 
   493 /*
   494 VoteSelect(Handle:menu, param1, param2 = 0)
   495 {
   496 	if (GetConVarInt(g_Cvar_VoteShow) == 1)
   497 	{
   498 		decl String:voter[64], String:junk[64], String:choice[64];
   499 		GetClientName(param1, voter, sizeof(voter));
   500 		GetMenuItem(menu, param2, junk, sizeof(junk), _, choice, sizeof(choice));
   501 		PrintToChatAll("[SM] %T", "Vote Select", LANG_SERVER, voter, choice);
   502 	}
   503 }
   504 */
   505 
   506 VoteMenuClose()
   507 {
   508 	CloseHandle(g_hVoteMenu);
   509 	g_hVoteMenu = INVALID_HANDLE;
   510 }
   511 
   512 Float:GetVotePercent(votes, totalVotes)
   513 {
   514 	return FloatDiv(float(votes),float(totalVotes));
   515 }
   516 
   517 bool:TestVoteDelay(client)
   518 {
   519  	new delay = CheckVoteDelay();
   520  	
   521  	if (delay > 0)
   522  	{
   523  		if (delay > 60)
   524  		{
   525  			ReplyToCommand(client, "[SM] %t", "Vote Delay Minutes", delay % 60);
   526  		}
   527  		else
   528  		{
   529  			ReplyToCommand(client, "[SM] %t", "Vote Delay Seconds", delay);
   530  		}
   531  		
   532  		return false;
   533  	}
   534  	
   535 	return true;
   536 }