plugins/funcommands/ice.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 freeze and freezebomb 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_FreezeSerial[MAXPLAYERS+1] = { 0, ... };
    35 new g_FreezeBombSerial[MAXPLAYERS+1] = { 0, ... };
    36 new g_FreezeTime[MAXPLAYERS+1] = { 0, ... };
    37 new g_FreezeBombTime[MAXPLAYERS+1] = { 0, ... };
    38 
    39 new Handle:g_Cvar_FreezeDuration = INVALID_HANDLE;
    40 new Handle:g_Cvar_FreezeBombTicks = INVALID_HANDLE;
    41 new Handle:g_Cvar_FreezeBombRadius = INVALID_HANDLE;
    42 new Handle:g_Cvar_FreezeBombMode = INVALID_HANDLE;
    43 
    44 FreezeClient(client, time)
    45 {
    46 	if (g_FreezeSerial[client] != 0)
    47 	{
    48 		UnfreezeClient(client);
    49 		return;
    50 	}
    51 	SetEntityMoveType(client, MOVETYPE_NONE);
    52 	SetEntityRenderColor(client, 0, 128, 255, 192);
    53 
    54 	if (g_FreezeSound[0])
    55 	{
    56 		new Float:vec[3];
    57 		GetClientEyePosition(client, vec);
    58 		EmitAmbientSound(g_FreezeSound, vec, client, SNDLEVEL_RAIDSIREN);
    59 	}
    60 
    61 	g_FreezeTime[client] = time;
    62 	g_FreezeSerial[client] = ++ g_Serial_Gen;
    63 	CreateTimer(1.0, Timer_Freeze, client | (g_Serial_Gen << 7), DEFAULT_TIMER_FLAGS);
    64 }
    65 
    66 UnfreezeClient(client)
    67 {
    68 	g_FreezeSerial[client] = 0;
    69 	g_FreezeTime[client] = 0;
    70 
    71 	if (IsClientInGame(client))
    72 	{
    73 		if (g_FreezeSound[0])
    74 		{
    75 			new Float:vec[3];
    76 			GetClientAbsOrigin(client, vec);
    77 			vec[2] += 10;	
    78 			
    79 			GetClientEyePosition(client, vec);
    80 			EmitAmbientSound(g_FreezeSound, vec, client, SNDLEVEL_RAIDSIREN);
    81 		}
    82 
    83 		SetEntityMoveType(client, MOVETYPE_WALK);
    84 		
    85 		SetEntityRenderColor(client, 255, 255, 255, 255);
    86 	}
    87 }
    88 
    89 CreateFreezeBomb(client)
    90 {
    91 	if (g_FreezeBombSerial[client] != 0)
    92 	{
    93 		KillFreezeBomb(client);
    94 		return;
    95 	}
    96 	g_FreezeBombTime[client] = GetConVarInt(g_Cvar_FreezeBombTicks);
    97 	g_FreezeBombSerial[client] = ++g_Serial_Gen;
    98 	CreateTimer(1.0, Timer_FreezeBomb, client | (g_Serial_Gen << 7), DEFAULT_TIMER_FLAGS);
    99 }
   100 
   101 KillFreezeBomb(client)
   102 {
   103 	g_FreezeBombSerial[client] = 0;
   104 	g_FreezeBombTime[client] = 0;
   105 
   106 	if (IsClientInGame(client))
   107 	{
   108 		SetEntityRenderColor(client, 255, 255, 255, 255);
   109 	}
   110 }
   111 
   112 KillAllFreezes( )
   113 {
   114 	for(new i = 1; i <= MaxClients; i++)
   115 	{
   116 		if (g_FreezeSerial[i] != 0)
   117 		{
   118 			UnfreezeClient(i);
   119 		}
   120 
   121 		if (g_FreezeBombSerial[i] != 0)
   122 		{
   123 			KillFreezeBomb(i);
   124 		}
   125 	}
   126 }
   127 
   128 PerformFreeze(client, target, time)
   129 {
   130 	FreezeClient(target, time);
   131 	LogAction(client, target, "\"%L\" froze \"%L\"", client, target);
   132 }
   133 
   134 PerformFreezeBomb(client, target)
   135 {
   136 	if (g_FreezeBombSerial[target] != 0)
   137 	{
   138 		KillFreezeBomb(target);
   139 		LogAction(client, target, "\"%L\" removed a FreezeBomb on \"%L\"", client, target);
   140 	}
   141 	else
   142 	{
   143 		CreateFreezeBomb(target);
   144 		LogAction(client, target, "\"%L\" set a FreezeBomb on \"%L\"", client, target);
   145 	}
   146 }
   147 
   148 public Action:Timer_Freeze(Handle:timer, any:value)
   149 {
   150 	new client = value & 0x7f;
   151 	new serial = value >> 7;
   152 
   153 	if (!IsClientInGame(client)
   154 		|| !IsPlayerAlive(client)
   155 		|| g_FreezeSerial[client] != serial)
   156 	{
   157 		UnfreezeClient(client);
   158 		return Plugin_Stop;
   159 	}
   160 
   161 	if (g_FreezeTime[client] == 0)
   162 	{
   163 		UnfreezeClient(client);
   164 		
   165 		/* HintText doesn't work on Dark Messiah */
   166 		if (g_GameEngine != Engine_DarkMessiah)
   167 		{
   168 			PrintHintText(client, "%t", "Unfrozen");
   169 		}
   170 		else
   171 		{
   172 			PrintCenterText(client, "%t", "Unfrozen");
   173 		}
   174 		
   175 		return Plugin_Stop;
   176 	}
   177 
   178 	if (g_GameEngine != Engine_DarkMessiah)
   179 	{
   180 		PrintHintText(client, "%t", "You will be unfrozen", g_FreezeTime[client]);
   181 	}
   182 	else
   183 	{
   184 		PrintCenterText(client, "%t", "You will be unfrozen", g_FreezeTime[client]);
   185 	}
   186 	
   187 	g_FreezeTime[client]--;
   188 	SetEntityMoveType(client, MOVETYPE_NONE);
   189 	SetEntityRenderColor(client, 0, 128, 255, 135);
   190 
   191 	new Float:vec[3];
   192 	GetClientAbsOrigin(client, vec);
   193 	vec[2] += 10;
   194 
   195 	if (g_GlowSprite > -1)
   196 	{
   197 		TE_SetupGlowSprite(vec, g_GlowSprite, 0.95, 1.5, 50);
   198 		TE_SendToAll();
   199 	}
   200 	else if (g_HaloSprite > -1)
   201 	{
   202 		TE_SetupGlowSprite(vec, g_HaloSprite, 0.95, 1.5, 50);
   203 		TE_SendToAll();
   204 	}
   205 
   206 	return Plugin_Continue;
   207 }
   208 
   209 public Action:Timer_FreezeBomb(Handle:timer, any:value)
   210 {
   211 	new client = value & 0x7f;
   212 	new serial = value >> 7;
   213 
   214 	if (!IsClientInGame(client)
   215 		|| !IsPlayerAlive(client)
   216 		|| g_FreezeBombSerial[client] != serial)
   217 	{
   218 		KillFreezeBomb(client);
   219 		return Plugin_Stop;
   220 	}
   221 
   222 	new Float:vec[3];
   223 	GetClientEyePosition(client, vec);
   224 	g_FreezeBombTime[client]--;
   225 
   226 	if (g_FreezeBombTime[client] > 0)
   227 	{
   228 		new color;
   229 
   230 		if (g_FreezeBombTime[client] > 1)
   231 		{
   232 			color = RoundToFloor(g_FreezeBombTime[client] * (255.0 / GetConVarFloat(g_Cvar_FreezeBombTicks)));
   233 			if (g_BeepSound[0])
   234 			{
   235 				EmitAmbientSound(g_BeepSound, vec, client, SNDLEVEL_RAIDSIREN);
   236 			}
   237 		}
   238 		else
   239 		{
   240 			color = 0;
   241 			if (g_FinalSound[0])
   242 			{
   243 				EmitAmbientSound(g_FinalSound, vec, client, SNDLEVEL_RAIDSIREN);
   244 			}
   245 		}
   246 		
   247 		SetEntityRenderColor(client, color, color, 255, 255);
   248 
   249 		decl String:name[64];
   250 		GetClientName(client, name, sizeof(name));
   251 		PrintCenterTextAll("%t", "Till Explodes", name, g_FreezeBombTime[client]);
   252 
   253 		if (g_BeamSprite > -1 && g_HaloSprite > -1)
   254 		{
   255 			GetClientAbsOrigin(client, vec);
   256 			vec[2] += 10;
   257 
   258 			TE_SetupBeamRingPoint(vec, 10.0, GetConVarFloat(g_Cvar_FreezeBombRadius) / 3.0, g_BeamSprite, g_HaloSprite, 0, 15, 0.5, 5.0, 0.0, greyColor, 10, 0);
   259 			TE_SendToAll();
   260 			TE_SetupBeamRingPoint(vec, 10.0, GetConVarFloat(g_Cvar_FreezeBombRadius) / 3.0, g_BeamSprite, g_HaloSprite, 0, 10, 0.6, 10.0, 0.5, whiteColor, 10, 0);
   261 			TE_SendToAll();
   262 		}
   263 		return Plugin_Continue;
   264 	}
   265 	else
   266 	{
   267 		if (g_ExplosionSprite > -1)
   268 		{
   269 			TE_SetupExplosion(vec, g_ExplosionSprite, 5.0, 1, 0, GetConVarInt(g_Cvar_FreezeBombRadius), 5000);
   270 			TE_SendToAll();
   271 		}
   272 
   273 		if (g_BoomSound[0])
   274 		{
   275 			EmitAmbientSound(g_BoomSound, vec, client, SNDLEVEL_RAIDSIREN);
   276 		}
   277 
   278 		KillFreezeBomb(client);
   279 		FreezeClient(client, GetConVarInt(g_Cvar_FreezeDuration));
   280 		
   281 		if (GetConVarInt(g_Cvar_FreezeBombMode) > 0)
   282 		{
   283 			new bool:teamOnly = ((GetConVarInt(g_Cvar_FreezeBombMode) == 1) ? true : false);
   284 			
   285 			for (new i = 1; i <= MaxClients; i++)
   286 			{
   287 				if (!IsClientInGame(i) || !IsPlayerAlive(i) || i == client)
   288 				{
   289 					continue;
   290 				}
   291 				
   292 				if (teamOnly && GetClientTeam(i) != GetClientTeam(client))
   293 				{
   294 					continue;
   295 				}
   296 				
   297 				new Float:pos[3];
   298 				GetClientEyePosition(i, pos);
   299 				
   300 				new Float:distance = GetVectorDistance(vec, pos);
   301 				
   302 				if (distance > GetConVarFloat(g_Cvar_FreezeBombRadius))
   303 				{
   304 					continue;
   305 				}
   306 				
   307 				if (g_HaloSprite > -1)
   308 				{
   309 					if (g_BeamSprite2 > -1)
   310 					{
   311 						TE_SetupBeamPoints(vec, pos, g_BeamSprite2, g_HaloSprite, 0, 1, 0.7, 20.0, 50.0, 1, 1.5, blueColor, 10);
   312 						TE_SendToAll();
   313 					}
   314 					else if (g_BeamSprite > -1)
   315 					{
   316 						TE_SetupBeamPoints(vec, pos, g_BeamSprite, g_HaloSprite, 0, 1, 0.7, 20.0, 50.0, 1, 1.5, blueColor, 10);
   317 						TE_SendToAll();
   318 					}
   319 				}
   320 				
   321 				FreezeClient(i, GetConVarInt(g_Cvar_FreezeDuration));
   322 			}		
   323 		}
   324 		return Plugin_Stop;
   325 	}
   326 }
   327 
   328 public AdminMenu_Freeze(Handle:topmenu, 
   329 					  TopMenuAction:action,
   330 					  TopMenuObject:object_id,
   331 					  param,
   332 					  String:buffer[],
   333 					  maxlength)
   334 {
   335 	if (action == TopMenuAction_DisplayOption)
   336 	{
   337 		Format(buffer, maxlength, "%T", "Freeze player", param);
   338 	}
   339 	else if (action == TopMenuAction_SelectOption)
   340 	{
   341 		DisplayFreezeMenu(param);
   342 	}
   343 }
   344 
   345 public AdminMenu_FreezeBomb(Handle:topmenu, 
   346 					  TopMenuAction:action,
   347 					  TopMenuObject:object_id,
   348 					  param,
   349 					  String:buffer[],
   350 					  maxlength)
   351 {
   352 	if (action == TopMenuAction_DisplayOption)
   353 	{
   354 		Format(buffer, maxlength, "%T", "FreezeBomb player", param);
   355 	}
   356 	else if (action == TopMenuAction_SelectOption)
   357 	{
   358 		DisplayFreezeBombMenu(param);
   359 	}
   360 }
   361 
   362 DisplayFreezeMenu(client)
   363 {
   364 	new Handle:menu = CreateMenu(MenuHandler_Freeze);
   365 	
   366 	decl String:title[100];
   367 	Format(title, sizeof(title), "%T:", "Freeze player", client);
   368 	SetMenuTitle(menu, title);
   369 	SetMenuExitBackButton(menu, true);
   370 	
   371 	AddTargetsToMenu(menu, client, true, true);
   372 	
   373 	DisplayMenu(menu, client, MENU_TIME_FOREVER);
   374 }
   375 
   376 DisplayFreezeBombMenu(client)
   377 {
   378 	new Handle:menu = CreateMenu(MenuHandler_FreezeBomb);
   379 	
   380 	decl String:title[100];
   381 	Format(title, sizeof(title), "%T:", "FreezeBomb player", client);
   382 	SetMenuTitle(menu, title);
   383 	SetMenuExitBackButton(menu, true);
   384 	
   385 	AddTargetsToMenu(menu, client, true, true);
   386 	
   387 	DisplayMenu(menu, client, MENU_TIME_FOREVER);
   388 }
   389 
   390 public MenuHandler_Freeze(Handle:menu, MenuAction:action, param1, param2)
   391 {
   392 	if (action == MenuAction_End)
   393 	{
   394 		CloseHandle(menu);
   395 	}
   396 	else if (action == MenuAction_Cancel)
   397 	{
   398 		if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
   399 		{
   400 			DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
   401 		}
   402 	}
   403 	else if (action == MenuAction_Select)
   404 	{
   405 		decl String:info[32];
   406 		new userid, target;
   407 		
   408 		GetMenuItem(menu, param2, info, sizeof(info));
   409 		userid = StringToInt(info);
   410 
   411 		if ((target = GetClientOfUserId(userid)) == 0)
   412 		{
   413 			PrintToChat(param1, "[SM] %t", "Player no longer available");
   414 		}
   415 		else if (!CanUserTarget(param1, target))
   416 		{
   417 			PrintToChat(param1, "[SM] %t", "Unable to target");
   418 		}
   419 		else
   420 		{
   421 			new String:name[32];
   422 			GetClientName(target, name, sizeof(name));
   423 			
   424 			PerformFreeze(param1, target, GetConVarInt(g_Cvar_FreezeDuration));
   425 			ShowActivity2(param1, "[SM] ", "%t", "Froze target", "_s", name);
   426 		}
   427 		
   428 		/* Re-draw the menu if they're still valid */
   429 		if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
   430 		{
   431 			DisplayFreezeMenu(param1);
   432 		}
   433 	}
   434 }
   435 
   436 public MenuHandler_FreezeBomb(Handle:menu, MenuAction:action, param1, param2)
   437 {
   438 	if (action == MenuAction_End)
   439 	{
   440 		CloseHandle(menu);
   441 	}
   442 	else if (action == MenuAction_Cancel)
   443 	{
   444 		if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
   445 		{
   446 			DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
   447 		}
   448 	}
   449 	else if (action == MenuAction_Select)
   450 	{
   451 		decl String:info[32];
   452 		new userid, target;
   453 		
   454 		GetMenuItem(menu, param2, info, sizeof(info));
   455 		userid = StringToInt(info);
   456 
   457 		if ((target = GetClientOfUserId(userid)) == 0)
   458 		{
   459 			PrintToChat(param1, "[SM] %t", "Player no longer available");
   460 		}
   461 		else if (!CanUserTarget(param1, target))
   462 		{
   463 			PrintToChat(param1, "[SM] %t", "Unable to target");
   464 		}
   465 		else
   466 		{
   467 			new String:name[32];
   468 			GetClientName(target, name, sizeof(name));
   469 			
   470 			PerformFreezeBomb(param1, target);
   471 			ShowActivity2(param1, "[SM] ", "%t", "Toggled FreezeBomb on target", "_s", name);
   472 		}
   473 		
   474 		/* Re-draw the menu if they're still valid */
   475 		if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
   476 		{
   477 			DisplayFreezeBombMenu(param1);
   478 		}
   479 	}
   480 }
   481 
   482 public Action:Command_Freeze(client, args)
   483 {
   484 	if (args < 1)
   485 	{
   486 		ReplyToCommand(client, "[SM] Usage: sm_freeze <#userid|name> [time]");
   487 		return Plugin_Handled;
   488 	}
   489 
   490 	decl String:arg[65];
   491 	GetCmdArg(1, arg, sizeof(arg));
   492 	
   493 	new seconds = GetConVarInt(g_Cvar_FreezeDuration);
   494 	
   495 	if (args > 1)
   496 	{
   497 		decl String:time[20];
   498 		GetCmdArg(2, time, sizeof(time));
   499 		if (StringToIntEx(time, seconds) == 0)
   500 		{
   501 			ReplyToCommand(client, "[SM] %t", "Invalid Amount");
   502 			return Plugin_Handled;
   503 		}
   504 	}	
   505 
   506 	decl String:target_name[MAX_TARGET_LENGTH];
   507 	decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
   508 	
   509 	if ((target_count = ProcessTargetString(
   510 			arg,
   511 			client,
   512 			target_list,
   513 			MAXPLAYERS,
   514 			COMMAND_FILTER_ALIVE,
   515 			target_name,
   516 			sizeof(target_name),
   517 			tn_is_ml)) <= 0)
   518 	{
   519 		ReplyToTargetError(client, target_count);
   520 		return Plugin_Handled;
   521 	}
   522 	
   523 	for (new i = 0; i < target_count; i++)
   524 	{
   525 		PerformFreeze(client, target_list[i], seconds);
   526 	}
   527 	
   528 	if (tn_is_ml)
   529 	{
   530 		ShowActivity2(client, "[SM] ", "%t", "Froze target", target_name);
   531 	}
   532 	else
   533 	{
   534 		ShowActivity2(client, "[SM] ", "%t", "Froze target", "_s", target_name);
   535 	}
   536 	
   537 	return Plugin_Handled;
   538 }
   539 
   540 public Action:Command_FreezeBomb(client, args)
   541 {
   542 	if (args < 1)
   543 	{
   544 		ReplyToCommand(client, "[SM] Usage: sm_freezebomb <#userid|name>");
   545 		return Plugin_Handled;
   546 	}
   547 
   548 	decl String:arg[65];
   549 	GetCmdArg(1, arg, sizeof(arg));
   550 
   551 	decl String:target_name[MAX_TARGET_LENGTH];
   552 	decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
   553 	
   554 	if ((target_count = ProcessTargetString(
   555 			arg,
   556 			client,
   557 			target_list,
   558 			MAXPLAYERS,
   559 			COMMAND_FILTER_ALIVE,
   560 			target_name,
   561 			sizeof(target_name),
   562 			tn_is_ml)) <= 0)
   563 	{
   564 		ReplyToTargetError(client, target_count);
   565 		return Plugin_Handled;
   566 	}
   567 	
   568 	for (new i = 0; i < target_count; i++)
   569 	{
   570 		PerformFreezeBomb(client, target_list[i]);
   571 	}
   572 	
   573 	if (tn_is_ml)
   574 	{
   575 		ShowActivity2(client, "[SM] ", "%t", "Toggled FreezeBomb on target", target_name);
   576 	}
   577 	else
   578 	{
   579 		ShowActivity2(client, "[SM] ", "%t", "Toggled FreezeBomb on target", "_s", target_name);
   580 	}
   581 	
   582 	return Plugin_Handled;
   583 }