/addons/sourcemod/scripting/funcommands/fire.sp
Unknown | 458 lines | 390 code | 68 blank | 0 comment | 0 complexity | 49c9a3543db0141f642e06cb5f1d7a97 MD5 | raw file
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
34new g_FireBombSerial[MAXPLAYERS+1] = { 0, ... };
35new g_FireBombTime[MAXPLAYERS+1] = { 0, ... };
36
37new Handle:g_Cvar_BurnDuration = INVALID_HANDLE;
38new Handle:g_Cvar_FireBombTicks = INVALID_HANDLE;
39new Handle:g_Cvar_FireBombRadius = INVALID_HANDLE;
40new Handle:g_Cvar_FireBombMode = INVALID_HANDLE;
41
42CreateFireBomb(client)
43{
44 g_FireBombSerial[client] = ++g_Serial_Gen;
45 CreateTimer(1.0, Timer_FireBomb, client | (g_Serial_Gen << 7), DEFAULT_TIMER_FLAGS);
46 g_FireBombTime[client] = GetConVarInt(g_Cvar_FireBombTicks);
47}
48
49KillFireBomb(client)
50{
51 g_FireBombSerial[client] = 0;
52
53 if (IsClientInGame(client))
54 {
55 SetEntityRenderColor(client, 255, 255, 255, 255);
56 }
57}
58
59KillAllFireBombs()
60{
61 for (new i = 1; i <= MaxClients; i++)
62 {
63 KillFireBomb(i);
64 }
65}
66
67PerformBurn(client, target, Float:seconds)
68{
69 IgniteEntity(target, seconds);
70 LogAction(client, target, "\"%L\" ignited \"%L\" (seconds \"%f\")", client, target, seconds);
71}
72
73PerformFireBomb(client, target)
74{
75 if (g_FireBombSerial[client] == 0)
76 {
77 CreateFireBomb(target);
78 LogAction(client, target, "\"%L\" set a FireBomb on \"%L\"", client, target);
79 }
80 else
81 {
82 KillFireBomb(target);
83 SetEntityRenderColor(client, 255, 255, 255, 255);
84 LogAction(client, target, "\"%L\" removed a FireBomb on \"%L\"", client, target);
85 }
86}
87
88public Action:Timer_FireBomb(Handle:timer, any:value)
89{
90 new client = value & 0x7f;
91 new serial = value >> 7;
92
93 if (!IsClientInGame(client)
94 || !IsPlayerAlive(client)
95 || g_FireBombSerial[client] != serial)
96 {
97 KillFireBomb(client);
98 return Plugin_Stop;
99 }
100 g_FireBombTime[client]--;
101
102 new Float:vec[3];
103 GetClientEyePosition(client, vec);
104
105 if (g_FireBombTime[client] > 0)
106 {
107 new color;
108
109 if (g_FireBombTime[client] > 1)
110 {
111 color = RoundToFloor(g_FireBombTime[client] * (255.0 / GetConVarFloat(g_Cvar_FireBombTicks)));
112 EmitAmbientSound(SOUND_BEEP, vec, client, SNDLEVEL_RAIDSIREN);
113 }
114 else
115 {
116 color = 0;
117 EmitAmbientSound(SOUND_FINAL, vec, client, SNDLEVEL_RAIDSIREN);
118 }
119
120 SetEntityRenderColor(client, 255, color, color, 255);
121
122 decl String:name[64];
123 GetClientName(client, name, sizeof(name));
124 PrintCenterTextAll("%t", "Till Explodes", name, g_FireBombTime[client]);
125
126 GetClientAbsOrigin(client, vec);
127 vec[2] += 10;
128
129 TE_SetupBeamRingPoint(vec, 10.0, GetConVarFloat(g_Cvar_FireBombRadius) / 3.0, g_BeamSprite, g_HaloSprite, 0, 15, 0.5, 5.0, 0.0, greyColor, 10, 0);
130 TE_SendToAll();
131 TE_SetupBeamRingPoint(vec, 10.0, GetConVarFloat(g_Cvar_FireBombRadius) / 3.0, g_BeamSprite, g_HaloSprite, 0, 10, 0.6, 10.0, 0.5, whiteColor, 10, 0);
132 TE_SendToAll();
133 return Plugin_Continue;
134 }
135 else
136 {
137 if (g_ExplosionSprite > -1)
138 {
139 TE_SetupExplosion(vec, g_ExplosionSprite, 0.1, 1, 0, GetConVarInt(g_Cvar_FireBombRadius), 5000);
140 TE_SendToAll();
141 }
142
143 GetClientAbsOrigin(client, vec);
144 vec[2] += 10;
145 TE_SetupBeamRingPoint(vec, 50.0, GetConVarFloat(g_Cvar_FireBombRadius), g_BeamSprite, g_HaloSprite, 0, 10, 0.5, 30.0, 1.5, orangeColor, 5, 0);
146 TE_SendToAll();
147 vec[2] += 15;
148 TE_SetupBeamRingPoint(vec, 40.0, GetConVarFloat(g_Cvar_FireBombRadius), g_BeamSprite, g_HaloSprite, 0, 10, 0.6, 30.0, 1.5, orangeColor, 5, 0);
149 TE_SendToAll();
150 vec[2] += 15;
151 TE_SetupBeamRingPoint(vec, 30.0, GetConVarFloat(g_Cvar_FireBombRadius), g_BeamSprite, g_HaloSprite, 0, 10, 0.7, 30.0, 1.5, orangeColor, 5, 0);
152 TE_SendToAll();
153 vec[2] += 15;
154 TE_SetupBeamRingPoint(vec, 20.0, GetConVarFloat(g_Cvar_FireBombRadius), g_BeamSprite, g_HaloSprite, 0, 10, 0.8, 30.0, 1.5, orangeColor, 5, 0);
155 TE_SendToAll();
156
157 EmitAmbientSound(SOUND_BOOM, vec, client, SNDLEVEL_RAIDSIREN);
158
159 IgniteEntity(client, GetConVarFloat(g_Cvar_BurnDuration));
160 KillFireBomb(client);
161 SetEntityRenderColor(client, 255, 255, 255, 255);
162
163 if (GetConVarInt(g_Cvar_FireBombMode) > 0)
164 {
165 new teamOnly = ((GetConVarInt(g_Cvar_FireBombMode) == 1) ? true : false);
166
167 for (new i = 1; i <= MaxClients; i++)
168 {
169 if (!IsClientInGame(i) || !IsPlayerAlive(i) || i == client)
170 {
171 continue;
172 }
173
174 if (teamOnly && GetClientTeam(i) != GetClientTeam(client))
175 {
176 continue;
177 }
178
179 new Float:pos[3];
180 GetClientAbsOrigin(i, pos);
181
182 new Float:distance = GetVectorDistance(vec, pos);
183
184 if (distance > GetConVarFloat(g_Cvar_FireBombRadius))
185 {
186 continue;
187 }
188
189 new Float:duration = GetConVarFloat(g_Cvar_BurnDuration);
190 duration *= (GetConVarFloat(g_Cvar_FireBombRadius) - distance) / GetConVarFloat(g_Cvar_FireBombRadius);
191
192 IgniteEntity(i, duration);
193 }
194 }
195 return Plugin_Stop;
196 }
197}
198
199public AdminMenu_Burn(Handle:topmenu,
200 TopMenuAction:action,
201 TopMenuObject:object_id,
202 param,
203 String:buffer[],
204 maxlength)
205{
206 if (action == TopMenuAction_DisplayOption)
207 {
208 Format(buffer, maxlength, "%T", "Burn player", param);
209 }
210 else if (action == TopMenuAction_SelectOption)
211 {
212 DisplayBurnMenu(param);
213 }
214}
215
216public AdminMenu_FireBomb(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", "FireBomb player", param);
226 }
227 else if (action == TopMenuAction_SelectOption)
228 {
229 DisplayFireBombMenu(param);
230 }
231}
232
233DisplayBurnMenu(client)
234{
235 new Handle:menu = CreateMenu(MenuHandler_Burn);
236
237 decl String:title[100];
238 Format(title, sizeof(title), "%T:", "Burn 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
247DisplayFireBombMenu(client)
248{
249 new Handle:menu = CreateMenu(MenuHandler_FireBomb);
250
251 decl String:title[100];
252 Format(title, sizeof(title), "%T:", "FireBomb player", client);
253 SetMenuTitle(menu, title);
254 SetMenuExitBackButton(menu, true);
255
256 AddTargetsToMenu(menu, client, true, true);
257
258 DisplayMenu(menu, client, MENU_TIME_FOREVER);
259}
260
261public MenuHandler_Burn(Handle:menu, MenuAction:action, param1, param2)
262{
263 if (action == MenuAction_End)
264 {
265 CloseHandle(menu);
266 }
267 else if (action == MenuAction_Cancel)
268 {
269 if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
270 {
271 DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
272 }
273 }
274 else if (action == MenuAction_Select)
275 {
276 decl String:info[32];
277 new userid, target;
278
279 GetMenuItem(menu, param2, info, sizeof(info));
280 userid = StringToInt(info);
281
282 if ((target = GetClientOfUserId(userid)) == 0)
283 {
284 PrintToChat(param1, "[SM] %t", "Player no longer available");
285 }
286 else if (!CanUserTarget(param1, target))
287 {
288 PrintToChat(param1, "[SM] %t", "Unable to target");
289 }
290 else
291 {
292 new String:name[32];
293 GetClientName(target, name, sizeof(name));
294 PerformBurn(param1, target, 20.0);
295 ShowActivity2(param1, "[SM] ", "%t", "Set target on fire", "_s", name);
296 }
297
298 /* Re-draw the menu if they're still valid */
299 if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
300 {
301 DisplayBurnMenu(param1);
302 }
303 }
304}
305
306public MenuHandler_FireBomb(Handle:menu, MenuAction:action, param1, param2)
307{
308 if (action == MenuAction_End)
309 {
310 CloseHandle(menu);
311 }
312 else if (action == MenuAction_Cancel)
313 {
314 if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
315 {
316 DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
317 }
318 }
319 else if (action == MenuAction_Select)
320 {
321 decl String:info[32];
322 new userid, target;
323
324 GetMenuItem(menu, param2, info, sizeof(info));
325 userid = StringToInt(info);
326
327 if ((target = GetClientOfUserId(userid)) == 0)
328 {
329 PrintToChat(param1, "[SM] %t", "Player no longer available");
330 }
331 else if (!CanUserTarget(param1, target))
332 {
333 PrintToChat(param1, "[SM] %t", "Unable to target");
334 }
335 else
336 {
337 new String:name[32];
338 GetClientName(target, name, sizeof(name));
339
340 PerformFireBomb(param1, target);
341 ShowActivity2(param1, "[SM] ", "%t", "Toggled FireBomb on target", "_s", name);
342 }
343
344 /* Re-draw the menu if they're still valid */
345 if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
346 {
347 DisplayFireBombMenu(param1);
348 }
349 }
350}
351
352public Action:Command_Burn(client, args)
353{
354 if (args < 1)
355 {
356 ReplyToCommand(client, "[SM] Usage: sm_burn <#userid|name> [time]");
357 return Plugin_Handled;
358 }
359
360 decl String:arg[65];
361 GetCmdArg(1, arg, sizeof(arg));
362
363 new Float:seconds = GetConVarFloat(g_Cvar_BurnDuration);
364
365 if (args > 1)
366 {
367 decl String:time[20];
368 GetCmdArg(2, time, sizeof(time));
369 if (StringToFloatEx(time, seconds) == 0)
370 {
371 ReplyToCommand(client, "[SM] %t", "Invalid Amount");
372 return Plugin_Handled;
373 }
374 }
375
376 decl String:target_name[MAX_TARGET_LENGTH];
377 decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
378
379 if ((target_count = ProcessTargetString(
380 arg,
381 client,
382 target_list,
383 MAXPLAYERS,
384 COMMAND_FILTER_ALIVE,
385 target_name,
386 sizeof(target_name),
387 tn_is_ml)) <= 0)
388 {
389 ReplyToTargetError(client, target_count);
390 return Plugin_Handled;
391 }
392
393 for (new i = 0; i < target_count; i++)
394 {
395 PerformBurn(client, target_list[i], seconds);
396 }
397
398 if (tn_is_ml)
399 {
400 ShowActivity2(client, "[SM] ", "%t", "Set target on fire", target_name);
401 }
402 else
403 {
404 ShowActivity2(client, "[SM] ", "%t", "Set target on fire", "_s", target_name);
405 }
406
407 return Plugin_Handled;
408}
409
410public Action:Command_FireBomb(client, args)
411{
412 if (args < 1)
413 {
414 ReplyToCommand(client, "[SM] Usage: sm_firebomb <#userid|name>");
415 return Plugin_Handled;
416 }
417
418 decl String:arg[65];
419 GetCmdArg(1, arg, sizeof(arg));
420
421 decl String:target_name[MAX_TARGET_LENGTH];
422 decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
423
424 if ((target_count = ProcessTargetString(
425 arg,
426 client,
427 target_list,
428 MAXPLAYERS,
429 COMMAND_FILTER_ALIVE,
430 target_name,
431 sizeof(target_name),
432 tn_is_ml)) <= 0)
433 {
434 ReplyToTargetError(client, target_count);
435 return Plugin_Handled;
436 }
437
438 for (new i = 0; i < target_count; i++)
439 {
440 PerformFireBomb(client, target_list[i]);
441 }
442
443 if (tn_is_ml)
444 {
445 ShowActivity2(client, "[SM] ", "%t", "Toggled FireBomb on target", target_name);
446 }
447 else
448 {
449 ShowActivity2(client, "[SM] ", "%t", "Toggled FireBomb on target", "_s", target_name);
450 }
451 return Plugin_Handled;
452}
453
454
455
456
457
458