HLMOD.HU Forrás Megtekintés - www.hlmod.hu
  1. /*================================================================================
  2.  
  3. ------------------------
  4. -*- Napalm Nades 1.3 -*-
  5. ------------------------
  6.  
  7. ~~~~~~~~~~~~~~~
  8. - Description -
  9. ~~~~~~~~~~~~~~~
  10.  
  11. This plugin turns one of the default grenades into a napalm bomb that
  12. can set players on fire. Basically a CS port of the "fire grenades"
  13. I originally developed for Zombie Plague, at the request of some people
  14. and since there were no similiar plugins around. Have fun!
  15.  
  16. ~~~~~~~~~~~~~~~~
  17. - Requirements -
  18. ~~~~~~~~~~~~~~~~
  19.  
  20. * Mods: Counter-Strike 1.6 or Condition-Zero
  21. * AMXX: Version 1.8.0 or later
  22.  
  23. ~~~~~~~~~~~~~~~~
  24. - Installation -
  25. ~~~~~~~~~~~~~~~~
  26.  
  27. * Extract .amxx file to your plugins folder, and add its name to plugins.ini
  28. * Extract flame.spr to the "sprites" folder on your server
  29. * To change models or sounds, open up the .sma with any text editor and look
  30. for the customization section. When you're done, recompile.
  31.  
  32. ~~~~~~~~~~~~
  33. - Commands -
  34. ~~~~~~~~~~~~
  35.  
  36. * say /napalm - Buy a napalm grenade (when override is off)
  37.  
  38. ~~~~~~~~~
  39. - CVARS -
  40. ~~~~~~~~~
  41.  
  42. * napalm_on <0/1> - Enable/Disable Napalm Nades
  43. * napalm_affect <1/2/3> - Which nades should be napalms (1-HE // 2-FB // 3-SG)
  44. * napalm_team <0/1/2> - Determines which team can buy/use napalm nades
  45. (0-both teams // 1-Terrorists only // 2-CTs only)
  46. * napalm_override <0/1> - If enabled, grenades will automatically become
  47. napalms without players having to buy them
  48. * napalm_price <1000> - Money needed to buy a napalm (when override is off)
  49. * napalm_buyzone <0/1> - If enabled, players need to be in a buyzone to
  50. purchase a napalm (when override is off)
  51. * napalm_carrylimit <1> - How many napalms can be carried at once
  52.  
  53. * napalm_radius <240> - Napalm explosion radius
  54. * napalm_hitself <0/1> - If enabled, napalms will also affect their owner
  55. * napalm_ff <0/1> - If enabled, napalms will also affect teammates
  56. * napalm_spread <0/1> - If enabled, players will be able to catch fire
  57. from others when they touch
  58. * napalm_keepexplosion <0/1> - Wether to keep the default CS explosion
  59.  
  60. * napalm_duration <5> - How long the burning lasts in seconds
  61. * napalm_damage <2> - How much damage the burning does (every 0.2 secs)
  62. * napalm_cankill <0/1> - If set, burning will be able to kill the victim
  63. * napalm_slowdown <0.5> - Burning slow down, set between: 0.1 (slower) and
  64. 0.9 (faster). Use 0 to disable.
  65. * napalm_screamrate <20> - How often players will scream when on fire
  66. (lower values = more screams). Use 0 to disable.
  67.  
  68. ~~~~~~~~~~~~~
  69. - Changelog -
  70. ~~~~~~~~~~~~~
  71.  
  72. * v1.0: (Jul 26, 2008)
  73. - First release
  74.  
  75. * v1.1: (Aug 15, 2008)
  76. - Grenades now explode based on their pev_dmgtime (means the
  77. plugin is now compatible with Nade Modes)
  78. - Changed method to identify napalm nades when override is off
  79. - Fire spread feature now fully working with CZ bots
  80.  
  81. * v1.1b: (Aug 23, 2008)
  82. - Optimized bandwidth usage for temp entity messages
  83.  
  84. * v1.1c: (Aug 26, 2008)
  85. - Fixed possible bugs with plugins that change a player's team
  86. after throwing a napalm nade
  87.  
  88. * v1.2: (Oct 05, 2008)
  89. - Added a few cvars that allow more customization
  90. - Optimized the code a bit
  91. - Fixed a bug where buying 2 napalms too quick would sometimes
  92. result in the second acting as a normal nade
  93.  
  94. * v1.3: (Feb 17, 2009)
  95. - Added ability to carry multiple napalms at once (+CVAR)
  96.  
  97. * v1.3a: (Mar 16, 2009)
  98. - Code optimized (+CVARs now cached at round start)
  99.  
  100. Fordította: BBk
  101. ================================================================================*/
  102.  
  103. #include <amxmodx>
  104. #include <fakemeta>
  105. #include <hamsandwich>
  106. #include <xs>
  107.  
  108. /*================================================================================
  109.  [Plugin Customization]
  110. =================================================================================*/
  111.  
  112. // Uncomment the following if you wish to set custom models for napalms
  113. //#define USE_NAPALM_CUSTOM_MODELS
  114.  
  115. #if defined USE_NAPALM_CUSTOM_MODELS // Then set your custom models here
  116. new const g_model_napalm_view[] = "models/v_hegrenade"
  117. new const g_model_napalm_player[] = "models/p_hegrenade.mdl"
  118. new const g_model_napalm_world[] = "models/w_hegrenade.mdl"
  119. #endif
  120.  
  121. // Explosion sounds
  122. new const grenade_fire[][] = { "weapons/hegrenade-1.wav" }
  123.  
  124. // Player burning sounds
  125. new const grenade_fire_player[][] = { "scientist/sci_fear8.wav", "scientist/sci_pain1.wav", "scientist/scream02.wav" }
  126.  
  127. // Grenade sprites
  128. new const sprite_grenade_fire[] = "sprites/flame.spr"
  129. new const sprite_grenade_smoke[] = "sprites/black_smoke3.spr"
  130. new const sprite_grenade_trail[] = "sprites/laserbeam.spr"
  131. new const sprite_grenade_ring[] = "sprites/shockwave.spr"
  132.  
  133. // Glow and trail colors (red, green, blue)
  134. const NAPALM_R = 200
  135. const NAPALM_G = 0
  136. const NAPALM_B = 0
  137.  
  138. /*===============================================================================*/
  139.  
  140. // Burning task
  141. const TASK_BURN = 1000
  142. #define ID_BURN (taskid - TASK_BURN)
  143. #define BURN_DURATION args[0]
  144. #define BURN_ATTACKER args[1]
  145.  
  146. // CS Player PData Offsets (win32)
  147. const OFFSET_CSTEAMS = 114
  148. const OFFSET_CSMONEY = 115
  149. const OFFSET_MAPZONE = 235
  150. new const AFFECTED_BPAMMO_OFFSETS[] = { 388, 387, 389 }
  151. const OFFSET_LINUX = 5 // offsets +5 in Linux builds
  152.  
  153. // CS Player CBase Offsets (win32)
  154. const OFFSET_ACTIVE_ITEM = 373
  155.  
  156. // CS Weapon PData Offsets (win32)
  157. const OFFSET_WEAPONID = 43
  158. const OFFSET_LINUX_WEAPONS = 4 // weapon offsets are only 4 steps higher on Linux
  159.  
  160. // CS Weapon CBase Offsets (win32)
  161. const OFFSET_WEAPONOWNER = 41
  162.  
  163. // Some constants
  164. const PLAYER_IN_BUYZONE = (1<<0)
  165.  
  166. // pev_ field used to store custom nade types and their values
  167. const PEV_NADE_TYPE = pev_flTimeStepSound
  168. const NADE_TYPE_NAPALM = 681856
  169.  
  170. // pev_ field used to store napalm's custom ammo
  171. const PEV_NAPALM_AMMO = pev_flSwimTime
  172.  
  173. // Weapons that can be napalms
  174. new const AFFECTED_NAMES[][] = { "HE", "FB", "SG" }
  175. new const AFFECTED_CLASSNAMES[][] = { "weapon_hegrenade", "weapon_flashbang", "weapon_smokegrenade" }
  176. new const AFFECTED_MODELS[][] = { "w_he", "w_fl", "w_sm" }
  177. new const AFFECTED_AMMOID[] = { 12, 11, 13 }
  178. #if defined USE_NAPALM_CUSTOM_MODELS
  179. new const AFFECTED_WEAPONS[] = { CSW_HEGRENADE, CSW_FLASHBANG, CSW_SMOKEGRENADE }
  180. #endif
  181.  
  182. // CS Sounds
  183. new const sound_buyammo[] = "items/9mmclip1.wav"
  184.  
  185. // Whether ham forwards are registered for CZ bots
  186. new g_hamczbots
  187.  
  188. // Precached sprites indices
  189. new g_flameSpr, g_smokeSpr, g_trailSpr, g_exploSpr
  190.  
  191. // Messages
  192. new g_msgDamage, g_msgMoney, g_msgBlinkAcct, g_msgAmmoPickup
  193.  
  194. // CVAR pointers
  195. new cvar_radius, cvar_price, cvar_hitself, cvar_duration, cvar_slowdown, cvar_override,
  196. cvar_damage, cvar_on, cvar_buyzone, cvar_ff, cvar_cankill, cvar_spread, cvar_botquota,
  197. cvar_teamrestrict, cvar_screamrate, cvar_keepexplosion, cvar_affect, cvar_carrylimit
  198.  
  199. // Cached stuff
  200. new g_maxplayers, g_on, g_affect, g_override, g_allowedteam, g_keepexplosion, g_spread,
  201. g_ff, g_duration, g_buyzone, g_price, g_carrylimit, g_hitself, g_screamrate, g_damage,
  202. Float:g_slowdown, g_cankill, Float:g_radius
  203.  
  204. // Precache all custom stuff
  205. public plugin_precache()
  206. {
  207. new i
  208. for (i = 0; i < sizeof grenade_fire; i++)
  209. engfunc(EngFunc_PrecacheSound, grenade_fire[i])
  210. for (i = 0; i < sizeof grenade_fire_player; i++)
  211. engfunc(EngFunc_PrecacheSound, grenade_fire_player[i])
  212.  
  213. g_flameSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_fire)
  214. g_smokeSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_smoke)
  215. g_trailSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_trail)
  216. g_exploSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_ring)
  217.  
  218. // CS sounds (just in case)
  219. engfunc(EngFunc_PrecacheSound, sound_buyammo)
  220.  
  221. #if defined USE_NAPALM_CUSTOM_MODELS
  222. engfunc(EngFunc_PrecacheModel, g_model_napalm_view)
  223. engfunc(EngFunc_PrecacheModel, g_model_napalm_player)
  224. engfunc(EngFunc_PrecacheModel, g_model_napalm_world)
  225. #endif
  226. }
  227.  
  228. public plugin_init()
  229. {
  230. // Register plugin call
  231. register_plugin("Napalm Nades", "1.3a", "MeRcyLeZZ")
  232.  
  233. // Events
  234. register_event("HLTV", "event_round_start", "a", "1=0", "2=0")
  235.  
  236. // Forwards
  237. register_forward(FM_SetModel, "fw_SetModel")
  238. RegisterHam(Ham_Think, "grenade", "fw_ThinkGrenade")
  239. RegisterHam(Ham_Touch, "player", "fw_TouchPlayer")
  240. #if defined USE_NAPALM_CUSTOM_MODELS
  241. for (new i = 0; i < sizeof AFFECTED_CLASSNAMES; i++)
  242. RegisterHam(Ham_Item_Deploy, AFFECTED_CLASSNAMES[i], "fw_Item_Deploy_Post", 1)
  243. #endif
  244.  
  245. // Client commands
  246. register_clcmd("say napalm", "buy_napalm")
  247. register_clcmd("say /napalm", "buy_napalm")
  248.  
  249. // CVARS
  250. cvar_on = register_cvar("napalm_on", "1")
  251. cvar_affect = register_cvar("napalm_affect", "1")
  252. cvar_teamrestrict = register_cvar("napalm_team", "0")
  253. cvar_override = register_cvar("napalm_override", "0")
  254. cvar_price = register_cvar("napalm_price", "1000")
  255. cvar_buyzone = register_cvar("napalm_buyzone", "1")
  256. cvar_carrylimit = register_cvar("napalm_carrylimit", "1")
  257.  
  258. cvar_radius = register_cvar("napalm_radius", "240")
  259. cvar_hitself = register_cvar("napalm_hitself", "1")
  260. cvar_ff = register_cvar("napalm_ff", "0")
  261. cvar_spread = register_cvar("napalm_spread", "1")
  262. cvar_keepexplosion = register_cvar("napalm_keepexplosion", "0")
  263.  
  264. cvar_duration = register_cvar("napalm_duration", "5")
  265. cvar_damage = register_cvar("napalm_damage", "2")
  266. cvar_cankill = register_cvar("napalm_cankill", "1")
  267. cvar_slowdown = register_cvar("napalm_slowdown", "0.5")
  268. cvar_screamrate = register_cvar("napalm_screamrate", "20")
  269.  
  270. cvar_botquota = get_cvar_pointer("bot_quota")
  271. g_maxplayers = get_maxplayers()
  272.  
  273. // Message ids
  274. g_msgDamage = get_user_msgid("Damage")
  275. g_msgMoney = get_user_msgid("Money")
  276. g_msgBlinkAcct = get_user_msgid("BlinkAcct")
  277. g_msgAmmoPickup = get_user_msgid("AmmoPickup")
  278. }
  279.  
  280. public plugin_cfg()
  281. {
  282. // Cache CVARs after configs are loaded
  283. set_task(0.5, "event_round_start")
  284. }
  285.  
  286. // Round Start Event
  287. public event_round_start()
  288. {
  289. // Cache CVARs
  290. g_on = get_pcvar_num(cvar_on)
  291. g_affect = get_pcvar_num(cvar_affect)
  292. g_override = get_pcvar_num(cvar_override)
  293. g_allowedteam = get_pcvar_num(cvar_teamrestrict)
  294. g_keepexplosion = get_pcvar_num(cvar_keepexplosion)
  295. g_spread = get_pcvar_num(cvar_spread)
  296. g_ff = get_pcvar_num(cvar_ff)
  297. g_duration = get_pcvar_num(cvar_duration)
  298. g_buyzone = get_pcvar_num(cvar_buyzone)
  299. g_price = get_pcvar_num(cvar_price)
  300. g_carrylimit = get_pcvar_num(cvar_carrylimit)
  301. g_hitself = get_pcvar_num(cvar_hitself)
  302. g_screamrate = get_pcvar_num(cvar_screamrate)
  303. g_slowdown = get_pcvar_float(cvar_slowdown)
  304. g_damage = floatround(get_pcvar_float(cvar_damage), floatround_ceil)
  305. g_cankill = get_pcvar_num(cvar_cankill)
  306. g_radius = get_pcvar_float(cvar_radius)
  307.  
  308. // Stop any burning tasks on players
  309. for (new id = 1; id <= g_maxplayers; id++)
  310. remove_task(id+TASK_BURN);
  311. }
  312.  
  313. // Client joins the game
  314. public client_putinserver(id)
  315. {
  316. // CZ bots seem to use a different "classtype" for player entities
  317. // (or something like that) which needs to be hooked separately
  318. if (!g_hamczbots && cvar_botquota && is_user_bot(id))
  319. {
  320. // Set a task to let the private data initialize
  321. set_task(0.1, "register_ham_czbots", id)
  322. }
  323. }
  324.  
  325. // Set Model Forward
  326. public fw_SetModel(entity, const model[])
  327. {
  328. // Napalm grenades disabled
  329. if (!g_on) return FMRES_IGNORED;
  330.  
  331. // Get damage time of grenade
  332. static Float:dmgtime
  333. pev(entity, pev_dmgtime, dmgtime)
  334.  
  335. // Grenade not yet thrown
  336. if (dmgtime == 0.0)
  337. return FMRES_IGNORED;
  338.  
  339. // Not an affected grenade
  340. if (!equal(model[7], AFFECTED_MODELS[g_affect-1], 4))
  341. return FMRES_IGNORED;
  342.  
  343. // Get owner of grenade and napalm weapon entity
  344. static owner, napalm_weaponent
  345. owner = pev(entity, pev_owner)
  346. napalm_weaponent = fm_get_user_current_weapon_ent(owner)
  347.  
  348. // Not a napalm grenade (because the weapon entity of its owner doesn't have the flag set)
  349. if (!g_override && pev(napalm_weaponent, PEV_NADE_TYPE) != NADE_TYPE_NAPALM)
  350. return FMRES_IGNORED;
  351.  
  352. // Get owner's team
  353. static owner_team
  354. owner_team = fm_get_user_team(owner)
  355.  
  356. // Player is on a restricted team
  357. if (g_allowedteam > 0 && g_allowedteam != owner_team)
  358. return FMRES_IGNORED;
  359.  
  360. // Give it a glow
  361. fm_set_rendering(entity, kRenderFxGlowShell, NAPALM_R, NAPALM_G, NAPALM_B, kRenderNormal, 16)
  362.  
  363. // And a colored trail
  364. message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
  365. write_byte(TE_BEAMFOLLOW) // TE id
  366. write_short(entity) // entity
  367. write_short(g_trailSpr) // sprite
  368. write_byte(10) // life
  369. write_byte(10) // width
  370. write_byte(NAPALM_R) // r
  371. write_byte(NAPALM_G) // g
  372. write_byte(NAPALM_B) // b
  373. write_byte(200) // brightness
  374. message_end()
  375.  
  376. // Reduce napalm ammo
  377. static napalm_ammo
  378. napalm_ammo = pev(napalm_weaponent, PEV_NAPALM_AMMO)
  379. set_pev(napalm_weaponent, PEV_NAPALM_AMMO, --napalm_ammo)
  380.  
  381. // Run out of napalms?
  382. if (napalm_ammo < 1)
  383. {
  384. // Remove napalm flag from the owner's weapon entity
  385. set_pev(napalm_weaponent, PEV_NADE_TYPE, 0)
  386. }
  387.  
  388. // Set grenade type on the thrown grenade entity
  389. set_pev(entity, PEV_NADE_TYPE, NADE_TYPE_NAPALM)
  390.  
  391. // Set owner's team on the thrown grenade entity
  392. set_pev(entity, pev_team, owner_team)
  393.  
  394. #if defined USE_NAPALM_CUSTOM_MODELS
  395. // Set custom model and supercede the original forward
  396. engfunc(EngFunc_SetModel, entity, g_model_napalm_world)
  397. return FMRES_SUPERCEDE;
  398. #else
  399. return FMRES_IGNORED;
  400. #endif
  401. }
  402.  
  403. // Grenade Think Forward
  404. public fw_ThinkGrenade(entity)
  405. {
  406. // Invalid entity
  407. if (!pev_valid(entity)) return HAM_IGNORED;
  408.  
  409. // Get damage time of grenade
  410. static Float:dmgtime
  411. pev(entity, pev_dmgtime, dmgtime)
  412.  
  413. // Check if it's time to go off
  414. if (dmgtime > get_gametime())
  415. return HAM_IGNORED;
  416.  
  417. // Not a napalm grenade
  418. if (pev(entity, PEV_NADE_TYPE) != NADE_TYPE_NAPALM)
  419. return HAM_IGNORED;
  420.  
  421. // Explode event
  422. napalm_explode(entity)
  423.  
  424. // Keep the original explosion?
  425. if (g_keepexplosion)
  426. {
  427. set_pev(entity, PEV_NADE_TYPE, 0)
  428. return HAM_IGNORED;
  429. }
  430.  
  431. // Get rid of the grenade
  432. engfunc(EngFunc_RemoveEntity, entity)
  433. return HAM_SUPERCEDE;
  434. }
  435.  
  436. // Player Touch Forward
  437. public fw_TouchPlayer(self, other)
  438. {
  439. // Spread cvar disabled or not touching a player
  440. if (!g_spread || !is_user_alive(other))
  441. return;
  442.  
  443. // Toucher not on fire or touched player already on fire
  444. if (!task_exists(self+TASK_BURN) || task_exists(other+TASK_BURN))
  445. return;
  446.  
  447. // Check if friendly fire is allowed
  448. if (!g_ff && fm_get_user_team(self) == fm_get_user_team(other))
  449. return;
  450.  
  451. // Heat icon
  452. message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, _, other)
  453. write_byte(0) // damage save
  454. write_byte(0) // damage take
  455. write_long(DMG_BURN) // damage type
  456. write_coord(0) // x
  457. write_coord(0) // y
  458. write_coord(0) // z
  459. message_end()
  460.  
  461. // Our task params
  462. static params[2]
  463. params[0] = g_duration * 2 // duration (reduced a bit)
  464. params[1] = self // attacker
  465.  
  466. // Set burning task on victim
  467. set_task(0.1, "burning_flame", other+TASK_BURN, params, sizeof params)
  468. }
  469.  
  470. #if defined USE_NAPALM_CUSTOM_MODELS
  471. // Ham Weapon Deploy Forward
  472. public fw_Item_Deploy_Post(entity)
  473. {
  474. // Napalm grenades disabled
  475. if (!g_on) return;
  476.  
  477. // Not a napalm grenade (because the weapon entity of its owner doesn't have the flag set)
  478. if (!g_override && pev(entity, PEV_NADE_TYPE) != NADE_TYPE_NAPALM)
  479. return;
  480.  
  481. // Get weapon's id
  482. static weaponid
  483. weaponid = fm_get_weapon_ent_id(entity)
  484.  
  485. // Not an affected grenade
  486. if (weaponid != AFFECTED_WEAPONS[g_affect-1])
  487. return;
  488.  
  489. // Get weapon's owner
  490. static owner
  491. owner = fm_get_weapon_ent_owner(entity)
  492.  
  493. // Player is on a restricted team
  494. if (g_allowedteam > 0 && g_allowedteam != fm_get_user_team(owner))
  495. return;
  496.  
  497. // Replace models
  498. set_pev(owner, pev_viewmodel2, g_model_napalm_view)
  499. set_pev(owner, pev_weaponmodel2, g_model_napalm_player)
  500. }
  501. #endif
  502.  
  503. // Napalm purchase command
  504. public buy_napalm(id)
  505. {
  506. // Napalm grenades disabled
  507. if (!g_on) return PLUGIN_CONTINUE;
  508.  
  509. // Check if override setting is enabled instead
  510. if (g_override)
  511. {
  512. client_print(id, print_center, "Csak egy %s granatot vasarolhatsz amit automatikusan napalmkent kapsz meg", AFFECTED_NAMES[g_affect-1])
  513. return PLUGIN_HANDLED;
  514. }
  515.  
  516. // Check if player is alive
  517. if (!is_user_alive(id))
  518. {
  519. client_print(id, print_center, "Nem vasarolhatsz, mert halott vagy!")
  520. return PLUGIN_HANDLED;
  521. }
  522.  
  523. // Check if the player is on a restricted team
  524. if (g_allowedteam > 0 && g_allowedteam != fm_get_user_team(id))
  525. {
  526. client_print(id, print_center, "A csapatod nem vehet napalm granatot!")
  527. return PLUGIN_HANDLED;
  528. }
  529.  
  530. // Check if player needs to be in a buyzone
  531. if (g_buyzone && !fm_get_user_buyzone(id))
  532. {
  533. client_print(id, print_center, "Nem a vasarlasi zonaban vagy!")
  534. return PLUGIN_HANDLED;
  535. }
  536.  
  537. // Check that player has the money
  538. if (fm_get_user_money(id) < g_price)
  539. {
  540. client_print(id, print_center, "#Cstrike_TitlesTXT_Not_Enough_Money")
  541.  
  542. // Blink money
  543. message_begin(MSG_ONE_UNRELIABLE, g_msgBlinkAcct, _, id)
  544. write_byte(2) // times
  545. message_end()
  546.  
  547. return PLUGIN_HANDLED;
  548. }
  549.  
  550. // Get napalm weapon entity
  551. static napalm_weaponent
  552. napalm_weaponent = fm_get_napalm_entity(id, g_affect)
  553.  
  554. // Does the player have a napalm already?
  555. if (napalm_weaponent != 0)
  556. {
  557. // Retrieve napalm ammo
  558. static napalm_ammo
  559. napalm_ammo = pev(napalm_weaponent, PEV_NAPALM_AMMO)
  560.  
  561. // Check if allowed to have this many napalms
  562. if (napalm_ammo < g_carrylimit)
  563. {
  564. // Increase napalm ammo
  565. set_pev(napalm_weaponent, PEV_NAPALM_AMMO, ++napalm_ammo)
  566.  
  567. // Increase player's backpack ammo
  568. set_pdata_int(id, AFFECTED_BPAMMO_OFFSETS[g_affect-1], get_pdata_int(id, AFFECTED_BPAMMO_OFFSETS[g_affect-1]) + 1, OFFSET_LINUX)
  569.  
  570. // Flash ammo in hud
  571. message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoPickup, _, id)
  572. write_byte(AFFECTED_AMMOID[g_affect-1]) // ammo id
  573. write_byte(1) // ammo amount
  574. message_end()
  575.  
  576. // Play clip purchase sound
  577. engfunc(EngFunc_EmitSound, id, CHAN_ITEM, sound_buyammo, 1.0, ATTN_NORM, 0, PITCH_NORM)
  578.  
  579. // Set napalm flag on the weapon entity (bugfix)
  580. set_pev(napalm_weaponent, PEV_NADE_TYPE, NADE_TYPE_NAPALM)
  581. }
  582. else
  583. {
  584. client_print(id, print_center, "Nem lehet nalad tobb napalm granat!")
  585. return PLUGIN_HANDLED;
  586. }
  587. }
  588. else
  589. {
  590. // Give napalm
  591. fm_give_item(id, AFFECTED_CLASSNAMES[g_affect-1])
  592.  
  593. // Get napalm weapon entity now it exists
  594. napalm_weaponent = fm_get_napalm_entity(id, g_affect)
  595.  
  596. // Set napalm flag on the weapon entity
  597. set_pev(napalm_weaponent, PEV_NADE_TYPE, NADE_TYPE_NAPALM)
  598.  
  599. // Set napalm ammo
  600. set_pev(napalm_weaponent, PEV_NAPALM_AMMO, 1)
  601. }
  602.  
  603. // Calculate new money amount
  604. static newmoney
  605. newmoney = fm_get_user_money(id) - g_price
  606.  
  607. // Update money offset
  608. fm_set_user_money(id, newmoney)
  609.  
  610. // Update money on HUD
  611. message_begin(MSG_ONE, g_msgMoney, _, id)
  612. write_long(newmoney) // amount
  613. write_byte(1) // flash
  614. message_end()
  615.  
  616. return PLUGIN_HANDLED;
  617. }
  618.  
  619. // Napalm Grenade Explosion
  620. napalm_explode(ent)
  621. {
  622. // Get attacker and its team
  623. static attacker, attacker_team
  624. attacker = pev(ent, pev_owner)
  625. attacker_team = pev(ent, pev_team)
  626.  
  627. // Get origin
  628. static Float:originF[3]
  629. pev(ent, pev_origin, originF)
  630.  
  631. // Custom explosion effect
  632. create_blast2(originF)
  633.  
  634. // Napalm explosion sound
  635. engfunc(EngFunc_EmitSound, ent, CHAN_WEAPON, grenade_fire[random_num(0, sizeof grenade_fire - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
  636.  
  637. // Collisions
  638. static victim
  639. victim = -1
  640.  
  641. while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, g_radius)) != 0)
  642. {
  643. // Only effect alive players
  644. if (!is_user_alive(victim))
  645. continue;
  646.  
  647. // Check if myself is allowed
  648. if (!g_hitself && victim == attacker)
  649. continue;
  650.  
  651. // Check if friendly fire is allowed
  652. if (!g_ff && victim != attacker && attacker_team == fm_get_user_team(victim))
  653. continue;
  654.  
  655. // Heat icon
  656. message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, _, victim)
  657. write_byte(0) // damage save
  658. write_byte(0) // damage take
  659. write_long(DMG_BURN) // damage type
  660. write_coord(0) // x
  661. write_coord(0) // y
  662. write_coord(0) // z
  663. message_end()
  664.  
  665. // Our task params
  666. static params[2]
  667. params[0] = g_duration * 5 // duration
  668. params[1] = attacker // attacker
  669.  
  670. // Set burning task on victim
  671. set_task(0.1, "burning_flame", victim+TASK_BURN, params, sizeof params)
  672. }
  673. }
  674.  
  675. // Burning Task
  676. public burning_flame(args[2], taskid)
  677. {
  678. // Player died/disconnected
  679. if (!is_user_alive(ID_BURN))
  680. return;
  681.  
  682. // Get player origin and flags
  683. static Float:originF[3], flags
  684. pev(ID_BURN, pev_origin, originF)
  685. flags = pev(ID_BURN, pev_flags)
  686.  
  687. // In water or burning stopped
  688. if ((flags & FL_INWATER) || BURN_DURATION < 1)
  689. {
  690. // Smoke sprite
  691. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  692. write_byte(TE_SMOKE) // TE id
  693. engfunc(EngFunc_WriteCoord, originF[0]) // x
  694. engfunc(EngFunc_WriteCoord, originF[1]) // y
  695. engfunc(EngFunc_WriteCoord, originF[2]-50.0) // z
  696. write_short(g_smokeSpr) // sprite
  697. write_byte(random_num(15, 20)) // scale
  698. write_byte(random_num(10, 20)) // framerate
  699. message_end()
  700.  
  701. return;
  702. }
  703.  
  704. // Randomly play burning sounds
  705. if (g_screamrate > 0 && random_num(1, g_screamrate) == 1)
  706. engfunc(EngFunc_EmitSound, ID_BURN, CHAN_VOICE, grenade_fire_player[random_num(0, sizeof grenade_fire_player - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
  707.  
  708. // Fire slow down
  709. if (g_slowdown > 0.0 && (flags & FL_ONGROUND))
  710. {
  711. static Float:velocity[3]
  712. pev(ID_BURN, pev_velocity, velocity)
  713. xs_vec_mul_scalar(velocity, g_slowdown, velocity)
  714. set_pev(ID_BURN, pev_velocity, velocity)
  715. }
  716.  
  717. // Get victim's health
  718. static health
  719. health = pev(ID_BURN, pev_health)
  720.  
  721. // Take damage from the fire
  722. if (health - g_damage > 0)
  723. set_pev(ID_BURN, pev_health, float(health - g_damage))
  724. else if (g_cankill)
  725. {
  726. // Kill victim
  727. ExecuteHamB(Ham_Killed, ID_BURN, BURN_ATTACKER, 0)
  728.  
  729. // Smoke sprite
  730. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  731. write_byte(TE_SMOKE) // TE id
  732. engfunc(EngFunc_WriteCoord, originF[0]) // x
  733. engfunc(EngFunc_WriteCoord, originF[1]) // y
  734. engfunc(EngFunc_WriteCoord, originF[2]-50.0) // z
  735. write_short(g_smokeSpr) // sprite
  736. write_byte(random_num(15, 20)) // scale
  737. write_byte(random_num(10, 20)) // framerate
  738. message_end()
  739.  
  740. return;
  741. }
  742.  
  743. // Flame sprite
  744. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  745. write_byte(TE_SPRITE) // TE id
  746. engfunc(EngFunc_WriteCoord, originF[0]+random_float(-5.0, 5.0)) // x
  747. engfunc(EngFunc_WriteCoord, originF[1]+random_float(-5.0, 5.0)) // y
  748. engfunc(EngFunc_WriteCoord, originF[2]+random_float(-10.0, 10.0)) // z
  749. write_short(g_flameSpr) // sprite
  750. write_byte(random_num(5, 10)) // scale
  751. write_byte(200) // brightness
  752. message_end()
  753.  
  754. // Decrease task cycle count
  755. BURN_DURATION -= 1;
  756.  
  757. // Keep sending flame messages
  758. set_task(0.2, "burning_flame", taskid, args, sizeof args)
  759. }
  760.  
  761. // Napalm Grenade: Fire Blast (originally made by Avalanche in Frostnades)
  762. create_blast2(const Float:originF[3])
  763. {
  764. // Smallest ring
  765. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  766. write_byte(TE_BEAMCYLINDER) // TE id
  767. engfunc(EngFunc_WriteCoord, originF[0]) // x
  768. engfunc(EngFunc_WriteCoord, originF[1]) // y
  769. engfunc(EngFunc_WriteCoord, originF[2]) // z
  770. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  771. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  772. engfunc(EngFunc_WriteCoord, originF[2]+385.0) // z axis
  773. write_short(g_exploSpr) // sprite
  774. write_byte(0) // startframe
  775. write_byte(0) // framerate
  776. write_byte(4) // life
  777. write_byte(60) // width
  778. write_byte(0) // noise
  779. write_byte(200) // red
  780. write_byte(100) // green
  781. write_byte(0) // blue
  782. write_byte(200) // brightness
  783. write_byte(0) // speed
  784. message_end()
  785.  
  786. // Medium ring
  787. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  788. write_byte(TE_BEAMCYLINDER) // TE id
  789. engfunc(EngFunc_WriteCoord, originF[0]) // x
  790. engfunc(EngFunc_WriteCoord, originF[1]) // y
  791. engfunc(EngFunc_WriteCoord, originF[2]) // z
  792. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  793. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  794. engfunc(EngFunc_WriteCoord, originF[2]+470.0) // z axis
  795. write_short(g_exploSpr) // sprite
  796. write_byte(0) // startframe
  797. write_byte(0) // framerate
  798. write_byte(4) // life
  799. write_byte(60) // width
  800. write_byte(0) // noise
  801. write_byte(200) // red
  802. write_byte(50) // green
  803. write_byte(0) // blue
  804. write_byte(200) // brightness
  805. write_byte(0) // speed
  806. message_end()
  807.  
  808. // Largest ring
  809. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  810. write_byte(TE_BEAMCYLINDER) // TE id
  811. engfunc(EngFunc_WriteCoord, originF[0]) // x
  812. engfunc(EngFunc_WriteCoord, originF[1]) // y
  813. engfunc(EngFunc_WriteCoord, originF[2]) // z
  814. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  815. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  816. engfunc(EngFunc_WriteCoord, originF[2]+555.0) // z axis
  817. write_short(g_exploSpr) // sprite
  818. write_byte(0) // startframe
  819. write_byte(0) // framerate
  820. write_byte(4) // life
  821. write_byte(60) // width
  822. write_byte(0) // noise
  823. write_byte(200) // red
  824. write_byte(0) // green
  825. write_byte(0) // blue
  826. write_byte(200) // brightness
  827. write_byte(0) // speed
  828. message_end()
  829. }
  830.  
  831. // Register Ham Forwards for CZ bots
  832. public register_ham_czbots(id)
  833. {
  834. // Make sure it's a CZ bot and it's still connected
  835. if (g_hamczbots || !get_pcvar_num(cvar_botquota) || !is_user_connected(id))
  836. return;
  837.  
  838. RegisterHamFromEntity(Ham_Touch, id, "fw_TouchPlayer")
  839.  
  840. // Ham forwards for CZ bots succesfully registered
  841. g_hamczbots = true;
  842. }
  843.  
  844. // Set entity's rendering type (from fakemeta_util)
  845. stock fm_set_rendering(entity, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16)
  846. {
  847. static Float:color[3]
  848. color[0] = float(r)
  849. color[1] = float(g)
  850. color[2] = float(b)
  851.  
  852. set_pev(entity, pev_renderfx, fx)
  853. set_pev(entity, pev_rendercolor, color)
  854. set_pev(entity, pev_rendermode, render)
  855. set_pev(entity, pev_renderamt, float(amount))
  856. }
  857.  
  858. // Give an item to a player (from fakemeta_util)
  859. stock fm_give_item(id, const item[])
  860. {
  861. static ent
  862. ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, item));
  863. if (!pev_valid(ent)) return;
  864.  
  865. static Float:originF[3]
  866. pev(id, pev_origin, originF);
  867. set_pev(ent, pev_origin, originF);
  868. set_pev(ent, pev_spawnflags, pev(ent, pev_spawnflags) | SF_NORESPAWN);
  869. dllfunc(DLLFunc_Spawn, ent);
  870.  
  871. static save
  872. save = pev(ent, pev_solid);
  873. dllfunc(DLLFunc_Touch, ent, id);
  874. if (pev(ent, pev_solid) != save)
  875. return;
  876.  
  877. engfunc(EngFunc_RemoveEntity, ent);
  878. }
  879.  
  880. // Find entity by its owner (from fakemeta_util)
  881. stock fm_find_ent_by_owner(entity, const classname[], owner)
  882. {
  883. while ((entity = engfunc(EngFunc_FindEntityByString, entity, "classname", classname)) && pev(entity, pev_owner) != owner) {}
  884.  
  885. return entity;
  886. }
  887.  
  888. // Finds napalm grenade weapon entity of a player
  889. stock fm_get_napalm_entity(id, g_affect)
  890. {
  891. return fm_find_ent_by_owner(-1, AFFECTED_CLASSNAMES[g_affect-1], id);
  892. }
  893.  
  894. // Get User Current Weapon Entity
  895. stock fm_get_user_current_weapon_ent(id)
  896. {
  897. return get_pdata_cbase(id, OFFSET_ACTIVE_ITEM, OFFSET_LINUX);
  898. }
  899.  
  900. // Get Weapon Entity's CSW_ ID
  901. stock fm_get_weapon_ent_id(ent)
  902. {
  903. return get_pdata_int(ent, OFFSET_WEAPONID, OFFSET_LINUX_WEAPONS);
  904. }
  905.  
  906. // Get Weapon Entity's Owner
  907. stock fm_get_weapon_ent_owner(ent)
  908. {
  909. return get_pdata_cbase(ent, OFFSET_WEAPONOWNER, OFFSET_LINUX_WEAPONS);
  910. }
  911.  
  912. // Get User Money
  913. stock fm_get_user_money(id)
  914. {
  915. return get_pdata_int(id, OFFSET_CSMONEY, OFFSET_LINUX);
  916. }
  917.  
  918. // Set User Money
  919. stock fm_set_user_money(id, amount)
  920. {
  921. set_pdata_int(id, OFFSET_CSMONEY, amount, OFFSET_LINUX);
  922. }
  923.  
  924. // Get User Team
  925. stock fm_get_user_team(id)
  926. {
  927. return get_pdata_int(id, OFFSET_CSTEAMS, OFFSET_LINUX);
  928. }
  929.  
  930. // Returns whether user is in a buyzone
  931. stock fm_get_user_buyzone(id)
  932. {
  933. if (get_pdata_int(id, OFFSET_MAPZONE) & PLAYER_IN_BUYZONE)
  934. return 1;
  935.  
  936. return 0;
  937. }
  938.