3 * =============================================================================
4 * SourceMod Basefuncommands Plugin
5 * Provides TimeBomb functionality
7 * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
8 * =============================================================================
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.
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
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/>.
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>.
34 new g_TimeBombSerial[MAXPLAYERS+1] = { 0, ... };
35 new g_TimeBombTime[MAXPLAYERS+1] = { 0, ... };
37 new Handle:g_Cvar_TimeBombTicks = INVALID_HANDLE;
38 new Handle:g_Cvar_TimeBombRadius = INVALID_HANDLE;
39 new Handle:g_Cvar_TimeBombMode = INVALID_HANDLE;
41 CreateTimeBomb(client)
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);
50 g_TimeBombSerial[client] = 0;
52 if (IsClientInGame(client))
54 SetEntityRenderColor(client, 255, 255, 255, 255);
60 for (new i = 1; i <= MaxClients; i++)
66 PerformTimeBomb(client, target)
68 if (g_TimeBombSerial[target] == 0)
70 CreateTimeBomb(target);
71 LogAction(client, target, "\"%L\" set a TimeBomb on \"%L\"", client, target);
76 SetEntityRenderColor(client, 255, 255, 255, 255);
77 LogAction(client, target, "\"%L\" removed a TimeBomb on \"%L\"", client, target);
81 public Action:Timer_TimeBomb(Handle:timer, any:value)
83 new client = value & 0x7f;
84 new serial = value >> 7;
86 if (!IsClientInGame(client)
87 || !IsPlayerAlive(client)
88 || serial != g_TimeBombSerial[client])
93 g_TimeBombTime[client]--;
96 GetClientEyePosition(client, vec);
98 if (g_TimeBombTime[client] > 0)
102 if (g_TimeBombTime[client] > 1)
104 color = RoundToFloor(g_TimeBombTime[client] * (128.0 / GetConVarFloat(g_Cvar_TimeBombTicks)));
105 EmitAmbientSound(SOUND_BEEP, vec, client, SNDLEVEL_RAIDSIREN);
110 EmitAmbientSound(SOUND_FINAL, vec, client, SNDLEVEL_RAIDSIREN);
113 SetEntityRenderColor(client, 255, 128, color, 255);
115 decl String:name[64];
116 GetClientName(client, name, sizeof(name));
117 PrintCenterTextAll("%t", "Till Explodes", name, g_TimeBombTime[client]);
119 GetClientAbsOrigin(client, vec);
122 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);
124 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);
126 return Plugin_Continue;
130 if (g_ExplosionSprite > -1)
132 TE_SetupExplosion(vec, g_ExplosionSprite, 5.0, 1, 0, GetConVarInt(g_Cvar_TimeBombRadius), 5000);
136 EmitAmbientSound(SOUND_BOOM, vec, client, SNDLEVEL_RAIDSIREN);
138 ForcePlayerSuicide(client);
139 KillTimeBomb(client);
140 SetEntityRenderColor(client, 255, 255, 255, 255);
142 if (GetConVarInt(g_Cvar_TimeBombMode) > 0)
144 new teamOnly = ((GetConVarInt(g_Cvar_TimeBombMode) == 1) ? true : false);
146 for (new i = 1; i <= MaxClients; i++)
148 if (!IsClientInGame(i) || !IsPlayerAlive(i) || i == client)
153 if (teamOnly && GetClientTeam(i) != GetClientTeam(client))
159 GetClientEyePosition(i, pos);
161 new Float:distance = GetVectorDistance(vec, pos);
163 if (distance > GetConVarFloat(g_Cvar_TimeBombRadius))
169 damage = RoundToFloor(damage * ((GetConVarFloat(g_Cvar_TimeBombRadius) - distance) / GetConVarFloat(g_Cvar_TimeBombRadius)));
171 SlapPlayer(i, damage, false);
173 if (g_ExplosionSprite > -1)
175 TE_SetupExplosion(pos, g_ExplosionSprite, 0.05, 1, 0, 1, 1);
181 SubtractVectors(vec, pos, dir);
182 TR_TraceRayFilter(vec, dir, MASK_SOLID, RayType_Infinite, TR_Filter_Client);
184 if (i == TR_GetEntityIndex())
187 new radius = GetConVarInt(g_Cvar_TimeBombRadius) / 2;
189 if (distance > radius)
192 damage = RoundToFloor(damage * ((radius - distance) / radius));
195 SlapPlayer(i, damage, false);
204 public AdminMenu_TimeBomb(Handle:topmenu,
205 TopMenuAction:action,
206 TopMenuObject:object_id,
211 if (action == TopMenuAction_DisplayOption)
213 Format(buffer, maxlength, "%T", "TimeBomb player", param);
215 else if (action == TopMenuAction_SelectOption)
217 DisplayTimeBombMenu(param);
221 DisplayTimeBombMenu(client)
223 new Handle:menu = CreateMenu(MenuHandler_TimeBomb);
225 decl String:title[100];
226 Format(title, sizeof(title), "%T:", "TimeBomb player", client);
227 SetMenuTitle(menu, title);
228 SetMenuExitBackButton(menu, true);
230 AddTargetsToMenu(menu, client, true, true);
232 DisplayMenu(menu, client, MENU_TIME_FOREVER);
235 public MenuHandler_TimeBomb(Handle:menu, MenuAction:action, param1, param2)
237 if (action == MenuAction_End)
241 else if (action == MenuAction_Cancel)
243 if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
245 DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
248 else if (action == MenuAction_Select)
250 decl String:info[32];
253 GetMenuItem(menu, param2, info, sizeof(info));
254 userid = StringToInt(info);
256 if ((target = GetClientOfUserId(userid)) == 0)
258 PrintToChat(param1, "[SM] %t", "Player no longer available");
260 else if (!CanUserTarget(param1, target))
262 PrintToChat(param1, "[SM] %t", "Unable to target");
267 GetClientName(target, name, sizeof(name));
269 PerformTimeBomb(param1, target);
270 ShowActivity2(param1, "[SM] ", "%t", "Toggled TimeBomb on target", "_s", name);
273 /* Re-draw the menu if they're still valid */
274 if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
276 DisplayTimeBombMenu(param1);
281 public Action:Command_TimeBomb(client, args)
285 ReplyToCommand(client, "[SM] Usage: sm_timebomb <#userid|name>");
286 return Plugin_Handled;
290 GetCmdArg(1, arg, sizeof(arg));
292 decl String:target_name[MAX_TARGET_LENGTH];
293 decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
295 if ((target_count = ProcessTargetString(
300 COMMAND_FILTER_ALIVE,
305 ReplyToTargetError(client, target_count);
306 return Plugin_Handled;
309 for (new i = 0; i < target_count; i++)
311 PerformTimeBomb(client, target_list[i]);
316 ShowActivity2(client, "[SM] ", "%t", "Toggled TimeBomb on target", target_name);
320 ShowActivity2(client, "[SM] ", "%t", "Toggled TimeBomb on target", "_s", target_name);
323 return Plugin_Handled;