plugins/funcommands/fire.sp
author Scott Ehlert <ds@alliedmods.net>
Sun Mar 30 07:00:22 2008 +0000 (2008-03-30)
changeset 1952 b7aa2b626807
child 2289 44045ead61cd
permissions -rw-r--r--
Spring Cleaning, Part Ichi (1)
Various minor things done to project files
Updated sample extension project file and updated makefile to the new unified version (more changes likely on the way)
Updated regex project file and makefile
     1 /**
     2  * vim: set ts=4 :
     3  * =============================================================================
     4  * SourceMod Basefuncommands Plugin
     5  * Provides FireBomb 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 Handle:g_FireBombTimers[MAXPLAYERS+1];
    35 new g_FireBombTracker[MAXPLAYERS+1];
    36 
    37 new Handle:g_BurnDuration = INVALID_HANDLE;
    38 new Handle:g_FireBombTicks = INVALID_HANDLE;
    39 new Handle:g_FireBombRadius = INVALID_HANDLE;
    40 new Handle:g_FireBombMode = INVALID_HANDLE;
    41 
    42 SetupFire()
    43 {
    44 	RegAdminCmd("sm_burn", Command_Burn, ADMFLAG_SLAY, "sm_burn <#userid|name> [time]");
    45 	RegAdminCmd("sm_firebomb", Command_FireBomb, ADMFLAG_SLAY, "sm_firebomb <#userid|name> [0/1]");	
    46 	
    47 	g_BurnDuration = CreateConVar("sm_burn_duration", "20", "Sets the default duration of sm_burn and firebomb victims.", 0, true, 0.5, true, 20.0);
    48 	g_FireBombTicks = CreateConVar("sm_firebomb_ticks", "10", "Sets how long the FireBomb fuse is.", 0, true, 5.0, true, 120.0);
    49 	g_FireBombRadius = CreateConVar("sm_firebomb_radius", "600", "Sets the bomb blast radius.", 0, true, 50.0, true, 3000.0);
    50 	g_FireBombMode = CreateConVar("sm_firebomb_mode", "0", "Who is targetted by the FireBomb? 0 = Target only, 1 = Target's team, 2 = Everyone", 0, true, 0.0, true, 2.0);
    51 }
    52 
    53 CreateFireBomb(client)
    54 {
    55 	g_FireBombTimers[client] = CreateTimer(1.0, Timer_FireBomb, client, TIMER_REPEAT);
    56 	g_FireBombTracker[client] = GetConVarInt(g_FireBombTicks);
    57 }
    58 
    59 KillFireBomb(client)
    60 {
    61 	KillTimer(g_FireBombTimers[client]);
    62 	g_FireBombTimers[client] = INVALID_HANDLE;
    63 }
    64 
    65 KillAllFireBombs()
    66 {
    67 	new maxclients = GetMaxClients();
    68 	for (new i = 1; i <= maxclients; i++)
    69 	{
    70 		if (g_FireBombTimers[i] != INVALID_HANDLE)
    71 		{
    72 			KillFireBomb(i);
    73 		}
    74 	}
    75 }
    76 
    77 PerformBurn(client, target, Float:seconds)
    78 {
    79 	LogAction(client, target, "\"%L\" ignited \"%L\" (seconds \"%f\")", client, target, seconds);
    80 	IgniteEntity(target, seconds);
    81 }
    82 
    83 PerformFireBomb(client, target, toggle)
    84 {
    85 	switch (toggle)
    86 	{
    87 		case (2):
    88 		{
    89 			if (g_FireBombTimers[target] == INVALID_HANDLE)
    90 			{
    91 				CreateFireBomb(target);
    92 				LogAction(client, target, "\"%L\" set a FireBomb on \"%L\"", client, target);
    93 			}
    94 			else
    95 			{
    96 				KillFireBomb(target);
    97 				SetEntityRenderColor(client, 255, 255, 255, 255);
    98 				LogAction(client, target, "\"%L\" removed a FireBomb on \"%L\"", client, target);
    99 			}			
   100 		}
   101 
   102 		case (1):
   103 		{
   104 			if (g_FireBombTimers[target] == INVALID_HANDLE)
   105 			{
   106 				CreateFireBomb(target);
   107 				LogAction(client, target, "\"%L\" set a FireBomb on \"%L\"", client, target);
   108 			}			
   109 		}
   110 		
   111 		case (0):
   112 		{
   113 			if (g_FireBombTimers[target] != INVALID_HANDLE)
   114 			{
   115 				KillFireBomb(target);
   116 				SetEntityRenderColor(client, 255, 255, 255, 255);
   117 				LogAction(client, target, "\"%L\" removed a FireBomb on \"%L\"", client, target);
   118 			}			
   119 		}
   120 	}
   121 }
   122 
   123 public Action:Timer_FireBomb(Handle:timer, any:client)
   124 {
   125 	if (!IsClientInGame(client) || !IsPlayerAlive(client))
   126 	{
   127 		KillFireBomb(client);		
   128 
   129 		return Plugin_Handled;
   130 	}
   131 	
   132 	g_FireBombTracker[client]--;
   133 	
   134 	new Float:vec[3];
   135 	GetClientEyePosition(client, vec);
   136 	
   137 	if (g_FireBombTracker[client] > 0)
   138 	{
   139 		new color;
   140 		
   141 		if (g_FireBombTracker[client] > 1)
   142 		{
   143 			color = RoundToFloor(g_FireBombTracker[client] * (255.0 / GetConVarFloat(g_FireBombTicks)));
   144 			EmitAmbientSound(SOUND_BEEP, vec, client, SNDLEVEL_RAIDSIREN);	
   145 		}
   146 		else
   147 		{
   148 			color = 0;
   149 			EmitAmbientSound(SOUND_FINAL, vec, client, SNDLEVEL_RAIDSIREN);
   150 		}
   151 		
   152 		SetEntityRenderColor(client, 255, color, color, 255);
   153 
   154 		decl String:name[64];
   155 		GetClientName(client, name, sizeof(name));
   156 		PrintCenterTextAll("%t", "Till Explodes", name, g_FireBombTracker[client]);		
   157 		
   158 		GetClientAbsOrigin(client, vec);
   159 		vec[2] += 10;
   160 
   161 		TE_SetupBeamRingPoint(vec, 10.0, GetConVarFloat(g_FireBombRadius) / 3.0, g_BeamSprite, g_HaloSprite, 0, 15, 0.5, 5.0, 0.0, greyColor, 10, 0);
   162 		TE_SendToAll();
   163 		TE_SetupBeamRingPoint(vec, 10.0, GetConVarFloat(g_FireBombRadius) / 3.0, g_BeamSprite, g_HaloSprite, 0, 10, 0.6, 10.0, 0.5, whiteColor, 10, 0);
   164 		TE_SendToAll();
   165 	}
   166 	else
   167 	{
   168 		TE_SetupExplosion(vec, g_ExplosionSprite, 0.1, 1, 0, GetConVarInt(g_FireBombRadius), 5000);
   169 		TE_SendToAll();
   170 		
   171 		GetClientAbsOrigin(client, vec);
   172 		vec[2] += 10;
   173 		TE_SetupBeamRingPoint(vec, 50.0, GetConVarFloat(g_FireBombRadius), g_BeamSprite, g_HaloSprite, 0, 10, 0.5, 30.0, 1.5, orangeColor, 5, 0);
   174 		TE_SendToAll();
   175 		vec[2] += 15;
   176 		TE_SetupBeamRingPoint(vec, 40.0, GetConVarFloat(g_FireBombRadius), g_BeamSprite, g_HaloSprite, 0, 10, 0.6, 30.0, 1.5, orangeColor, 5, 0);
   177 		TE_SendToAll();	
   178 		vec[2] += 15;
   179 		TE_SetupBeamRingPoint(vec, 30.0, GetConVarFloat(g_FireBombRadius), g_BeamSprite, g_HaloSprite, 0, 10, 0.7, 30.0, 1.5, orangeColor, 5, 0);
   180 		TE_SendToAll();
   181 		vec[2] += 15;
   182 		TE_SetupBeamRingPoint(vec, 20.0, GetConVarFloat(g_FireBombRadius), g_BeamSprite, g_HaloSprite, 0, 10, 0.8, 30.0, 1.5, orangeColor, 5, 0);
   183 		TE_SendToAll();		
   184 		
   185 		EmitAmbientSound(SOUND_BOOM, vec, client, SNDLEVEL_RAIDSIREN);
   186 
   187 		IgniteEntity(client, GetConVarFloat(g_BurnDuration));
   188 		KillFireBomb(client);
   189 		SetEntityRenderColor(client, 255, 255, 255, 255);
   190 		
   191 		if (GetConVarInt(g_FireBombMode) > 0)
   192 		{
   193 			new teamOnly = ((GetConVarInt(g_FireBombMode) == 1) ? true : false);
   194 			new maxClients = GetMaxClients();
   195 			
   196 			for (new i = 1; i < maxClients; i++)
   197 			{
   198 				if (!IsClientInGame(i) || !IsPlayerAlive(i) || i == client)
   199 				{
   200 					continue;
   201 				}
   202 				
   203 				if (teamOnly && GetClientTeam(i) != GetClientTeam(client))
   204 				{
   205 					continue;
   206 				}
   207 				
   208 				new Float:pos[3];
   209 				GetClientAbsOrigin(i, pos);
   210 				
   211 				new Float:distance = GetVectorDistance(vec, pos);
   212 				
   213 				if (distance > GetConVarFloat(g_FireBombRadius))
   214 				{
   215 					continue;
   216 				}
   217 				
   218 				new Float:duration = GetConVarFloat(g_BurnDuration);
   219 				duration *= (GetConVarFloat(g_FireBombRadius) - distance) / GetConVarFloat(g_FireBombRadius);
   220 
   221 				IgniteEntity(i, duration);
   222 			}		
   223 		}
   224 	}
   225 			
   226 	return Plugin_Handled;
   227 }
   228 
   229 public AdminMenu_Burn(Handle:topmenu, 
   230 					  TopMenuAction:action,
   231 					  TopMenuObject:object_id,
   232 					  param,
   233 					  String:buffer[],
   234 					  maxlength)
   235 {
   236 	if (action == TopMenuAction_DisplayOption)
   237 	{
   238 		Format(buffer, maxlength, "%T", "Burn player", param);
   239 	}
   240 	else if (action == TopMenuAction_SelectOption)
   241 	{
   242 		DisplayBurnMenu(param);
   243 	}
   244 }
   245 
   246 public AdminMenu_FireBomb(Handle:topmenu, 
   247 					  TopMenuAction:action,
   248 					  TopMenuObject:object_id,
   249 					  param,
   250 					  String:buffer[],
   251 					  maxlength)
   252 {
   253 	if (action == TopMenuAction_DisplayOption)
   254 	{
   255 		Format(buffer, maxlength, "%T", "FireBomb player", param);
   256 	}
   257 	else if (action == TopMenuAction_SelectOption)
   258 	{
   259 		DisplayFireBombMenu(param);
   260 	}
   261 }
   262 
   263 DisplayBurnMenu(client)
   264 {
   265 	new Handle:menu = CreateMenu(MenuHandler_Burn);
   266 	
   267 	decl String:title[100];
   268 	Format(title, sizeof(title), "%T:", "Burn player", client);
   269 	SetMenuTitle(menu, title);
   270 	SetMenuExitBackButton(menu, true);
   271 	
   272 	AddTargetsToMenu(menu, client, true, true);
   273 	
   274 	DisplayMenu(menu, client, MENU_TIME_FOREVER);
   275 }
   276 
   277 DisplayFireBombMenu(client)
   278 {
   279 	new Handle:menu = CreateMenu(MenuHandler_FireBomb);
   280 	
   281 	decl String:title[100];
   282 	Format(title, sizeof(title), "%T:", "FireBomb player", client);
   283 	SetMenuTitle(menu, title);
   284 	SetMenuExitBackButton(menu, true);
   285 	
   286 	AddTargetsToMenu(menu, client, true, true);
   287 	
   288 	DisplayMenu(menu, client, MENU_TIME_FOREVER);
   289 }
   290 
   291 public MenuHandler_Burn(Handle:menu, MenuAction:action, param1, param2)
   292 {
   293 	if (action == MenuAction_End)
   294 	{
   295 		CloseHandle(menu);
   296 	}
   297 	else if (action == MenuAction_Cancel)
   298 	{
   299 		if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
   300 		{
   301 			DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
   302 		}
   303 	}
   304 	else if (action == MenuAction_Select)
   305 	{
   306 		decl String:info[32];
   307 		new userid, target;
   308 		
   309 		GetMenuItem(menu, param2, info, sizeof(info));
   310 		userid = StringToInt(info);
   311 
   312 		if ((target = GetClientOfUserId(userid)) == 0)
   313 		{
   314 			PrintToChat(param1, "[SM] %t", "Player no longer available");
   315 		}
   316 		else if (!CanUserTarget(param1, target))
   317 		{
   318 			PrintToChat(param1, "[SM] %t", "Unable to target");
   319 		}
   320 		else
   321 		{
   322 			new String:name[32];
   323 			GetClientName(target, name, sizeof(name));
   324 			PerformBurn(param1, target, 20.0);
   325 			ShowActivity2(param1, "[SM] ", "%t", "Set target on fire", "_s", name);
   326 		}
   327 		
   328 		/* Re-draw the menu if they're still valid */
   329 		if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
   330 		{
   331 			DisplayBurnMenu(param1);
   332 		}
   333 	}
   334 }
   335 
   336 public MenuHandler_FireBomb(Handle:menu, MenuAction:action, param1, param2)
   337 {
   338 	if (action == MenuAction_End)
   339 	{
   340 		CloseHandle(menu);
   341 	}
   342 	else if (action == MenuAction_Cancel)
   343 	{
   344 		if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
   345 		{
   346 			DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
   347 		}
   348 	}
   349 	else if (action == MenuAction_Select)
   350 	{
   351 		decl String:info[32];
   352 		new userid, target;
   353 		
   354 		GetMenuItem(menu, param2, info, sizeof(info));
   355 		userid = StringToInt(info);
   356 
   357 		if ((target = GetClientOfUserId(userid)) == 0)
   358 		{
   359 			PrintToChat(param1, "[SM] %t", "Player no longer available");
   360 		}
   361 		else if (!CanUserTarget(param1, target))
   362 		{
   363 			PrintToChat(param1, "[SM] %t", "Unable to target");
   364 		}
   365 		else
   366 		{
   367 			new String:name[32];
   368 			GetClientName(target, name, sizeof(name));
   369 			
   370 			PerformFireBomb(param1, target, 2);
   371 			ShowActivity2(param1, "[SM] ", "%t", "Toggled FireBomb on target", "_s", name);
   372 		}
   373 		
   374 		/* Re-draw the menu if they're still valid */
   375 		if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
   376 		{
   377 			DisplayFireBombMenu(param1);
   378 		}
   379 	}
   380 }
   381 
   382 public Action:Command_Burn(client, args)
   383 {
   384 	if (args < 1)
   385 	{
   386 		ReplyToCommand(client, "[SM] Usage: sm_burn <#userid|name> [time]");
   387 		return Plugin_Handled;
   388 	}
   389 
   390 	decl String:arg[65];
   391 	GetCmdArg(1, arg, sizeof(arg));
   392 
   393 	new Float:seconds = GetConVarFloat(g_BurnDuration);
   394 	
   395 	if (args > 1)
   396 	{
   397 		decl String:time[20];
   398 		GetCmdArg(2, time, sizeof(time));
   399 		if (StringToFloatEx(time, seconds) == 0)
   400 		{
   401 			ReplyToCommand(client, "[SM] %t", "Invalid Amount");
   402 			return Plugin_Handled;
   403 		}
   404 	}
   405 	
   406 	decl String:target_name[MAX_TARGET_LENGTH];
   407 	decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
   408 	
   409 	if ((target_count = ProcessTargetString(
   410 			arg,
   411 			client,
   412 			target_list,
   413 			MAXPLAYERS,
   414 			COMMAND_FILTER_ALIVE,
   415 			target_name,
   416 			sizeof(target_name),
   417 			tn_is_ml)) <= 0)
   418 	{
   419 		ReplyToTargetError(client, target_count);
   420 		return Plugin_Handled;
   421 	}
   422 	
   423 	for (new i = 0; i < target_count; i++)
   424 	{
   425 		PerformBurn(client, target_list[i], seconds);
   426 	}
   427 	
   428 	if (tn_is_ml)
   429 	{
   430 		ShowActivity2(client, "[SM] ", "%t", "Set target on fire", target_name);
   431 	}
   432 	else
   433 	{
   434 		ShowActivity2(client, "[SM] ", "%t", "Set target on fire", "_s", target_name);
   435 	}
   436 
   437 	return Plugin_Handled;
   438 }
   439 
   440 public Action:Command_FireBomb(client, args)
   441 {
   442 	if (args < 1)
   443 	{
   444 		ReplyToCommand(client, "[SM] Usage: sm_firebomb <#userid|name> [0/1]");
   445 		return Plugin_Handled;
   446 	}
   447 
   448 	decl String:arg[65];
   449 	GetCmdArg(1, arg, sizeof(arg));
   450 	
   451 	new toggle = 2;
   452 	if (args > 1)
   453 	{
   454 		decl String:arg2[2];
   455 		GetCmdArg(2, arg2, sizeof(arg2));
   456 		if (arg2[0])
   457 		{
   458 			toggle = 1;
   459 		}
   460 		else
   461 		{
   462 			toggle = 0;
   463 		}
   464 	}
   465 
   466 	decl String:target_name[MAX_TARGET_LENGTH];
   467 	decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
   468 	
   469 	if ((target_count = ProcessTargetString(
   470 			arg,
   471 			client,
   472 			target_list,
   473 			MAXPLAYERS,
   474 			COMMAND_FILTER_ALIVE,
   475 			target_name,
   476 			sizeof(target_name),
   477 			tn_is_ml)) <= 0)
   478 	{
   479 		ReplyToTargetError(client, target_count);
   480 		return Plugin_Handled;
   481 	}
   482 	
   483 	for (new i = 0; i < target_count; i++)
   484 	{
   485 		PerformFireBomb(client, target_list[i], toggle);
   486 	}
   487 	
   488 	if (tn_is_ml)
   489 	{
   490 		ShowActivity2(client, "[SM] ", "%t", "Toggled FireBomb on target", target_name);
   491 	}
   492 	else
   493 	{
   494 		ShowActivity2(client, "[SM] ", "%t", "Toggled FireBomb on target", "_s", target_name);
   495 	}
   496 	
   497 	return Plugin_Handled;
   498 }
   499 
   500 
   501 
   502 
   503 
   504