/addons/sourcemod/scripting/funcommands/fire.sp

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