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