plugins/funcommands/timebomb.sp
author Ruben Gonzalez <drifter01620@gmail.com>
Thu May 22 09:49:27 2014 -0400 (2014-05-22)
changeset 4378 568f4497ef4a
parent 4310 896868764315
permissions -rw-r--r--
Update CS:GO team score gamedata.
     1 /**
     2  * vim: set ts=4 :
     3  * =============================================================================
     4  * SourceMod Basefuncommands Plugin
     5  * Provides TimeBomb functionality
     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 new g_TimeBombSerial[MAXPLAYERS+1] = { 0, ... };
    35 new g_TimeBombTime[MAXPLAYERS+1] = { 0, ... };
    36 
    37 new Handle:g_Cvar_TimeBombTicks = INVALID_HANDLE;
    38 new Handle:g_Cvar_TimeBombRadius = INVALID_HANDLE;
    39 new Handle:g_Cvar_TimeBombMode = INVALID_HANDLE;
    40 
    41 CreateTimeBomb(client)
    42 {
    43 	g_TimeBombSerial[client] = ++g_Serial_Gen;
    44 	CreateTimer(1.0, Timer_TimeBomb, client | (g_Serial_Gen << 7), DEFAULT_TIMER_FLAGS);
    45 	g_TimeBombTime[client] = GetConVarInt(g_Cvar_TimeBombTicks);
    46 }
    47 
    48 KillTimeBomb(client)
    49 {
    50 	g_TimeBombSerial[client] = 0;
    51 
    52 	if (IsClientInGame(client))
    53 	{
    54 		SetEntityRenderColor(client, 255, 255, 255, 255);
    55 	}
    56 }
    57 
    58 KillAllTimeBombs()
    59 {
    60 	for (new i = 1; i <= MaxClients; i++)
    61 	{
    62 		KillTimeBomb(i);
    63 	}
    64 }
    65 
    66 PerformTimeBomb(client, target)
    67 {
    68 	if (g_TimeBombSerial[target] == 0)
    69 	{
    70 		CreateTimeBomb(target);
    71 		LogAction(client, target, "\"%L\" set a TimeBomb on \"%L\"", client, target);
    72 	}
    73 	else
    74 	{
    75 		KillTimeBomb(target);
    76 		SetEntityRenderColor(client, 255, 255, 255, 255);
    77 		LogAction(client, target, "\"%L\" removed a TimeBomb on \"%L\"", client, target);
    78 	}
    79 }
    80 
    81 public Action:Timer_TimeBomb(Handle:timer, any:value)
    82 {
    83 	new client = value & 0x7f;
    84 	new serial = value >> 7;
    85 
    86 	if (!IsClientInGame(client)
    87 		|| !IsPlayerAlive(client)
    88 		|| serial != g_TimeBombSerial[client])
    89 	{
    90 		KillTimeBomb(client);
    91 		return Plugin_Stop;
    92 	}	
    93 	g_TimeBombTime[client]--;
    94 	
    95 	new Float:vec[3];
    96 	GetClientEyePosition(client, vec);
    97 	
    98 	if (g_TimeBombTime[client] > 0)
    99 	{
   100 		new color;
   101 		
   102 		if (g_TimeBombTime[client] > 1)
   103 		{
   104 			color = RoundToFloor(g_TimeBombTime[client] * (128.0 / GetConVarFloat(g_Cvar_TimeBombTicks)));
   105 			if (g_BeepSound[0])
   106 			{
   107 				EmitAmbientSound(g_BeepSound, vec, client, SNDLEVEL_RAIDSIREN);	
   108 			}
   109 		}
   110 		else
   111 		{
   112 			color = 0;
   113 			if (g_FinalSound[0])
   114 			{
   115 				EmitAmbientSound(g_FinalSound, vec, client, SNDLEVEL_RAIDSIREN);
   116 			}
   117 		}
   118 		
   119 		SetEntityRenderColor(client, 255, 128, color, 255);
   120 
   121 		decl String:name[64];
   122 		GetClientName(client, name, sizeof(name));
   123 		PrintCenterTextAll("%t", "Till Explodes", name, g_TimeBombTime[client]);
   124 		
   125 		if (g_BeamSprite > -1 && g_HaloSprite > -1)
   126 		{
   127 			GetClientAbsOrigin(client, vec);
   128 			vec[2] += 10;
   129 
   130 			TE_SetupBeamRingPoint(vec, 10.0, GetConVarFloat(g_Cvar_TimeBombRadius) / 3.0, g_BeamSprite, g_HaloSprite, 0, 15, 0.5, 5.0, 0.0, greyColor, 10, 0);
   131 			TE_SendToAll();
   132 			TE_SetupBeamRingPoint(vec, 10.0, GetConVarFloat(g_Cvar_TimeBombRadius) / 3.0, g_BeamSprite, g_HaloSprite, 0, 10, 0.6, 10.0, 0.5, whiteColor, 10, 0);
   133 			TE_SendToAll();
   134 		}
   135 		return Plugin_Continue;
   136 	}
   137 	else
   138 	{
   139 		if (g_ExplosionSprite > -1)
   140 		{
   141 			TE_SetupExplosion(vec, g_ExplosionSprite, 5.0, 1, 0, GetConVarInt(g_Cvar_TimeBombRadius), 5000);
   142 			TE_SendToAll();
   143 		}
   144 
   145 		if (g_BoomSound[0])
   146 		{
   147 			EmitAmbientSound(g_BoomSound, vec, client, SNDLEVEL_RAIDSIREN);
   148 		}
   149 
   150 		ForcePlayerSuicide(client);
   151 		KillTimeBomb(client);
   152 		SetEntityRenderColor(client, 255, 255, 255, 255);
   153 		
   154 		if (GetConVarInt(g_Cvar_TimeBombMode) > 0)
   155 		{
   156 			new teamOnly = ((GetConVarInt(g_Cvar_TimeBombMode) == 1) ? true : false);
   157 			
   158 			for (new i = 1; i <= MaxClients; i++)
   159 			{
   160 				if (!IsClientInGame(i) || !IsPlayerAlive(i) || i == client)
   161 				{
   162 					continue;
   163 				}
   164 				
   165 				if (teamOnly && GetClientTeam(i) != GetClientTeam(client))
   166 				{
   167 					continue;
   168 				}
   169 				
   170 				new Float:pos[3];
   171 				GetClientEyePosition(i, pos);
   172 				
   173 				new Float:distance = GetVectorDistance(vec, pos);
   174 				
   175 				if (distance > GetConVarFloat(g_Cvar_TimeBombRadius))
   176 				{
   177 					continue;
   178 				}
   179 				
   180 				new damage = 220;
   181 				damage = RoundToFloor(damage * ((GetConVarFloat(g_Cvar_TimeBombRadius) - distance) / GetConVarFloat(g_Cvar_TimeBombRadius)));
   182 					
   183 				SlapPlayer(i, damage, false);
   184 				
   185 				if (g_ExplosionSprite > -1)
   186 				{
   187 					TE_SetupExplosion(pos, g_ExplosionSprite, 0.05, 1, 0, 1, 1);
   188 					TE_SendToAll();	
   189 				}
   190 				
   191 				/* ToDo
   192 				new Float:dir[3];
   193 				SubtractVectors(vec, pos, dir);
   194 				TR_TraceRayFilter(vec, dir, MASK_SOLID, RayType_Infinite, TR_Filter_Client);
   195 
   196 				if (i == TR_GetEntityIndex())
   197 				{
   198 					new damage = 100;
   199 					new radius = GetConVarInt(g_Cvar_TimeBombRadius) / 2;
   200 					
   201 					if (distance > radius)
   202 					{
   203 						distance -= radius;
   204 						damage = RoundToFloor(damage * ((radius - distance) / radius));
   205 					}
   206 					
   207 					SlapPlayer(i, damage, false);
   208 				}
   209 				*/
   210 			}		
   211 		}
   212 		return Plugin_Stop;
   213 	}
   214 }
   215 
   216 public AdminMenu_TimeBomb(Handle:topmenu, 
   217 					  TopMenuAction:action,
   218 					  TopMenuObject:object_id,
   219 					  param,
   220 					  String:buffer[],
   221 					  maxlength)
   222 {
   223 	if (action == TopMenuAction_DisplayOption)
   224 	{
   225 		Format(buffer, maxlength, "%T", "TimeBomb player", param);
   226 	}
   227 	else if (action == TopMenuAction_SelectOption)
   228 	{
   229 		DisplayTimeBombMenu(param);
   230 	}
   231 }
   232 
   233 DisplayTimeBombMenu(client)
   234 {
   235 	new Handle:menu = CreateMenu(MenuHandler_TimeBomb);
   236 	
   237 	decl String:title[100];
   238 	Format(title, sizeof(title), "%T:", "TimeBomb player", client);
   239 	SetMenuTitle(menu, title);
   240 	SetMenuExitBackButton(menu, true);
   241 	
   242 	AddTargetsToMenu(menu, client, true, true);
   243 	
   244 	DisplayMenu(menu, client, MENU_TIME_FOREVER);
   245 }
   246 
   247 public MenuHandler_TimeBomb(Handle:menu, MenuAction:action, param1, param2)
   248 {
   249 	if (action == MenuAction_End)
   250 	{
   251 		CloseHandle(menu);
   252 	}
   253 	else if (action == MenuAction_Cancel)
   254 	{
   255 		if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
   256 		{
   257 			DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
   258 		}
   259 	}
   260 	else if (action == MenuAction_Select)
   261 	{
   262 		decl String:info[32];
   263 		new userid, target;
   264 		
   265 		GetMenuItem(menu, param2, info, sizeof(info));
   266 		userid = StringToInt(info);
   267 
   268 		if ((target = GetClientOfUserId(userid)) == 0)
   269 		{
   270 			PrintToChat(param1, "[SM] %t", "Player no longer available");
   271 		}
   272 		else if (!CanUserTarget(param1, target))
   273 		{
   274 			PrintToChat(param1, "[SM] %t", "Unable to target");
   275 		}
   276 		else
   277 		{
   278 			new String:name[32];
   279 			GetClientName(target, name, sizeof(name));
   280 			
   281 			PerformTimeBomb(param1, target);
   282 			ShowActivity2(param1, "[SM] ", "%t", "Toggled TimeBomb on target", "_s", name);
   283 		}
   284 		
   285 		/* Re-draw the menu if they're still valid */
   286 		if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
   287 		{
   288 			DisplayTimeBombMenu(param1);
   289 		}
   290 	}
   291 }
   292 
   293 public Action:Command_TimeBomb(client, args)
   294 {
   295 	if (args < 1)
   296 	{
   297 		ReplyToCommand(client, "[SM] Usage: sm_timebomb <#userid|name>");
   298 		return Plugin_Handled;
   299 	}
   300 
   301 	decl String:arg[65];
   302 	GetCmdArg(1, arg, sizeof(arg));
   303 
   304 	decl String:target_name[MAX_TARGET_LENGTH];
   305 	decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
   306 	
   307 	if ((target_count = ProcessTargetString(
   308 			arg,
   309 			client,
   310 			target_list,
   311 			MAXPLAYERS,
   312 			COMMAND_FILTER_ALIVE,
   313 			target_name,
   314 			sizeof(target_name),
   315 			tn_is_ml)) <= 0)
   316 	{
   317 		ReplyToTargetError(client, target_count);
   318 		return Plugin_Handled;
   319 	}
   320 	
   321 	for (new i = 0; i < target_count; i++)
   322 	{
   323 		PerformTimeBomb(client, target_list[i]);
   324 	}
   325 	
   326 	if (tn_is_ml)
   327 	{
   328 		ShowActivity2(client, "[SM] ", "%t", "Toggled TimeBomb on target", target_name);
   329 	}
   330 	else
   331 	{
   332 		ShowActivity2(client, "[SM] ", "%t", "Toggled TimeBomb on target", "_s", target_name);
   333 	}
   334 	
   335 	return Plugin_Handled;
   336 }