Guest User

Untitled

a guest
Jan 9th, 2014
172
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 296.70 KB | None | 0 0
  1.  
  2. // mod by waza123a 09.01.2014 , added longjump to all
  3. /*================================================================================
  4.  
  5. ***********************************************
  6. ********** [Zombie Plague Mod 3.6] ************
  7. ***********************************************
  8.  
  9. (c) Copyright 2008 by MeRcyLeZZ
  10.  
  11. ----------------------
  12. -*- Licensing Info -*-
  13. ----------------------
  14.  
  15. This file is provided "as-is" and comes with no warranties of any kind.
  16.  
  17. You are free to use, redistribute and/or modify this plugin to your
  18. liking with the following restrictions:
  19.  
  20. * You cannot alter/remove/replace the register_plugin() call
  21. * You cannot alter/remove/replace any credits info
  22. * You cannot alter/remove/replace this license
  23.  
  24. -------------------
  25. -*- Description -*-
  26. -------------------
  27.  
  28. Zombie Plague is a Counter-Strike server modification, developed as an
  29. AMX Mod X plugin, which turns the game into a Humans vs Zombies struggle.
  30. It is based on the original infection mod, but it takes the concept to
  31. a new level by introducing:
  32.  
  33. * New Gameplay Modes: Nemesis, Survivor, Multiple Infection, Swarm Mode
  34. * Zombie Classes: a total of six, each with his own strengths
  35. * Ammo Packs: awarded to skilled players, can be used to purchase goods
  36. * Custom Grenades: Fire, Frost, Flare, and Infection Bomb
  37. * Deathmatch Mode: players may respawn as zombies, humans, or randomly
  38. * Admin commands: can be performed through an easy ingame menu
  39. * Special GFX Effects: from the HL Engine
  40. * Customizable Models and Sounds
  41.  
  42. It brings many customization through CVARS as well:
  43.  
  44. * Change nightvision/flashlight colors and size
  45. * Adjust in-game light level (lightnings available for the dark settings)
  46. * Set zombies/humans health, speed, gravity, ammo pack rewards, and more
  47. * Enable unlimited ammo or knockback for weapons
  48. * Enable random spawning (CSDM-spawns friendly)
  49. * Separately enable and customize the new gameplay modes to your liking
  50.  
  51. ---------------
  52. -*- History -*-
  53. ---------------
  54.  
  55. This project started back on December 2007, when the free infection mods
  56. around were quite buggy. I wanted to make one on my own, but with little
  57. to no experience at AMXX scripting, I had to start from the very scratch.
  58.  
  59. Not after spending over a week looking at many plugins (mainly Zombie
  60. Swarm) and scarce tutorials, I somehow managed to have all the basic
  61. stuff working quite well (even though the code was really messy). The
  62. following months were spent polishing things up and trying to fulfill
  63. new original ideas, most of them quite worth the hard work.
  64.  
  65. In the meantime, I had the chance to try the plugin out on a 32 man
  66. server. This meant a huge progress on development, and after lots of
  67. testing and bug fixing, the mod turned out to be more than the simple
  68. infection plugin I had originally planned it to be.
  69.  
  70. The project has come a long way since, and I'm glad to say I'm finally
  71. making it freely available. All I'm asking in return is to keep my
  72. name in the plugin.
  73.  
  74. -Enjoy!
  75.  
  76. -------------
  77. -*- Media -*-
  78. -------------
  79.  
  80. * Gameplay Video 1: http://www.youtube.com/watch?v=HFUyF7-_uzw
  81. * Gameplay Video 2: http://www.youtube.com/watch?v=XByif6Mti-w
  82.  
  83. --------------------
  84. -*- Requirements -*-
  85. --------------------
  86.  
  87. * Mods: Counter-Strike 1.6 or Condition-Zero
  88. * AMXX: Version 1.8.0 or higher
  89. * Modules: FakeMeta, HamSandwich
  90.  
  91. --------------------
  92. -*- Installation -*-
  93. --------------------
  94.  
  95. Just extract all the contents from the .zip file to your server's mod
  96. directory ("cstrike" or "czero"). Make sure to keep folder structure.
  97.  
  98. -------------------------------
  99. -*- CVARS and Customization -*-
  100. -------------------------------
  101.  
  102. For a complete and in-depth cvar list, look at the zombieplague.cfg file
  103. located in the amxmodx\configs directory.
  104.  
  105. Additionally, you can change player models, sounds, weather effects,
  106. and some other stuff by looking at the beginning of the .sma for the
  107. "Plugin Customization" section. Once you're done making your changes,
  108. remember to recompile!
  109.  
  110. ----------------------
  111. -*- Admin Commands -*-
  112. ----------------------
  113.  
  114. The following console commands are available:
  115.  
  116. * zp_zombie <name> - Turn someone into a Zombie
  117. * zp_human <name> - Turn someone back to Human
  118. * zp_nemesis <name> - Turn someone into a Nemesis (*)
  119. * zp_survivor <name> - Turn someone into a Survivor (*)
  120. * zp_respawn <name> - Respawn someone
  121. * zp_swarm - Start Swarm Mode (*)
  122. * zp_multi - Start Multi Infection (*)
  123.  
  124. (*) - These commands can only be used at round start, that is, when the
  125. T-Virus notice is shown on screen.
  126.  
  127. --------------------
  128. -*- In-Game Menu -*-
  129. --------------------
  130.  
  131. Players can access the mod menu by typing "zpmenu" on chat, or by
  132. pressing the M ("chooseteam") key. The menu allows players to choose
  133. their zombie class, buy extra items, get unstuck, or see the ingame
  134. help. Admins will find an additional option to easily perform all
  135. console commands.
  136.  
  137. ----------------------
  138. -*- Infection Mode -*-
  139. ----------------------
  140.  
  141. On every round players start out as humans, equip themselves with a few
  142. weapons and grenades, and head to the closest cover they find, knowing
  143. that one of them is infected with the T-Virus, and will suddenly turn
  144. into a vicious brain eating creature.
  145.  
  146. Only little time after, the battle for survival begins. The first zombie
  147. has to infect as many humans as possible to cluster a numerous zombie
  148. horde and take over the world.
  149.  
  150. Maps are set in the dark by default. Humans must use flashlights to light
  151. their way and spot any enemies. Zombies, on the other hand, have night
  152. vision but can only attack melee.
  153.  
  154. --------------------------
  155. -*- New Gameplay Modes -*-
  156. --------------------------
  157.  
  158. * Nemesis:
  159. The first zombie may turn into a Nemesis, a powerful fast-moving
  160. beast. His goal is to kill every human while sustaining the gunfire.
  161.  
  162. * Survivor:
  163. Everyone became a zombie except him. The survivor gets a machinegun
  164. with unlimited ammo and has to stop the never-ending army of undead.
  165.  
  166. * Multiple Infection:
  167. The round starts with many humans infected, so the remaining players
  168. will have to act quickly in order to control the situation.
  169.  
  170. * Swarm Mode:
  171. Half of the players turn into zombies, the rest become immune and
  172. cannot be infected. It's a battle to death.
  173.  
  174. ----------------------
  175. -*- Zombie Classes -*-
  176. ----------------------
  177.  
  178. There are six zombie classes by default:
  179.  
  180. * Classic Zombie: well balanced zombie for beginners.
  181. * Raptor Zombie: fast moving zombie, but also the weakest.
  182. * Poison Zombie: light weighed zombie, jumps higher.
  183. * Big Zombie: slow but strong zombie, with lots of hit points.
  184. * Leech Zombie: regains the most health when infecting.
  185. * Rage Zombie: emits a radioactive green glow.
  186.  
  187. -------------------
  188. -*- Extra Items -*-
  189. -------------------
  190.  
  191. Besides weapons, players can buy the following items:
  192.  
  193. * Night Vision: makes you able to see in the dark, lasts a single round.
  194. * T-Virus Antidote: makes you turn back to your human form.
  195. * Zombie Madness: you develop a powerful shield for a short time.
  196. * Infection Bomb: infects anyone within its explosion radius.
  197.  
  198. ----------------
  199. -*- Includes -*-
  200. ----------------
  201.  
  202. From version 3.6, some natives and forwards have been added to ease the
  203. development of sub-plugins, though you may also find them useful to work
  204. out compatibility issues with existing plugins.
  205.  
  206. Look for the zombieplague.inc file in your amxmodx\scripting\include
  207. folder for the full list.
  208.  
  209. --------------------
  210. -*- Contact Info -*-
  211. --------------------
  212.  
  213. For the official Zombie Plague thread visit:
  214. http://forums.alliedmods.net/showthread.php?t=72505
  215.  
  216. For personal contact you can send me an email at:
  217. wils_90@hotmail.com
  218.  
  219. ---------------
  220. -*- Credits -*-
  221. ---------------
  222.  
  223. * AMXX Dev Team: for all the hard work which made this possible
  224. * Imperio LNJ Community: for providing the first server where I
  225. could really test the plugin and for everyone's support
  226. * Mini_Midget: for his Zombie Swarm plugin which I used for reference
  227. on earliest stages of development
  228. * Avalanche: for the random spawning code I got from GunGame and the
  229. original Frostnades concept that I ported in here
  230. * cheap_suit: for some modelchange and knockback codes that I got from
  231. Biohazard
  232. * Simon Logic: for the Pain Shock Free feature
  233. * KRoT@L: for some code from Follow the Wounded, used to make the zombie
  234. bleeding feature
  235. * VEN: for Fakemeta Utilities and some useful stocks
  236. * RaaPuar and Goltark: for the custom grenade models
  237. * ML Translations: DKs/nunoabc (BP), JahMan/KWo (PL), DA (DE),
  238. hleV (LT), darkbad945 (BG)
  239. * Everyone who enjoys killing zombies!
  240.  
  241. ------------------
  242. -*- Change Log -*-
  243. ------------------
  244.  
  245. * v1.0: (Dec 2007)
  246. - First Release: most of the basic stuff done.
  247. - Added: random spawning, HP display on hud, lighting setting,
  248. simple buy menu, custom nightvision, admin commands, Nemesis
  249. and Survivor modes, glow and leap settings for them.
  250.  
  251. * v2.2: (Jan 2008)
  252. - Added: zombie classes, ammo packs system, buying ammo for weapons,
  253. custom flashlight, admin skins setting, zombieplague.cfg file
  254. - Upgraded: weapons menu improved, flashlight and nightvision colors
  255. now customizable, HamSandwich module used to handle damage.
  256. - Fixed various bugs.
  257.  
  258. * v3.0: (Mar 2008)
  259. - Added: door removal setting, unstuck feature, human cvars, armor
  260. cvar for zombies, weapon knockback, zombie bleeding, flares,
  261. extra items (weapons, antidote, infection bomb), pain shock
  262. free setting, Multiple Infection and Swarm modes.
  263. - Upgraded: dumped Engine, Fun and Cstrike modules, code optimized,
  264. new model change method, new gfx effects for zombie infections.
  265. - Fixed a bunch of gameplay bugs.
  266.  
  267. * v3.5: (May 2008)
  268. - Added: deathmatch setting with spawn protection, unlimited ammo
  269. setting, fire and frost grenades, additional customization cvars,
  270. new extra items, help menu.
  271. - Upgraded: better objectives removal method, dropped weapons now
  272. keep their bpammo, code optimized a lot.
  273. - Fixed: no more game commencing bug when last zombie/human leaves,
  274. no more hegrenade infection bug, reduced svc_bad errors, and
  275. many more.
  276.  
  277. * v3.6: (Jun 2008)
  278. - Added: a few natives and forwards for sub-plugins support,
  279. zombie classes can now have their own models, additional
  280. knockback customization, bot support, various CVARS.
  281. - Upgraded: extra items now supporting grenades and pistols, changed
  282. bomb removal method, players can join on survivor/swarm rounds,
  283. extended lightnings support to other dark settings.
  284. - Fixed: a bunch of minor bugs, and a server crash with CZ bots.
  285.  
  286. =================================================================================*/
  287.  
  288. #include <amxmodx>
  289. #include <amxmisc>
  290. #include <fakemeta>
  291. #include <hamsandwich>
  292. #include <xs>
  293.  
  294. /*================================================================================
  295. [Plugin Customization]
  296. =================================================================================*/
  297.  
  298. // Access Flag Required to use Admin Commands
  299. const ACCESS_FLAG = ADMIN_BAN
  300.  
  301. // Access Flag Required to Turn the Mod On/Off
  302. const ACCESS_FLAG2 = ADMIN_RCON
  303.  
  304. // Player Models (randomly chosen, add as many as you want) -32 chars max per model-
  305. new const model_zombie_class1[][] = { "zombie_source" } // Zombie (Classic)
  306. new const model_zombie_class2[][] = { "zombie_source" } // Zombie (Raptor)
  307. new const model_zombie_class3[][] = { "zombie_source" } // Zombie (Poison)
  308. new const model_zombie_class4[][] = { "zombie_source" } // Zombie (Fat)
  309. new const model_zombie_class5[][] = { "zombie_source" } // Zombie (Leech)
  310. new const model_zombie_class6[][] = { "zombie_source" } // Zombie (Rage)
  311. new const model_nemesis[][] = { "zombie_source" } // Nemesis
  312. new const model_human[][] = { "arctic", "guerilla", "leet", "terror", "gign", "gsg9", "sas", "urban" } // Human
  313. new const model_admin[][] = { "vip" } // Admin
  314.  
  315. // Custom Weapon Models
  316. new const model_vknife_zombie[] = { "models/zombie_plague/v_knife_zombie.mdl" }
  317. new const model_pknife_zombie[] = { "" }
  318. new const model_vknife_nemesis[] = { "models/zombie_plague/v_knife_zombie.mdl" }
  319. new const model_pknife_nemesis[] = { "" }
  320. new const model_grenade_infect[] = { "models/zombie_plague/v_grenade_infect.mdl" }
  321. new const model_grenade_fire[] = { "models/zombie_plague/v_grenade_fire.mdl" }
  322. new const model_grenade_frost[] = { "models/zombie_plague/v_grenade_frost.mdl" }
  323. new const model_grenade_flare[] = { "models/zombie_plague/v_grenade_flare.mdl" }
  324.  
  325. // Grenade Sprites
  326. new const sprite_grenade_trail[] = { "sprites/laserbeam.spr" }
  327. new const sprite_grenade_ring[] = { "sprites/shockwave.spr" }
  328. new const sprite_grenade_fire[] = { "sprites/flame.spr" }
  329. new const sprite_grenade_smoke[] = { "sprites/black_smoke3.spr" }
  330. new const sprite_grenade_glass[] = { "models/glassgibs.mdl" }
  331.  
  332. // Sound list (randomly chosen, add as many as you want)
  333. new const sound_win_zombies[][] = { "ambience/the_horror1.wav", "ambience/the_horror3.wav", "ambience/the_horror4.wav" }
  334. new const sound_win_humans[][] = { "zombie_plague/win_humans1.wav", "zombie_plague/win_humans2.wav" }
  335. new const sound_win_no_one[][] = { "" }
  336. new const zombie_infect[][] = { "zombie_plague/zombie_infec1.wav", "zombie_plague/zombie_infec2.wav", "zombie_plague/zombie_infec3.wav", "scientist/c1a0_sci_catscream.wav", "scientist/scream01.wav" }
  337. new const zombie_pain[][] = { "zombie_plague/zombie_pain1.wav", "zombie_plague/zombie_pain2.wav", "zombie_plague/zombie_pain3.wav", "zombie_plague/zombie_pain4.wav", "zombie_plague/zombie_pain5.wav" }
  338. new const nemesis_pain[][] = { "zombie_plague/nemesis_pain1.wav", "zombie_plague/nemesis_pain2.wav", "zombie_plague/nemesis_pain3.wav" }
  339. new const zombie_die[][] = { "zombie_plague/zombie_die1.wav", "zombie_plague/zombie_die2.wav", "zombie_plague/zombie_die3.wav", "zombie_plague/zombie_die4.wav", "zombie_plague/zombie_die5.wav" }
  340. new const zombie_fall[][] = { "zombie_plague/zombie_fall1.wav" }
  341. new const zombie_idle[][] = { "nihilanth/nil_now_die.wav", "nihilanth/nil_slaves.wav", "nihilanth/nil_alone.wav", "zombie_plague/zombie_brains1.wav", "zombie_plague/zombie_brains2.wav" }
  342. new const zombie_idle_last[][] = { "nihilanth/nil_thelast.wav" }
  343. new const zombie_madness[][] = { "zombie_plague/zombie_madness1.wav" }
  344. new const sound_nemesis[][] = { "zombie_plague/nemesis1.wav", "zombie_plague/nemesis2.wav" }
  345. new const sound_survivor[][] = { "zombie_plague/survivor1.wav", "zombie_plague/survivor2.wav" }
  346. new const sound_swarm[][] = { "ambience/the_horror2.wav" }
  347. new const sound_multi[][] = { "ambience/the_horror2.wav" }
  348. new const grenade_infect[][] = { "zombie_plague/grenade_infect.wav" }
  349. new const grenade_infect_player[][] = { "scientist/scream20.wav", "scientist/scream22.wav", "scientist/scream05.wav" }
  350. new const grenade_fire[][] = { "zombie_plague/grenade_explode.wav" }
  351. new const grenade_fire_player[][] = { "zombie_plague/zombie_burn3.wav","zombie_plague/zombie_burn4.wav","zombie_plague/zombie_burn5.wav","zombie_plague/zombie_burn6.wav","zombie_plague/zombie_burn7.wav" }
  352. new const grenade_frost[][] = { "warcraft3/frostnova.wav" }
  353. new const grenade_frost_player[][] = { "warcraft3/impalehit.wav" }
  354. new const grenade_frost_break[][] = { "warcraft3/impalelaunch1.wav" }
  355. new const grenade_flare[][] = { "items/nvg_on.wav" }
  356. new const sound_antidote[][] = { "items/smallmedkit1.wav" }
  357. new const sound_thunder[][] = { "zombie_plague/thunder1.wav", "zombie_plague/thunder2.wav" }
  358.  
  359. // Uncomment the following line to enable ambience sounds
  360. //#define AMBIENCE_SOUNDS
  361.  
  362. #if defined AMBIENCE_SOUNDS // Ambience Sounds List (only .wav and .mp3 formats supported)
  363. new const sound_ambience[][] = { "zombie_plague/ambience.wav" }
  364. new const Float:sound_ambience_duration[] = { 17.0 } // duration in seconds
  365. #endif
  366.  
  367. // Buy Menu: Primary Weapons (9 max)
  368. new const g_primary_names[][] = { "SG-552 Commando", "Steyr AUG A1", "M4A1 Carbine", "AK-47 Kalashnikov", "IMI Galil", "Famas", "M3 Super 90", "XM1014 M4", "MP5 Navy" }
  369. new const g_primary_classes[][] = { "Rifle", "Rifle", "Rifle", "Rifle", "Rifle", "Rifle", "Shotgun", "Shotgun", "SMG" }
  370. new const g_primary_items[][] = { "weapon_sg552", "weapon_aug", "weapon_m4a1", "weapon_ak47", "weapon_galil", "weapon_famas", "weapon_m3", "weapon_xm1014", "weapon_mp5navy" }
  371.  
  372. // Buy Menu: Secondary Weapons (9 max)
  373. new const g_secondary_names[][] = { "Glock 18C", "USP .45 ACP Tactical", "P228", "Desert Eagle .50 AE", "FiveseveN", "Dual 96G Elite Berettas" }
  374. new const g_secondary_classes[][] = { "Pistol", "Pistol", "Pistol", "Pistol", "Pistol", "Pistol" }
  375. new const g_secondary_items[][] = { "weapon_glock18", "weapon_usp", "weapon_p228", "weapon_deagle", "weapon_fiveseven", "weapon_elite" }
  376.  
  377. // Additional Items to give after buying all weapons (e.g. grenades)
  378. new const g_additional_items[][] = { "weapon_hegrenade", "weapon_flashbang", "weapon_smokegrenade" }
  379.  
  380. // Extra Items: Weapons and their costs (5 max)
  381. new const g_extra_names[][] = { "Fire Grenade", "AWP Sniper", "M249 Machinegun", "SG550 Auto-Sniper", "G3SG1 Auto-Sniper" }
  382. new const g_extra_items[][] = { "weapon_hegrenade", "weapon_awp", "weapon_m249", "weapon_sg550", "weapon_g3sg1" }
  383. new const g_extra_costs[] = { 6, 8, 10, 12, 12 }
  384.  
  385. // Extra Items: costs for Night Vision, Antidote, Zombie Madness, and Infection Bomb
  386. new const g_extra_costs2[] = { 15, 15, 17, 20 }
  387.  
  388. // Weather Effects: uncomment a line to have the desired effect
  389. //#define AMBIENCE_RAIN // Rain
  390. //#define AMBIENCE_SNOW // Snow
  391. //#define AMBIENCE_FOG // Fog
  392.  
  393. #if defined AMBIENCE_FOG // Fog Customization (if enabled)
  394. new const FOG_DENSITY[] = "0.0018" // Density
  395. new const FOG_COLOR[] = "128 128 128" // Color: Red Green Blue
  396. #endif
  397.  
  398. // Sky Names (randomly chosen, add as many as you want)
  399. new const skynames[][] = { "space" }
  400.  
  401. // Lightning Lights Cycle
  402. new const lights_thunder1[][] = { "i" ,"j", "k", "l", "m", "n", "o", "n", "m", "l", "k", "j", "i", "h", "g", "f", "e", "d", "c", "b", "a"}
  403. new const lights_thunder2[][] = { "k", "l", "m", "l", "k", "j", "i", "h", "g", "f", "e", "d", "c", "b", "a", "a", "b", "c", "d", "e", "d", "c", "b", "a"}
  404. new const lights_thunder3[][] = { "b", "c", "d", "e", "f", "e", "d", "c", "i" ,"j", "k", "l", "m", "l", "k", "j", "i", "h", "g", "f", "e", "d", "c", "b", "a"}
  405.  
  406. // Decal List for Zombie Bloodstains/Footsteps
  407. new const zombie_decals[] = { 99, 107, 108, 184, 185, 186, 187, 188, 189 }
  408.  
  409. // Multipliers for zombie classes as follows: (percents)
  410. // Classic, Raptor, Poison, Fat, Leech, Rage
  411. new const zombie_multihp[] = { 100, 50, 75, 150, 75, 125 }
  412. new const zombie_multispd[] = { 100, 120, 100, 80, 100, 110 }
  413. new const zombie_multigrav[] = { 100, 100, 75, 100, 100, 87 }
  414. new const zombie_multiknockback[] = { 100, 150, 125, 50, 125, 100 }
  415.  
  416. // Knockback Power values for all weapons
  417. // Note: to disable knockback power on a specific weapon use a negative value
  418. new const Float:kb_weapon_power[] =
  419. {
  420. -1.0, // ---
  421. 2.4, // P228
  422. -1.0, // ---
  423. 6.5, // SCOUT
  424. -1.0, // ---
  425. 8.0, // XM1014
  426. -1.0, // ---
  427. 2.3, // MAC10
  428. 5.0, // AUG
  429. -1.0, // ---
  430. 2.4, // ELITE
  431. 2.0, // FIVESEVEN
  432. 2.4, // UMP45
  433. 5.3, // SG550
  434. 5.5, // GALIL
  435. 5.5, // FAMAS
  436. 2.2, // USP
  437. 2.0, // GLOCK18
  438. 10.0, // AWP
  439. 2.5, // MP5NAVY
  440. 5.2, // M249
  441. 8.0, // M3
  442. 5.0, // M4A1
  443. 2.4, // TMP
  444. 6.5, // G3SG1
  445. -1.0, // ---
  446. 5.3, // DEAGLE
  447. 5.0, // SG552
  448. 6.0, // AK47
  449. -1.0, // ---
  450. 2.0 // P90
  451. }
  452.  
  453. // Objective entites and anything that would affect plugin gameplay
  454. new const g_objective_ents[][] = { "func_bomb_target", "info_bomb_target", "info_vip_start", "func_vip_safetyzone", "func_escapezone", "hostage_entity",
  455. "monster_scientist", "func_hostage_rescue", "info_hostage_rescue", "env_fog", "env_rain", "env_snow", "func_vehicle", "item_longjump" }
  456.  
  457. // ***************************************************************
  458. // *** If you experience many SVC_BAD kicks, try the following ***
  459. // ***************************************************************
  460. // 1. Increase the delay between model changes here: (eg. set it to 0.5)
  461. const Float:MODELCHANGE_DELAY = 0.2
  462. // 2. If the above doesn't help, uncomment the following line:
  463. //#define HANDLE_MODELS_ON_SEPARATE_ENT // experimental, uses more CPU
  464.  
  465. // ---------------------------------------------------------------
  466. // ------------------ Customization ends here!! ------------------
  467. // ---------------------------------------------------------------
  468.  
  469. /*================================================================================
  470. [Offsets and Constants]
  471. =================================================================================*/
  472.  
  473. // Plugin Version
  474. new const PLUGIN_VERSION[] = "3.61"
  475.  
  476. // Task offsets
  477. const MODEL_TASK = 2000
  478. const TEAM_TASK = 2100
  479. const SPAWN_TASK = 2200
  480. const BLOOD_TASK = 2300
  481. const NVISION_TASK = 2400
  482. const FLASH_TASK = 2500
  483. const CHARGE_TASK = 2600
  484. const SHOWHUD_TASK = 2700
  485. const NADES_TASK = 2800
  486. const MAKEZOMBIE_TASK = 2900
  487. const WELCOMEMSG_TASK = 3000
  488. const THUNDER_PRE_TASK = 3100
  489. const THUNDER_TASK = 3200
  490.  
  491. // IDs inside tasks
  492. #define ID_MODEL (taskid - MODEL_TASK)
  493. #define ID_TEAM (taskid - TEAM_TASK)
  494. #define ID_SPAWN (taskid - SPAWN_TASK)
  495. #define ID_BLOOD (taskid - BLOOD_TASK)
  496. #define ID_NVISION (taskid - NVISION_TASK)
  497. #define ID_FLASH (taskid - FLASH_TASK)
  498. #define ID_CHARGE (taskid - CHARGE_TASK)
  499. #define ID_SHOWHUD (taskid - SHOWHUD_TASK)
  500.  
  501. // For player list menu handlers
  502. #define PL_STARTID (g_menu_item[id][0])
  503. #define PL_ACTION (g_menu_item[id][1])
  504. #define PL_TARGET (key+g_menu_item[id][0]+1)
  505.  
  506. // Hard coded extra items
  507. enum
  508. {
  509. EXTRA_NVISION = 0,
  510. EXTRA_ANTIDOTE,
  511. EXTRA_MADNESS,
  512. EXTRA_INFBOMB
  513. }
  514.  
  515. // Zombie classes
  516. enum
  517. {
  518. ZCLASS_NONE = -1,
  519. ZCLASS_CLASSIC,
  520. ZCLASS_RAPTOR,
  521. ZCLASS_POISON,
  522. ZCLASS_FAT,
  523. ZCLASS_LEECH,
  524. ZCLASS_RAGE
  525. }
  526.  
  527. // Game modes
  528. enum
  529. {
  530. MODE_NONE = 0,
  531. MODE_INFECTION,
  532. MODE_NEMESIS,
  533. MODE_SURVIVOR,
  534. MODE_SWARM,
  535. MODE_MULTI
  536. }
  537.  
  538. // CS Offsets
  539. #if cellbits == 32
  540. const OFFSET_CSTEAMS = 114
  541. const OFFSET_CSMONEY = 115
  542. const OFFSET_NVGOGGLES = 129
  543. const OFFSET_ZOOMTYPE = 363
  544. const OFFSET_CSDEATHS = 444
  545. const OFFSET_AWM_AMMO = 377
  546. const OFFSET_SCOUT_AMMO = 378
  547. const OFFSET_PARA_AMMO = 379
  548. const OFFSET_FAMAS_AMMO = 380
  549. const OFFSET_M3_AMMO = 381
  550. const OFFSET_USP_AMMO = 382
  551. const OFFSET_FIVESEVEN_AMMO = 383
  552. const OFFSET_DEAGLE_AMMO = 384
  553. const OFFSET_P228_AMMO = 385
  554. const OFFSET_GLOCK_AMMO = 386
  555. const OFFSET_FLASH_AMMO = 387
  556. const OFFSET_HE_AMMO = 388
  557. const OFFSET_SMOKE_AMMO = 389
  558. const OFFSET_C4_AMMO = 390
  559. const OFFSET_CLIPAMMO = 51
  560. #else
  561. const OFFSET_CSTEAMS = 139
  562. const OFFSET_CSMONEY = 140
  563. const OFFSET_NVGOGGLES = 155
  564. const OFFSET_ZOOMTYPE = 402
  565. const OFFSET_CSDEATHS = 493
  566. const OFFSET_AWM_AMMO = 426
  567. const OFFSET_SCOUT_AMMO = 427
  568. const OFFSET_PARA_AMMO = 428
  569. const OFFSET_FAMAS_AMMO = 429
  570. const OFFSET_M3_AMMO = 430
  571. const OFFSET_USP_AMMO = 431
  572. const OFFSET_FIVESEVEN_AMMO = 432
  573. const OFFSET_DEAGLE_AMMO = 433
  574. const OFFSET_P228_AMMO = 434
  575. const OFFSET_GLOCK_AMMO = 435
  576. const OFFSET_FLASH_AMMO = 46
  577. const OFFSET_HE_AMMO = 437
  578. const OFFSET_SMOKE_AMMO = 438
  579. const OFFSET_C4_AMMO = 439
  580. const OFFSET_CLIPAMMO = 65
  581. #endif
  582. const OFFSET_LINUX = 5 // offsets 5 higher in Linux builds
  583. const OFFSET_LINUX_WEAPONS = 4 // weapon offsets are only 4 steps higher on Linux
  584.  
  585. // CS Teams
  586. enum
  587. {
  588. CS_TEAM_UNASSIGNED = 0,
  589. CS_TEAM_T,
  590. CS_TEAM_CT,
  591. CS_TEAM_SPECTATOR
  592. }
  593.  
  594. // Other consts
  595. const HIDE_MONEY = (1<<5)
  596. const ATTRIB_BOMB = (1<<1)
  597. const DMG_HEGRENADE = (1<<24)
  598. const CS_NO_ZOOM = 0x5A
  599.  
  600. // Max BP ammo for weapons
  601. new const MAXAMMO[] = { -1, 52, -1, 90, -1, 32, 1, 100, 90, -1, 120, 100, 100, 90, 90, 90, 100, 120,
  602. 30, 120, 200, 32, 90, 120, 90, -1, 35, 90, 90, -1, 100 }
  603.  
  604. // Max Clip for weapons
  605. new const MAXCLIP[] = { -1, 13, -1, 10, 1, 7, -1, 30, 30, 1, 30, 20, 25, 30, 35, 25, 12, 20,
  606. 10, 30, 100, 8, 30, 30, 20, 2, 7, 30, 30, -1, 50 }
  607.  
  608. // Amount of ammo to give when buying additional clips for weapons
  609. new const BUYAMMO[] = { -1, 13, -1, 30, -1, 8, -1, 12, 30, -1, 30, 50, 12, 30, 30, 30, 12, 30,
  610. 10, 30, 30, 8, 30, 30, 30, -1, 7, 30, 30, -1, 50 }
  611.  
  612. // Weapon bitsums
  613. const PRIMARY_WEAPONS_BIT_SUM = ((1<<CSW_SCOUT)|(1<<CSW_XM1014)|(1<<CSW_MAC10)|(1<<CSW_AUG)|(1<<CSW_UMP45)|(1<<CSW_SG550)|(1<<CSW_GALIL)|(1<<CSW_FAMAS)|(1<<CSW_AWP)|(1<<CSW_MP5NAVY)|(1<<CSW_M249)|(1<<CSW_M3)|(1<<CSW_M4A1)|(1<<CSW_TMP)|(1<<CSW_G3SG1)|(1<<CSW_SG552)|(1<<CSW_AK47)|(1<<CSW_P90))
  614. const SECONDARY_WEAPONS_BIT_SUM = ((1<<CSW_P228)|(1<<CSW_ELITE)|(1<<CSW_FIVESEVEN)|(1<<CSW_USP)|(1<<CSW_GLOCK18)|(1<<CSW_DEAGLE))
  615.  
  616. // Menu keys
  617. const KEYSMENU = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)
  618.  
  619. /*================================================================================
  620. [Global Variables]
  621. =================================================================================*/
  622.  
  623. // Stupid compiler
  624. #pragma unused g_models_i
  625.  
  626. // Player vars
  627. new g_zombie[33] // is zombie
  628. new g_nemesis[33] // is nemesis
  629. new g_survivor[33] // is surivor
  630. new g_firstzombie[33] // is the first zombie
  631. new g_lastzombie[33] // is last zombie
  632. new g_lasthuman[33] // is last human
  633. new g_frozen[33] // is frozen (can't move)
  634. new g_nodamage[33] // has spawn protection/zombie madness
  635. new g_respawn_as_zombie[33] // should respawn as zombie
  636. new g_nvision[33] // has night vision
  637. new g_nvisionenabled[33] // has night vision turned on
  638. new g_zombieclass[33] // zombie class
  639. new g_zombieclassnext[33] // zombie class for next infection
  640. new g_flashlight[33] // has custom flashlight turned on
  641. new g_flashbattery[33] = { 100, ... } // custom flashlight battery
  642. new g_currentweapon[33] // current weapon the player is holding
  643. new g_canbuy[33] // is allowed to buy a new weapon through the menu
  644. new g_ammopacks[33] // ammo pack count
  645. new g_damagedealt[33] // damage dealt to zombies (used to calculate ammo packs reward)
  646. new g_spec_target[33] // last spectator target (for game nvg fix)
  647. new g_spec_first_person[33] // was player spectating on first person (for game nvg fix)
  648. new g_restorevel[33], Float:g_velocity[33][3] // Pain Shock Free vars
  649. new g_switchingteam[33] // is switching team
  650. new g_firstspawnignored[33] // whether first Ham_Spawn was ignored for this player
  651. new g_playermodel[33][33] // current model's short name [player][model]
  652.  
  653. // Game vars
  654. new g_newround // new round starting
  655. new g_endround // round ended
  656. new g_nemround // nemesis round
  657. new g_survround // survivor round
  658. new g_swarmround // swarm round
  659. new g_scorezombies, g_scorehumans // team scores
  660. new g_spawnCount // available spawn points count
  661. new Float:g_spawns[128][3] // spawn points data
  662. new g_lights_i // lightning current lights counter
  663. new Float:g_models_i // delay between Model Change messages
  664. new Float:g_teams_i // delay between Team Change messages
  665. new g_MsgSync, g_MsgSync2 // message sync objects
  666. new g_trailSpr, g_exploSpr, g_flameSpr, g_smokeSpr, g_glassSpr // grenade sprites
  667. new g_modname[32]
  668. new g_maxplayers // max players count
  669. new g_czero // whether we are running on a CZ server
  670. new g_hamczbots // whether ham forwards are registered for CZ bots
  671. new g_fwSpawn // spawn forward handle
  672. new g_menu_item[33][2] // starting indices for player list menus
  673.  
  674. // Some forward handlers
  675. new g_fwRoundStart, g_fwRoundEnd, g_fwUserInfected_pre, g_fwUserInfected_post,
  676. g_fwUserHumanized_pre, g_fwUserHumanized_post, g_fwDummyResult
  677.  
  678. // Database vars (used to save players stats in case they get disconnected)
  679. new db_name[100][64] // player name [slot id][player name]
  680. new db_ammopacks[100] // ammo pack count [slot id]
  681. new db_zombieclass[100] // zombie class [slot id]
  682. new db_slot_i // additional saved slots count (should start on maxplayers+1)
  683.  
  684. // Message IDs vars
  685. new g_msgScoreInfo, g_msgNVGToggle, g_msgScoreAttrib, g_msgAmmoPickup,
  686. g_msgScreenFade, g_msgDeathMsg, g_msgSetFOV, g_msgFlashlight, g_msgFlashBat,
  687. g_msgSendAudio, g_msgTeamInfo, g_msgDamage
  688.  
  689. // CVAR pointers
  690. new cvar_zombiehp, cvar_zombiefirsthp, cvar_zombiespeed, cvar_lighting, cvar_zombiegravity,
  691. cvar_removemoney, cvar_thunder, cvar_zombiefov, cvar_zombiebonushp, cvar_zombiefirstleap,
  692. cvar_nem, cvar_nemchance, cvar_nemhp, cvar_nemglow, cvar_surv, cvar_cnvg, cvar_nemleap,
  693. cvar_nemgravity, cvar_flashsize, cvar_ammodamage, cvar_zombiearmor, cvar_deathmatch,
  694. cvar_nempainfree, cvar_nemspd, cvar_survchance, cvar_survhp, cvar_survspd, cvar_humanspd,
  695. cvar_swarmchance, cvar_flashdrain, cvar_zombiebleeding, cvar_removedoors, cvar_survpainfree,
  696. cvar_randspawn, cvar_multi, cvar_multichance, cvar_infammo, cvar_swarm, cvar_ammoinfect,
  697. cvar_zombiepainfree, cvar_knockbackpower, cvar_freezeduration, cvar_triggered, cvar_survleap,
  698. cvar_firegrenades, cvar_frostgrenades, cvar_survgravity, cvar_humanhp, cvar_logcommands,
  699. cvar_humangravity, cvar_spawnprotection, cvar_nvgsize, cvar_flareduration, cvar_zclasses,
  700. cvar_extraitems, cvar_showactivity, cvar_humanlasthp, cvar_nemignorefrags, cvar_warmup,
  701. cvar_flashdist, cvar_flarecolor, cvar_survignorefrags, cvar_fireduration, cvar_firedamage,
  702. cvar_flaregrenades, cvar_knockbackducking, cvar_knockbackdamage, cvar_knockbackzvel,
  703. cvar_multiratio, cvar_flaresize, cvar_spawndelay, cvar_extra_antidote, cvar_survglow,
  704. cvar_extra_weapons, cvar_extra_nvision, cvar_extra_madness, cvar_dropwpn, cvar_survaura,
  705. cvar_botquota, cvar_buycustom, cvar_toggle, cvar_fireslowdown, cvar_blockpushables,
  706. cvar_nvggive, cvar_nemignoreammo, cvar_survignoreammo, cvar_nemaura, cvar_extra_infbomb,
  707. cvar_cflash, cvar_knockback, cvar_nemnvgcolor[3], cvar_flashcolor[3], cvar_nvgcolor[3]
  708.  
  709. /*================================================================================
  710. [Natives, Precache and Init]
  711. =================================================================================*/
  712.  
  713. public plugin_natives()
  714. {
  715. // Player specific natives
  716. register_native("zp_get_user_zombie", "native_get_user_zombie", 1)
  717. register_native("zp_get_user_nemesis", "native_get_user_nemesis", 1)
  718. register_native("zp_get_user_survivor", "native_get_user_survivor", 1)
  719. register_native("zp_get_user_first_zombie", "native_get_user_first_zombie", 1)
  720. register_native("zp_get_user_last_zombie", "native_get_user_last_zombie", 1)
  721. register_native("zp_get_user_last_human", "native_get_user_last_human", 1)
  722. register_native("zp_get_user_zombie_class", "native_get_user_zombie_class", 1)
  723. register_native("zp_get_user_ammo_packs", "native_get_user_ammo_packs", 1)
  724. register_native("zp_set_user_ammo_packs", "native_set_user_ammo_packs", 1)
  725. register_native("zp_get_zombie_maxhealth", "native_get_zombie_maxhealth", 1)
  726.  
  727. // Round natives
  728. register_native("zp_has_round_started", "native_has_round_started", 1)
  729. register_native("zp_is_nemesis_round", "native_is_nemesis_round", 1)
  730. register_native("zp_is_survivor_round", "native_is_survivor_round", 1)
  731. register_native("zp_is_swarm_round", "native_is_swarm_round", 1)
  732. }
  733.  
  734. public plugin_precache()
  735. {
  736. // To switch plugin on/off
  737. register_concmd("zp_toggle", "cmd_toggle", ACCESS_FLAG2, "<1/0> - Enable/Disable Zombie Plague (will restart the current map)")
  738. cvar_toggle = register_cvar("zp_on", "1")
  739.  
  740. // Plugin disabled?
  741. if (!get_pcvar_num(cvar_toggle)) return;
  742.  
  743. new i, playermodel[100]
  744.  
  745. // Custom player models
  746. for (i = 0; i < sizeof model_zombie_class1; i++)
  747. {
  748. formatex(playermodel, sizeof playermodel - 1, "models/player/%s/%s.mdl", model_zombie_class1[i], model_zombie_class1[i])
  749. engfunc(EngFunc_PrecacheModel, playermodel)
  750. }
  751. for (i = 0; i < sizeof model_zombie_class2; i++)
  752. {
  753. formatex(playermodel, sizeof playermodel - 1, "models/player/%s/%s.mdl", model_zombie_class2[i], model_zombie_class2[i])
  754. engfunc(EngFunc_PrecacheModel, playermodel)
  755. }
  756. for (i = 0; i < sizeof model_zombie_class3; i++)
  757. {
  758. formatex(playermodel, sizeof playermodel - 1, "models/player/%s/%s.mdl", model_zombie_class3[i], model_zombie_class3[i])
  759. engfunc(EngFunc_PrecacheModel, playermodel)
  760. }
  761. for (i = 0; i < sizeof model_zombie_class4; i++)
  762. {
  763. formatex(playermodel, sizeof playermodel - 1, "models/player/%s/%s.mdl", model_zombie_class4[i], model_zombie_class4[i])
  764. engfunc(EngFunc_PrecacheModel, playermodel)
  765. }
  766. for (i = 0; i < sizeof model_zombie_class5; i++)
  767. {
  768. formatex(playermodel, sizeof playermodel - 1, "models/player/%s/%s.mdl", model_zombie_class5[i], model_zombie_class5[i])
  769. engfunc(EngFunc_PrecacheModel, playermodel)
  770. }
  771. for (i = 0; i < sizeof model_zombie_class6; i++)
  772. {
  773. formatex(playermodel, sizeof playermodel - 1, "models/player/%s/%s.mdl", model_zombie_class6[i], model_zombie_class6[i])
  774. engfunc(EngFunc_PrecacheModel, playermodel)
  775. }
  776. for (i = 0; i < sizeof model_nemesis; i++)
  777. {
  778. formatex(playermodel, sizeof playermodel - 1, "models/player/%s/%s.mdl", model_nemesis[i], model_nemesis[i])
  779. engfunc(EngFunc_PrecacheModel, playermodel)
  780. }
  781. for (i = 0; i < sizeof model_human; i++)
  782. {
  783. formatex(playermodel, sizeof playermodel - 1, "models/player/%s/%s.mdl", model_human[i], model_human[i])
  784. engfunc(EngFunc_PrecacheModel, playermodel)
  785. }
  786. for (i = 0; i < sizeof model_admin; i++)
  787. {
  788. formatex(playermodel, sizeof playermodel - 1, "models/player/%s/%s.mdl", model_admin[i], model_admin[i])
  789. engfunc(EngFunc_PrecacheModel, playermodel)
  790. }
  791.  
  792. // Custom weapon models
  793. engfunc(EngFunc_PrecacheModel, model_vknife_zombie)
  794. engfunc(EngFunc_PrecacheModel, model_pknife_zombie)
  795. engfunc(EngFunc_PrecacheModel, model_vknife_nemesis)
  796. engfunc(EngFunc_PrecacheModel, model_pknife_nemesis)
  797. engfunc(EngFunc_PrecacheModel, model_grenade_infect)
  798. engfunc(EngFunc_PrecacheModel, model_grenade_fire)
  799. engfunc(EngFunc_PrecacheModel, model_grenade_frost)
  800. engfunc(EngFunc_PrecacheModel, model_grenade_flare)
  801.  
  802. // Custom sounds
  803. for (i = 0; i < sizeof sound_thunder; i++)
  804. engfunc(EngFunc_PrecacheSound, sound_thunder[i])
  805. for (i = 0; i < sizeof zombie_idle; i++)
  806. engfunc(EngFunc_PrecacheSound, zombie_idle[i])
  807. for (i = 0; i < sizeof zombie_idle_last; i++)
  808. engfunc(EngFunc_PrecacheSound, zombie_idle_last[i])
  809. for (i = 0; i < sizeof zombie_infect; i++)
  810. engfunc(EngFunc_PrecacheSound, zombie_infect[i])
  811. for (i = 0; i < sizeof zombie_die; i++)
  812. engfunc(EngFunc_PrecacheSound, zombie_die[i])
  813. for (i = 0; i < sizeof zombie_pain; i++)
  814. engfunc(EngFunc_PrecacheSound, zombie_pain[i])
  815. for (i = 0; i < sizeof nemesis_pain; i++)
  816. engfunc(EngFunc_PrecacheSound, nemesis_pain[i])
  817. for (i = 0; i < sizeof zombie_fall; i++)
  818. engfunc(EngFunc_PrecacheSound, zombie_fall[i])
  819. for (i = 0; i < sizeof zombie_madness; i++)
  820. engfunc(EngFunc_PrecacheSound, zombie_madness[i])
  821. for (i = 0; i < sizeof sound_nemesis; i++)
  822. engfunc(EngFunc_PrecacheSound, sound_nemesis[i])
  823. for (i = 0; i < sizeof sound_survivor; i++)
  824. engfunc(EngFunc_PrecacheSound, sound_survivor[i])
  825. for (i = 0; i < sizeof sound_swarm; i++)
  826. engfunc(EngFunc_PrecacheSound, sound_swarm[i])
  827. for (i = 0; i < sizeof sound_multi; i++)
  828. engfunc(EngFunc_PrecacheSound, sound_multi[i])
  829. for (i = 0; i < sizeof grenade_infect; i++)
  830. engfunc(EngFunc_PrecacheSound, grenade_infect[i])
  831. for (i = 0; i < sizeof grenade_infect_player; i++)
  832. engfunc(EngFunc_PrecacheSound, grenade_infect_player[i])
  833. for (i = 0; i < sizeof grenade_fire; i++)
  834. engfunc(EngFunc_PrecacheSound, grenade_fire[i])
  835. for (i = 0; i < sizeof grenade_fire_player; i++)
  836. engfunc(EngFunc_PrecacheSound, grenade_fire_player[i])
  837. for (i = 0; i < sizeof grenade_frost; i++)
  838. engfunc(EngFunc_PrecacheSound, grenade_frost[i])
  839. for (i = 0; i < sizeof grenade_frost_player; i++)
  840. engfunc(EngFunc_PrecacheSound, grenade_frost_player[i])
  841. for (i = 0; i < sizeof grenade_frost_break; i++)
  842. engfunc(EngFunc_PrecacheSound, grenade_frost_break[i])
  843. for (i = 0; i < sizeof grenade_flare; i++)
  844. engfunc(EngFunc_PrecacheSound, grenade_flare[i])
  845. for (i = 0; i < sizeof sound_antidote; i++)
  846. engfunc(EngFunc_PrecacheSound, sound_antidote[i])
  847. #if defined AMBIENCE_SOUNDS
  848. for (i = 0; i < sizeof sound_ambience; i++)
  849. engfunc(EngFunc_PrecacheSound, sound_ambience[i])
  850. #endif
  851.  
  852. // Custom models/sprites for grenades
  853. g_trailSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_trail)
  854. g_exploSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_ring)
  855. g_flameSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_fire)
  856. g_smokeSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_smoke)
  857. g_glassSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_glass)
  858.  
  859. #if defined AMBIENCE_FOG
  860. new ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "env_fog"))
  861. fm_set_kvd(ent, "density", FOG_DENSITY, "env_fog")
  862. fm_set_kvd(ent, "rendercolor", FOG_COLOR, "env_fog")
  863. #endif
  864.  
  865. #if defined AMBIENCE_RAIN
  866. engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "env_rain"))
  867. #endif
  868.  
  869. #if defined AMBIENCE_SNOW
  870. engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "env_snow"))
  871. #endif
  872.  
  873. // Fake BombSite (to force round ending)
  874. engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_bomb_target"))
  875.  
  876. // Prevent some entities from spawning
  877. g_fwSpawn = register_forward(FM_Spawn, "fw_Spawn")
  878. }
  879.  
  880. public plugin_init()
  881. {
  882. // Register plugin call
  883. register_plugin("Zombie Plague", PLUGIN_VERSION, "MeRcyLeZZ")
  884.  
  885. // Plugin disabled?
  886. if (!get_pcvar_num(cvar_toggle)) return;
  887.  
  888. // Language files
  889. register_dictionary("zombie_plague.txt")
  890.  
  891. // Events
  892. register_event("HLTV", "event_round_start", "a", "1=0", "2=0")
  893. register_logevent("event_round_end", 2, "1=Round_End")
  894. register_event("SpecHealth2", "event_spect_target", "bd")
  895. register_event("TextMsg", "event_spect_mode", "b")
  896.  
  897. // Forwards
  898. RegisterHam(Ham_Spawn, "player", "fw_PlayerSpawn", 1)
  899. RegisterHam(Ham_Killed, "player", "fw_Killed")
  900. RegisterHam(Ham_TakeDamage, "player", "fw_TakeDamage")
  901. RegisterHam(Ham_TraceAttack, "player", "fw_TraceAttack")
  902. RegisterHam(Ham_Use, "func_tank", "fw_UseStationary")
  903. RegisterHam(Ham_Use, "func_tankmortar", "fw_UseStationary")
  904. RegisterHam(Ham_Use, "func_tankrocket", "fw_UseStationary")
  905. RegisterHam(Ham_Use, "func_tanklaser", "fw_UseStationary")
  906. RegisterHam(Ham_Use, "func_pushable", "fw_PushBox")
  907. RegisterHam(Ham_Touch, "weaponbox", "fw_WeaponTouch")
  908. RegisterHam(Ham_Touch, "armoury_entity", "fw_WeaponTouch")
  909. RegisterHam(Ham_Touch, "weapon_shield", "fw_WeaponTouch")
  910. register_forward(FM_EmitSound, "fw_EmitSound")
  911. #if !defined HANDLE_MODELS_ON_SEPARATE_ENT
  912. register_forward(FM_SetClientKeyValue, "fw_SetClientKeyValue")
  913. register_forward(FM_ClientUserInfoChanged, "fw_ClientUserInfoChanged")
  914. #endif
  915. register_forward(FM_GetGameDescription, "fw_GameDesc")
  916. register_forward(FM_CmdStart, "fw_CmdStart")
  917. register_forward(FM_CreateNamedEntity, "fw_CreateNamedEntity")
  918. register_forward(FM_SetModel, "fw_SetModel")
  919. register_forward(FM_PlayerPreThink, "fw_PreThink")
  920. register_forward(FM_PlayerPreThink, "fw_PreThink_Post", 1)
  921. unregister_forward(FM_Spawn, g_fwSpawn)
  922.  
  923. // Client commands
  924. register_clcmd("say", "clcmd_say")
  925. register_clcmd("say_team", "clcmd_say")
  926. register_clcmd("nightvision", "clcmd_nvgtoggle")
  927. register_clcmd("drop", "clcmd_drop")
  928. register_clcmd("buyammo1", "clcmd_buyammo")
  929. register_clcmd("buyammo2", "clcmd_buyammo")
  930. register_clcmd("chooseteam", "clcmd_changeteam")
  931. register_clcmd("jointeam", "clcmd_changeteam")
  932.  
  933. // Menus
  934. register_menu("Buy Menu 1", KEYSMENU, "menu_buy1")
  935. register_menu("Buy Menu 2", KEYSMENU, "menu_buy2")
  936. register_menu("Zombie Menu", KEYSMENU, "menu_zombie")
  937. register_menu("Game Menu", KEYSMENU, "menu_game")
  938. register_menu("Extra Items", KEYSMENU, "menu_extras")
  939. register_menu("Mod Info", KEYSMENU, "menu_info")
  940. register_menu("Admin Menu", KEYSMENU, "menu_admin")
  941. register_menu("Player List Menu", KEYSMENU, "menu_player_list")
  942.  
  943. // Admin commands
  944. register_concmd("zp_zombie", "cmd_zombie", ACCESS_FLAG, "<name> - Turn someone into a Zombie")
  945. register_concmd("zp_human", "cmd_human", ACCESS_FLAG, "<name> - Turn someone back to Human")
  946. register_concmd("zp_nemesis", "cmd_nemesis", ACCESS_FLAG, "<name> - Turn someone into a Nemesis")
  947. register_concmd("zp_survivor", "cmd_survivor", ACCESS_FLAG, "<name> - Turn someone into a Survivor")
  948. register_concmd("zp_respawn", "cmd_respawn", ACCESS_FLAG, "<name> - Respawn someone")
  949. register_concmd("zp_swarm", "cmd_swarm", ACCESS_FLAG, " - Start Swarm Mode")
  950. register_concmd("zp_multi", "cmd_multi", ACCESS_FLAG, " - Start Multi Infection")
  951.  
  952. // Message IDs
  953. g_msgScoreInfo = get_user_msgid("ScoreInfo")
  954. g_msgTeamInfo = get_user_msgid("TeamInfo")
  955. g_msgDeathMsg = get_user_msgid("DeathMsg")
  956. g_msgScoreAttrib = get_user_msgid("ScoreAttrib")
  957. g_msgSetFOV = get_user_msgid("SetFOV")
  958. g_msgScreenFade = get_user_msgid("ScreenFade")
  959. g_msgNVGToggle = get_user_msgid("NVGToggle")
  960. g_msgFlashlight = get_user_msgid("Flashlight")
  961. g_msgFlashBat = get_user_msgid("FlashBat")
  962. g_msgAmmoPickup = get_user_msgid("AmmoPickup")
  963. g_msgSendAudio = get_user_msgid("SendAudio")
  964. g_msgDamage = get_user_msgid("Damage")
  965.  
  966. // Message hooks
  967. register_message(get_user_msgid("CurWeapon"), "message_cur_weapon")
  968. register_message(get_user_msgid("Money"), "message_money")
  969. register_message(get_user_msgid("Health"), "message_health")
  970. register_message(get_user_msgid("HideWeapon"), "message_hideweapon")
  971. register_message(g_msgFlashBat, "message_flashbat")
  972. register_message(g_msgScreenFade, "message_screenfade")
  973. register_message(g_msgScoreAttrib, "message_scoreattrib")
  974. register_message(get_user_msgid("StatusIcon"), "message_statusicon")
  975. #if defined HANDLE_MODELS_ON_SEPARATE_ENT
  976. register_message(get_user_msgid("ClCorpse"), "message_clcorpse")
  977. #endif
  978. register_message(get_user_msgid("WeapPickup"), "message_weappickup")
  979. register_message(g_msgAmmoPickup, "message_ammopickup")
  980. register_message(get_user_msgid("Scenario"), "message_scenario")
  981. register_message(get_user_msgid("HostagePos"), "message_hostagepos")
  982. register_message(get_user_msgid("BombDrop"), "message_bombdrop")
  983. register_message(get_user_msgid("TextMsg"), "message_textmsg")
  984. register_message(g_msgSendAudio, "message_sendaudio")
  985. register_message(get_user_msgid("TeamScore"), "message_teamscore")
  986. register_message(g_msgTeamInfo, "message_teaminfo")
  987.  
  988. // CVARS - General Purpose
  989. cvar_warmup = register_cvar("zp_delay", "10")
  990. cvar_lighting = register_cvar("zp_lighting", "a")
  991. cvar_thunder = register_cvar("zp_thunderclap", "90")
  992. cvar_triggered = register_cvar("zp_triggered_lights", "1")
  993. cvar_removedoors = register_cvar("zp_remove_doors", "0")
  994. cvar_blockpushables = register_cvar("zp_blockuse_pushables", "1")
  995. cvar_deathmatch = register_cvar("zp_deathmatch", "0")
  996. cvar_spawndelay = register_cvar("zp_spawn_delay", "5")
  997. cvar_spawnprotection = register_cvar("zp_spawn_protection", "5")
  998. cvar_randspawn = register_cvar("zp_random_spawn", "1")
  999. cvar_removemoney = register_cvar("zp_remove_money", "1")
  1000. cvar_buycustom = register_cvar("zp_buy_custom", "1")
  1001. cvar_zclasses = register_cvar("zp_zombie_classes", "1")
  1002.  
  1003. // CVARS - Extra Items
  1004. cvar_extraitems = register_cvar("zp_extra_items", "1")
  1005. cvar_extra_weapons = register_cvar("zp_extra_weapons", "1")
  1006. cvar_extra_nvision = register_cvar("zp_extra_nvision", "1")
  1007. cvar_extra_antidote = register_cvar("zp_extra_antidote", "1")
  1008. cvar_extra_madness = register_cvar("zp_extra_madness", "1")
  1009. cvar_extra_infbomb = register_cvar("zp_extra_infbomb", "1")
  1010.  
  1011. // CVARS - Flashlight and Nightvision
  1012. cvar_nvggive = register_cvar("zp_nvg_give", "1")
  1013. cvar_cnvg = register_cvar("zp_nvg_custom", "1")
  1014. cvar_nvgsize = register_cvar("zp_nvg_size", "80")
  1015. cvar_nvgcolor[0] = register_cvar("zp_nvg_color_R", "0")
  1016. cvar_nvgcolor[1] = register_cvar("zp_nvg_color_G", "150")
  1017. cvar_nvgcolor[2] = register_cvar("zp_nvg_color_B", "0")
  1018. cvar_nemnvgcolor[0] = register_cvar("zp_nvg_nem_color_R", "150")
  1019. cvar_nemnvgcolor[1] = register_cvar("zp_nvg_nem_color_G", "0")
  1020. cvar_nemnvgcolor[2] = register_cvar("zp_nvg_nem_color_B", "0")
  1021. cvar_cflash = register_cvar("zp_flash_custom", "0")
  1022. cvar_flashsize = register_cvar("zp_flash_size", "10")
  1023. cvar_flashdrain = register_cvar("zp_flash_drain", "1")
  1024. cvar_flashdist = register_cvar("zp_flash_distance", "1000")
  1025. cvar_flashcolor[0] = register_cvar("zp_flash_color_R", "100")
  1026. cvar_flashcolor[1] = register_cvar("zp_flash_color_G", "100")
  1027. cvar_flashcolor[2] = register_cvar("zp_flash_color_B", "100")
  1028.  
  1029. // CVARS - Knockback
  1030. cvar_knockback = register_cvar("zp_knockback", "0")
  1031. cvar_knockbackdamage = register_cvar("zp_knockback_damage", "1")
  1032. cvar_knockbackpower = register_cvar("zp_knockback_power", "1")
  1033. cvar_knockbackzvel = register_cvar("zp_knockback_zvel", "0")
  1034. cvar_knockbackducking = register_cvar("zp_knockback_ducking", "0")
  1035.  
  1036. // CVARS - Humans
  1037. cvar_humanhp = register_cvar("zp_human_health", "100")
  1038. cvar_humanlasthp = register_cvar("zp_human_last_extrahp", "0")
  1039. cvar_humanspd = register_cvar("zp_human_speed", "240")
  1040. cvar_humangravity = register_cvar("zp_human_gravity", "1.0")
  1041. cvar_infammo = register_cvar("zp_human_unlimited_ammo", "0")
  1042. cvar_dropwpn = register_cvar("zp_human_drop_weapons", "2")
  1043. cvar_ammodamage = register_cvar("zp_human_damage_reward", "500")
  1044. cvar_firegrenades = register_cvar("zp_fire_grenades", "1")
  1045. cvar_fireduration = register_cvar("zp_fire_duration", "10")
  1046. cvar_firedamage = register_cvar("zp_fire_damage", "5")
  1047. cvar_fireslowdown = register_cvar("zp_fire_slowdown", "0.5")
  1048. cvar_frostgrenades = register_cvar("zp_frost_grenades", "1")
  1049. cvar_freezeduration = register_cvar("zp_frost_duration", "3")
  1050. cvar_flaregrenades = register_cvar("zp_flare_grenades","1")
  1051. cvar_flareduration = register_cvar("zp_flare_duration", "60")
  1052. cvar_flaresize = register_cvar("zp_flare_size", "25")
  1053. cvar_flarecolor = register_cvar("zp_flare_color", "0")
  1054.  
  1055. // CVARS - Zombies
  1056. cvar_zombiehp = register_cvar("zp_zombie_health", "1800")
  1057. cvar_zombiefirsthp = register_cvar("zp_zombie_fhealth", "3600")
  1058. cvar_zombiearmor = register_cvar("zp_zombie_armor", "0.75")
  1059. cvar_zombiespeed = register_cvar("zp_zombie_speed", "190")
  1060. cvar_zombiegravity = register_cvar("zp_zombie_gravity", "1.0")
  1061. cvar_zombiebonushp = register_cvar("zp_zombie_infect_health", "100")
  1062. cvar_zombiefov = register_cvar("zp_zombie_fov", "110")
  1063. cvar_zombiefirstleap = register_cvar("zp_zombie_first_leap", "0")
  1064. cvar_zombiepainfree = register_cvar("zp_zombie_painfree", "2")
  1065. cvar_zombiebleeding = register_cvar("zp_zombie_bleeding", "1")
  1066. cvar_ammoinfect = register_cvar("zp_zombie_infect_reward", "1")
  1067.  
  1068. // CVARS - Nemesis
  1069. cvar_nem = register_cvar("zp_nem_enabled", "1")
  1070. cvar_nemchance = register_cvar("zp_nem_chance", "20")
  1071. cvar_nemhp = register_cvar("zp_nem_health", "0")
  1072. cvar_nemspd = register_cvar("zp_nem_speed", "250")
  1073. cvar_nemgravity = register_cvar("zp_nem_gravity", "0.5")
  1074. cvar_nemglow = register_cvar("zp_nem_glow", "1")
  1075. cvar_nemaura = register_cvar("zp_nem_aura", "1")
  1076. cvar_nemleap = register_cvar("zp_nem_leap", "1")
  1077. cvar_nempainfree = register_cvar("zp_nem_painfree", "0")
  1078. cvar_nemignorefrags = register_cvar("zp_nem_ignore_frags", "0")
  1079. cvar_nemignoreammo = register_cvar("zp_nem_ignore_rewards", "1")
  1080.  
  1081. // CVARS - Survivor
  1082. cvar_surv = register_cvar("zp_surv_enabled", "1")
  1083. cvar_survchance = register_cvar("zp_surv_chance", "20")
  1084. cvar_survhp = register_cvar("zp_surv_health", "0")
  1085. cvar_survspd = register_cvar("zp_surv_speed", "230")
  1086. cvar_survgravity = register_cvar("zp_surv_gravity", "1.25")
  1087. cvar_survglow = register_cvar("zp_surv_glow", "1")
  1088. cvar_survaura = register_cvar("zp_surv_aura", "1")
  1089. cvar_survleap = register_cvar("zp_surv_leap", "0")
  1090. cvar_survpainfree = register_cvar("zp_surv_painfree", "1")
  1091. cvar_survignorefrags = register_cvar("zp_surv_ignore_frags", "0")
  1092. cvar_survignoreammo = register_cvar("zp_surv_ignore_rewards", "1")
  1093.  
  1094. // CVARS - Swarm Mode
  1095. cvar_swarm = register_cvar("zp_swarm_enabled", "1")
  1096. cvar_swarmchance = register_cvar("zp_swarm_chance","20")
  1097.  
  1098. // CVARS - Multi Infection
  1099. cvar_multi = register_cvar("zp_multi_enabled", "1")
  1100. cvar_multichance = register_cvar("zp_multi_chance", "20")
  1101. cvar_multiratio = register_cvar("zp_multi_ratio", "0.15")
  1102.  
  1103. // CVARS - Others
  1104. cvar_logcommands = register_cvar("zp_logcommands", "1")
  1105. cvar_showactivity = get_cvar_pointer("amx_show_activity")
  1106. cvar_botquota = get_cvar_pointer("bot_quota")
  1107. register_cvar("zp_version", PLUGIN_VERSION, FCVAR_SERVER|FCVAR_SPONLY)
  1108. set_cvar_string("zp_version", PLUGIN_VERSION)
  1109.  
  1110. // Custom Forwards
  1111. g_fwRoundStart = CreateMultiForward("zp_round_started", ET_CONTINUE, FP_CELL, FP_CELL)
  1112. g_fwRoundEnd = CreateMultiForward("zp_round_ended", ET_CONTINUE, FP_CELL)
  1113. g_fwUserInfected_pre = CreateMultiForward("zp_user_infected_pre", ET_CONTINUE, FP_CELL, FP_CELL)
  1114. g_fwUserInfected_post = CreateMultiForward("zp_user_infected_post", ET_CONTINUE, FP_CELL, FP_CELL)
  1115. g_fwUserHumanized_pre = CreateMultiForward("zp_user_humanized_pre", ET_CONTINUE, FP_CELL)
  1116. g_fwUserHumanized_post = CreateMultiForward("zp_user_humanized_post", ET_CONTINUE, FP_CELL)
  1117.  
  1118. // Check for CSDM spawns of the current map
  1119. new mapname[32], cfgdir[32], filepath[100], linedata[64]
  1120. get_configsdir(cfgdir, sizeof cfgdir - 1);
  1121. get_mapname(mapname, sizeof mapname - 1);
  1122. formatex(filepath, sizeof filepath - 1, "%s/csdm/%s.spawns.cfg", cfgdir, mapname);
  1123.  
  1124. // Load CSDM spawns if present
  1125. if (file_exists(filepath))
  1126. {
  1127. new csdmdata[10][6], file = fopen(filepath,"rt")
  1128.  
  1129. while (file && !feof(file))
  1130. {
  1131. fgets(file, linedata, sizeof linedata - 1);
  1132.  
  1133. // invalid spawn
  1134. if(!linedata[0] || str_count(linedata,' ') < 2) continue;
  1135.  
  1136. // get spawn point data
  1137. parse(linedata,csdmdata[0],5,csdmdata[1],5,csdmdata[2],5,csdmdata[3],5,csdmdata[4],5,csdmdata[5],5,csdmdata[6],5,csdmdata[7],5,csdmdata[8],5,csdmdata[9],5);
  1138.  
  1139. // origin
  1140. g_spawns[g_spawnCount][0] = floatstr(csdmdata[0]);
  1141. g_spawns[g_spawnCount][1] = floatstr(csdmdata[1]);
  1142. g_spawns[g_spawnCount][2] = floatstr(csdmdata[2]);
  1143.  
  1144. // increase spawn count
  1145. g_spawnCount++;
  1146. if (g_spawnCount >= sizeof g_spawns) break;
  1147. }
  1148. if (file) fclose(file);
  1149. }
  1150. else
  1151. {
  1152. // if not, collect regular spawns
  1153. collect_spawns("info_player_start")
  1154. collect_spawns("info_player_deathmatch")
  1155. }
  1156.  
  1157. // Execute config file (zombieplague.cfg)
  1158. server_cmd("exec %s/zombieplague.cfg", cfgdir)
  1159.  
  1160. // Set a random skybox
  1161. set_cvar_string("sv_skyname", skynames[random_num(0, sizeof skynames - 1)])
  1162.  
  1163. // Disable sky lighting so it doesn't mess up our custom lighting
  1164. set_cvar_num("sv_skycolor_r", 0)
  1165. set_cvar_num("sv_skycolor_g", 0)
  1166. set_cvar_num("sv_skycolor_b", 0)
  1167.  
  1168. // Create the HUD Sync Objects
  1169. g_MsgSync = CreateHudSyncObj()
  1170. g_MsgSync2 = CreateHudSyncObj()
  1171.  
  1172. // Format mod name
  1173. formatex(g_modname, sizeof g_modname - 1, "Zombie Plague %s", PLUGIN_VERSION)
  1174.  
  1175. // Get Max Players
  1176. g_maxplayers = get_maxplayers()
  1177.  
  1178. // Reserved saving slots starts on maxplayers+1
  1179. db_slot_i = g_maxplayers+1
  1180.  
  1181. // Check if it's a CZ server
  1182. new mymod[6]; get_modname(mymod, sizeof mymod - 1);
  1183. if (equal(mymod, "czero")) g_czero = 1;
  1184.  
  1185. // Lighting task
  1186. set_task(5.0, "lighting_effects", _, _, _, "b")
  1187.  
  1188. #if defined AMBIENCE_SOUNDS // Ambience sounds task
  1189. set_task(1.0, "ambience_sound_effects", 7331, _, _, "b")
  1190. #endif
  1191.  
  1192. // Call Round Start
  1193. set_task(1.0, "event_round_start");
  1194. }
  1195.  
  1196. /*================================================================================
  1197. [Main Events]
  1198. =================================================================================*/
  1199.  
  1200. // Round Start Event
  1201. public event_round_start()
  1202. {
  1203. // Remove all tasks bound to custom nades (since they're removed on new round)
  1204. remove_task(NADES_TASK);
  1205.  
  1206. // Remove doors and/or lights
  1207. set_task(0.2, "remove_stuff")
  1208.  
  1209. // New round starting
  1210. g_newround = true
  1211. g_endround = false
  1212. g_survround = false
  1213. g_nemround = false
  1214. g_swarmround = false
  1215. g_teams_i = 0.0 // reset team change count
  1216. g_models_i = 0.0 // reset model change count
  1217.  
  1218. // Show welcome message and T-Virus notice
  1219. remove_task(WELCOMEMSG_TASK)
  1220. set_task(2.0, "welcome_msg", WELCOMEMSG_TASK)
  1221.  
  1222. // Set a new "Make Zombie Task"
  1223. remove_task(MAKEZOMBIE_TASK)
  1224. set_task(2.0+random_float(get_pcvar_float(cvar_warmup), get_pcvar_float(cvar_warmup)+3.0), "make_zombie_task", MAKEZOMBIE_TASK)
  1225. }
  1226.  
  1227. // Round End Event
  1228. public event_round_end()
  1229. {
  1230. // Save player's stats on round end
  1231. static id
  1232. for (id = 1; id <= g_maxplayers; id++)
  1233. {
  1234. if (!is_user_connected(id))
  1235. continue; // skip if not connected
  1236.  
  1237. if (fm_get_user_team(id) == CS_TEAM_SPECTATOR || fm_get_user_team(id) == CS_TEAM_UNASSIGNED)
  1238. continue; // skip if not playing
  1239.  
  1240. save_stats(id)
  1241. }
  1242.  
  1243. // Round ended
  1244. g_endround = true
  1245. g_teams_i = 0.0 // reset teams change count
  1246. g_models_i = 0.0 // reset model change count
  1247.  
  1248. // Stop old tasks (if any)
  1249. remove_task(WELCOMEMSG_TASK)
  1250. remove_task(MAKEZOMBIE_TASK)
  1251.  
  1252. // Balance the teams
  1253. set_task(0.1, "balance_teams")
  1254.  
  1255. // Show HUD notice, play win sound, update team scores...
  1256. if (!fnGetZombies())
  1257. {
  1258. // Human team wins
  1259. set_hudmessage(0, 0, 200, -1.0, 0.17, 0, 0.0, 3.0, 2.0, 1.0, -1)
  1260. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "WIN_HUMAN")
  1261.  
  1262. // Play win sound and increase score
  1263. PlaySound(sound_win_humans[random_num(0, sizeof sound_win_humans -1)])
  1264. g_scorehumans++
  1265.  
  1266. // Round end forward
  1267. ExecuteForward(g_fwRoundEnd, g_fwDummyResult, 2);
  1268. }
  1269. else if (!fnGetHumans())
  1270. {
  1271. // Zombie team wins
  1272. set_hudmessage(200, 0, 0, -1.0, 0.17, 0, 0.0, 3.0, 2.0, 1.0, -1)
  1273. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "WIN_ZOMBIE")
  1274.  
  1275. // Play win sound and increase score
  1276. PlaySound(sound_win_zombies[random_num(0, sizeof sound_win_zombies -1)])
  1277. g_scorezombies++
  1278.  
  1279. // Round end forward
  1280. ExecuteForward(g_fwRoundEnd, g_fwDummyResult, 1);
  1281. }
  1282. else
  1283. {
  1284. // No one wins
  1285. set_hudmessage(0, 200, 0, -1.0, 0.17, 0, 0.0, 3.0, 2.0, 1.0, -1)
  1286. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "WIN_NO_ONE")
  1287. PlaySound(sound_win_no_one[random_num(0, sizeof sound_win_no_one -1)])
  1288.  
  1289. // Round end forward
  1290. ExecuteForward(g_fwRoundEnd, g_fwDummyResult, 0);
  1291. }
  1292. }
  1293.  
  1294. // Event Spectator Mode
  1295. public event_spect_mode(id)
  1296. {
  1297. if (get_pcvar_num(cvar_cnvg)) // custom night vision isn't affected by this
  1298. return;
  1299.  
  1300. static specmode[12] // get text message string
  1301. read_data(2, specmode, sizeof specmode - 1)
  1302.  
  1303. if (!equal(specmode, "#Spec_Mode", 10)) // not a spectator mode event
  1304. return;
  1305.  
  1306. if (g_spec_first_person[id]) // if last mode was first person
  1307. {
  1308. if (g_nvisionenabled[id]) // and nvg was on
  1309. set_user_gnvision(id, 1); // we need to restore it
  1310. g_spec_first_person[id] = false;
  1311. }
  1312.  
  1313. if (specmode[10] == '4') // First Person Mode
  1314. g_spec_first_person[id] = true
  1315. }
  1316.  
  1317. // Event Spectator Target
  1318. public event_spect_target(id)
  1319. {
  1320. if (get_pcvar_num(cvar_cnvg) || !id) // custom night vision isn't affected by this
  1321. return;
  1322.  
  1323. // If previous target died and nvg was on
  1324. if (g_nvisionenabled[id] && !is_user_alive(g_spec_target[id]))
  1325. set_user_gnvision(id, 1); // we need to restore it
  1326.  
  1327. g_spec_target[id] = read_data(2); // update last spectator target
  1328. }
  1329.  
  1330. /*================================================================================
  1331. [Main Forwards]
  1332. =================================================================================*/
  1333.  
  1334. // Client disconnect
  1335. public client_disconnect(id)
  1336. {
  1337. // Plugin disabled?
  1338. if (!get_pcvar_num(cvar_toggle)) return;
  1339.  
  1340. // Check that we still have both humans and zombies to keep the round going
  1341. if (is_user_alive(id)) check_round(id);
  1342.  
  1343. // Save player stats
  1344. save_stats(id)
  1345.  
  1346. // Remove previous tasks
  1347. remove_task(id+TEAM_TASK)
  1348. remove_task(id+MODEL_TASK)
  1349. remove_task(id+FLASH_TASK)
  1350. remove_task(id+CHARGE_TASK)
  1351. remove_task(id+SPAWN_TASK)
  1352. remove_task(id+BLOOD_TASK)
  1353. remove_task(id+NVISION_TASK)
  1354. remove_task(id+SHOWHUD_TASK)
  1355.  
  1356. // Reset for next client
  1357. g_firstspawnignored[id] = false
  1358.  
  1359. // Last Zombie Check
  1360. set_task(0.1, "fnCheckLastZombie")
  1361. }
  1362.  
  1363. // Client joins the game
  1364. public client_putinserver(id)
  1365. {
  1366. // Plugin disabled?
  1367. if (!get_pcvar_num(cvar_toggle)) return;
  1368.  
  1369. // Initialize player vars
  1370. reset_vars(id, 1)
  1371.  
  1372. // Try load player stats
  1373. load_stats(id)
  1374.  
  1375. // Set the custom HUD display task
  1376. set_task(1.0, "ShowHUD", id+SHOWHUD_TASK, _, _, "b")
  1377.  
  1378. // CZ bots seem to use a different "classtype" for player entities
  1379. // (or something like that) which needs to be hooked separately
  1380. if (cvar_botquota && !g_hamczbots) set_task(0.1, "register_ham_czbots", id)
  1381. }
  1382.  
  1383. // Entity Spawn Forward
  1384. public fw_Spawn(entity)
  1385. {
  1386. // Get classname
  1387. static classname[32]
  1388. pev(entity, pev_classname, classname, sizeof classname - 1)
  1389.  
  1390. // Check whether it needs to be removed
  1391. static i
  1392. for (i = 0; i < sizeof g_objective_ents; i++)
  1393. {
  1394. if (equal(classname, g_objective_ents[i]))
  1395. {
  1396. engfunc(EngFunc_RemoveEntity, entity)
  1397. return FMRES_SUPERCEDE
  1398. }
  1399. }
  1400.  
  1401. return FMRES_IGNORED
  1402. }
  1403.  
  1404. // Ham Player Spawn Forward
  1405. public fw_PlayerSpawn(id)
  1406. {
  1407. if (!g_firstspawnignored[id]) // first Ham_Spawn should be always ignored
  1408. {
  1409. g_firstspawnignored[id] = true;
  1410. return;
  1411. }
  1412.  
  1413. if (!is_user_alive(id)) // not alive
  1414. return;
  1415.  
  1416. // Remove previous tasks
  1417. remove_task(id+SPAWN_TASK)
  1418. remove_task(id+TEAM_TASK)
  1419. remove_task(id+MODEL_TASK)
  1420. remove_task(id+BLOOD_TASK)
  1421. remove_task(id+FLASH_TASK)
  1422. remove_task(id+CHARGE_TASK)
  1423.  
  1424. // Spawn randomly?
  1425. if (get_pcvar_num(cvar_randspawn)) do_random_spawn(id)
  1426.  
  1427. // Respawn as zombie?
  1428. if (g_respawn_as_zombie[id] && !g_newround)
  1429. {
  1430. reset_vars(id, 0) // reset player vars
  1431. zombieme(id, 0, 0, 0) // make him zombie right away
  1432. return;
  1433. }
  1434.  
  1435. // Reset player vars
  1436. reset_vars(id, 0)
  1437.  
  1438. // Bots stuff
  1439. if (is_user_bot(id))
  1440. {
  1441. // Turn off NVG for bots
  1442. fm_set_bot_nvg(id, 0);
  1443.  
  1444. // Automatically buy extra items/weapons after first zombie is chosen
  1445. if (get_pcvar_num(cvar_extraitems))
  1446. {
  1447. if (g_newround) set_task(10.0+get_pcvar_float(cvar_warmup), "bot_buy_extras", id+SPAWN_TASK)
  1448. else set_task(10.0, "bot_buy_extras", id+SPAWN_TASK)
  1449. }
  1450. }
  1451.  
  1452. fm_set_user_health(id, get_pcvar_num(cvar_humanhp)) // set health
  1453. set_pev(id, pev_gravity, get_pcvar_float(cvar_humangravity)) // set gravity
  1454.  
  1455. #if defined HANDLE_MODELS_ON_SEPARATE_ENT
  1456.  
  1457. // Set the right model
  1458. if (get_user_flags(id) & ACCESS_FLAG)
  1459. copy(g_playermodel[id], 32, model_admin[random_num(0, sizeof model_admin -1)])
  1460. else
  1461. copy(g_playermodel[id], 32, model_human[random_num(0, sizeof model_human -1)])
  1462.  
  1463. fm_set_user_model_ent(id) // set model on player_model entity
  1464. fm_set_rendering(fm_find_ent_by_owner(-1, "player_model", id)); // remove glow on player_model entity
  1465. fm_set_rendering(id, kRenderFxNone, 255, 255, 255, kRenderTransTexture, 0) // make original player entity invisible
  1466.  
  1467. #else
  1468.  
  1469. // Set the right model, but check that we don't have it already
  1470. static currentmodel[33], already_has_model, i
  1471. already_has_model = false;
  1472. fm_get_user_model(id, currentmodel, sizeof currentmodel - 1); // get current model
  1473.  
  1474. if (get_user_flags(id) & ACCESS_FLAG)
  1475. {
  1476. for (i = 0; i < sizeof model_admin; i++)
  1477. if (equal(model_admin[i], currentmodel)) already_has_model = true;
  1478.  
  1479. if (!already_has_model) copy(g_playermodel[id], 32, model_admin[random_num(0, sizeof model_admin -1)])
  1480. }
  1481. else
  1482. {
  1483. for (i = 0; i < sizeof model_human; i++)
  1484. if (equal(model_human[i], currentmodel)) already_has_model = true;
  1485.  
  1486. if (!already_has_model) copy(g_playermodel[id], 32, model_human[random_num(0, sizeof model_human -1)])
  1487. }
  1488.  
  1489. if (!already_has_model) // need to change the model?
  1490. {
  1491. if (g_newround) // round start?
  1492. {
  1493. set_task(0.1+(MODELCHANGE_DELAY*2)+g_models_i, "fm_set_user_model", id+MODEL_TASK) // set model with a delay
  1494. g_models_i += MODELCHANGE_DELAY;
  1495. }
  1496. else
  1497. {
  1498. fm_set_user_model(id+MODEL_TASK) // set model instantly
  1499. }
  1500. }
  1501.  
  1502. fm_set_rendering(id); // remove glow
  1503.  
  1504. #endif
  1505.  
  1506. // Show custom buy menu?
  1507. if (get_pcvar_num(cvar_buycustom))
  1508. {
  1509. set_task(0.5, "show_menu_buy1", id+SPAWN_TASK);
  1510. set_task(10.5, "show_menu_buy1", id+SPAWN_TASK); // re-show in case it gets overlapped
  1511. }
  1512.  
  1513. // Respawn player in case he dies by worldspawn or something
  1514. set_task(5.0, "respawn_player", id+SPAWN_TASK)
  1515.  
  1516. // Enable spawn protection for humans spawning mid-round
  1517. if (!g_newround && get_pcvar_float(cvar_spawnprotection) > 0.0)
  1518. {
  1519. g_nodamage[id] = true; // dont take any damage
  1520. set_pev(id, pev_effects, pev(id, pev_effects) | EF_NODRAW) // make temporarily invisible
  1521. set_task(get_pcvar_float(cvar_spawnprotection), "remove_spawn_protection", id+SPAWN_TASK)
  1522. }
  1523.  
  1524. // Last Zombie Check
  1525. set_task(0.1, "fnCheckLastZombie")
  1526. }
  1527.  
  1528. // Ham Player Killed Forward
  1529. public fw_Killed(victim, attacker, shouldgib)
  1530. {
  1531. set_task(0.2, "spec_nvision", victim) // enable dead players nightvision
  1532. set_task(0.1, "fnCheckLastZombie") // Last Zombie Check
  1533.  
  1534. if (g_zombie[victim]) // stop bleeding/burning when killed
  1535. remove_task(victim+BLOOD_TASK)
  1536.  
  1537. if (g_nemesis[victim]) // nemesis explodes!
  1538. SetHamParamInteger(3, 2)
  1539.  
  1540. // Killed by a non-player entity or self killed
  1541. if (victim == attacker || !is_user_connected(attacker))
  1542. return;
  1543.  
  1544. // Ignore Nemesis/Survivor Frags?
  1545. if ((g_nemesis[attacker] && get_pcvar_num(cvar_nemignorefrags)) || (g_survivor[attacker] && get_pcvar_num(cvar_survignorefrags)))
  1546. RemoveFrags(attacker, victim)
  1547.  
  1548. // Zombie/nemesis killed human, reward ammo packs
  1549. if (g_zombie[attacker] && (!g_nemesis[attacker] || !get_pcvar_num(cvar_nemignoreammo)))
  1550. g_ammopacks[attacker] += get_pcvar_num(cvar_ammoinfect)
  1551.  
  1552. // Respawn if Deathmatch is enabled
  1553. if (get_pcvar_num(cvar_deathmatch))
  1554. {
  1555. set_task(get_pcvar_float(cvar_spawndelay), "respawn_player", victim+SPAWN_TASK)
  1556. if ((get_pcvar_num(cvar_deathmatch) == 2) || (get_pcvar_num(cvar_deathmatch) == 3 && random_num(0, 1)))
  1557. g_respawn_as_zombie[victim] = true // respawn as zombie
  1558. }
  1559. }
  1560.  
  1561. // Ham Take Damage Forward (inflictor = weapon)
  1562. public fw_TakeDamage(victim, inflictor, attacker, Float:damage, damage_type)
  1563. {
  1564. if (victim == attacker || !is_user_connected(attacker)) // non-player damage or self damage
  1565. return HAM_IGNORED
  1566.  
  1567. if (g_newround || g_endround) // new round starting or round ended, cant attack
  1568. return HAM_SUPERCEDE
  1569.  
  1570. if (g_nodamage[victim] || g_frozen[victim]) // victim shouldn't take damage or victim is frozen
  1571. return HAM_SUPERCEDE
  1572.  
  1573. if (g_zombie[attacker] == g_zombie[victim]) // prevent team killing
  1574. return HAM_SUPERCEDE
  1575.  
  1576. if (!g_zombie[attacker] && g_zombie[victim]) // human attacks zombie
  1577. {
  1578. if (!g_nemesis[victim]) // armor multiplier for the final damage on normal zombies
  1579. {
  1580. damage *= get_pcvar_float(cvar_zombiearmor)
  1581. SetHamParamFloat(4, damage)
  1582. }
  1583.  
  1584. // Reward ammo packs (survivor doesn't get any)
  1585. if (!g_survivor[attacker] || !get_pcvar_num(cvar_survignoreammo))
  1586. {
  1587. // Store damage dealt
  1588. g_damagedealt[attacker] += floatround(damage);
  1589.  
  1590. // Reward ammo packs for every [ammo damage] dealt
  1591. while (g_damagedealt[attacker] >= get_pcvar_num(cvar_ammodamage))
  1592. {
  1593. g_ammopacks[attacker]++
  1594. g_damagedealt[attacker] -= get_pcvar_num(cvar_ammodamage);
  1595. }
  1596. }
  1597.  
  1598. return HAM_IGNORED
  1599. }
  1600.  
  1601. if (g_nemesis[attacker] && !g_zombie[victim]) // nemesis one-hit kill
  1602. {
  1603. SetHamParamFloat(4, 255.0) // set a higher damage
  1604. return HAM_IGNORED
  1605. }
  1606.  
  1607. if (g_zombie[attacker] && !g_zombie[victim]) // zombie attacks human
  1608. {
  1609. if (damage_type & DMG_HEGRENADE) // prevent infection by HE grenade (bugfix)
  1610. return HAM_SUPERCEDE
  1611.  
  1612. if (g_swarmround || fnGetHumans() == 1) // last human or swarm round
  1613. {
  1614. return HAM_IGNORED // human is killed
  1615. }
  1616. else
  1617. {
  1618. SendDeathMsg(attacker, victim); // send death notice
  1619. FixDeadAttrib(victim) // fix the "dead" attrib on scoreboard
  1620. UpdateFrags(attacker, victim); // add corresponding frags and deaths
  1621.  
  1622. // Infect the victim
  1623. zombieme(victim, attacker, 0, 0)
  1624.  
  1625. // Ammo packs given to zombie for infection
  1626. g_ammopacks[attacker] += get_pcvar_num(cvar_ammoinfect)
  1627.  
  1628. // Attacker gets HP bonus for the infection
  1629. if (g_zombieclass[attacker] == ZCLASS_LEECH) // 3x bonus for leech zombie
  1630. fm_set_user_health(attacker, pev(attacker, pev_health)+(get_pcvar_num(cvar_zombiebonushp)*3))
  1631. else
  1632. fm_set_user_health(attacker, pev(attacker, pev_health)+get_pcvar_num(cvar_zombiebonushp))
  1633.  
  1634. return HAM_SUPERCEDE
  1635. }
  1636. }
  1637.  
  1638. return HAM_IGNORED
  1639. }
  1640.  
  1641. // Ham Trace Attack Forward
  1642. public fw_TraceAttack(victim, attacker, Float:damage, Float:direction[3], tracehandle, damagetype)
  1643. {
  1644. if (!get_pcvar_num(cvar_knockback)) // knockback disabled
  1645. return;
  1646.  
  1647. if (!(damagetype & DMG_BULLET)) // not bullet damage
  1648. return;
  1649.  
  1650. if (victim == attacker || !is_user_connected(attacker)) // non-player damage or self damage
  1651. return;
  1652.  
  1653. if (g_zombie[attacker] || !g_zombie[victim] || g_nemesis[victim]) // only for humans attacking a zombie
  1654. return;
  1655.  
  1656. if (!get_pcvar_num(cvar_knockbackducking) && (pev(victim, pev_flags) & FL_DUCKING)) // zombie is ducking
  1657. return;
  1658.  
  1659. // Get victim's velocity
  1660. static Float:velocity1[3], Float:velocity2[3]
  1661. pev(victim, pev_velocity, velocity1)
  1662. xs_vec_copy(velocity1, velocity2)
  1663.  
  1664. // Use damage on knockback calculation
  1665. if (get_pcvar_num(cvar_knockbackdamage))
  1666. xs_vec_mul_scalar(direction, damage, direction)
  1667.  
  1668. // Use weapon power on knockback calculation
  1669. if (get_pcvar_num(cvar_knockbackpower) && kb_weapon_power[g_currentweapon[attacker]] > 0.0)
  1670. xs_vec_mul_scalar(direction, kb_weapon_power[g_currentweapon[attacker]], direction)
  1671.  
  1672. // Add up the new vector
  1673. xs_vec_add(direction, velocity1, velocity1)
  1674.  
  1675. // Should knockback affect vertical velocity?
  1676. if (!get_pcvar_num(cvar_knockbackzvel))
  1677. velocity1[2] = velocity2[2]
  1678.  
  1679. // Set the knockback'd victim's velocity
  1680. set_pev(victim, pev_velocity, velocity1)
  1681. }
  1682.  
  1683. // Ham Use Stationary Gun Forward
  1684. public fw_UseStationary(entity, caller, activator, use_type)
  1685. {
  1686. if (!is_user_connected(caller)) // not a player
  1687. return HAM_IGNORED;
  1688.  
  1689. if (use_type == 2 && g_zombie[caller]) // prevent zombies from using stationary guns
  1690. return HAM_SUPERCEDE
  1691.  
  1692. if (use_type == 0) // someone stopped using stationary gun
  1693. set_task(0.1, "replace_models", caller); // replace weapon models (bugfix)
  1694.  
  1695. return HAM_IGNORED
  1696. }
  1697.  
  1698. // Ham Use Pushable
  1699. public fw_PushBox()
  1700. {
  1701. if (cvar_blockpushables) // prevent speed bug with boxes, etc.
  1702. return HAM_SUPERCEDE
  1703.  
  1704. return HAM_IGNORED
  1705. }
  1706.  
  1707. // Ham Weapon Touch Forward
  1708. public fw_WeaponTouch(weapon, id)
  1709. {
  1710. if (!is_user_connected(id)) // not a player
  1711. return HAM_IGNORED
  1712.  
  1713. if (g_zombie[id] || (g_survivor[id] && !is_user_bot(id))) // dont pickup weapons if zombie or survivor
  1714. return HAM_SUPERCEDE
  1715.  
  1716. return HAM_IGNORED
  1717. }
  1718.  
  1719. // Emit Sound Forward
  1720. public fw_EmitSound(id, channel, const sample[], Float:volume, Float:attn, flags, pitch)
  1721. {
  1722. if (!is_user_connected(id) || !g_zombie[id]) // replace these sounds for zombies only
  1723. return FMRES_IGNORED
  1724.  
  1725. if ((sample[7] == 'd' && sample[8] == 'i' && sample[9] == 'e') || (sample[7] == 'd' && sample[8] == 'e' && sample[9] == 'a') || (sample[10] == 'd' && sample[11] == 'i' && sample[12] == 'e')) // die
  1726. {
  1727. engfunc(EngFunc_EmitSound, id, channel, zombie_die[random_num(0, sizeof zombie_die - 1)], volume, attn, flags, pitch)
  1728. return FMRES_SUPERCEDE
  1729. }
  1730.  
  1731. if (sample[7] == 'b' && sample[8] == 'h' && sample[9] == 'i' && sample[10] == 't') // being hit
  1732. {
  1733. if (g_nemesis[id])
  1734. engfunc(EngFunc_EmitSound, id, channel, nemesis_pain[random_num(0, sizeof nemesis_pain - 1)], volume, attn, flags, pitch)
  1735. else
  1736. engfunc(EngFunc_EmitSound, id, channel, zombie_pain[random_num(0, sizeof zombie_pain - 1)], volume, attn, flags, pitch)
  1737. return FMRES_SUPERCEDE
  1738. }
  1739.  
  1740. if (sample[10] == 'f' && sample[11] == 'a' && sample[12] == 'l' && sample[13] == 'l') // fall off
  1741. {
  1742. engfunc(EngFunc_EmitSound, id, channel, zombie_fall[random_num(0, sizeof zombie_fall - 1)], volume, attn, flags, pitch)
  1743. return FMRES_SUPERCEDE
  1744. }
  1745.  
  1746. return FMRES_IGNORED
  1747. }
  1748.  
  1749. #if !defined HANDLE_MODELS_ON_SEPARATE_ENT
  1750. // Forward Set ClientKey Value -prevent CS from changing player models-
  1751. public fw_SetClientKeyValue(id, infobuffer, const key[])
  1752. {
  1753. if (equal(key, "model")) // block CS model change
  1754. return FMRES_SUPERCEDE;
  1755.  
  1756. return FMRES_IGNORED;
  1757. }
  1758.  
  1759. // Forward Client User Info Changed -prevent players from changing models-
  1760. public fw_ClientUserInfoChanged(id)
  1761. {
  1762. static currentmodel[33] // get current model
  1763. fm_get_user_model(id, currentmodel, sizeof currentmodel - 1);
  1764.  
  1765. // If they're different, set model again
  1766. if (!equal(currentmodel, g_playermodel[id]) && !task_exists(id+MODEL_TASK))
  1767. fm_set_user_model(id+MODEL_TASK)
  1768. }
  1769. #endif
  1770.  
  1771. // Forward Game Description
  1772. public fw_GameDesc()
  1773. {
  1774. // Return the new mod name
  1775. forward_return(FMV_STRING, g_modname)
  1776.  
  1777. return FMRES_SUPERCEDE
  1778. }
  1779.  
  1780. // Forward CmdStart
  1781. public fw_CmdStart(id, handle)
  1782. {
  1783. if (!is_user_alive(id)) // not alive
  1784. return FMRES_IGNORED
  1785.  
  1786. // Get impulse id
  1787. static impulseid
  1788. impulseid = get_uc(handle, UC_Impulse)
  1789.  
  1790. if (impulseid == 100) // impulse 100 = flashlight
  1791. {
  1792. // Block it for zombies, survivor (and override it for humans when custom flashlight is on)
  1793. if (g_zombie[id] || g_survivor[id] || (!g_zombie[id] && get_pcvar_num(cvar_cflash)))
  1794. {
  1795. if (!g_zombie[id] && !g_survivor[id]) // human's custom flashlight should be turned on instead
  1796. {
  1797. // Turn custom flashlight on/off
  1798. g_flashlight[id] = !(g_flashlight[id])
  1799.  
  1800. // Set the flashlight charge task
  1801. remove_task(id+CHARGE_TASK)
  1802. set_task(1.0, "flashlight_charge", id+CHARGE_TASK, _, _, "b")
  1803.  
  1804. // Update flashlight status on the HUD
  1805. message_begin(MSG_ONE, g_msgFlashlight, _, id);
  1806. write_byte(g_flashlight[id]); // toggle
  1807. write_byte(g_flashbattery[id]); // battery
  1808. message_end();
  1809.  
  1810. // Turn off original flashlight if active
  1811. set_pev(id, pev_effects, pev(id, pev_effects) & ~EF_DIMLIGHT);
  1812.  
  1813. // Play flashlight toggle sound
  1814. engfunc(EngFunc_EmitSound, id, CHAN_ITEM, "items/flashlight1.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)
  1815.  
  1816. // Finally call our custom flashlight task
  1817. remove_task(id+FLASH_TASK)
  1818. set_task(0.1, "set_user_flashlight", id+FLASH_TASK, _, _, "b")
  1819. }
  1820.  
  1821. set_uc(handle, UC_Impulse, 0) // block the impulse
  1822. return FMRES_SUPERCEDE
  1823. }
  1824. }
  1825. return FMRES_IGNORED
  1826. }
  1827.  
  1828. // Forward Create Named Entity
  1829. public fw_CreateNamedEntity(classid)
  1830. {
  1831. static classname[10]
  1832. engfunc(EngFunc_SzFromIndex, classid, classname, sizeof classname - 1)
  1833.  
  1834. // Prevent c4 from spawning
  1835. if (classname[7] == 'c' && classname[8] == '4')
  1836. return FMRES_SUPERCEDE
  1837.  
  1838. return FMRES_IGNORED
  1839. }
  1840.  
  1841. // Forward Set Model
  1842. public fw_SetModel(entity, const model[])
  1843. {
  1844. // Get gravity of grenade
  1845. static Float:gravity
  1846. pev(entity, pev_gravity, gravity)
  1847.  
  1848. // Grenade not yet thrown
  1849. if (gravity == 0.0)
  1850. return;
  1851.  
  1852. if (equal(model[7], "w_hegrenade.mdl"))
  1853. {
  1854. static id // get grenade owner
  1855. id = pev(entity, pev_owner)
  1856.  
  1857. if (g_zombie[id]) // [ZOMBIE] - Infection Grenade
  1858. {
  1859. // Give it a glow
  1860. fm_set_rendering(entity, kRenderFxGlowShell, 0, 200, 0, kRenderNormal, 16);
  1861.  
  1862. // And a colored trail
  1863. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  1864. write_byte(TE_BEAMFOLLOW);
  1865. write_short(entity); // entity
  1866. write_short(g_trailSpr);// sprite
  1867. write_byte(10); // life
  1868. write_byte(10); // width
  1869. write_byte(0); // r
  1870. write_byte(200); // g
  1871. write_byte(0); // b
  1872. write_byte(200); // brightness
  1873. message_end();
  1874.  
  1875. // Prevent hegrenade from exploding
  1876. set_pev(entity, pev_nextthink, get_gametime()+10.0);
  1877.  
  1878. static args[1] // our task params
  1879. args[0] = entity; // entity id
  1880.  
  1881. // Actual explode event
  1882. set_task(1.5, "infection_explode", NADES_TASK, args, sizeof args)
  1883.  
  1884. }
  1885. else if (get_pcvar_num(cvar_firegrenades)) // [HUMAN] - Fire Grenade
  1886. {
  1887. // Give it a glow
  1888. fm_set_rendering(entity, kRenderFxGlowShell, 200, 0, 0, kRenderNormal, 16);
  1889.  
  1890. // And a colored trail
  1891. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  1892. write_byte(TE_BEAMFOLLOW);
  1893. write_short(entity); // entity
  1894. write_short(g_trailSpr);// sprite
  1895. write_byte(10); // life
  1896. write_byte(10); // width
  1897. write_byte(200); // r
  1898. write_byte(0); // g
  1899. write_byte(0); // b
  1900. write_byte(200); // brightness
  1901. message_end();
  1902.  
  1903. // Prevent hegrenade from exploding
  1904. set_pev(entity, pev_nextthink, get_gametime()+10.0);
  1905.  
  1906. static args[1] // our task params
  1907. args[0] = entity; // entity id
  1908.  
  1909. // Actual explode event
  1910. set_task(1.5, "fire_explode", NADES_TASK, args, sizeof args)
  1911. }
  1912. }
  1913. else if (equal(model[7], "w_flashbang.mdl") && get_pcvar_num(cvar_frostgrenades)) // Frost Grenade
  1914. {
  1915. // Give it a glow
  1916. fm_set_rendering(entity, kRenderFxGlowShell, 0, 100, 200, kRenderNormal, 16);
  1917.  
  1918. // And a colored trail
  1919. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  1920. write_byte(TE_BEAMFOLLOW);
  1921. write_short(entity); // entity
  1922. write_short(g_trailSpr);// sprite
  1923. write_byte(10); // life
  1924. write_byte(10); // width
  1925. write_byte(0); // r
  1926. write_byte(100); // g
  1927. write_byte(200); // b
  1928. write_byte(200); // brightness
  1929. message_end();
  1930.  
  1931. // Prevent flashbang from exploding
  1932. set_pev(entity, pev_nextthink, get_gametime()+10.0);
  1933.  
  1934. static args[1] // our task params
  1935. args[0] = entity; // entity id
  1936.  
  1937. // Actual explode event
  1938. set_task(1.5, "frost_explode", NADES_TASK, args, sizeof args)
  1939. }
  1940. else if (equal(model[7], "w_smokegrenade.mdl") && get_pcvar_num(cvar_flaregrenades)) // Flare
  1941. {
  1942. static args[5] // our task params
  1943. args[0] = entity; // entity id
  1944. args[1] = get_pcvar_num(cvar_flareduration)/5; // duration
  1945.  
  1946. switch (get_pcvar_num(cvar_flarecolor))
  1947. {
  1948. case 0: // white
  1949. {
  1950. args[2] = 255 // r
  1951. args[3] = 255 // g
  1952. args[4] = 255 // b
  1953. }
  1954. case 1: // red
  1955. {
  1956. args[2] = random_num(50,255) // r
  1957. args[3] = 0 // g
  1958. args[4] = 0 // b
  1959. }
  1960. case 2: // green
  1961. {
  1962. args[2] = 0 // r
  1963. args[3] = random_num(50,255) // g
  1964. args[4] = 0 // b
  1965. }
  1966. case 3: // blue
  1967. {
  1968. args[2] = 0 // r
  1969. args[3] = 0 // g
  1970. args[4] = random_num(50,255) // b
  1971. }
  1972. case 4: // random (all colors)
  1973. {
  1974. args[2] = random_num(50,200) // r
  1975. args[3] = random_num(50,200) // g
  1976. args[4] = random_num(50,200) // b
  1977. }
  1978. case 5: // random (r,g,b)
  1979. {
  1980. switch (random_num(1, 3))
  1981. {
  1982. case 1: // red
  1983. {
  1984. args[2] = random_num(50,255) // r
  1985. args[3] = 0 // g
  1986. args[4] = 0 // b
  1987. }
  1988. case 2: // green
  1989. {
  1990. args[2] = 0 // r
  1991. args[3] = random_num(50,255) // g
  1992. args[4] = 0 // b
  1993. }
  1994. case 3: // blue
  1995. {
  1996. args[2] = 0 // r
  1997. args[3] = 0 // g
  1998. args[4] = random_num(50,255) // b
  1999. }
  2000. }
  2001. }
  2002. }
  2003.  
  2004. // Give it a glow
  2005. fm_set_rendering(entity, kRenderFxGlowShell, args[2], args[3], args[4], kRenderNormal, 16);
  2006.  
  2007. // And a colored trail
  2008. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  2009. write_byte(TE_BEAMFOLLOW);
  2010. write_short(entity); // entity
  2011. write_short(g_trailSpr);// sprite
  2012. write_byte(10); // life
  2013. write_byte(10); // width
  2014. write_byte(args[2]); // r
  2015. write_byte(args[3]); // g
  2016. write_byte(args[4]); // b
  2017. write_byte(200); // brightness
  2018. message_end();
  2019.  
  2020. // Prevent smokegrenade from exploding
  2021. set_pev(entity, pev_nextthink, get_gametime()+10.0);
  2022.  
  2023. // Actual explode event
  2024. set_task(1.5, "flare_explode", NADES_TASK, args, sizeof args)
  2025. }
  2026. }
  2027.  
  2028. // Forward Client PreThink
  2029. public fw_PreThink(id)
  2030. {
  2031. if (!is_user_alive(id)) // not alive
  2032. return;
  2033.  
  2034. // Silent footsteps
  2035. if (g_zombie[id] && !g_nemesis[id] && g_zombieclass[id] != ZCLASS_RAGE)
  2036. set_pev(id, pev_flTimeStepSound, 999)
  2037.  
  2038. // Set Player MaxSpeed
  2039. if (g_frozen[id])
  2040. {
  2041. set_pev(id, pev_velocity, Float:{0.0,0.0,0.0}) // stop motion
  2042. set_pev(id, pev_maxspeed, 1.0) // prevent from moving
  2043. }
  2044. else
  2045. {
  2046. if (g_zombie[id])
  2047. {
  2048. if (g_nemesis[id])
  2049. set_pev(id, pev_maxspeed, get_pcvar_float(cvar_nemspd))
  2050. else
  2051. set_pev(id, pev_maxspeed, get_pcvar_float(cvar_zombiespeed)*zombie_multispd[g_zombieclass[id]]/100)
  2052. }
  2053. else
  2054. {
  2055. if (g_survivor[id])
  2056. set_pev(id, pev_maxspeed, get_pcvar_float(cvar_survspd))
  2057. else
  2058. set_pev(id, pev_maxspeed, get_pcvar_float(cvar_humanspd))
  2059. }
  2060. }
  2061.  
  2062. // Pain Shock Free for zombies/nemesis/survivor (if enabled)
  2063. if (g_zombie[id] || g_survivor[id])
  2064. {
  2065. if (pev(id, pev_flags) & FL_ONGROUND)
  2066. {
  2067. if (g_nemesis[id] && !get_pcvar_num(cvar_nempainfree)) // Nemesis cvar not enabled
  2068. return;
  2069.  
  2070. if (g_survivor[id] && !get_pcvar_num(cvar_survpainfree)) // Survivor cvar not enabled
  2071. return;
  2072.  
  2073. if (get_pcvar_num(cvar_zombiepainfree) == 0 && g_zombie[id] && !g_nemesis[id]) // Zombie cvar not enabled
  2074. return;
  2075.  
  2076. if (get_pcvar_num(cvar_zombiepainfree) == 2 && g_zombie[id] && !g_nemesis[id] && !g_lastzombie[id]) // not the last zombie
  2077. return;
  2078.  
  2079. pev(id, pev_velocity, g_velocity[id])
  2080. g_restorevel[id] = true
  2081. }
  2082. }
  2083. }
  2084.  
  2085. // Forward Client PreThink Post
  2086. public fw_PreThink_Post(id)
  2087. {
  2088. if (!is_user_alive(id)) // not alive
  2089. return FMRES_IGNORED
  2090.  
  2091. if (g_restorevel[id]) // Pain Shock Free: restore velocity if needed
  2092. {
  2093. g_restorevel[id] = false
  2094.  
  2095. if (!(FL_ONTRAIN & pev(id, pev_flags)))
  2096. {
  2097. // NOTE: within DLL PlayerPreThink Jump() function is called;
  2098. // there is a conveyor velocity addiction we should care of
  2099.  
  2100. static ent
  2101. ent = pev(id, pev_groundentity);
  2102.  
  2103. if (pev_valid(ent) && (FL_CONVEYOR & pev(ent, pev_flags)))
  2104. {
  2105. static Float:tempvel[3]
  2106. pev(id, pev_basevelocity, tempvel)
  2107. xs_vec_add(g_velocity[id], tempvel, g_velocity[id])
  2108. }
  2109.  
  2110. set_pev(id, pev_velocity, g_velocity[id])
  2111.  
  2112. return FMRES_HANDLED
  2113. }
  2114. }
  2115.  
  2116. return FMRES_IGNORED
  2117. }
  2118.  
  2119. /*================================================================================
  2120. [Client Commands]
  2121. =================================================================================*/
  2122.  
  2123. // Say
  2124. public clcmd_say(id)
  2125. {
  2126. static text[10]
  2127. read_args(text, sizeof text - 1)
  2128.  
  2129. if (equali(text[1], "zpmenu", 6) || equali(text[2], "zpmenu", 6))
  2130. show_menu_game(id); // show game menu
  2131. }
  2132.  
  2133. // Nightvision toggle
  2134. public clcmd_nvgtoggle(id)
  2135. {
  2136. if (g_nvision[id])
  2137. {
  2138. // Enable-disable
  2139. g_nvisionenabled[id] = !(g_nvisionenabled[id])
  2140.  
  2141. if (get_pcvar_num(cvar_cnvg)) // custom nvg?
  2142. {
  2143. remove_task(id+NVISION_TASK);
  2144. set_task(0.1, "set_user_nvision", id+NVISION_TASK, _, _, "b")
  2145. }
  2146. else set_user_gnvision(id, g_nvisionenabled[id])
  2147. }
  2148.  
  2149. return PLUGIN_HANDLED
  2150. }
  2151.  
  2152. // Drop a Weapon
  2153. public clcmd_drop(id)
  2154. {
  2155. if (g_survivor[id]) // survivor should stick with m249
  2156. return PLUGIN_HANDLED
  2157.  
  2158. return PLUGIN_CONTINUE
  2159. }
  2160.  
  2161. // Buy BP Ammo
  2162. public clcmd_buyammo(id)
  2163. {
  2164. if (get_pcvar_num(cvar_infammo) || !is_user_alive(id)) // dont bother
  2165. return PLUGIN_HANDLED
  2166.  
  2167. if (!g_zombie[id]) // only humans buy ammo
  2168. {
  2169. if (g_ammopacks[id] > 0) // enough ammo packs?
  2170. {
  2171. g_ammopacks[id]--
  2172. engfunc(EngFunc_EmitSound, id, CHAN_ITEM, "items/9mmclip1.wav", 1.0, ATTN_NORM, 0, PITCH_NORM) // ammo sound
  2173. client_print(id, print_chat, "[ZP] %L", id, "AMMO_BOUGHT") // tell the player
  2174.  
  2175. static weapons[32], num, i
  2176. num = 0 // reset passed weapons count (bugfix)
  2177. get_user_weapons(id, weapons, num)
  2178.  
  2179. for (i = 0; i < num; i++)
  2180. {
  2181. if ((1<<weapons[i]) & PRIMARY_WEAPONS_BIT_SUM)
  2182. {
  2183. static currentammo
  2184. currentammo = fm_get_user_bpammo(id, weapons[i]) // get current ammo
  2185.  
  2186. if (currentammo <= MAXAMMO[weapons[i]]-BUYAMMO[weapons[i]])
  2187. {
  2188. message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoPickup, _, id); // flash ammo in hud
  2189. write_byte(3); // ammo id
  2190. write_byte(BUYAMMO[weapons[i]]) // ammo amount
  2191. message_end();
  2192. fm_set_user_bpammo(id, weapons[i], currentammo + BUYAMMO[weapons[i]]); // increase BP ammo
  2193. }
  2194. else
  2195. {
  2196. message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoPickup, _, id); // flash ammo in hud
  2197. write_byte(3); // ammo id
  2198. write_byte(MAXAMMO[weapons[i]]-currentammo) // ammo amount
  2199. message_end();
  2200. fm_set_user_bpammo(id, weapons[i], MAXAMMO[weapons[i]]); // reached the limit
  2201. }
  2202. }
  2203. else if ((1<<weapons[i]) & SECONDARY_WEAPONS_BIT_SUM)
  2204. {
  2205. static currentammo
  2206. currentammo = fm_get_user_bpammo(id, weapons[i]) // get current ammo
  2207.  
  2208. if (currentammo <= MAXAMMO[weapons[i]]-BUYAMMO[weapons[i]])
  2209. {
  2210. message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoPickup, _, id); // flash ammo in hud
  2211. write_byte(10); // ammo id
  2212. write_byte(BUYAMMO[weapons[i]]) // ammo amount
  2213. message_end();
  2214. fm_set_user_bpammo(id, weapons[i], currentammo + BUYAMMO[weapons[i]]); // increase BP ammo
  2215. }
  2216. else
  2217. {
  2218. message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoPickup, _, id); // flash ammo in hud
  2219. write_byte(10); // ammo id
  2220. write_byte(MAXAMMO[weapons[i]]-currentammo) // ammo amount
  2221. message_end();
  2222. fm_set_user_bpammo(id, weapons[i], MAXAMMO[weapons[i]]); // reached the limit
  2223. }
  2224. }
  2225. }
  2226. }
  2227. else
  2228. {
  2229. client_print(id, print_chat, "[ZP] %L", id, "NOT_ENOUGH_AMMO")
  2230. }
  2231. }
  2232. else
  2233. {
  2234. client_print(id, print_chat, "[ZP] %L", id, "CMD_HUMAN_ONLY")
  2235. }
  2236.  
  2237. return PLUGIN_HANDLED
  2238. }
  2239.  
  2240. // Block Team Change
  2241. public clcmd_changeteam(id)
  2242. {
  2243. // Spectator joins the game
  2244. if (fm_get_user_team(id) == CS_TEAM_SPECTATOR || fm_get_user_team(id) == CS_TEAM_UNASSIGNED)
  2245. return PLUGIN_CONTINUE
  2246.  
  2247. show_menu_game(id); // pressing 'M' (chooseteam) ingame should show the main menu
  2248. return PLUGIN_HANDLED
  2249. }
  2250.  
  2251. /*================================================================================
  2252. [Menus]
  2253. =================================================================================*/
  2254.  
  2255. // Game Menu
  2256. public show_menu_game(id)
  2257. {
  2258. static menu[150]
  2259.  
  2260. formatex(menu, sizeof menu - 1, "\yZombie Plague\w^n^n1. %L^n2. %L^n3. %L^n4. %L^n^n5. %L^n^n6. %L^n^n0. %L", id, "MENU_EXTRABUY", id,"MENU_ZCLASS", id, "MENU_UNSTUCK", id, "MENU_INFO", id, "MENU_ADMIN", id, "MENU_SPECTATOR", id, "MENU_EXIT")
  2261. show_menu(id, KEYSMENU, menu, -1, "Game Menu")
  2262. }
  2263.  
  2264. // Buy Menu 1
  2265. public show_menu_buy1(taskid)
  2266. {
  2267. // Zombies or survivors get no guns
  2268. if (g_zombie[ID_SPAWN] || g_survivor[ID_SPAWN] || !g_canbuy[ID_SPAWN] || !is_user_alive(ID_SPAWN))
  2269. return;
  2270.  
  2271. // Bots pick their weapons randomly
  2272. if (is_user_bot(ID_SPAWN))
  2273. {
  2274. menu_buy1(ID_SPAWN, random_num(0, sizeof g_primary_names - 1))
  2275. return;
  2276. }
  2277.  
  2278. static menu[300], len, i
  2279. len = 0
  2280.  
  2281. len += formatex(menu[len], sizeof menu - 1 - len, "\y%L^n", ID_SPAWN, "MENU_BUY1_TITLE")
  2282. for (i = 0; i < sizeof g_primary_names; i++) len += formatex(menu[len], sizeof menu - 1 - len, "\w^n%d. %s \y%s", i+1, g_primary_names[i], g_primary_classes[i])
  2283. len += formatex(menu[len], sizeof menu - 1 - len, "\w^n^n0. %L", ID_SPAWN, "MENU_EXIT")
  2284. show_menu(ID_SPAWN, KEYSMENU, menu, 10, "Buy Menu 1")
  2285. }
  2286.  
  2287. // Buy Menu 2
  2288. show_menu_buy2(id)
  2289. {
  2290. // Bots pick their weapons randomly
  2291. if (is_user_bot(id))
  2292. {
  2293. menu_buy2(id, random_num(0, sizeof g_secondary_names - 1))
  2294. return;
  2295. }
  2296.  
  2297. static menu[300], len, i
  2298. len = 0
  2299.  
  2300. len += formatex(menu[len], sizeof menu - 1 - len, "\y%L^n", id, "MENU_BUY2_TITLE")
  2301. for (i = 0; i < sizeof g_secondary_names; i++) len += formatex(menu[len], sizeof menu - 1 - len, "\w^n%d. %s \y%s", i+1, g_secondary_names[i], g_secondary_classes[i])
  2302. len += formatex(menu[len], sizeof menu - 1 - len, "\w^n^n0. %L", id, "MENU_EXIT")
  2303. show_menu(id, KEYSMENU, menu, 10, "Buy Menu 2")
  2304. }
  2305.  
  2306. // Zombie Class Menu
  2307. public show_menu_zombie(id)
  2308. {
  2309. if (!is_user_connected(id)) // player not connected
  2310. return;
  2311.  
  2312. // Bots pick their zombie class randomly
  2313. if (is_user_bot(id))
  2314. {
  2315. menu_zombie(id, random_num(0, sizeof zombie_multihp - 1))
  2316. return;
  2317. }
  2318.  
  2319. static menu[250], len
  2320. len = 0
  2321.  
  2322. len += formatex(menu[len], sizeof menu - 1 - len, "\y%L\w^n^n1. %L \y%L\w^n2. %L \y%L\w^n3. %L \y%L\w^n4. %L \y%L\w^n5. %L \y%L", id, "MENU_ZCLASS_TITLE", id, "CLASS_ZOMBIE1", id, "MENU_ZCLASS1", id, "CLASS_ZOMBIE2", id, "MENU_ZCLASS2", id, "CLASS_ZOMBIE3", id, "MENU_ZCLASS3", id, "CLASS_ZOMBIE4", id, "MENU_ZCLASS4", id, "CLASS_ZOMBIE5", id, "MENU_ZCLASS5")
  2323. len += formatex(menu[len], sizeof menu - 1 - len, "\w^n6. %L \y %L \w^n^n0. %L", id, "CLASS_ZOMBIE6", id, "MENU_ZCLASS6", id, "MENU_EXIT")
  2324. show_menu(id, KEYSMENU, menu, -1, "Zombie Menu")
  2325. }
  2326.  
  2327. // Extra Items Menu
  2328. show_menu_extras(id)
  2329. {
  2330. static menu[450], len, i
  2331. len = 0
  2332.  
  2333. len += formatex(menu[len], sizeof menu - 1 - len, "\y%L\r^n^n%L:", id, "MENU_EXTRA_TITLE", id, "CLASS_HUMAN")
  2334. if (get_pcvar_num(cvar_extra_weapons)) for (i = 0; i < sizeof g_extra_names; i++) len += formatex(menu[len], sizeof menu - 1 - len, "\w^n%d. %s \y%d %L", i+1, g_extra_names[i], g_extra_costs[i], id, "AMMO_PACKS2")
  2335. else i = sizeof g_extra_names
  2336. if (get_pcvar_num(cvar_extra_nvision)) len += formatex(menu[len], sizeof menu - 1 - len, "\w^n%d. %L \y%d %L", i+1, id, "MENU_EXTRA1", g_extra_costs2[EXTRA_NVISION], id, "AMMO_PACKS2")
  2337. len += formatex(menu[len], sizeof menu - 1 - len, "\r^n^n%L:", id, "CLASS_ZOMBIE")
  2338. if (get_pcvar_num(cvar_extra_antidote)) len += formatex(menu[len], sizeof menu - 1 - len, "\w^n%d. %L \y%d %L", i+2, id, "MENU_EXTRA2", g_extra_costs2[EXTRA_ANTIDOTE], id, "AMMO_PACKS2")
  2339. if (get_pcvar_num(cvar_extra_madness)) len += formatex(menu[len], sizeof menu - 1 - len, "\w^n%d. %L \y%d %L", i+3, id, "MENU_EXTRA3", g_extra_costs2[EXTRA_MADNESS], id, "AMMO_PACKS2")
  2340. if (get_pcvar_num(cvar_extra_infbomb)) len += formatex(menu[len], sizeof menu - 1 - len, "\w^n%d. %L \y%d %L", i+4, id, "MENU_EXTRA4", g_extra_costs2[EXTRA_INFBOMB], id, "AMMO_PACKS2")
  2341. len += formatex(menu[len], sizeof menu - 1 - len, "\w^n^n0. %L", id, "MENU_EXIT")
  2342.  
  2343. show_menu(id, KEYSMENU, menu, -1, "Extra Items")
  2344. }
  2345.  
  2346. // Help Menu
  2347. public show_menu_info(id)
  2348. {
  2349. if (!is_user_connected(id)) // player not connected
  2350. return;
  2351.  
  2352. static menu[100]
  2353.  
  2354. formatex(menu, sizeof menu - 1, "\y%L\w^n^n1. %L^n2. %L^n3. %L^n4. %L^n^n0. %L", id, "MENU_INFO_TITLE", id, "MENU_INFO1", id,"MENU_INFO2", id,"MENU_INFO3", id,"MENU_INFO4", id, "MENU_EXIT")
  2355. show_menu(id, KEYSMENU, menu, -1, "Mod Info")
  2356. }
  2357.  
  2358. // Admin Menu
  2359. show_menu_admin(id)
  2360. {
  2361. static menu[200]
  2362.  
  2363. formatex(menu, sizeof menu - 1, "\y%L\w^n^n1. %L^n2. %L^n3. %L^n4. %L^n5. %L^n6. %L^n^n0. %L", id, "MENU_ADMIN_TITLE", id, "MENU_ADMIN1", id,"MENU_ADMIN2", id,"MENU_ADMIN3", id,"MENU_ADMIN4", id,"MENU_ADMIN5", id,"MENU_ADMIN6", id, "MENU_EXIT")
  2364. show_menu(id, KEYSMENU, menu, -1, "Admin Menu")
  2365. }
  2366.  
  2367. // Player List Menu
  2368. show_menu_player_list(id)
  2369. {
  2370. static menu[400], len
  2371. len = 0
  2372.  
  2373. // Title
  2374. switch (PL_ACTION)
  2375. {
  2376. case 0: len += formatex(menu[len], sizeof menu - 1 - len, "\y%L ", id, "MENU_ADMIN1")
  2377. case 1: len += formatex(menu[len], sizeof menu - 1 - len, "\y%L ", id, "MENU_ADMIN2")
  2378. case 2: len += formatex(menu[len], sizeof menu - 1 - len, "\y%L ", id, "MENU_ADMIN3")
  2379. case 3: len += formatex(menu[len], sizeof menu - 1 - len, "\y%L ", id, "MENU_ADMIN4")
  2380. }
  2381.  
  2382. len += formatex(menu[len], sizeof menu - 1 - len, "\r[%d-%d]^n^n", PL_STARTID+1, (PL_STARTID+7 <= g_maxplayers) ? PL_STARTID+7 : g_maxplayers)
  2383.  
  2384. // 1-7. player list
  2385. static player
  2386. for (player = PL_STARTID+1; (PL_STARTID+7 <= g_maxplayers) ? (player <= PL_STARTID+7) : (player <= g_maxplayers); player++)
  2387. {
  2388. if (is_user_connected(player))
  2389. {
  2390. static name[32]
  2391. get_user_name(player, name, sizeof name - 1)
  2392.  
  2393. switch (PL_ACTION)
  2394. {
  2395. case 0:
  2396. {
  2397. if (g_zombie[player])
  2398. {
  2399. if (allowed_human(player))
  2400. len += formatex(menu[len], sizeof menu - 1 - len, "\w%d. %s \r[%L]^n", player-PL_STARTID, name, id, "CLASS_ZOMBIE")
  2401. else
  2402. len += formatex(menu[len], sizeof menu - 1 - len, "\d%d. %s [%L]^n", player-PL_STARTID, name, id, "CLASS_ZOMBIE")
  2403. }
  2404. else
  2405. {
  2406. if (allowed_zombie(player))
  2407. len += formatex(menu[len], sizeof menu - 1 - len, "\w%d. %s \y[%L]^n", player-PL_STARTID, name, id, "CLASS_HUMAN")
  2408. else
  2409. len += formatex(menu[len], sizeof menu - 1 - len, "\d%d. %s [%L]^n", player-PL_STARTID, name, id, "CLASS_HUMAN")
  2410. }
  2411. }
  2412. case 1:
  2413. {
  2414. if (allowed_nemesis(player))
  2415. len += formatex(menu[len], sizeof menu - 1 - len, "\w%d. %s^n", player-PL_STARTID, name)
  2416. else
  2417. len += formatex(menu[len], sizeof menu - 1 - len, "\d%d. %s^n", player-PL_STARTID, name)
  2418. }
  2419. case 2:
  2420. {
  2421. if (allowed_survivor(player))
  2422. len += formatex(menu[len], sizeof menu - 1 - len, "\w%d. %s^n", player-PL_STARTID, name)
  2423. else
  2424. len += formatex(menu[len], sizeof menu - 1 - len, "\d%d. %s^n", player-PL_STARTID, name)
  2425. }
  2426. case 3:
  2427. {
  2428. if (allowed_respawn(player))
  2429. len += formatex(menu[len], sizeof menu - 1 - len, "\w%d. %s^n", player-PL_STARTID, name)
  2430. else
  2431. len += formatex(menu[len], sizeof menu - 1 - len, "\d%d. %s^n", player-PL_STARTID, name)
  2432. }
  2433. }
  2434. }
  2435. else
  2436. {
  2437. len += formatex(menu[len], sizeof menu - 1 - len, "\d%d. -----^n", player-PL_STARTID)
  2438. }
  2439. }
  2440.  
  2441. // 8. Back - 9. Next - 0. Exit
  2442. len += formatex(menu[len], sizeof menu - 1 - len, "\w^n8. %L^n9. %L^n^n0. %L", id, "MENU_BACK", id, "MENU_NEXT", id, "MENU_EXIT")
  2443.  
  2444. show_menu(id, KEYSMENU, menu, -1, "Player List Menu")
  2445. }
  2446.  
  2447. /*================================================================================
  2448. [Menu Handlers]
  2449. =================================================================================*/
  2450.  
  2451. // Game Menu
  2452. public menu_game(id, key)
  2453. {
  2454. switch (key)
  2455. {
  2456. case 0: get_pcvar_num(cvar_extraitems) ? show_menu_extras(id) : client_print(id, print_chat, "[ZP] %L", id ,"CMD_NOT_EXTRAS")
  2457. case 1: get_pcvar_num(cvar_zclasses) ? show_menu_zombie(id) : client_print(id, print_chat, "[ZP] %L", id ,"CMD_NOT_ZCLASSES")
  2458. case 2: is_user_alive(id) && is_player_stuck(id) ? do_random_spawn(id) : client_print(id, print_chat, "[ZP] %L", id ,"CMD_NOT_STUCK")
  2459. case 3: show_menu_info(id)
  2460. case 4: get_user_flags(id) & ACCESS_FLAG ? show_menu_admin(id) : client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT_ACCESS")
  2461. case 5:
  2462. {
  2463. // Move to Spectator, make sure it's dead before
  2464. if (is_user_alive(id))
  2465. {
  2466. check_round(id)
  2467. dllfunc(DLLFunc_ClientKill, id)
  2468. }
  2469. fm_set_user_team(id, CS_TEAM_SPECTATOR)
  2470. fm_set_user_team_msg(id+TEAM_TASK)
  2471. }
  2472. }
  2473.  
  2474. return PLUGIN_HANDLED;
  2475. }
  2476.  
  2477. // Admin Menu
  2478. public menu_admin(id, key)
  2479. {
  2480. switch (key)
  2481. {
  2482. case 0 .. 3:
  2483. {
  2484. PL_ACTION = key;
  2485. show_menu_player_list(id);
  2486. }
  2487. case 4:
  2488. {
  2489. allowed_swarm() ? command_swarm(id) : client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT")
  2490. show_menu_admin(id);
  2491. }
  2492. case 5:
  2493. {
  2494. allowed_multi() ? command_multi(id) : client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT")
  2495. show_menu_admin(id);
  2496. }
  2497. }
  2498.  
  2499. return PLUGIN_HANDLED
  2500. }
  2501.  
  2502. // Player List Menu
  2503. public menu_player_list(id, key)
  2504. {
  2505. switch (key)
  2506. {
  2507. case 7: if (PL_STARTID-7 >= 0) PL_STARTID -= 7 // back
  2508. case 8: if (PL_STARTID+7 < g_maxplayers) PL_STARTID += 7 // next
  2509. case 9: // go back to admin menu
  2510. {
  2511. show_menu_admin(id);
  2512. return PLUGIN_HANDLED
  2513. }
  2514. default: // perform action on player
  2515. {
  2516. if (is_user_connected(PL_TARGET))
  2517. {
  2518. switch (PL_ACTION)
  2519. {
  2520. case 0:
  2521. {
  2522. if (g_zombie[PL_TARGET])
  2523. {
  2524. if (allowed_human(PL_TARGET))
  2525. command_human(id, PL_TARGET)
  2526. else
  2527. client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT")
  2528. }
  2529. else
  2530. {
  2531. if (allowed_zombie(PL_TARGET))
  2532. command_zombie(id, PL_TARGET)
  2533. else
  2534. client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT")
  2535. }
  2536. }
  2537. case 1:
  2538. {
  2539. if (allowed_nemesis(PL_TARGET))
  2540. command_nemesis(id, PL_TARGET)
  2541. else
  2542. client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT")
  2543. }
  2544. case 2:
  2545. {
  2546. if (allowed_survivor(PL_TARGET))
  2547. command_survivor(id, PL_TARGET)
  2548. else
  2549. client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT")
  2550. }
  2551. case 3:
  2552. {
  2553. if (allowed_respawn(PL_TARGET))
  2554. command_respawn(id, PL_TARGET)
  2555. else
  2556. client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT")
  2557. }
  2558. }
  2559. }
  2560. else
  2561. {
  2562. client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT")
  2563. }
  2564. }
  2565. }
  2566.  
  2567. show_menu_player_list(id);
  2568. return PLUGIN_HANDLED
  2569. }
  2570.  
  2571. // Info Menu
  2572. public menu_info(id, key)
  2573. {
  2574. switch (key)
  2575. {
  2576. case 0:
  2577. {
  2578. static motd[1000], len, weather, lights[2]
  2579. len = 0
  2580. weather = 0
  2581.  
  2582. get_pcvar_string(cvar_lighting, lights, sizeof lights - 1)
  2583. strtolower(lights)
  2584.  
  2585. len += formatex(motd[len], sizeof motd - 1 - len, "%L ", id, "MOTD_INFO11", "Zombie Plague", PLUGIN_VERSION, "MeRcyLeZZ")
  2586. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO12")
  2587. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_A")
  2588.  
  2589. #if defined AMBIENCE_FOG
  2590. len += formatex(motd[len], sizeof motd - 1 - len, (weather < 1) ? " %L" : ". %L", id, "MOTD_FOG")
  2591. weather++
  2592. #endif
  2593. #if defined AMBIENCE_RAIN
  2594. len += formatex(motd[len], sizeof motd - 1 - len, (weather < 1) ? " %L" : ". %L", id, "MOTD_RAIN")
  2595. weather++
  2596. #endif
  2597. #if defined AMBIENCE_SNOW
  2598. len += formatex(motd[len], sizeof motd - 1 - len, (weather < 1) ? " %L" : ". %L", id, "MOTD_SNOW")
  2599. weather++
  2600. #endif
  2601. if (weather < 1) len += formatex(motd[len], sizeof motd - 1 - len, " %L", id, "MOTD_DISABLED")
  2602.  
  2603. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_B", lights)
  2604. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_C", id, get_pcvar_num(cvar_triggered) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2605. if (lights[0] == 'a' && get_pcvar_num(cvar_thunder)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_D", get_pcvar_num(cvar_thunder))
  2606. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_E", id, get_pcvar_num(cvar_removedoors) > 0 ? get_pcvar_num(cvar_removedoors) > 1 ? "MOTD_DOORS" : "MOTD_ROTATING" : "MOTD_ENABLED")
  2607. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_F", id, get_pcvar_num(cvar_deathmatch) > 0 ? get_pcvar_num(cvar_deathmatch) > 1 ? get_pcvar_num(cvar_deathmatch) > 2 ? "MOTD_ENABLED" : "MOTD_DM_ZOMBIE" : "MOTD_DM_HUMAN" : "MOTD_DISABLED")
  2608. if (get_pcvar_num(cvar_deathmatch)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_G", get_pcvar_num(cvar_spawnprotection))
  2609. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_H", id, get_pcvar_num(cvar_randspawn) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2610. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_I", id, get_pcvar_num(cvar_extraitems) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2611. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_J", id, get_pcvar_num(cvar_zclasses) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2612. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_K", id, get_pcvar_num(cvar_cnvg) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2613. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_L", id, get_pcvar_num(cvar_cflash) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2614.  
  2615. show_motd(id, motd)
  2616. }
  2617. case 1:
  2618. {
  2619. static motd[650], len
  2620. len = 0
  2621.  
  2622. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2")
  2623. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_A", get_pcvar_num(cvar_humanhp))
  2624. if (get_pcvar_num(cvar_humanlasthp) > 0) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_B", get_pcvar_num(cvar_humanlasthp))
  2625. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_C", get_pcvar_num(cvar_humanspd))
  2626. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_D", floatround(get_pcvar_float(cvar_humangravity)*800))
  2627. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_E", id, get_pcvar_num(cvar_infammo) > 0 ? get_pcvar_num(cvar_infammo) > 1 ? "MOTD_AMMO_CLIP" : "MOTD_AMMO_BP" : "MOTD_LIMITED")
  2628. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_F", get_pcvar_num(cvar_ammodamage))
  2629. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_G", id, get_pcvar_num(cvar_firegrenades) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2630. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_H", id, get_pcvar_num(cvar_frostgrenades) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2631. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_I", id, get_pcvar_num(cvar_flaregrenades) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2632. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_J", id, get_pcvar_num(cvar_knockback) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2633.  
  2634. show_motd(id, motd)
  2635. }
  2636. case 2:
  2637. {
  2638. static motd[650], len
  2639. len = 0
  2640.  
  2641. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3")
  2642. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3_A", get_pcvar_num(cvar_zombiehp))
  2643. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3_B", get_pcvar_num(cvar_zombiefirsthp))
  2644. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3_C", floatround(get_pcvar_float(cvar_zombiearmor)*100))
  2645. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3_D", get_pcvar_num(cvar_zombiespeed))
  2646. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3_E", floatround(get_pcvar_float(cvar_zombiegravity)*800))
  2647. if (get_pcvar_num(cvar_zombiebonushp)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3_F", get_pcvar_num(cvar_zombiebonushp))
  2648. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3_G", id, get_pcvar_num(cvar_zombiepainfree) > 0 ? get_pcvar_num(cvar_zombiepainfree) > 1 ? "MOTD_LASTZOMBIE" : "MOTD_ENABLED" : "MOTD_DISABLED")
  2649. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3_H", id, get_pcvar_num(cvar_zombiebleeding) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2650. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3_I", get_pcvar_num(cvar_ammoinfect))
  2651.  
  2652. show_motd(id, motd)
  2653. }
  2654. case 3:
  2655. {
  2656. static motd[900], len, nemhp[5], survhp[5]
  2657. len = 0
  2658.  
  2659. num_to_str(get_pcvar_num(cvar_nemhp), nemhp, sizeof nemhp - 1) // nemesis health
  2660. num_to_str(get_pcvar_num(cvar_survhp), survhp, sizeof survhp - 1) // survivor health
  2661.  
  2662. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4")
  2663. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_A", id, get_pcvar_num(cvar_nem) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2664. if (get_pcvar_num(cvar_nem)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_B", get_pcvar_num(cvar_nemchance))
  2665. if (get_pcvar_num(cvar_nem)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_C", get_pcvar_num(cvar_nemhp) > 0 ? nemhp : "[Auto]")
  2666. if (get_pcvar_num(cvar_nem)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_D", get_pcvar_num(cvar_nemspd))
  2667. if (get_pcvar_num(cvar_nem)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_E", floatround(get_pcvar_float(cvar_nemgravity)*800))
  2668. if (get_pcvar_num(cvar_nem)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_F", id, get_pcvar_num(cvar_nemleap) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2669. if (get_pcvar_num(cvar_nem)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_G", id, get_pcvar_num(cvar_nempainfree) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2670. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_H", id, get_pcvar_num(cvar_surv) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2671. if (get_pcvar_num(cvar_surv)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_I", get_pcvar_num(cvar_survchance))
  2672. if (get_pcvar_num(cvar_surv)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_J", get_pcvar_num(cvar_survhp) > 0 ? survhp : "[Auto]")
  2673. if (get_pcvar_num(cvar_surv)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_K", get_pcvar_num(cvar_survspd))
  2674. if (get_pcvar_num(cvar_surv)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_L", floatround(get_pcvar_float(cvar_survgravity)*800))
  2675. if (get_pcvar_num(cvar_surv)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_M", id, get_pcvar_num(cvar_survleap) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2676. if (get_pcvar_num(cvar_surv)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_N", id, get_pcvar_num(cvar_survpainfree) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2677. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_O", id, get_pcvar_num(cvar_swarm) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2678. if (get_pcvar_num(cvar_swarm)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_P", get_pcvar_num(cvar_swarmchance))
  2679. len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_Q", id, get_pcvar_num(cvar_multi) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  2680. if (get_pcvar_num(cvar_multi)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_R", get_pcvar_num(cvar_multichance))
  2681. if (get_pcvar_num(cvar_multi)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_S", floatround(get_pcvar_float(cvar_multiratio)*100))
  2682.  
  2683. show_motd(id, motd)
  2684. }
  2685. default: return PLUGIN_HANDLED;
  2686. }
  2687.  
  2688. set_task(0.2, "show_menu_info", id);
  2689.  
  2690. return PLUGIN_HANDLED;
  2691. }
  2692.  
  2693. // Extra Items Menu
  2694. public menu_extras(id, key)
  2695. {
  2696. // Nemesis or Survivor shouldnt get extra items
  2697. if (!is_user_alive(id) || g_survivor[id] || g_nemesis[id])
  2698. {
  2699. client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT")
  2700. return PLUGIN_HANDLED;
  2701. }
  2702.  
  2703. switch (key)
  2704. {
  2705. case 0 .. sizeof g_extra_items - 1:
  2706. {
  2707. if (get_pcvar_num(cvar_extra_weapons))
  2708. {
  2709. if (!g_zombie[id])
  2710. {
  2711. if (g_ammopacks[id] >= g_extra_costs[key])
  2712. {
  2713. if (MAXAMMO[get_weaponid(g_extra_items[key])] > 1) // (this adds grenades support)
  2714. {
  2715. // Drop previous weapon and give BP ammo for the new one
  2716. (1<<get_weaponid(g_extra_items[key])) & PRIMARY_WEAPONS_BIT_SUM ? drop_weapons(id, 1) : drop_weapons(id, 2);
  2717. fm_set_user_bpammo(id, get_weaponid(g_extra_items[key]), MAXAMMO[get_weaponid(g_extra_items[key])]);
  2718. }
  2719. fm_give_item(id, g_extra_items[key]);
  2720. g_ammopacks[id] -= g_extra_costs[key];
  2721. }
  2722. else
  2723. {
  2724. client_print(id, print_chat, "[ZP] %L", id ,"NOT_ENOUGH_AMMO")
  2725. }
  2726. }
  2727. else
  2728. {
  2729. client_print(id, print_chat, "[ZP] %L", id ,"CMD_HUMAN_ONLY")
  2730. }
  2731. }
  2732. }
  2733. case sizeof g_extra_items + 0:
  2734. {
  2735. if (get_pcvar_num(cvar_extra_nvision))
  2736. {
  2737. if (!g_zombie[id])
  2738. {
  2739. if (g_ammopacks[id] >= g_extra_costs2[EXTRA_NVISION])
  2740. {
  2741. g_nvision[id] = true; // Night Vision
  2742. g_nvisionenabled[id] = true
  2743.  
  2744. if (get_pcvar_num(cvar_cnvg)) // custom nvg?
  2745. {
  2746. remove_task(id+NVISION_TASK);
  2747. set_task(0.1, "set_user_nvision", id+NVISION_TASK, _, _, "b")
  2748. }
  2749. else set_user_gnvision(id, 1)
  2750.  
  2751. g_ammopacks[id] -= g_extra_costs2[EXTRA_NVISION];
  2752. }
  2753. else
  2754. {
  2755. client_print(id, print_chat, "[ZP] %L", id ,"NOT_ENOUGH_AMMO")
  2756. }
  2757. }
  2758. else
  2759. {
  2760. client_print(id, print_chat, "[ZP] %L", id ,"CMD_HUMAN_ONLY")
  2761. }
  2762. }
  2763. }
  2764. case sizeof g_extra_items + 1:
  2765. {
  2766. if (get_pcvar_num(cvar_extra_antidote))
  2767. {
  2768. if (g_zombie[id])
  2769. {
  2770. if (!g_endround && !g_swarmround && !g_nemround && !g_survround && fnGetZombies() > 1)
  2771. {
  2772. if (g_ammopacks[id] >= g_extra_costs2[EXTRA_ANTIDOTE])
  2773. {
  2774. humanme(id, 0) // Antidote
  2775. g_ammopacks[id] -= g_extra_costs2[EXTRA_ANTIDOTE];
  2776. }
  2777. else
  2778. {
  2779. client_print(id, print_chat, "[ZP] %L", id ,"NOT_ENOUGH_AMMO")
  2780. }
  2781. }
  2782. else
  2783. {
  2784. client_print(id, print_chat, "[ZP] %L", id ,"CMD_NOT_CANTUSE")
  2785. }
  2786. }
  2787. else
  2788. {
  2789. client_print(id, print_chat, "[ZP] %L", id ,"CMD_ZOMBIE_ONLY")
  2790. }
  2791. }
  2792. }
  2793. case sizeof g_extra_items + 2:
  2794. {
  2795. if (get_pcvar_num(cvar_extra_madness))
  2796. {
  2797. if (g_zombie[id])
  2798. {
  2799. if (!g_swarmround && !g_nemround && !g_survround && !g_nodamage[id])
  2800. {
  2801. if (g_ammopacks[id] >= g_extra_costs2[EXTRA_MADNESS])
  2802. {
  2803. g_nodamage[id] = true // Zombie Madness
  2804. infectionFX2(id) // aura
  2805. engfunc(EngFunc_EmitSound, id, CHAN_VOICE, zombie_madness[random_num(0, sizeof zombie_madness - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
  2806. set_task(5.0, "madness_over", id+BLOOD_TASK)
  2807. g_ammopacks[id] -= g_extra_costs2[EXTRA_MADNESS];
  2808. }
  2809. else
  2810. {
  2811. client_print(id, print_chat, "[ZP] %L", id ,"NOT_ENOUGH_AMMO")
  2812. }
  2813. }
  2814. else
  2815. {
  2816. client_print(id, print_chat, "[ZP] %L", id ,"CMD_NOT_CANTUSE")
  2817. }
  2818. }
  2819. else
  2820. {
  2821. client_print(id, print_chat, "[ZP] %L", id ,"CMD_ZOMBIE_ONLY")
  2822. }
  2823. }
  2824. }
  2825. case sizeof g_extra_items + 3:
  2826. {
  2827. if (get_pcvar_num(cvar_extra_infbomb))
  2828. {
  2829. if (g_zombie[id])
  2830. {
  2831. if (!g_swarmround && !g_nemround && !g_survround)
  2832. {
  2833. if (g_ammopacks[id] >= g_extra_costs2[EXTRA_INFBOMB])
  2834. {
  2835. fm_give_item(id, "weapon_hegrenade"); // Infection Bomb
  2836. g_ammopacks[id] -= g_extra_costs2[EXTRA_INFBOMB];
  2837. }
  2838. else
  2839. {
  2840. client_print(id, print_chat, "[ZP] %L", id ,"NOT_ENOUGH_AMMO")
  2841. }
  2842. }
  2843. else
  2844. {
  2845. client_print(id, print_chat, "[ZP] %L", id ,"CMD_NOT_CANTUSE")
  2846. }
  2847. }
  2848. else
  2849. {
  2850. client_print(id, print_chat, "[ZP] %L", id ,"CMD_ZOMBIE_ONLY")
  2851. }
  2852. }
  2853. }
  2854. }
  2855.  
  2856. return PLUGIN_HANDLED;
  2857. }
  2858.  
  2859. // Buy Menu 1
  2860. public menu_buy1(id, key)
  2861. {
  2862. // Zombies or survivors get no guns
  2863. if (!is_user_alive(id) || g_zombie[id] || g_survivor[id] || !g_canbuy[id])
  2864. return PLUGIN_HANDLED;
  2865.  
  2866. // Exit
  2867. if (key >= sizeof g_primary_names) return PLUGIN_HANDLED;
  2868.  
  2869. // Drop previous weapons
  2870. drop_weapons(id, 1);
  2871. drop_weapons(id, 2);
  2872.  
  2873. // Strip off from weapons
  2874. fm_strip_user_weapons(id)
  2875. fm_give_item(id, "weapon_knife")
  2876.  
  2877. // Give the new weapon
  2878. fm_give_item(id, g_primary_items[key])
  2879. fm_set_user_bpammo(id, get_weaponid(g_primary_items[key]), MAXAMMO[get_weaponid(g_primary_items[key])])
  2880.  
  2881. static i // weapons bought, give additional items
  2882. for (i = 0; i < sizeof g_additional_items; i++) fm_give_item(id, g_additional_items[i])
  2883.  
  2884. g_canbuy[id] = false
  2885. show_menu_buy2(id); // show pistol menu
  2886.  
  2887. return PLUGIN_HANDLED;
  2888. }
  2889.  
  2890. // Buy Menu 2
  2891. public menu_buy2(id, key)
  2892. {
  2893. // Zombies or survivors get no guns
  2894. if (!is_user_alive(id) || g_zombie[id] || g_survivor[id])
  2895. return PLUGIN_HANDLED;
  2896.  
  2897. // Exit
  2898. if (key >= sizeof g_secondary_names) return PLUGIN_HANDLED;
  2899.  
  2900. // Drop secondary gun again, in case we picked another (bugfix)
  2901. drop_weapons(id, 2);
  2902.  
  2903. // Give the new weapon
  2904. fm_give_item(id, g_secondary_items[key])
  2905. fm_set_user_bpammo(id, get_weaponid(g_secondary_items[key]), MAXAMMO[get_weaponid(g_secondary_items[key])])
  2906.  
  2907. return PLUGIN_HANDLED;
  2908. }
  2909.  
  2910. // Zombie Menu
  2911. public menu_zombie(id, key)
  2912. {
  2913. switch (key)
  2914. {
  2915. case ZCLASS_CLASSIC: client_print(id, print_chat, "[ZP] %L: %L", id, "ZOMBIE_SELECT", id, "CLASS_ZOMBIE1")
  2916. case ZCLASS_RAPTOR: client_print(id, print_chat, "[ZP] %L: %L", id, "ZOMBIE_SELECT", id, "CLASS_ZOMBIE2")
  2917. case ZCLASS_POISON: client_print(id, print_chat, "[ZP] %L: %L", id, "ZOMBIE_SELECT", id, "CLASS_ZOMBIE3")
  2918. case ZCLASS_FAT: client_print(id, print_chat, "[ZP] %L: %L", id, "ZOMBIE_SELECT", id, "CLASS_ZOMBIE4")
  2919. case ZCLASS_LEECH: client_print(id, print_chat, "[ZP] %L: %L", id, "ZOMBIE_SELECT", id, "CLASS_ZOMBIE5")
  2920. case ZCLASS_RAGE: client_print(id, print_chat, "[ZP] %L: %L", id, "ZOMBIE_SELECT", id, "CLASS_ZOMBIE6")
  2921. default: return PLUGIN_HANDLED;
  2922. }
  2923.  
  2924. g_zombieclassnext[id] = key;
  2925.  
  2926. client_print(id, print_chat, "[ZP] %L: %d %L: %d %L: %d %L: %d%%", id, "ZOMBIE_ATTRIB1", floatround(get_pcvar_float(cvar_zombiehp)*zombie_multihp[g_zombieclassnext[id]]/100), id, "ZOMBIE_ATTRIB2", floatround(get_pcvar_float(cvar_zombiespeed)*zombie_multispd[g_zombieclassnext[id]]/100),
  2927. id, "ZOMBIE_ATTRIB3", floatround(get_pcvar_float(cvar_zombiegravity)*zombie_multigrav[g_zombieclassnext[id]]/100*800), id, "ZOMBIE_ATTRIB4", zombie_multiknockback[g_zombieclassnext[id]])
  2928.  
  2929. return PLUGIN_HANDLED;
  2930. }
  2931.  
  2932. /*================================================================================
  2933. [Admin Commands]
  2934. =================================================================================*/
  2935.  
  2936. // zp_toggle [1/0]
  2937. public cmd_toggle(id, level, cid)
  2938. {
  2939. if (!cmd_access(id, level, cid, 2)) // check for access flag
  2940. return PLUGIN_HANDLED
  2941.  
  2942. static arg[2], mapname[32]
  2943. read_argv(1, arg, sizeof arg - 1)
  2944. get_mapname(mapname, sizeof mapname - 1);
  2945.  
  2946. // set toggle cvar
  2947. set_pcvar_num(cvar_toggle, str_to_num(arg))
  2948.  
  2949. // restart the map
  2950. server_cmd("changelevel %s", mapname)
  2951.  
  2952. return PLUGIN_HANDLED
  2953. }
  2954.  
  2955. // zp_zombie [target]
  2956. public cmd_zombie(id, level, cid)
  2957. {
  2958. if (!cmd_access(id, level, cid, 2)) // check for access flag
  2959. return PLUGIN_HANDLED
  2960.  
  2961. static arg[32], player
  2962. read_argv(1, arg, sizeof arg - 1)
  2963. player = cmd_target(id, arg, 4 | 2) // find target
  2964.  
  2965. if (!player) return PLUGIN_HANDLED
  2966.  
  2967. if (!allowed_zombie(player))
  2968. {
  2969. client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")
  2970. return PLUGIN_HANDLED
  2971. }
  2972.  
  2973. command_zombie(id, player)
  2974.  
  2975. return PLUGIN_HANDLED
  2976. }
  2977.  
  2978. // zp_human [target]
  2979. public cmd_human(id, level, cid)
  2980. {
  2981. if (!cmd_access(id, level, cid, 2)) // check for access flag
  2982. return PLUGIN_HANDLED
  2983.  
  2984. static arg[32], player
  2985. read_argv(1, arg, sizeof arg - 1)
  2986. player = cmd_target(id, arg, 4 | 2) // find target
  2987.  
  2988. if (!player) return PLUGIN_HANDLED
  2989.  
  2990. if (!allowed_human(player))
  2991. {
  2992. client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")
  2993. return PLUGIN_HANDLED
  2994. }
  2995.  
  2996. command_human(id, player)
  2997.  
  2998. return PLUGIN_HANDLED
  2999. }
  3000.  
  3001. // zp_survivor [target]
  3002. public cmd_survivor(id, level, cid)
  3003. {
  3004. if (!cmd_access(id, level, cid, 2)) // check for access flag
  3005. return PLUGIN_HANDLED
  3006.  
  3007. static arg[32], player
  3008. read_argv(1, arg, sizeof arg - 1)
  3009. player = cmd_target(id, arg, 4 | 2) // find target
  3010.  
  3011. if (!player) return PLUGIN_HANDLED
  3012.  
  3013. if (!allowed_survivor(player))
  3014. {
  3015. client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")
  3016. return PLUGIN_HANDLED
  3017. }
  3018.  
  3019. command_survivor(id, player)
  3020.  
  3021. return PLUGIN_HANDLED
  3022. }
  3023.  
  3024. // zp_nemesis [target]
  3025. public cmd_nemesis(id, level, cid)
  3026. {
  3027. if (!cmd_access(id, level, cid, 2)) // check for access flag
  3028. return PLUGIN_HANDLED
  3029.  
  3030. static arg[32], player
  3031. read_argv(1, arg, sizeof arg - 1)
  3032. player = cmd_target(id, arg, 4 | 2) // find target
  3033.  
  3034. if (!player) return PLUGIN_HANDLED
  3035.  
  3036. if (!allowed_nemesis(player))
  3037. {
  3038. client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")
  3039. return PLUGIN_HANDLED
  3040. }
  3041.  
  3042. command_nemesis(id, player)
  3043.  
  3044. return PLUGIN_HANDLED
  3045. }
  3046.  
  3047. // zp_respawn [target]
  3048. public cmd_respawn(id, level, cid)
  3049. {
  3050. if (!cmd_access(id, level, cid, 2)) // check for access flag
  3051. return PLUGIN_HANDLED
  3052.  
  3053. static arg[32], player
  3054. read_argv(1, arg, sizeof arg - 1)
  3055. player = cmd_target(id, arg, 2) // find target
  3056.  
  3057. if (!player) return PLUGIN_HANDLED
  3058.  
  3059. if (!allowed_respawn(player))
  3060. {
  3061. client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")
  3062. return PLUGIN_HANDLED
  3063. }
  3064.  
  3065. command_respawn(id, player)
  3066.  
  3067. return PLUGIN_HANDLED
  3068. }
  3069.  
  3070. // zp_swarm
  3071. public cmd_swarm(id, level, cid)
  3072. {
  3073. if (!cmd_access(id, level, cid, 1)) // check for access flag
  3074. return PLUGIN_HANDLED
  3075.  
  3076. if (!allowed_swarm())
  3077. {
  3078. client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")
  3079. return PLUGIN_HANDLED
  3080. }
  3081.  
  3082. command_swarm(id)
  3083.  
  3084. return PLUGIN_HANDLED
  3085. }
  3086.  
  3087. // zp_multi
  3088. public cmd_multi(id, level, cid)
  3089. {
  3090. if (!cmd_access(id, level, cid, 1)) // check for access flag
  3091. return PLUGIN_HANDLED
  3092.  
  3093. if (!allowed_multi())
  3094. {
  3095. client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")
  3096. return PLUGIN_HANDLED
  3097. }
  3098.  
  3099. command_multi(id)
  3100.  
  3101. return PLUGIN_HANDLED
  3102. }
  3103.  
  3104. /*================================================================================
  3105. [Message Hooks]
  3106. =================================================================================*/
  3107.  
  3108. // Current Weapon
  3109. public message_cur_weapon(msg_id, msg_dest, msg_entity)
  3110. {
  3111. // Player not alive or not an active weapon
  3112. if (!is_user_alive(msg_entity) || get_msg_arg_int(1) != 1)
  3113. return;
  3114.  
  3115. static weapon, clip
  3116. weapon = get_msg_arg_int(2) // get weapon ID
  3117. clip = get_msg_arg_int(3) // get weapon clip
  3118.  
  3119. g_currentweapon[msg_entity] = weapon // store weapon id for reference
  3120.  
  3121. // Retrieve our custom bpammo from the weapon entity
  3122. static wname[32], weapon_ent, extra_ammo
  3123. get_weaponname(weapon, wname, sizeof wname - 1);
  3124. weapon_ent = fm_find_ent_by_owner(-1, wname, msg_entity); // get weapon entity
  3125. extra_ammo = pev(weapon_ent, pev_iuser1); // get additional ammo (hack)
  3126.  
  3127. if (extra_ammo) // spare ammo goes to our bpammo (dont exceed max though)
  3128. {
  3129. fm_set_user_bpammo(msg_entity, weapon, min(fm_get_user_bpammo(msg_entity, weapon)+extra_ammo, MAXAMMO[weapon]))
  3130. set_pev(weapon_ent, pev_iuser1, 0)
  3131. }
  3132.  
  3133. // Unlimited BPAmmo
  3134. if ((get_pcvar_num(cvar_infammo) && MAXAMMO[weapon] > 1) || (g_survivor[msg_entity] && weapon == CSW_M249))
  3135. {
  3136. if (fm_get_user_bpammo(msg_entity, weapon) < MAXAMMO[weapon])
  3137. fm_set_user_bpammo(msg_entity, weapon, MAXAMMO[weapon])
  3138. }
  3139.  
  3140. // Unlimited Clip Ammo
  3141. if (get_pcvar_num(cvar_infammo) > 1 || (g_survivor[msg_entity] && weapon == CSW_M249))
  3142. {
  3143. if (MAXCLIP[weapon] > 2) // skip grenades
  3144. {
  3145. set_msg_arg_int(3, get_msg_argtype(3), MAXCLIP[weapon]) // HUD should show full clip all the time
  3146. if (clip < 2) fm_set_weapon_ammo(weapon_ent, MAXCLIP[weapon]) // refill
  3147. }
  3148. }
  3149.  
  3150. // Bots automatically buy ammo when needed
  3151. if (is_user_bot(msg_entity) && !g_zombie[msg_entity] && !g_survround && g_ammopacks[msg_entity] > 0 && MAXCLIP[weapon] > 2 && fm_get_user_bpammo(msg_entity, weapon) <= BUYAMMO[weapon])
  3152. clcmd_buyammo(msg_entity);
  3153.  
  3154. // Replace custom weapon models
  3155. replace_models(msg_entity);
  3156.  
  3157. // If zombie is not holding a knife/infection bomb for some reason
  3158. if (g_zombie[msg_entity] && weapon != CSW_KNIFE && weapon != CSW_HEGRENADE)
  3159. engclient_cmd(msg_entity, "weapon_knife"); // force him to do so
  3160. }
  3161.  
  3162. // Take off player's money
  3163. public message_money(msg_id, msg_dest, msg_entity)
  3164. {
  3165. if (!get_pcvar_num(cvar_removemoney))
  3166. return PLUGIN_CONTINUE;
  3167.  
  3168. set_pdata_int(msg_entity, OFFSET_CSMONEY, 0, OFFSET_LINUX);
  3169. return PLUGIN_HANDLED;
  3170. }
  3171.  
  3172. // Fix the HL engine bug when HP is multiples of 256
  3173. public message_health(msg_id, msg_dest, msg_entity)
  3174. {
  3175. static health
  3176. health = get_msg_arg_int(1) // get health
  3177.  
  3178. if (health < 256) return; // dont bother
  3179.  
  3180. if (floatfract(float(health)/256.0) == 0.0) // check if we need to fix it
  3181. fm_set_user_health(msg_entity, health+1)
  3182.  
  3183. set_msg_arg_int(1, get_msg_argtype(1), 255); // HUD only shows as much as 255 hp
  3184. }
  3185.  
  3186. // Hide player's money
  3187. public message_hideweapon()
  3188. {
  3189. if (!get_pcvar_num(cvar_removemoney))
  3190. return;
  3191.  
  3192. set_msg_arg_int(1, get_msg_argtype(1), get_msg_arg_int(1) | HIDE_MONEY);
  3193. }
  3194.  
  3195. // Block flashlight battery messages when it's not available, or if custom flashlight is enabled instead
  3196. public message_flashbat(msg_id, msg_dest, msg_entity)
  3197. {
  3198. if (get_pcvar_num(cvar_cflash) || !is_user_alive(msg_entity) || g_zombie[msg_entity] || g_survivor[msg_entity])
  3199. return PLUGIN_HANDLED;
  3200.  
  3201. return PLUGIN_CONTINUE;
  3202. }
  3203.  
  3204. // Flashbangs should only affect zombies
  3205. public message_screenfade(msg_id, msg_dest, msg_entity)
  3206. {
  3207. if (get_msg_arg_int(4) != 255 || get_msg_arg_int(5) != 255 || get_msg_arg_int(6) != 255 || get_msg_arg_int(7) < 200)
  3208. return PLUGIN_CONTINUE;
  3209.  
  3210. if (g_zombie[msg_entity] && !g_nemesis[msg_entity]) // nemesis shouldn't be FBed
  3211. {
  3212. // Set flash color to nighvision's
  3213. set_msg_arg_int(4, get_msg_argtype(4), get_pcvar_num(cvar_nvgcolor[0]))
  3214. set_msg_arg_int(5, get_msg_argtype(5), get_pcvar_num(cvar_nvgcolor[1]))
  3215. set_msg_arg_int(6, get_msg_argtype(6), get_pcvar_num(cvar_nvgcolor[2]))
  3216. return PLUGIN_CONTINUE;
  3217. }
  3218.  
  3219. return PLUGIN_HANDLED;
  3220. }
  3221.  
  3222. // Hide bomb carrier on the scoreboard
  3223. public message_scoreattrib()
  3224. {
  3225. if (get_msg_arg_int(2) & ATTRIB_BOMB)
  3226. set_msg_arg_int(2, get_msg_argtype(2), get_msg_arg_int(2) & ~ATTRIB_BOMB)
  3227. }
  3228.  
  3229. // Hide C4 icon display on HUD
  3230. public message_statusicon()
  3231. {
  3232. static sprite[3]
  3233. get_msg_arg_string(2, sprite, sizeof sprite - 1)
  3234.  
  3235. if(sprite[0] == 'c' && sprite[1] == '4')
  3236. return PLUGIN_HANDLED;
  3237.  
  3238. return PLUGIN_CONTINUE;
  3239. }
  3240.  
  3241. #if defined HANDLE_MODELS_ON_SEPARATE_ENT
  3242. // Set correct model for player corpses
  3243. public message_clcorpse()
  3244. {
  3245. set_msg_arg_string(1, g_playermodel[get_msg_arg_int(12)])
  3246. }
  3247. #endif
  3248.  
  3249. // Block weapon pickup messsages
  3250. public message_weappickup(msg_id, msg_dest, msg_entity)
  3251. {
  3252. if (g_zombie[msg_entity]) // prevent zombies from seeing any weapon pickup icon
  3253. return PLUGIN_HANDLED;
  3254.  
  3255. return PLUGIN_CONTINUE;
  3256. }
  3257.  
  3258. // Block ammo pickup messages
  3259. public message_ammopickup(msg_id, msg_dest, msg_entity)
  3260. {
  3261. if (g_zombie[msg_entity]) // prevent zombies from seeing any ammo pickup icon
  3262. return PLUGIN_HANDLED;
  3263.  
  3264. return PLUGIN_CONTINUE;
  3265. }
  3266.  
  3267. // Block hostage HUD display
  3268. public message_scenario()
  3269. {
  3270. if (get_msg_args() > 1)
  3271. {
  3272. static sprite[8]
  3273. get_msg_arg_string(2, sprite, sizeof sprite - 1)
  3274.  
  3275. if (equal(sprite, "hostage"))
  3276. return PLUGIN_HANDLED;
  3277. }
  3278.  
  3279. return PLUGIN_CONTINUE;
  3280. }
  3281.  
  3282. // Block hostages from appearing on radar
  3283. public message_hostagepos()
  3284. {
  3285. return PLUGIN_HANDLED;
  3286. }
  3287.  
  3288. // Block bomb dropped message so it doesn't show up in the radar
  3289. public message_bombdrop()
  3290. {
  3291. return PLUGIN_HANDLED;
  3292. }
  3293.  
  3294. // Block some text messages
  3295. public message_textmsg()
  3296. {
  3297. static textmsg[22]
  3298. get_msg_arg_string(2, textmsg, sizeof textmsg - 1);
  3299.  
  3300. // Game restarting, reset scores and call round end to balance the teams
  3301. if (equal(textmsg, "#Game_will_restart_in"))
  3302. {
  3303. g_scorehumans = 0
  3304. g_scorezombies = 0
  3305. event_round_end()
  3306. }
  3307. // Block bomb/round related messages
  3308. else if (equal(textmsg, "#Game_bomb_drop") || equal(textmsg, "#Target_Saved") || equal(textmsg, "#Round_Draw") || equal(textmsg, "#Terrorists_Win") || equal(textmsg, "#CTs_Win"))
  3309. {
  3310. return PLUGIN_HANDLED;
  3311. }
  3312.  
  3313. return PLUGIN_CONTINUE;
  3314. }
  3315.  
  3316. // Block round win audio messages
  3317. public message_sendaudio()
  3318. {
  3319. static audio[17]
  3320. get_msg_arg_string(2, audio, sizeof audio - 1)
  3321.  
  3322. if(equal(audio, "%!MRAD_terwin") || equal(audio, "%!MRAD_ctwin") || equal(audio, "%!MRAD_rounddraw"))
  3323. return PLUGIN_HANDLED;
  3324.  
  3325. return PLUGIN_CONTINUE;
  3326. }
  3327.  
  3328. // Send actual team scores (T = zombies // CT = humans)
  3329. public message_teamscore()
  3330. {
  3331. static team[2]
  3332. get_msg_arg_string(1, team, sizeof team - 1)
  3333.  
  3334. if (team[0] == 'C') // CT
  3335. set_msg_arg_int(2, get_msg_argtype(2), g_scorehumans);
  3336.  
  3337. else if (team[0] == 'T') // Terrorist
  3338. set_msg_arg_int(2, get_msg_argtype(2), g_scorezombies);
  3339. }
  3340.  
  3341. // Team Switch (or player joining a team for first time)
  3342. public message_teaminfo(msg_id, msg_dest)
  3343. {
  3344. // Only hook global messages
  3345. if (msg_dest != MSG_ALL && msg_dest != MSG_BROADCAST) return;
  3346.  
  3347. static id // get player id
  3348. id = get_msg_arg_int(1)
  3349.  
  3350. // Don't pick up our own TeamInfo messages for this player (bugfix)
  3351. if (g_switchingteam[id]) return;
  3352.  
  3353. static team[2] // get his new team
  3354. get_msg_arg_string(2, team, sizeof team - 1)
  3355.  
  3356. if (team[0] == 'C') // CT
  3357. {
  3358. if (!g_newround) // round started
  3359. {
  3360. if (g_survround && fnGetHumans()) // survivor alive --> switch to T and spawn as zombie
  3361. {
  3362. g_respawn_as_zombie[id] = true;
  3363. remove_task(id+TEAM_TASK)
  3364. fm_set_user_team(id, CS_TEAM_T)
  3365. set_msg_arg_string(2, "Terrorist")
  3366. }
  3367. else if (!fnGetZombies()) // no zombies alive --> switch to T and spawn as zombie
  3368. {
  3369. g_respawn_as_zombie[id] = true;
  3370. remove_task(id+TEAM_TASK)
  3371. fm_set_user_team(id, CS_TEAM_T)
  3372. set_msg_arg_string(2, "Terrorist")
  3373. }
  3374. }
  3375. }
  3376. else if (team[0] == 'T') // Terrorist
  3377. {
  3378. if (!g_newround) // round started
  3379. {
  3380. if ((g_swarmround || g_survround) && fnGetHumans()) // survivor alive or swarm round w/ humans --> spawn as zombie
  3381. {
  3382. g_respawn_as_zombie[id] = true;
  3383. }
  3384. else if (fnGetZombies()) // zombies alive --> switch to CT
  3385. {
  3386. remove_task(id+TEAM_TASK)
  3387. fm_set_user_team(id, CS_TEAM_CT)
  3388. set_msg_arg_string(2, "CT")
  3389. }
  3390. }
  3391. }
  3392.  
  3393. // Enable spectators' nightvision if not spawning
  3394. set_task(0.2, "spec_nvision", id)
  3395. }
  3396.  
  3397. /*================================================================================
  3398. [Main Functions]
  3399. =================================================================================*/
  3400.  
  3401. // Make Zombie Task
  3402. public make_zombie_task()
  3403. {
  3404. // Call make a zombie with no specific mode
  3405. make_a_zombie(MODE_NONE, 0);
  3406. }
  3407.  
  3408. // Make a Zombie Function
  3409. make_a_zombie(mode, id)
  3410. {
  3411. // Get alive players count
  3412. static iPlayersnum
  3413. iPlayersnum = fnGetAlive()
  3414.  
  3415. if (iPlayersnum < 1) // not enough players
  3416. {
  3417. set_task(10.0, "make_zombie_task", MAKEZOMBIE_TASK)
  3418. return;
  3419. }
  3420.  
  3421. g_models_i = 0.0 // reset model change count
  3422. g_teams_i = 0.0 // reset teams change count
  3423.  
  3424. // round starting
  3425. g_newround = false
  3426. g_survround = false
  3427. g_nemround = false
  3428. g_swarmround = false
  3429.  
  3430. if ((mode == MODE_NONE && random_num(1, get_pcvar_num(cvar_survchance)) == get_pcvar_num(cvar_surv)) || mode == MODE_SURVIVOR)
  3431. {
  3432. // Survivor Mode
  3433.  
  3434. if (mode == MODE_NONE) // choose player randomly?
  3435. id = fnGetRandomAlive(random_num(1, iPlayersnum))
  3436.  
  3437. g_survround = true // survivor round
  3438.  
  3439. // remember id for calling our forward later
  3440. static fwid; fwid = id;
  3441.  
  3442. humanme(id, 1) // turn into survivor
  3443.  
  3444. // Turn the rest of players into zombies
  3445. for (id = 1; id <= g_maxplayers; id++)
  3446. {
  3447. if (!is_user_alive(id)) // skip dead
  3448. continue;
  3449.  
  3450. if (g_survivor[id]) // skip the survivor
  3451. continue;
  3452.  
  3453. zombieme(id, 0, 0, 1) // turn into a zombie
  3454. }
  3455.  
  3456. // Round start forward
  3457. ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_SURVIVOR, fwid);
  3458. }
  3459. else if ((mode == MODE_NONE && random_num(1, get_pcvar_num(cvar_swarmchance)) == get_pcvar_num(cvar_swarm)) || mode == MODE_SWARM)
  3460. {
  3461. // Swarm Mode
  3462.  
  3463. g_swarmround = true // swarm round
  3464.  
  3465. // Turn all the T into zombies
  3466. for (id = 1; id <= g_maxplayers; id++)
  3467. {
  3468. if (!is_user_alive(id)) // not alive
  3469. continue;
  3470.  
  3471. if (fm_get_user_team(id) == CS_TEAM_T) // only Terrorists
  3472. zombieme(id, 0, 0, 1) // turn into a zombie
  3473. }
  3474.  
  3475. // Play swarm sound
  3476. PlaySound(sound_swarm[random_num(0, sizeof sound_swarm -1)]);
  3477.  
  3478. // Show Swarm HUD notice
  3479. set_hudmessage(20, 255, 20, -1.0, 0.17, 1, 0.0, 5.0, 1.0, 1.0, -1)
  3480. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_SWARM")
  3481.  
  3482. // Round start forward
  3483. ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_SWARM, 0);
  3484. }
  3485. else if ((mode == MODE_NONE && random_num(1, get_pcvar_num(cvar_multichance)) == get_pcvar_num(cvar_multi) && floatround(iPlayersnum*get_pcvar_float(cvar_multiratio), floatround_ceil) > 1) || mode == MODE_MULTI)
  3486. {
  3487. // Multi Infection Mode
  3488.  
  3489. static iZombies, iMaxZombies
  3490.  
  3491. // iMaxZombies is rounded up, in case there aren't enough players
  3492. iMaxZombies = floatround(iPlayersnum*get_pcvar_float(cvar_multiratio), floatround_ceil)
  3493. iZombies = 0
  3494.  
  3495. // Randomly turn iMaxZombies players into zombies
  3496. while (iZombies < iMaxZombies)
  3497. {
  3498. if (id < g_maxplayers)
  3499. id++
  3500. else
  3501. id = 1
  3502.  
  3503. if (!is_user_alive(id) || g_zombie[id]) // dead or already a zombie
  3504. continue;
  3505.  
  3506. if (random_num(0, 1))
  3507. {
  3508. zombieme(id, 0, 0, 1) // turn into a zombie
  3509. iZombies++
  3510. }
  3511. }
  3512.  
  3513. // Turn the rest of players into humans
  3514. for (id = 1; id <= g_maxplayers; id++)
  3515. {
  3516. if (!is_user_alive(id) || g_zombie[id]) // only those of them who arent zombies
  3517. continue
  3518.  
  3519. // remove previous tasks
  3520. remove_task(id+TEAM_TASK)
  3521.  
  3522. // Switch to CT
  3523. if (fm_get_user_team(id) != CS_TEAM_CT) // need to change team?
  3524. {
  3525. fm_set_user_team(id, CS_TEAM_CT)
  3526. set_task(0.1+g_teams_i, "fm_set_user_team_msg", id+TEAM_TASK)
  3527. g_teams_i += 0.1; // increase teams task count
  3528. }
  3529. }
  3530.  
  3531. // Play multi infection sound
  3532. PlaySound(sound_multi[random_num(0, sizeof sound_multi -1)]);
  3533.  
  3534. // Show Multi Infection HUD notice
  3535. set_hudmessage(200, 50, 0, -1.0, 0.17, 1, 0.0, 5.0, 1.0, 1.0, -1)
  3536. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_MULTI")
  3537.  
  3538. // Round start forward
  3539. ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_MULTI, 0);
  3540. }
  3541. else
  3542. {
  3543. // Single Infection Mode - Nemesis Mode
  3544.  
  3545. if (mode == MODE_NONE) // choose player randomly?
  3546. id = fnGetRandomAlive(random_num(1, iPlayersnum))
  3547.  
  3548. // remember id for calling our forward later
  3549. static fwid; fwid = id;
  3550.  
  3551. if ((mode == MODE_NONE && random_num(1, get_pcvar_num(cvar_nemchance)) == get_pcvar_num(cvar_nem)) || mode == MODE_NEMESIS)
  3552. {
  3553. g_nemround = true // nemesis round
  3554. zombieme(id, 0, 1, 0); // turn into nemesis
  3555. }
  3556. else
  3557. {
  3558. zombieme(id, 0, 0, 0) // boring first zombie
  3559. }
  3560.  
  3561. // Rest of players should be humans (CTs)
  3562. for (id = 1; id <= g_maxplayers; id++)
  3563. {
  3564. if (!is_user_alive(id)) // skip dead
  3565. continue;
  3566.  
  3567. if (g_zombie[id]) // skip our first zombie/nemesis
  3568. continue;
  3569.  
  3570. // Remove previous tasks
  3571. remove_task(id+TEAM_TASK)
  3572.  
  3573. // Switch to CT
  3574. if (fm_get_user_team(id) != CS_TEAM_CT) // need to change team?
  3575. {
  3576. fm_set_user_team(id, CS_TEAM_CT)
  3577. set_task(0.1+g_teams_i, "fm_set_user_team_msg", id+TEAM_TASK)
  3578. g_teams_i += 0.1; // increase teams task count
  3579. }
  3580. }
  3581.  
  3582. // Round start forward
  3583. if (g_nemround) ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_NEMESIS, fwid);
  3584. else ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_INFECTION, fwid);
  3585. }
  3586.  
  3587. // Last Zombie Check
  3588. set_task(0.1, "fnCheckLastZombie")
  3589. }
  3590.  
  3591. // Zombie Me Function (player id, infector, turn into a nemesis, special mode)
  3592. zombieme(id, infector, nemesis, specialmode)
  3593. {
  3594. if (g_zombie[id]) // already a zombie...
  3595. return;
  3596.  
  3597. // Pre user infect forward
  3598. ExecuteForward(g_fwUserInfected_pre, g_fwDummyResult, id, infector);
  3599.  
  3600. // Show zombie class menu if they haven't chosen any (e.g. just connected)
  3601. if (g_zombieclass[id] == ZCLASS_NONE && get_pcvar_num(cvar_zclasses))
  3602. set_task(2.0, "show_menu_zombie", id);
  3603.  
  3604. // Set our new zombie class
  3605. g_zombieclass[id] = g_zombieclassnext[id];
  3606.  
  3607. // Way to go...
  3608. g_zombie[id] = true
  3609.  
  3610. if (!specialmode) // no special mode
  3611. {
  3612. if (nemesis)
  3613. {
  3614. // Nemesis
  3615. g_nemesis[id] = true
  3616.  
  3617. if (get_pcvar_num(cvar_nemleap)) // give nemesis leap?
  3618. fm_give_item(id, "item_longjump")
  3619.  
  3620. if (!get_pcvar_num(cvar_nemhp)) // nemesis health
  3621. fm_set_user_health(id, 1+get_pcvar_num(cvar_zombiehp)*fnGetHumans())
  3622. else
  3623. fm_set_user_health(id, get_pcvar_num(cvar_nemhp))
  3624.  
  3625. set_pev(id, pev_gravity, get_pcvar_float(cvar_nemgravity)) // nemesis gravity
  3626.  
  3627. // Play Nemesis sound
  3628. PlaySound(sound_nemesis[random_num(0, sizeof sound_nemesis -1)]);
  3629.  
  3630. static name[32]
  3631. get_user_name(id, name, sizeof name - 1)
  3632.  
  3633. // Show Nemesis HUD notice
  3634. set_hudmessage(255, 20, 20, -1.0, 0.17, 1, 0.0, 5.0, 1.0, 1.0, -1)
  3635. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_NEMESIS", name)
  3636. }
  3637. else if (fnGetZombies() == 1)
  3638. {
  3639. // First zombie
  3640. g_firstzombie[id] = true
  3641.  
  3642. fm_set_user_health(id, get_pcvar_num(cvar_zombiefirsthp)*zombie_multihp[g_zombieclass[id]]/100)
  3643. set_pev(id, pev_gravity, get_pcvar_float(cvar_zombiegravity)*zombie_multigrav[g_zombieclass[id]]/100)
  3644.  
  3645. // Play First Zombie sound
  3646. engfunc(EngFunc_EmitSound, id, CHAN_VOICE, zombie_infect[random_num(0, sizeof zombie_infect - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
  3647.  
  3648. if (get_pcvar_num(cvar_zombiefirstleap)) // give leap to First Zombie?
  3649. fm_give_item(id, "item_longjump")
  3650.  
  3651. static name[32]
  3652. get_user_name(id, name, sizeof name - 1)
  3653.  
  3654. // Show First Zombie HUD notice
  3655. set_hudmessage(255, 0, 0, -1.0, 0.17, 0, 0.0, 5.0, 1.0, 1.0, -1)
  3656. ShowSyncHudMsg(0, g_MsgSync, "%L",LANG_PLAYER, "NOTICE_FIRST", name)
  3657. }
  3658. else
  3659. {
  3660. // Infected by someone
  3661. fm_set_user_health(id, get_pcvar_num(cvar_zombiehp)*zombie_multihp[g_zombieclass[id]]/100)
  3662. set_pev(id, pev_gravity, get_pcvar_float(cvar_zombiegravity)*zombie_multigrav[g_zombieclass[id]]/100)
  3663.  
  3664. // Play Infection sound
  3665. engfunc(EngFunc_EmitSound, id, CHAN_VOICE, zombie_infect[random_num(0, sizeof zombie_infect - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
  3666.  
  3667. static name[32]
  3668. get_user_name(id, name, sizeof name - 1)
  3669.  
  3670. // Show Infection HUD notice
  3671. set_hudmessage(255, 0, 0, 0.05, 0.45, 0, 0.0, 5.0, 1.0, 1.0, -1)
  3672.  
  3673. if (infector) // infected by someone?
  3674. {
  3675. static name2[32]
  3676. get_user_name(infector, name2, sizeof name2 - 1)
  3677. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_INFECT2", name, name2)
  3678. }
  3679. else ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_INFECT", name)
  3680. }
  3681. }
  3682. else
  3683. {
  3684. // Survivor/multi infection mode/infection grenade: normal zombie stats, no HUD notice
  3685. fm_set_user_health(id, get_pcvar_num(cvar_zombiehp)*zombie_multihp[g_zombieclass[id]]/100)
  3686. set_pev(id, pev_gravity, get_pcvar_float(cvar_zombiegravity)*zombie_multigrav[g_zombieclass[id]]/100)
  3687. }
  3688.  
  3689. // Remove previous tasks
  3690. remove_task(id+TEAM_TASK)
  3691. remove_task(id+MODEL_TASK)
  3692. remove_task(id+BLOOD_TASK)
  3693.  
  3694. // Switch to T
  3695. if (fm_get_user_team(id) != CS_TEAM_T) // need to change team?
  3696. {
  3697. if (specialmode) // set a longer delay for survivor/multi infection mode/infection grenade
  3698. {
  3699. fm_set_user_team(id, CS_TEAM_T);
  3700. set_task(0.1+g_teams_i, "fm_set_user_team_msg", id+TEAM_TASK)
  3701. g_teams_i += 0.1;
  3702. }
  3703. else
  3704. {
  3705. fm_set_user_team(id, CS_TEAM_T)
  3706. set_task(0.1, "fm_set_user_team_msg", id+TEAM_TASK)
  3707. }
  3708. }
  3709.  
  3710. #if defined HANDLE_MODELS_ON_SEPARATE_ENT
  3711.  
  3712. // Set the right model
  3713. if (g_nemesis[id])
  3714. copy(g_playermodel[id], 32, model_nemesis[random_num(0, sizeof model_nemesis -1)])
  3715. else
  3716. {
  3717. switch (g_zombieclass[id])
  3718. {
  3719. case ZCLASS_CLASSIC: copy(g_playermodel[id], 32, model_zombie_class1[random_num(0, sizeof model_zombie_class1 -1)])
  3720. case ZCLASS_RAPTOR: copy(g_playermodel[id], 32, model_zombie_class2[random_num(0, sizeof model_zombie_class2 -1)])
  3721. case ZCLASS_POISON: copy(g_playermodel[id], 32, model_zombie_class3[random_num(0, sizeof model_zombie_class3 -1)])
  3722. case ZCLASS_FAT: copy(g_playermodel[id], 32, model_zombie_class4[random_num(0, sizeof model_zombie_class4 -1)])
  3723. case ZCLASS_LEECH: copy(g_playermodel[id], 32, model_zombie_class5[random_num(0, sizeof model_zombie_class5 -1)])
  3724. case ZCLASS_RAGE: copy(g_playermodel[id], 32, model_zombie_class6[random_num(0, sizeof model_zombie_class6 -1)])
  3725. }
  3726. }
  3727.  
  3728. fm_set_user_model_ent(id) // set model on entity
  3729.  
  3730. #else
  3731.  
  3732. // Set the right model, but check that we don't have it already
  3733. static currentmodel[33], already_has_model, i
  3734. already_has_model = false;
  3735. fm_get_user_model(id, currentmodel, sizeof currentmodel - 1); // get current model
  3736.  
  3737. if (g_nemesis[id])
  3738. {
  3739. for (i = 0; i < sizeof model_nemesis; i++)
  3740. if (equal(model_nemesis[i], currentmodel)) already_has_model = true;
  3741.  
  3742. if (!already_has_model) copy(g_playermodel[id], 32, model_nemesis[random_num(0, sizeof model_nemesis -1)])
  3743. }
  3744. else
  3745. {
  3746. switch (g_zombieclass[id])
  3747. {
  3748. case ZCLASS_CLASSIC:
  3749. {
  3750. for (i = 0; i < sizeof model_zombie_class1; i++)
  3751. if (equal(model_zombie_class1[i], currentmodel)) already_has_model = true;
  3752.  
  3753. if (!already_has_model) copy(g_playermodel[id], 32, model_zombie_class1[random_num(0, sizeof model_zombie_class1 -1)])
  3754. }
  3755. case ZCLASS_RAPTOR:
  3756. {
  3757. for (i = 0; i < sizeof model_zombie_class2; i++)
  3758. if (equal(model_zombie_class2[i], currentmodel)) already_has_model = true;
  3759.  
  3760. if (!already_has_model) copy(g_playermodel[id], 32, model_zombie_class2[random_num(0, sizeof model_zombie_class2 -1)])
  3761. }
  3762. case ZCLASS_POISON:
  3763. {
  3764. for (i = 0; i < sizeof model_zombie_class3; i++)
  3765. if (equal(model_zombie_class3[i], currentmodel)) already_has_model = true;
  3766.  
  3767. if (!already_has_model) copy(g_playermodel[id], 32, model_zombie_class3[random_num(0, sizeof model_zombie_class3 -1)])
  3768. }
  3769. case ZCLASS_FAT:
  3770. {
  3771. for (i = 0; i < sizeof model_zombie_class4; i++)
  3772. if (equal(model_zombie_class4[i], currentmodel)) already_has_model = true;
  3773.  
  3774. if (!already_has_model) copy(g_playermodel[id], 32, model_zombie_class4[random_num(0, sizeof model_zombie_class4 -1)])
  3775. }
  3776. case ZCLASS_LEECH:
  3777. {
  3778. for (i = 0; i < sizeof model_zombie_class5; i++)
  3779. if (equal(model_zombie_class5[i], currentmodel)) already_has_model = true;
  3780.  
  3781. if (!already_has_model) copy(g_playermodel[id], 32, model_zombie_class5[random_num(0, sizeof model_zombie_class5 -1)])
  3782. }
  3783. case ZCLASS_RAGE:
  3784. {
  3785. for (i = 0; i < sizeof model_zombie_class6; i++)
  3786. if (equal(model_zombie_class6[i], currentmodel)) already_has_model = true;
  3787.  
  3788. if (!already_has_model) copy(g_playermodel[id], 32, model_zombie_class6[random_num(0, sizeof model_zombie_class6 -1)])
  3789. }
  3790. }
  3791. }
  3792.  
  3793. if (!already_has_model) // need to change the model?
  3794. {
  3795. if (specialmode) // longer delay for survivor/multi infection mode/infection grenade
  3796. {
  3797. set_task(0.1+MODELCHANGE_DELAY+g_models_i, "fm_set_user_model", id+MODEL_TASK) // set model with a delay
  3798. g_models_i += MODELCHANGE_DELAY;
  3799. }
  3800. else
  3801. {
  3802. fm_set_user_model(id+MODEL_TASK) // set model instantly
  3803. }
  3804. }
  3805.  
  3806. #endif
  3807.  
  3808. // Remove any zoom (bugfix)
  3809. fm_remove_user_zoom(id)
  3810.  
  3811. // Drop weapons when infected?
  3812. if (get_pcvar_num(cvar_dropwpn) > 0) drop_weapons(id, 1);
  3813. if (get_pcvar_num(cvar_dropwpn) > 1) drop_weapons(id, 2);
  3814.  
  3815. fm_strip_user_weapons(id) // strip zombies from guns
  3816. fm_give_item(id, "weapon_knife")
  3817.  
  3818. // Some fancy effects
  3819. infectionFX1(id);
  3820. infectionFX2(id);
  3821.  
  3822. // Give Zombies Night Vision?
  3823. if (get_pcvar_num(cvar_nvggive))
  3824. {
  3825. if (!is_user_bot(id))
  3826. {
  3827. g_nvision[id] = true
  3828.  
  3829. // Turn on Night Vision automatically?
  3830. if (get_pcvar_num(cvar_nvggive) == 1)
  3831. {
  3832. g_nvisionenabled[id] = true
  3833.  
  3834. if (get_pcvar_num(cvar_cnvg)) // custom nvg?
  3835. {
  3836. remove_task(id+NVISION_TASK);
  3837. set_task(0.1, "set_user_nvision", id+NVISION_TASK, _, _, "b")
  3838. }
  3839. else set_user_gnvision(id, 1)
  3840. }
  3841. }
  3842. else fm_set_bot_nvg(id, 1); // turn on NVG for bots
  3843. }
  3844.  
  3845. #if defined HANDLE_MODELS_ON_SEPARATE_ENT
  3846. if (g_nemesis[id] && get_pcvar_num(cvar_nemglow)) // nemesis glow
  3847. fm_set_rendering(fm_find_ent_by_owner(-1, "player_model", id), kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 25)
  3848. if (!g_nemesis[id] && g_zombieclass[id] == ZCLASS_RAGE) // rage zombie glow
  3849. fm_set_rendering(fm_find_ent_by_owner(-1, "player_model", id), kRenderFxGlowShell, 0, 255, 0, kRenderNormal, 25)
  3850. #else
  3851. if (g_nemesis[id] && get_pcvar_num(cvar_nemglow)) // nemesis glow
  3852. fm_set_rendering(id, kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 25)
  3853. if (!g_nemesis[id] && g_zombieclass[id] == ZCLASS_RAGE) // rage zombie glow
  3854. fm_set_rendering(id, kRenderFxGlowShell, 0, 255, 0, kRenderNormal, 25)
  3855. #endif
  3856.  
  3857. // Set custom FOV
  3858. if (get_pcvar_num(cvar_zombiefov) != 90 && get_pcvar_num(cvar_zombiefov) != 0)
  3859. {
  3860. message_begin(MSG_ONE, g_msgSetFOV, _, id);
  3861. write_byte(get_pcvar_num(cvar_zombiefov));
  3862. message_end();
  3863. }
  3864.  
  3865. // Call the bloody task
  3866. if (!g_nemesis[id] && get_pcvar_num(cvar_zombiebleeding))
  3867. set_task(0.7, "make_blood", id+BLOOD_TASK, _, _, "b")
  3868.  
  3869. // Idle sounds task
  3870. if (!g_nemesis[id])
  3871. set_task(random_float(50.0, 70.0), "zombie_play_idle", id+BLOOD_TASK, _, _, "b");
  3872.  
  3873. // Turn off zombie's flashlight
  3874. turn_off_flashlight(id)
  3875. set_task(3.0, "turn_off_flashlight", id) // bugfix
  3876.  
  3877. // Post user infect forward
  3878. ExecuteForward(g_fwUserInfected_post, g_fwDummyResult, id, infector);
  3879. fm_give_item(id, "item_longjump")
  3880. // Last Zombie Check
  3881. set_task(0.1, "fnCheckLastZombie")
  3882. }
  3883.  
  3884. // Function Human Me (player id, turn into a survivor)
  3885. humanme(id, survivor)
  3886. {
  3887. // Pre user humanize forward
  3888. ExecuteForward(g_fwUserHumanized_pre, g_fwDummyResult, id);
  3889.  
  3890. // Remove previous tasks
  3891. remove_task(id+TEAM_TASK)
  3892. remove_task(id+MODEL_TASK)
  3893. remove_task(id+BLOOD_TASK)
  3894.  
  3895. // Reset some vars
  3896. g_zombie[id] = false
  3897. g_firstzombie[id] = false
  3898. g_nodamage[id] = false
  3899. g_canbuy[id] = true
  3900. g_nvision[id] = false
  3901. g_nvisionenabled[id] = false
  3902.  
  3903. // Switch to CT
  3904. if (fm_get_user_team(id) != CS_TEAM_CT) // need to change team?
  3905. {
  3906. fm_set_user_team(id, CS_TEAM_CT);
  3907. fm_set_user_team_msg(id+TEAM_TASK);
  3908. }
  3909.  
  3910. #if defined HANDLE_MODELS_ON_SEPARATE_ENT
  3911.  
  3912. // Set the right model
  3913. if (get_user_flags(id) & ACCESS_FLAG)
  3914. copy(g_playermodel[id], 32, model_admin[random_num(0, sizeof model_admin -1)])
  3915. else
  3916. copy(g_playermodel[id], 32, model_human[random_num(0, sizeof model_human -1)])
  3917.  
  3918. fm_set_user_model_ent(id) // set model
  3919. if (!g_frozen[id]) fm_set_rendering(fm_find_ent_by_owner(-1, "player_model", id)) // remove glow, unless frozen
  3920.  
  3921. #else
  3922.  
  3923. // Set the right model, but check that we don't have it already
  3924. static currentmodel[33], already_has_model, i
  3925. already_has_model = false;
  3926. fm_get_user_model(id, currentmodel, sizeof currentmodel - 1); // get current model
  3927.  
  3928. if (get_user_flags(id) & ACCESS_FLAG)
  3929. {
  3930. for (i = 0; i < sizeof model_admin; i++)
  3931. if (equal(model_admin[i], currentmodel)) already_has_model = true;
  3932.  
  3933. if (!already_has_model) copy(g_playermodel[id], 32, model_admin[random_num(0, sizeof model_admin -1)])
  3934. }
  3935. else
  3936. {
  3937. for (i = 0; i < sizeof model_human; i++)
  3938. if (equal(model_human[i], currentmodel)) already_has_model = true;
  3939.  
  3940. if (!already_has_model) copy(g_playermodel[id], 32, model_human[random_num(0, sizeof model_human -1)])
  3941. }
  3942.  
  3943. if (!already_has_model) fm_set_user_model(id+MODEL_TASK) // set model instantly
  3944. if (!g_frozen[id]) fm_set_rendering(id) // remove glow, unless frozen
  3945.  
  3946. #endif
  3947.  
  3948. // Restore FOV
  3949. if (get_pcvar_num(cvar_zombiefov) != 90 && get_pcvar_num(cvar_zombiefov) != 0)
  3950. {
  3951. message_begin(MSG_ONE, g_msgSetFOV, _, id);
  3952. write_byte(90);
  3953. message_end();
  3954. }
  3955.  
  3956. // Disable nightvision
  3957. if (is_user_bot(id)) fm_set_bot_nvg(id, 0)
  3958. else if (!get_pcvar_num(cvar_cnvg)) set_user_gnvision(id, 0)
  3959.  
  3960. // Remove leap
  3961. engfunc(EngFunc_SetPhysicsKeyValue, id, "slj", "0")
  3962.  
  3963. // Replace custom weapon models
  3964. replace_models(id);
  3965.  
  3966. if (survivor)
  3967. {
  3968. // Survivor
  3969.  
  3970. g_survivor[id] = true // set var
  3971.  
  3972. if (get_pcvar_num(cvar_survleap)) // give survivor leap?
  3973. fm_give_item(id, "item_longjump")
  3974.  
  3975. // Set Health [0 = auto]
  3976. if (!get_pcvar_num(cvar_survhp))
  3977. fm_set_user_health(id, fnGetHumans()*get_pcvar_num(cvar_humanhp))
  3978. else
  3979. fm_set_user_health(id, get_pcvar_num(cvar_survhp))
  3980.  
  3981. // Set Gravity
  3982. set_pev(id, pev_gravity, get_pcvar_float(cvar_survgravity))
  3983.  
  3984. // Glow?
  3985. if (get_pcvar_num(cvar_survglow))
  3986. {
  3987. #if defined HANDLE_MODELS_ON_SEPARATE_ENT
  3988. fm_set_rendering(fm_find_ent_by_owner(-1, "player_model", id), kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 25)
  3989. #else
  3990. fm_set_rendering(id, kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 25)
  3991. #endif
  3992. }
  3993.  
  3994. fm_strip_user_weapons(id) // strip player from weapons
  3995. fm_give_item(id, "weapon_knife")
  3996. fm_give_item(id, "weapon_m249") // give M249
  3997.  
  3998. // Turn off his flashlight
  3999. turn_off_flashlight(id)
  4000. set_task(3.0, "turn_off_flashlight", id) // bugfix
  4001.  
  4002. // Give the survivor a bright light
  4003. if (get_pcvar_num(cvar_survaura)) set_pev(id, pev_effects, pev(id, pev_effects) | EF_BRIGHTLIGHT)
  4004.  
  4005. // Survivor bots will also need nightvision to see in the dark
  4006. if (is_user_bot(id)) fm_set_bot_nvg(id, 1);
  4007.  
  4008. // Play survivor sound
  4009. PlaySound(sound_survivor[random_num(0, sizeof sound_survivor -1)]);
  4010.  
  4011. static name[32]
  4012. get_user_name(id, name, sizeof name - 1)
  4013.  
  4014. // show Survivor HUD notice
  4015. set_hudmessage(20, 20, 255, -1.0, 0.17, 1, 0.0, 5.0, 1.0, 1.0, -1)
  4016. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_SURVIVOR", name)
  4017. }
  4018. else
  4019. {
  4020. // Human taking an antidote
  4021.  
  4022. // Antidote sound
  4023. engfunc(EngFunc_EmitSound, id, CHAN_ITEM, sound_antidote[random_num(0, sizeof sound_antidote - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
  4024.  
  4025. // Restore health
  4026. fm_set_user_health(id, get_pcvar_num(cvar_humanhp))
  4027.  
  4028. // Restore gravity, unless frozen
  4029. if (!g_frozen[id]) set_pev(id, pev_gravity, get_pcvar_float(cvar_humangravity))
  4030.  
  4031. // Show custom buy menu?
  4032. if (get_pcvar_num(cvar_buycustom))
  4033. {
  4034. set_task(0.5, "show_menu_buy1", id+SPAWN_TASK);
  4035. set_task(10.5, "show_menu_buy1", id+SPAWN_TASK); // re-show in case it gets overlapped
  4036. }
  4037.  
  4038. static name[32]
  4039. get_user_name(id, name, sizeof name - 1)
  4040.  
  4041. // show Antidote HUD notice
  4042. set_hudmessage(0, 0, 255, 0.05, 0.45, 0, 0.0, 5.0, 1.0, 1.0, -1)
  4043. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_ANTIDOTE", name)
  4044. }
  4045.  
  4046. // Post user humanize forward
  4047. ExecuteForward(g_fwUserHumanized_post, g_fwDummyResult, id);
  4048. fm_give_item(id, "item_longjump")
  4049. // Last Zombie Check
  4050. set_task(0.1, "fnCheckLastZombie")
  4051. }
  4052.  
  4053. /*================================================================================
  4054. [Other Functions and Tasks]
  4055. =================================================================================*/
  4056.  
  4057. // Register Ham Forwards for CZ bots
  4058. public register_ham_czbots(id)
  4059. {
  4060. // Make sure it's a CZ bot and it's still connected
  4061. if (g_hamczbots || !get_pcvar_num(cvar_botquota) || !is_user_connected(id) || !is_user_bot(id))
  4062. return;
  4063.  
  4064. RegisterHamFromEntity(Ham_Spawn, id, "fw_PlayerSpawn", 1)
  4065. RegisterHamFromEntity(Ham_Killed, id, "fw_Killed")
  4066. RegisterHamFromEntity(Ham_TakeDamage, id, "fw_TakeDamage")
  4067. RegisterHamFromEntity(Ham_TraceAttack, id, "fw_TraceAttack")
  4068.  
  4069. // At this point, the first Ham_Spawn was already ignored for this player
  4070. g_firstspawnignored[id] = true;
  4071.  
  4072. // Ham forwards for CZ bots succesfully registered
  4073. g_hamczbots = true;
  4074. }
  4075.  
  4076. // Bots automatically buy extra items
  4077. public bot_buy_extras(taskid)
  4078. {
  4079. // Nemesis or Survivor shouldnt get extra items
  4080. if (!is_user_alive(ID_SPAWN) || g_survivor[ID_SPAWN] || g_nemesis[ID_SPAWN])
  4081. return;
  4082.  
  4083. if (!g_zombie[ID_SPAWN]) // human bots
  4084. {
  4085. // Attempt to buy Night Vision
  4086. if (get_pcvar_num(cvar_extra_nvision))
  4087. {
  4088. if (g_ammopacks[ID_SPAWN] >= g_extra_costs2[EXTRA_NVISION] && !g_nvision[ID_SPAWN])
  4089. {
  4090. fm_set_bot_nvg(ID_SPAWN, 1)
  4091. g_ammopacks[ID_SPAWN] -= g_extra_costs2[EXTRA_NVISION]
  4092. }
  4093. }
  4094.  
  4095. // Attempt to buy a weapon
  4096. if (get_pcvar_num(cvar_extra_weapons))
  4097. {
  4098. // Make a random weapon selection
  4099. static key
  4100. key = random_num(0, sizeof g_extra_items - 1)
  4101.  
  4102. if (g_ammopacks[ID_SPAWN] >= g_extra_costs[key] && !random_num(0, 3))
  4103. {
  4104. if (MAXAMMO[get_weaponid(g_extra_items[key])] > 1) // (this adds grenades support)
  4105. {
  4106. // Drop previous weapon and give BP ammo for the new one
  4107. (1<<get_weaponid(g_extra_items[key])) & PRIMARY_WEAPONS_BIT_SUM ? drop_weapons(ID_SPAWN, 1) : drop_weapons(ID_SPAWN, 2);
  4108. fm_set_user_bpammo(ID_SPAWN, get_weaponid(g_extra_items[key]), MAXAMMO[get_weaponid(g_extra_items[key])]);
  4109. }
  4110. fm_give_item(ID_SPAWN, g_extra_items[key]);
  4111. g_ammopacks[ID_SPAWN] -= g_extra_costs[key];
  4112. }
  4113. }
  4114. }
  4115. else // zombie bots
  4116. {
  4117. // Attempt to buy an Antidote
  4118. if (get_pcvar_num(cvar_extra_antidote))
  4119. {
  4120. if (g_ammopacks[ID_SPAWN] >= g_extra_costs2[EXTRA_ANTIDOTE] && !g_endround && !g_swarmround && !g_nemround && !g_survround && fnGetZombies() > 1)
  4121. {
  4122. humanme(ID_SPAWN, 0)
  4123. g_ammopacks[ID_SPAWN] -= g_extra_costs2[EXTRA_ANTIDOTE]
  4124. }
  4125. }
  4126. }
  4127. }
  4128.  
  4129. // Balance Teams Task
  4130. public balance_teams()
  4131. {
  4132. // Get users playing
  4133. static iPlayersnum
  4134. iPlayersnum = fnGetPlaying()
  4135.  
  4136. // No players, don't bother
  4137. if (iPlayersnum < 1) return;
  4138.  
  4139. static g_team[33], id, iTerrors, iMaxTerrors
  4140. iMaxTerrors = iPlayersnum/2
  4141. iTerrors = 0
  4142.  
  4143. for (id = 1; id <= g_maxplayers; id++) // mark everyone's team as CT
  4144. g_team[id] = CS_TEAM_CT;
  4145.  
  4146. while (iTerrors < iMaxTerrors) // then randomly mark half of players as Terrorists
  4147. {
  4148. if (id < g_maxplayers)
  4149. id++
  4150. else
  4151. id = 1
  4152.  
  4153. if (!is_user_connected(id))
  4154. continue; // skip if not connected
  4155.  
  4156. if (fm_get_user_team(id) == CS_TEAM_SPECTATOR || fm_get_user_team(id) == CS_TEAM_UNASSIGNED)
  4157. continue; // skip if not playing
  4158.  
  4159. if (g_team[id] == CS_TEAM_T)
  4160. continue; // already a Terrorist
  4161.  
  4162. if (random_num(0, 1))
  4163. {
  4164. g_team[id] = CS_TEAM_T
  4165. iTerrors++
  4166. }
  4167. }
  4168.  
  4169. for (id = 1; id <= g_maxplayers; id++) // actually set everyone's team
  4170. {
  4171. if (!is_user_connected(id))
  4172. continue; // skip if not connected
  4173.  
  4174. if (fm_get_user_team(id) == CS_TEAM_SPECTATOR || fm_get_user_team(id) == CS_TEAM_UNASSIGNED)
  4175. continue // skip if not playing
  4176.  
  4177. // set correct team
  4178. remove_task(id+TEAM_TASK)
  4179. fm_set_user_team(id, g_team[id])
  4180. }
  4181. }
  4182.  
  4183. // Welcome Message Task
  4184. public welcome_msg(id)
  4185. {
  4186. client_print(0, print_chat, "**** %s by MeRcyLeZZ ****", g_modname)
  4187. client_print(0, print_chat, "[ZP] %L", LANG_PLAYER, "NOTICE_INFO1")
  4188. if (!get_pcvar_num(cvar_infammo)) client_print(0, print_chat, "[ZP] %L", LANG_PLAYER, "NOTICE_INFO2")
  4189.  
  4190. set_hudmessage(0, 125, 200, -1.0, 0.17, 0, 0.0, 3.0, 2.0, 1.0, -1)
  4191. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_VIRUS_FREE") // show T-virus HUD notice
  4192. }
  4193.  
  4194. // Respawn Player Task
  4195. public respawn_player(taskid)
  4196. {
  4197. // Respawn on infection rounds only
  4198. if (!is_user_alive(ID_SPAWN) && !g_endround && !g_survround && !g_swarmround && !g_nemround)
  4199. {
  4200. g_respawn_as_zombie[ID_SPAWN] ? fm_set_user_team(ID_SPAWN, CS_TEAM_T) : fm_set_user_team(ID_SPAWN, CS_TEAM_CT);
  4201. ExecuteHamB(Ham_CS_RoundRespawn, ID_SPAWN);
  4202. }
  4203. }
  4204.  
  4205. // Check Round Task -check that we still have both zombies & humans on a round-
  4206. check_round(leaving_player)
  4207. {
  4208. if (!g_endround && !task_exists(MAKEZOMBIE_TASK)) // only if no round end and no make_a_zombie task
  4209. {
  4210. if (fnGetZombies() == 1 && g_zombie[leaving_player]) // last zombie disconnecting
  4211. {
  4212. static iPlayersnum
  4213. iPlayersnum = fnGetAlive() // how many players alive
  4214.  
  4215. if (iPlayersnum < 2) // dont bother
  4216. return;
  4217.  
  4218. // pick random one
  4219. static id
  4220. while ((id = fnGetRandomAlive(random_num(1, iPlayersnum))) == leaving_player ) {}
  4221.  
  4222. static name[32]
  4223. get_user_name(id, name, sizeof name - 1)
  4224. client_print(0, print_chat, "[ZP] %L", LANG_PLAYER, "LAST_ZOMBIE_LEFT", name)
  4225.  
  4226. if (g_nemesis[leaving_player])
  4227. make_a_zombie(MODE_NEMESIS, id) // turn into a Nemesis zombie
  4228. else
  4229. zombieme(id, 0, 0, 0); // turn him into a zombie
  4230. }
  4231. else if (fnGetHumans() == 1 && !g_zombie[leaving_player]) // last human disconnecting
  4232. {
  4233. static iPlayersnum
  4234. iPlayersnum = fnGetAlive() // how many players alive
  4235.  
  4236. if (iPlayersnum < 2) // dont bother
  4237. return;
  4238.  
  4239. // pick random one
  4240. static id
  4241. while ((id = fnGetRandomAlive(random_num(1, iPlayersnum))) == leaving_player ) {}
  4242.  
  4243. static name[32]
  4244. get_user_name(id, name, sizeof name - 1)
  4245. client_print(0, print_chat, "[ZP] %L", LANG_PLAYER, "LAST_HUMAN_LEFT", name)
  4246.  
  4247. if (g_survivor[leaving_player])
  4248. make_a_zombie(MODE_SURVIVOR, id) // turn into a Survivor
  4249. else
  4250. humanme(id, 0); // turn him into a human
  4251. }
  4252. }
  4253. }
  4254.  
  4255. // Lighting Effects Task
  4256. public lighting_effects()
  4257. {
  4258. // Lighting style ["a"-"z"]
  4259. static lights[2]
  4260. get_pcvar_string(cvar_lighting, lights, sizeof lights - 1)
  4261. strtolower(lights)
  4262.  
  4263. if (lights[0] >= 'a' && lights[0] <= 'd') // darkest light settings
  4264. {
  4265. // Set thunderclap tasks if neccesary
  4266. if (get_pcvar_num(cvar_thunder) && !task_exists(THUNDER_PRE_TASK) && !task_exists(THUNDER_TASK))
  4267. {
  4268. g_lights_i = 0;
  4269. switch (random_num(0,2))
  4270. {
  4271. case 0: set_task(get_pcvar_float(cvar_thunder), "thunderclap1", THUNDER_PRE_TASK)
  4272. case 1: set_task(get_pcvar_float(cvar_thunder), "thunderclap2", THUNDER_PRE_TASK)
  4273. case 2: set_task(get_pcvar_float(cvar_thunder), "thunderclap3", THUNDER_PRE_TASK)
  4274. }
  4275. }
  4276. // Set lighting
  4277. if (!task_exists(THUNDER_TASK)) engfunc(EngFunc_LightStyle, 0, lights)
  4278. }
  4279. else
  4280. {
  4281. // Remove thunderclap tasks
  4282. remove_task(THUNDER_PRE_TASK)
  4283. remove_task(THUNDER_TASK)
  4284. // Set lighting
  4285. engfunc(EngFunc_LightStyle, 0, lights)
  4286. }
  4287. }
  4288.  
  4289. // Thunderclap 1
  4290. public thunderclap1()
  4291. {
  4292. // Play thunder sound
  4293. if (!g_lights_i) PlaySound(sound_thunder[random_num(0, sizeof sound_thunder - 1)])
  4294.  
  4295. // Set lighting
  4296. engfunc(EngFunc_LightStyle, 0, lights_thunder1[g_lights_i])
  4297. g_lights_i++
  4298.  
  4299. // Loop the task until we reach the end
  4300. if (g_lights_i >= sizeof lights_thunder1)
  4301. {
  4302. remove_task(THUNDER_TASK)
  4303. lighting_effects()
  4304. }
  4305. else if (!task_exists(THUNDER_TASK))
  4306. set_task(0.1, "thunderclap1", THUNDER_TASK, _, _, "b")
  4307. }
  4308.  
  4309. // Thunderclap 2
  4310. public thunderclap2()
  4311. {
  4312. // Play thunder sound
  4313. if (!g_lights_i) PlaySound(sound_thunder[random_num(0, sizeof sound_thunder - 1)])
  4314.  
  4315. // Set lighting
  4316. engfunc(EngFunc_LightStyle, 0, lights_thunder2[g_lights_i])
  4317. g_lights_i++
  4318.  
  4319. // Loop the task until we reach the end
  4320. if (g_lights_i >= sizeof lights_thunder1)
  4321. {
  4322. remove_task(THUNDER_TASK)
  4323. lighting_effects()
  4324. }
  4325. else if (!task_exists(THUNDER_TASK))
  4326. set_task(0.1, "thunderclap1", THUNDER_TASK, _, _, "b")
  4327. }
  4328.  
  4329. // Thunderclap 3
  4330. public thunderclap3()
  4331. {
  4332. // Play thunder sound
  4333. if (!g_lights_i) PlaySound(sound_thunder[random_num(0, sizeof sound_thunder - 1)])
  4334.  
  4335. // Set lighting
  4336. engfunc(EngFunc_LightStyle, 0, lights_thunder3[g_lights_i])
  4337. g_lights_i++
  4338.  
  4339. // Loop the task until we reach the end
  4340. if (g_lights_i >= sizeof lights_thunder1)
  4341. {
  4342. remove_task(THUNDER_TASK)
  4343. lighting_effects()
  4344. }
  4345. else if (!task_exists(THUNDER_TASK))
  4346. set_task(0.1, "thunderclap1", THUNDER_TASK, _, _, "b")
  4347. }
  4348.  
  4349. #if defined AMBIENCE_SOUNDS
  4350. // Ambience Sound Effects Task
  4351. public ambience_sound_effects(taskid)
  4352. {
  4353. // Pick a random sound
  4354. static isound
  4355. isound = random_num(0, sizeof sound_ambience - 1)
  4356.  
  4357. // Play it on clients
  4358. if (equal(sound_ambience[isound][strlen(sound_ambience[isound])-4], ".mp3"))
  4359. client_cmd(0, "mp3 play sound/%s", sound_ambience[isound])
  4360. else
  4361. client_cmd(0, "spk %s", sound_ambience[isound])
  4362.  
  4363. // Call the task again after the sound is done playing
  4364. change_task(taskid, (sound_ambience_duration[isound]/2))
  4365. }
  4366. #endif
  4367.  
  4368. // Flashlight Charge Task
  4369. public flashlight_charge(taskid)
  4370. {
  4371. // Custom flashlight disabled or flashlight not available for player
  4372. if (!get_pcvar_num(cvar_cflash) || !is_user_alive(ID_CHARGE) || g_zombie[ID_CHARGE] || g_survivor[ID_CHARGE])
  4373. {
  4374. // task not needed anymore
  4375. remove_task(taskid);
  4376. return;
  4377. }
  4378.  
  4379. // Drain or recharge
  4380. if (g_flashlight[ID_CHARGE])
  4381. g_flashbattery[ID_CHARGE] -= get_pcvar_num(cvar_flashdrain)
  4382. else
  4383. g_flashbattery[ID_CHARGE] += 5
  4384.  
  4385. // Battery fully charged
  4386. if (g_flashbattery[ID_CHARGE] >= 100)
  4387. {
  4388. // Don't exceed 100%
  4389. g_flashbattery[ID_CHARGE] = 100;
  4390.  
  4391. // Update flashlight battery on HUD
  4392. message_begin(MSG_ONE_UNRELIABLE, g_msgFlashBat, _, ID_CHARGE);
  4393. write_byte(g_flashbattery[ID_CHARGE]);
  4394. message_end();
  4395.  
  4396. // task not needed anymore
  4397. remove_task(taskid);
  4398. return;
  4399. }
  4400.  
  4401. // Battery depleted
  4402. if (g_flashbattery[ID_CHARGE] <= 0)
  4403. {
  4404. // Turn it off
  4405. g_flashlight[ID_CHARGE] = false;
  4406. g_flashbattery[ID_CHARGE] = 0;
  4407.  
  4408. // Update flashlight status on HUD
  4409. message_begin(MSG_ONE, g_msgFlashlight, _, ID_CHARGE);
  4410. write_byte(g_flashlight[ID_CHARGE]);
  4411. write_byte(g_flashbattery[ID_CHARGE]);
  4412. message_end();
  4413. }
  4414. else
  4415. {
  4416. // Update flashlight battery on HUD
  4417. message_begin(MSG_ONE_UNRELIABLE, g_msgFlashBat, _, ID_CHARGE);
  4418. write_byte(g_flashbattery[ID_CHARGE]);
  4419. message_end();
  4420. }
  4421. }
  4422.  
  4423. // Remove Spawn Protection Task
  4424. public remove_spawn_protection(taskid)
  4425. {
  4426. if (!is_user_alive(ID_SPAWN)) // not alive
  4427. return;
  4428.  
  4429. // Remove spawn protection
  4430. g_nodamage[ID_SPAWN] = false;
  4431. set_pev(ID_SPAWN, pev_effects, pev(ID_SPAWN, pev_effects) & ~EF_NODRAW)
  4432. }
  4433.  
  4434. // Turn Off Game Flashlight
  4435. public turn_off_flashlight(id)
  4436. {
  4437. if (!is_user_alive(id) || (!g_zombie[id] && !g_survivor[id]))
  4438. return;
  4439.  
  4440. // Check if flashlight is on
  4441. if (pev(id, pev_effects) & EF_DIMLIGHT)
  4442. {
  4443. // Turn it off
  4444. set_pev(id, pev_effects, pev(id, pev_effects) & ~EF_DIMLIGHT);
  4445. // Update HUD
  4446. message_begin(MSG_ONE, g_msgFlashlight, _, id);
  4447. write_byte(0);
  4448. write_byte(0);
  4449. message_end();
  4450. }
  4451. }
  4452.  
  4453. // Infection Grenade Explosion
  4454. public infection_explode(const args[1])
  4455. {
  4456. // args[0] = entity id
  4457.  
  4458. static ent
  4459. ent = args[0]
  4460.  
  4461. // invalid entity
  4462. if (!pev_valid(ent)) return;
  4463.  
  4464. // get origin
  4465. static origin[3], Float:originF[3]
  4466. pev(ent, pev_origin, originF);
  4467. FVecIVec(originF, origin);
  4468.  
  4469. // explosion
  4470. create_blast(origin);
  4471.  
  4472. // infection nade sound
  4473. engfunc(EngFunc_EmitSound, ent, CHAN_WEAPON, grenade_infect[random_num(0, sizeof grenade_infect - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
  4474.  
  4475. // round ended (bugfix)
  4476. if (g_endround) return;
  4477.  
  4478. // get grenade's owner
  4479. static attacker
  4480. attacker = pev(ent, pev_owner);
  4481.  
  4482. g_models_i = 0.0 // reset model change count
  4483. g_teams_i = 0.0 // reset team change count
  4484.  
  4485. // collisions
  4486. static victim
  4487. victim = -1;
  4488.  
  4489. while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, 240.0)) != 0)
  4490. {
  4491. // only effect alive non-spawnprotected humans
  4492. if (!is_user_alive(victim) || g_zombie[victim] || g_nodamage[victim])
  4493. continue;
  4494.  
  4495. if (fnGetHumans() == 1) // last human can't be infected
  4496. {
  4497. ExecuteHamB(Ham_Killed, victim, attacker, 0) // now it's killed
  4498. continue;
  4499. }
  4500.  
  4501. // infection nade sound
  4502. engfunc(EngFunc_EmitSound, victim, CHAN_VOICE, grenade_infect_player[random_num(0, sizeof grenade_infect_player - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
  4503.  
  4504. zombieme(victim, attacker, 0, 1) // turn into zombie
  4505.  
  4506. SendDeathMsg(attacker, victim); // send death notice
  4507. UpdateFrags(attacker, victim); // add corresponding frags & deaths
  4508. FixDeadAttrib(victim) // fix the "dead" attrib on scoreboard
  4509.  
  4510. // ammo packs given to zombie for infection
  4511. g_ammopacks[attacker] += get_pcvar_num(cvar_ammoinfect)
  4512.  
  4513. // infection HP bonus
  4514. if (g_zombieclass[attacker] == ZCLASS_LEECH)
  4515. fm_set_user_health(attacker, pev(attacker, pev_health)+(get_pcvar_num(cvar_zombiebonushp)*3))
  4516. else
  4517. fm_set_user_health(attacker, pev(attacker, pev_health)+get_pcvar_num(cvar_zombiebonushp))
  4518. }
  4519.  
  4520. // get rid of the old grenade
  4521. engfunc(EngFunc_RemoveEntity, ent)
  4522. }
  4523.  
  4524. // Fire Grenade Explosion
  4525. public fire_explode(const args[1])
  4526. {
  4527. // args[0] = entity id
  4528.  
  4529. static ent
  4530. ent = args[0]
  4531.  
  4532. // invalid entity
  4533. if (!pev_valid(ent)) return;
  4534.  
  4535. // get origin
  4536. static origin[3], Float:originF[3]
  4537. pev(ent, pev_origin, originF);
  4538. FVecIVec(originF, origin);
  4539.  
  4540. // explosion
  4541. create_blast2(origin);
  4542.  
  4543. // flame nade sound
  4544. engfunc(EngFunc_EmitSound, ent, CHAN_WEAPON, grenade_fire[random_num(0, sizeof grenade_fire - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
  4545.  
  4546. // collisions
  4547. static victim
  4548. victim = -1;
  4549.  
  4550. while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, 240.0)) != 0)
  4551. {
  4552. // only effect alive zombies
  4553. if (!is_user_alive(victim) || !g_zombie[victim] || g_nodamage[victim])
  4554. continue;
  4555.  
  4556. // heat icon
  4557. message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, _, victim)
  4558. write_byte(0) // damage save
  4559. write_byte(0) // damage take
  4560. write_long(DMG_BURN) // damage type
  4561. write_coord(0) // x
  4562. write_coord(0) // y
  4563. write_coord(0) // z
  4564. message_end();
  4565.  
  4566. // our task params
  4567. static params[1]
  4568.  
  4569. if (g_nemesis[victim]) // fire duration (nemesis takes less)
  4570. params[0] = get_pcvar_num(cvar_fireduration);
  4571. else
  4572. params[0] = get_pcvar_num(cvar_fireduration)*5;
  4573.  
  4574. // set burning task on him
  4575. set_task(0.1, "burning_flame", victim+BLOOD_TASK, params, sizeof params)
  4576. }
  4577.  
  4578. // get rid of the old grenade
  4579. engfunc(EngFunc_RemoveEntity, ent)
  4580. }
  4581.  
  4582. // Frost Grenade Explosion
  4583. public frost_explode(const args[1])
  4584. {
  4585. // args[0] = entity id
  4586.  
  4587. static ent
  4588. ent = args[0]
  4589.  
  4590. // invalid entity
  4591. if (!pev_valid(ent)) return;
  4592.  
  4593. // get origin
  4594. static origin[3], Float:originF[3]
  4595. pev(ent, pev_origin, originF);
  4596. FVecIVec(originF, origin);
  4597.  
  4598. // explosion
  4599. create_blast3(origin);
  4600.  
  4601. // frost nade explode sound
  4602. engfunc(EngFunc_EmitSound, ent, CHAN_WEAPON, grenade_frost[random_num(0, sizeof grenade_frost - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
  4603.  
  4604. // collisions
  4605. static victim
  4606. victim = -1;
  4607.  
  4608. while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, 240.0)) != 0)
  4609. {
  4610. // only effect alive unfrozen zombies
  4611. if (!is_user_alive(victim) || !g_zombie[victim] || g_frozen[victim] || g_nodamage[victim])
  4612. continue;
  4613.  
  4614. // nemesis shouldn't be frozen
  4615. if (g_nemesis[victim])
  4616. {
  4617. // get player's origin
  4618. static origin[3], Float:originF[3]
  4619. pev(victim, pev_origin, originF)
  4620. FVecIVec(originF, origin)
  4621.  
  4622. // play the broken glass sound
  4623. engfunc(EngFunc_EmitSound, victim, CHAN_BODY, grenade_frost_break[random_num(0, sizeof grenade_frost_break - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
  4624.  
  4625. // glass shatter
  4626. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  4627. write_byte(TE_BREAKMODEL);
  4628. write_coord(origin[0]); // x
  4629. write_coord(origin[1]); // y
  4630. write_coord(origin[2] + 24); // z
  4631. write_coord(16); // size x
  4632. write_coord(16); // size y
  4633. write_coord(16); // size z
  4634. write_coord(random_num(-50,50));// velocity x
  4635. write_coord(random_num(-50,50));// velocity y
  4636. write_coord(25); // velocity z
  4637. write_byte(10); // random velocity
  4638. write_short(g_glassSpr); // model
  4639. write_byte(10); // count
  4640. write_byte(25); // life
  4641. write_byte(0x01); // flags: BREAK_GLASS
  4642. message_end();
  4643.  
  4644. continue;
  4645. }
  4646.  
  4647. // freeze icon
  4648. message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, _, victim)
  4649. write_byte(0) // damage save
  4650. write_byte(0) // damage take
  4651. write_long(DMG_DROWN) // damage type - DMG_FREEZE
  4652. write_coord(0) // x
  4653. write_coord(0) // y
  4654. write_coord(0) // z
  4655. message_end();
  4656.  
  4657. // light blue glow while frozen
  4658. #if defined HANDLE_MODELS_ON_SEPARATE_ENT
  4659. fm_set_rendering(fm_find_ent_by_owner(-1, "player_model", victim), kRenderFxGlowShell, 0, 100, 200, kRenderNormal, 25)
  4660. #else
  4661. fm_set_rendering(victim, kRenderFxGlowShell, 0, 100, 200, kRenderNormal, 25)
  4662. #endif
  4663.  
  4664. // play freeze sound
  4665. engfunc(EngFunc_EmitSound, victim, CHAN_BODY, grenade_frost_player[random_num(0, sizeof grenade_frost_player - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
  4666.  
  4667. // add a blue tint to their screen
  4668. message_begin(MSG_ONE, g_msgScreenFade, _, victim);
  4669. write_short(~0); // duration
  4670. write_short(~0); // hold time
  4671. write_short(0x0004); // flags: FFADE_STAYOUT
  4672. write_byte(0); // red
  4673. write_byte(50); // green
  4674. write_byte(200); // blue
  4675. write_byte(100); // alpha
  4676. message_end();
  4677.  
  4678. // prevent from jumping
  4679. if (pev(victim, pev_flags) & FL_ONGROUND)
  4680. set_pev(victim, pev_gravity, 999999.9) // set really high
  4681. else
  4682. set_pev(victim, pev_gravity, 0.000001) // no gravity
  4683.  
  4684. // freeze the victim, and set a task to remove the freeze
  4685. g_frozen[victim] = true;
  4686. set_task(get_pcvar_float(cvar_freezeduration), "remove_freeze", victim)
  4687. }
  4688.  
  4689. // get rid of the old grenade
  4690. engfunc(EngFunc_RemoveEntity, ent)
  4691. }
  4692.  
  4693. // Remove freeze task
  4694. public remove_freeze(id)
  4695. {
  4696. if (!is_user_alive(id) || !g_frozen[id]) // not alive / not frozen anymore
  4697. return;
  4698.  
  4699. // unfreeze
  4700. g_frozen[id] = false;
  4701.  
  4702. // restore normal gravity
  4703. if (g_zombie[id])
  4704. set_pev(id, pev_gravity, get_pcvar_float(cvar_zombiegravity)*zombie_multigrav[g_zombieclass[id]]/100)
  4705. else
  4706. set_pev(id, pev_gravity, get_pcvar_float(cvar_humangravity))
  4707.  
  4708. // play the broken glass sound
  4709. engfunc(EngFunc_EmitSound, id, CHAN_BODY, grenade_frost_break[random_num(0, sizeof grenade_frost_break - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
  4710.  
  4711. // remove glow (or just replace it if it's a rage zombie)
  4712. #if defined HANDLE_MODELS_ON_SEPARATE_ENT
  4713. if (g_zombie[id] && g_zombieclass[id] == ZCLASS_RAGE)
  4714. fm_set_rendering(fm_find_ent_by_owner(-1, "player_model", id), kRenderFxGlowShell, 0, 255, 0, kRenderNormal, 25)
  4715. else
  4716. fm_set_rendering(fm_find_ent_by_owner(-1, "player_model", id))
  4717. #else
  4718. if (g_zombie[id] && g_zombieclass[id] == ZCLASS_RAGE)
  4719. fm_set_rendering(id, kRenderFxGlowShell, 0, 255, 0, kRenderNormal, 25)
  4720. else
  4721. fm_set_rendering(id)
  4722. #endif
  4723.  
  4724. // clear screen fade
  4725. message_begin(MSG_ONE, g_msgScreenFade, _, id);
  4726. write_short(0); // duration
  4727. write_short(0); // hold time
  4728. write_short(0); // flags
  4729. write_byte(0); // red
  4730. write_byte(0); // green
  4731. write_byte(0); // blue
  4732. write_byte(0); // alpha
  4733. message_end();
  4734.  
  4735. // get player's origin
  4736. static origin[3], Float:originF[3]
  4737. pev(id, pev_origin, originF)
  4738. FVecIVec(originF, origin)
  4739.  
  4740. // glass shatter
  4741. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  4742. write_byte(TE_BREAKMODEL);
  4743. write_coord(origin[0]); // x
  4744. write_coord(origin[1]); // y
  4745. write_coord(origin[2] + 24); // z
  4746. write_coord(16); // size x
  4747. write_coord(16); // size y
  4748. write_coord(16); // size z
  4749. write_coord(random_num(-50,50));// velocity x
  4750. write_coord(random_num(-50,50));// velocity y
  4751. write_coord(25); // velocity z
  4752. write_byte(10); // random velocity
  4753. write_short(g_glassSpr); // model
  4754. write_byte(10); // count
  4755. write_byte(25); // life
  4756. write_byte(0x01); // flags: BREAK_GLASS
  4757. message_end();
  4758. }
  4759.  
  4760. // Flare "Explosion"
  4761. public flare_explode(const args[5])
  4762. {
  4763. // args[0] = entity id
  4764. // args[1] = duration
  4765. // args[2] = r
  4766. // args[3] = g
  4767. // args[4] = b
  4768.  
  4769. static ent
  4770. ent = args[0]
  4771.  
  4772. // invalid entity
  4773. if (!pev_valid(ent)) return;
  4774.  
  4775. // prevent smokegrenade from exploding
  4776. set_pev(ent, pev_nextthink, get_gametime()+10.0);
  4777.  
  4778. // Light up when it's stopped on ground
  4779. if ((pev(ent, pev_flags) & FL_ONGROUND) && fm_get_speed(ent) < 10)
  4780. {
  4781. // flare sound
  4782. engfunc(EngFunc_EmitSound, ent, CHAN_WEAPON, grenade_flare[random_num(0, sizeof grenade_flare - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
  4783.  
  4784. // call our lighting task
  4785. set_task(0.1, "flare_lighting", NADES_TASK, args, sizeof args)
  4786. }
  4787. else
  4788. {
  4789. // not on ground, keep looping
  4790. set_task(0.5, "flare_explode", NADES_TASK, args, sizeof args)
  4791. }
  4792. }
  4793.  
  4794. // Remove Stuff Task
  4795. public remove_stuff()
  4796. {
  4797. static ent
  4798.  
  4799. // Doors
  4800. if (get_pcvar_num(cvar_removedoors) > 0) // remove rotating doors only
  4801. {
  4802. ent = -1;
  4803. while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "func_door_rotating")) != 0)
  4804. engfunc(EngFunc_SetOrigin, ent, Float:{8192.0,8192.0,8192.0})
  4805. }
  4806. if (get_pcvar_num(cvar_removedoors) > 1) // remove all doors
  4807. {
  4808. ent = -1;
  4809. while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "func_door")) != 0)
  4810. engfunc(EngFunc_SetOrigin, ent, Float:{8192.0,8192.0,8192.0})
  4811. }
  4812.  
  4813. // Triggered lights
  4814. if (!get_pcvar_num(cvar_triggered))
  4815. {
  4816. ent = -1
  4817. while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "light")) != 0) // disable light triggers
  4818. {
  4819. dllfunc(DLLFunc_Use, ent, 0); // turn off the light
  4820. set_pev(ent, pev_targetname, 0) // prevent it from being triggered
  4821. }
  4822. }
  4823. }
  4824.  
  4825. // Set Custom Weapon Models
  4826. public replace_models(id)
  4827. {
  4828. if (!is_user_alive(id)) // not alive
  4829. return;
  4830.  
  4831. if (g_currentweapon[id] == CSW_KNIFE) // custom knife models
  4832. {
  4833. if (g_zombie[id] && !g_newround && !g_endround)
  4834. {
  4835. if (g_nemesis[id])
  4836. {
  4837. set_pev(id, pev_viewmodel2, model_vknife_nemesis)
  4838. set_pev(id, pev_weaponmodel2, model_pknife_nemesis)
  4839. }
  4840. else
  4841. {
  4842. set_pev(id, pev_viewmodel2, model_vknife_zombie)
  4843. set_pev(id, pev_weaponmodel2, model_pknife_zombie)
  4844. }
  4845. }
  4846. else
  4847. {
  4848. set_pev(id, pev_viewmodel2, "models/v_knife.mdl")
  4849. set_pev(id, pev_weaponmodel2, "models/p_knife.mdl")
  4850. }
  4851. }
  4852. else if (g_currentweapon[id] == CSW_HEGRENADE) // infection bomb or fire grenade
  4853. {
  4854. if (g_zombie[id] && !g_newround && !g_endround)
  4855. set_pev(id, pev_viewmodel2, model_grenade_infect)
  4856. else
  4857. set_pev(id, pev_viewmodel2, model_grenade_fire)
  4858. }
  4859. else if (g_currentweapon[id] == CSW_FLASHBANG) // frost grenade
  4860. set_pev(id, pev_viewmodel2, model_grenade_frost)
  4861.  
  4862. else if (g_currentweapon[id] == CSW_SMOKEGRENADE) // flare grenade
  4863. set_pev(id, pev_viewmodel2, model_grenade_flare)
  4864.  
  4865. #if defined HANDLE_MODELS_ON_SEPARATE_ENT
  4866. static model[64]
  4867. pev(id, pev_weaponmodel2, model, sizeof model - 1) // get weapon model
  4868. fm_set_weapon_model_ent(id, model) // set correct model on weapon_model entity
  4869. #endif
  4870. }
  4871.  
  4872. // Reset Player Vars
  4873. reset_vars(id, resetall)
  4874. {
  4875. g_zombie[id] = false
  4876. g_nemesis[id] = false
  4877. g_survivor[id] = false
  4878. g_firstzombie[id] = false
  4879. g_lastzombie[id] = false
  4880. g_lasthuman[id] = false
  4881. g_frozen[id] = false
  4882. g_nodamage[id] = false
  4883. g_respawn_as_zombie[id] = false
  4884. g_nvision[id] = false
  4885. g_nvisionenabled[id] = false
  4886. g_flashlight[id] = false
  4887. g_flashbattery[id] = 100
  4888. g_canbuy[id] = true
  4889.  
  4890. if (resetall)
  4891. {
  4892. g_ammopacks[id] = 5
  4893. g_zombieclass[id] = ZCLASS_NONE
  4894. g_zombieclassnext[id] = ZCLASS_CLASSIC
  4895. g_damagedealt[id] = 0
  4896. }
  4897. }
  4898.  
  4899. // Set spectators nightvision
  4900. public spec_nvision(id)
  4901. {
  4902. if (!is_user_connected(id) || is_user_alive(id) || is_user_bot(id)) // not connected, not dead, or bot
  4903. return;
  4904.  
  4905. // Give Night Vision?
  4906. if (get_pcvar_num(cvar_nvggive))
  4907. {
  4908. g_nvision[id] = true; // give spectator nvision
  4909.  
  4910. // Turn on Night Vision automatically?
  4911. if (get_pcvar_num(cvar_nvggive) == 1)
  4912. {
  4913. g_nvisionenabled[id] = true
  4914.  
  4915. if (get_pcvar_num(cvar_cnvg)) // custom nvg?
  4916. {
  4917. remove_task(id+NVISION_TASK);
  4918. set_task(0.1, "set_user_nvision", id+NVISION_TASK, _, _, "b")
  4919. }
  4920. else set_user_gnvision(id, 1)
  4921. }
  4922. }
  4923. }
  4924.  
  4925. // Show HUD Task
  4926. public ShowHUD(taskid)
  4927. {
  4928. static id
  4929. id = ID_SHOWHUD;
  4930.  
  4931. if (!is_user_alive(id)) // player dead
  4932. {
  4933. id = pev(id, pev_iuser2); // get spectating target
  4934. if (!is_user_alive(id)) // target not alive
  4935. return;
  4936. }
  4937.  
  4938. static class[16], red, green, blue
  4939.  
  4940. if (!g_zombie[id])
  4941. {
  4942. red = 0
  4943. green = 0
  4944. blue = 255
  4945.  
  4946. if (g_survivor[id])
  4947. copy(class, sizeof class - 1, "CLASS_SURVIVOR")
  4948. else
  4949. copy(class, sizeof class - 1, "CLASS_HUMAN")
  4950. }
  4951. else
  4952. {
  4953. red = 200
  4954. green = 250
  4955. blue = 0
  4956.  
  4957. if (g_nemesis[id])
  4958. copy(class, sizeof class - 1, "CLASS_NEMESIS")
  4959. else
  4960. {
  4961. switch (g_zombieclass[id])
  4962. {
  4963. case ZCLASS_CLASSIC: copy(class, sizeof class - 1, "CLASS_ZOMBIE1")
  4964. case ZCLASS_RAPTOR: copy(class, sizeof class - 1, "CLASS_ZOMBIE2")
  4965. case ZCLASS_POISON: copy(class, sizeof class - 1, "CLASS_ZOMBIE3")
  4966. case ZCLASS_FAT: copy(class, sizeof class - 1, "CLASS_ZOMBIE4")
  4967. case ZCLASS_LEECH: copy(class, sizeof class - 1, "CLASS_ZOMBIE5")
  4968. case ZCLASS_RAGE: copy(class, sizeof class - 1, "CLASS_ZOMBIE6")
  4969. }
  4970. }
  4971. }
  4972.  
  4973. if (id != ID_SHOWHUD) // spectating
  4974. {
  4975. static name[32]
  4976. get_user_name(id, name, sizeof name - 1) // get target name
  4977. set_hudmessage(255, 255, 255, 0.7, 0.8, 0, 6.0, 1.1, 0.0, 0.0, -1)
  4978. ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync2, "%L %s^nHP: %d - %L %L", ID_SHOWHUD, "SPECTATING", name, pev(id, pev_health), ID_SHOWHUD, "CLASS_CLASS", ID_SHOWHUD, class) // show name, health, and class
  4979. }
  4980. else // player's own HUD display
  4981. {
  4982. set_hudmessage(red, green, blue, 0.02, 0.9, 0, 6.0, 1.1, 0.0, 0.0, -1)
  4983. ShowSyncHudMsg(id, g_MsgSync2, "%L: %d - %L %L - %L %d", id, "ZOMBIE_ATTRIB1", pev(id, pev_health), id, "CLASS_CLASS", id, class, id, "AMMO_PACKS1", g_ammopacks[id]) // show health, class and ammo
  4984. }
  4985. }
  4986.  
  4987. // Make zombies leave footsteps and bloodstains on the floor task
  4988. public make_blood(taskid)
  4989. {
  4990. // only bleed when moving on ground
  4991. if (fm_get_speed(ID_BLOOD) < 100 || !(pev(ID_BLOOD, pev_flags) & FL_ONGROUND))
  4992. return;
  4993.  
  4994. // get user origin
  4995. static origin[3], Float:originF[3]
  4996. pev(ID_BLOOD, pev_origin, originF);
  4997. FVecIVec(originF, origin);
  4998.  
  4999. // if ducking set a little lower
  5000. if (pev(ID_BLOOD, pev_bInDuck))
  5001. origin[2] -= 18
  5002. else
  5003. origin[2] -= 36
  5004.  
  5005. // send the decal message
  5006. message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
  5007. write_byte(TE_WORLDDECAL)
  5008. write_coord(origin[0]) // x
  5009. write_coord(origin[1]) // y
  5010. write_coord(origin[2]) // z
  5011. write_byte(zombie_decals[random_num(0, sizeof zombie_decals - 1)] + (g_czero*12)) // random decal number (offsets +12 for CZ)
  5012. message_end()
  5013. }
  5014.  
  5015. // Play idle zombie sounds
  5016. public zombie_play_idle(taskid)
  5017. {
  5018. if (g_endround || g_newround) // round ended/new one starting
  5019. return;
  5020.  
  5021. if (g_lastzombie[ID_BLOOD]) // last zombie sound
  5022. engfunc(EngFunc_EmitSound, ID_BLOOD, CHAN_VOICE, zombie_idle_last[random_num(0, sizeof zombie_idle_last - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
  5023. else
  5024. engfunc(EngFunc_EmitSound, ID_BLOOD, CHAN_VOICE, zombie_idle[random_num(0, sizeof zombie_idle - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
  5025. }
  5026.  
  5027. // Madness Over Task
  5028. public madness_over(taskid)
  5029. {
  5030. g_nodamage[ID_BLOOD] = false;
  5031. }
  5032.  
  5033. // Place a user at a random spawn
  5034. do_random_spawn(id)
  5035. {
  5036. if (!g_spawnCount) // no spawns
  5037. return;
  5038.  
  5039. static sp_index, i
  5040. sp_index = random_num(0, g_spawnCount - 1); // random spawn
  5041.  
  5042. for (i = sp_index + 1; i != 999; i++)
  5043. {
  5044. // start over when we reach the end
  5045. if (i >= g_spawnCount) i = 0;
  5046.  
  5047. // free spawn space?
  5048. if (is_hull_vacant(id, g_spawns[i]))
  5049. {
  5050. engfunc(EngFunc_SetOrigin, id, g_spawns[i]);
  5051. break;
  5052. }
  5053.  
  5054. // loop completed, no free space found
  5055. if (i == sp_index) break;
  5056. }
  5057. }
  5058.  
  5059. // Get Zombies -returns alive zombies number-
  5060. fnGetZombies()
  5061. {
  5062. static iZombies, id
  5063. iZombies = 0 // our counter
  5064.  
  5065. for (id = 1; id <= g_maxplayers; id++)
  5066. {
  5067. if (is_user_alive(id) && g_zombie[id])
  5068. iZombies++
  5069. }
  5070.  
  5071. return iZombies
  5072. }
  5073.  
  5074. // Get Humans -returns alive humans number-
  5075. fnGetHumans()
  5076. {
  5077. static iHumans, id
  5078. iHumans = 0 // our counter
  5079.  
  5080. for (id = 1; id <= g_maxplayers; id++)
  5081. {
  5082. if (is_user_alive(id) && !g_zombie[id])
  5083. iHumans++
  5084. }
  5085.  
  5086. return iHumans
  5087. }
  5088.  
  5089. // Get Alive -returns alive players number-
  5090. fnGetAlive()
  5091. {
  5092. static iAlive, id
  5093. iAlive = 0 // our counter
  5094.  
  5095. for (id = 1; id <= g_maxplayers; id++)
  5096. {
  5097. if (is_user_alive(id))
  5098. iAlive++
  5099. }
  5100.  
  5101. return iAlive
  5102. }
  5103.  
  5104. // Get Playing -returns number of users playing-
  5105. fnGetPlaying()
  5106. {
  5107. static iPlaying, id
  5108. iPlaying = 0 // our counter
  5109.  
  5110. for (id = 1; id <= g_maxplayers; id++)
  5111. {
  5112. if (is_user_connected(id))
  5113. {
  5114. if (fm_get_user_team(id) != CS_TEAM_SPECTATOR && fm_get_user_team(id) != CS_TEAM_UNASSIGNED)
  5115. iPlaying++
  5116. }
  5117. }
  5118.  
  5119. return iPlaying
  5120. }
  5121.  
  5122. // Get Random Alive -returns index of alive player number n -
  5123. fnGetRandomAlive(n)
  5124. {
  5125. static iAlive, id
  5126. iAlive = 0 // our counter
  5127.  
  5128. for (id = 1; id <= g_maxplayers; id++)
  5129. {
  5130. if (is_user_alive(id))
  5131. iAlive++
  5132.  
  5133. if (iAlive == n)
  5134. return id
  5135. }
  5136.  
  5137. return -1;
  5138. }
  5139.  
  5140. // Last Zombie Check -check for last zombie and set its flag-
  5141. public fnCheckLastZombie()
  5142. {
  5143. static id
  5144. for (id = 1; id <= g_maxplayers; id++)
  5145. {
  5146. if (is_user_alive(id) && g_zombie[id] && fnGetZombies() == 1) // last zombie
  5147. g_lastzombie[id] = true
  5148. else
  5149. g_lastzombie[id] = false
  5150.  
  5151. if (is_user_alive(id) && !g_zombie[id] && !g_survivor[id] && fnGetHumans() == 1) // last human
  5152. {
  5153. if (!g_lasthuman[id]) fm_set_user_health(id, pev(id, pev_health)+get_pcvar_num(cvar_humanlasthp))
  5154. g_lasthuman[id] = true
  5155. }
  5156. else g_lasthuman[id] = false
  5157. }
  5158. }
  5159.  
  5160. // Save player's stats into the database
  5161. save_stats(id)
  5162. {
  5163. static name[64]
  5164. get_user_name(id, name, sizeof name - 1) // get his name
  5165.  
  5166. // check whether there is another record already in that slot
  5167. if (db_name[id][0] && !equal(name, db_name[id]))
  5168. {
  5169. if (db_slot_i >= sizeof db_name) // if DB size is exceeded
  5170. db_slot_i = g_maxplayers+1 // write over old records
  5171.  
  5172. // move previous record onto an additional save slot
  5173. copy(db_name[db_slot_i], 63, db_name[id])
  5174. db_ammopacks[db_slot_i] = db_ammopacks[id]
  5175. db_zombieclass[db_slot_i] = db_zombieclass[id]
  5176. db_slot_i++
  5177. }
  5178.  
  5179. // now save the current player stats
  5180. copy(db_name[id], 63, name) // store the name
  5181. db_ammopacks[id] = g_ammopacks[id] // store ammo packs
  5182. db_zombieclass[id] = g_zombieclassnext[id] // store zombie type
  5183. }
  5184.  
  5185. // Load player's stats from the database (if a record is found)
  5186. load_stats(id)
  5187. {
  5188. static name[64], i
  5189. get_user_name(id, name, sizeof name - 1) // get player name
  5190.  
  5191. for (i = 0; i < sizeof db_name; i++) // look for a matching record in the DB
  5192. {
  5193. if (equal(name, db_name[i]))
  5194. {
  5195. g_ammopacks[id] = db_ammopacks[i];
  5196. g_zombieclass[id] = db_zombieclass[i];
  5197. g_zombieclassnext[id] = db_zombieclass[i];
  5198. return;
  5199. }
  5200. }
  5201. }
  5202.  
  5203. // Checks if a player is allowed to be a zombie
  5204. allowed_zombie(id)
  5205. {
  5206. if (!is_user_alive(id) || g_zombie[id] || g_swarmround || g_nemround || g_survround || g_endround || task_exists(WELCOMEMSG_TASK) || (!g_zombie[id] && fnGetHumans() == 1))
  5207. return false
  5208.  
  5209. return true
  5210. }
  5211.  
  5212. // Checks if a player is allowed to be a human
  5213. allowed_human(id)
  5214. {
  5215. if (!is_user_alive(id) || !g_zombie[id] || g_swarmround || g_nemround || g_survround || g_endround || (g_zombie[id] && fnGetZombies() == 1))
  5216. return false
  5217.  
  5218. return true
  5219. }
  5220.  
  5221. // Checks if a player is allowed to be a survivor
  5222. allowed_survivor(id)
  5223. {
  5224. if (!is_user_alive(id) || !get_pcvar_num(cvar_surv) || g_endround || !g_newround || task_exists(WELCOMEMSG_TASK))
  5225. return false
  5226.  
  5227. return true
  5228. }
  5229.  
  5230. // Checks if a player is allowed to be a nemesis
  5231. allowed_nemesis(id)
  5232. {
  5233. if (!is_user_alive(id) || !get_pcvar_num(cvar_nem) || g_endround || !g_newround || task_exists(WELCOMEMSG_TASK))
  5234. return false
  5235.  
  5236. return true
  5237. }
  5238.  
  5239. // Checks if a player is allowed to respawn
  5240. allowed_respawn(id)
  5241. {
  5242. if (!is_user_connected(id) || is_user_alive(id) || g_endround || g_survround || g_swarmround || g_nemround)
  5243. return false
  5244.  
  5245. return true
  5246. }
  5247.  
  5248. // Checks if swarm mode is allowed
  5249. allowed_swarm()
  5250. {
  5251. if (!get_pcvar_num(cvar_swarm) || g_endround || !g_newround || task_exists(WELCOMEMSG_TASK))
  5252. return false
  5253.  
  5254. return true
  5255. }
  5256.  
  5257. // Checks if multi infection mode is allowed
  5258. allowed_multi()
  5259. {
  5260. if (!get_pcvar_num(cvar_multi) || g_endround || !g_newround || task_exists(WELCOMEMSG_TASK))
  5261. return false
  5262.  
  5263. return true
  5264. }
  5265.  
  5266. // Admin Command. zp_zombie
  5267. command_zombie(id, player)
  5268. {
  5269. static name1[32], name2[32]
  5270. get_user_name(id, name1, sizeof name1 - 1)
  5271. get_user_name(player, name2, sizeof name2 - 1)
  5272.  
  5273. switch (get_pcvar_num(cvar_showactivity)) // show activity?
  5274. {
  5275. case 1: client_print(0, print_chat, "ADMIN - %s %L", name2, LANG_PLAYER, "CMD_INFECT")
  5276. case 2: client_print(0, print_chat, "ADMIN %s - %s %L", name1, name2, LANG_PLAYER, "CMD_INFECT")
  5277. }
  5278.  
  5279. if (get_pcvar_num(cvar_logcommands)) // Log to Zombie Plague log file?
  5280. {
  5281. static logdata[100]
  5282. formatex(logdata, sizeof logdata - 1, "ADMIN %s - %s %L (Players: %d/%d)", name1, name2, LANG_SERVER, "CMD_INFECT", fnGetPlaying(), g_maxplayers)
  5283. log_to_file("zombieplague.log", logdata)
  5284. }
  5285.  
  5286. if (g_newround) // new round, set as first zombie
  5287. {
  5288. remove_task(MAKEZOMBIE_TASK)
  5289. make_a_zombie(MODE_INFECTION, player);
  5290. }
  5291. else
  5292. {
  5293. zombieme(player, 0, 0, 0) // just infect
  5294. }
  5295. }
  5296.  
  5297. // Admin Command. zp_human
  5298. command_human(id, player)
  5299. {
  5300. static name1[32], name2[32]
  5301. get_user_name(id, name1, sizeof name1 - 1)
  5302. get_user_name(player, name2, sizeof name2 - 1)
  5303.  
  5304. switch (get_pcvar_num(cvar_showactivity)) // show activity?
  5305. {
  5306. case 1: client_print(0, print_chat, "ADMIN - %s %L", name2, LANG_PLAYER, "CMD_DISINFECT")
  5307. case 2: client_print(0, print_chat, "ADMIN %s - %s %L", name1, name2, LANG_PLAYER, "CMD_DISINFECT")
  5308. }
  5309.  
  5310. if (get_pcvar_num(cvar_logcommands)) // Log to Zombie Plague log file?
  5311. {
  5312. static logdata[100]
  5313. formatex(logdata, sizeof logdata - 1, "ADMIN %s - %s %L (Players: %d/%d)", name1, name2, LANG_SERVER,"CMD_DISINFECT", fnGetPlaying(), g_maxplayers)
  5314. log_to_file("zombieplague.log", logdata)
  5315. }
  5316.  
  5317. humanme(player, 0) // turn back to human
  5318. }
  5319.  
  5320. // Admin Command. zp_survivor
  5321. command_survivor(id, player)
  5322. {
  5323. static name1[32], name2[32]
  5324. get_user_name(id, name1, sizeof name1 - 1)
  5325. get_user_name(player, name2, sizeof name2 - 1)
  5326.  
  5327. switch (get_pcvar_num(cvar_showactivity)) // show activity?
  5328. {
  5329. case 1: client_print(0, print_chat, "ADMIN - %s %L", name2, LANG_PLAYER, "CMD_SURVIVAL")
  5330. case 2: client_print(0, print_chat, "ADMIN %s - %s %L", name1, name2, LANG_PLAYER, "CMD_SURVIVAL")
  5331. }
  5332.  
  5333. if (get_pcvar_num(cvar_logcommands)) // Log to Zombie Plague log file?
  5334. {
  5335. static logdata[100]
  5336. formatex(logdata, sizeof logdata - 1, "ADMIN %s - %s %L (Players: %d/%d)", name1, name2, LANG_SERVER,"CMD_SURVIVAL", fnGetPlaying(), g_maxplayers)
  5337. log_to_file("zombieplague.log", logdata)
  5338. }
  5339.  
  5340. remove_task(MAKEZOMBIE_TASK)
  5341. make_a_zombie(MODE_SURVIVOR, player) // turn into a Survivor
  5342. }
  5343.  
  5344. // Admin Command. zp_nemesis
  5345. command_nemesis(id, player)
  5346. {
  5347. static name1[32], name2[32]
  5348. get_user_name(id, name1, sizeof name1 - 1)
  5349. get_user_name(player, name2, sizeof name2 - 1)
  5350.  
  5351. switch (get_pcvar_num(cvar_showactivity)) // show activity?
  5352. {
  5353. case 1: client_print(0, print_chat, "ADMIN - %s %L", name2, LANG_PLAYER, "CMD_NEMESIS")
  5354. case 2: client_print(0, print_chat, "ADMIN %s - %s %L", name1, name2, LANG_PLAYER, "CMD_NEMESIS")
  5355. }
  5356.  
  5357. if (get_pcvar_num(cvar_logcommands)) // Log to Zombie Plague log file?
  5358. {
  5359. static logdata[100]
  5360. formatex(logdata, sizeof logdata - 1, "ADMIN %s - %s %L (Players: %d/%d)", name1, name2, LANG_SERVER,"CMD_NEMESIS", fnGetPlaying(), g_maxplayers)
  5361. log_to_file("zombieplague.log", logdata)
  5362. }
  5363.  
  5364. remove_task(MAKEZOMBIE_TASK)
  5365. make_a_zombie(MODE_NEMESIS, player) // turn into a Nemesis zombie
  5366. }
  5367.  
  5368. // Admin Command. zp_swarm
  5369. command_swarm(id)
  5370. {
  5371. static name1[32]
  5372. get_user_name(id, name1, sizeof name1 - 1)
  5373.  
  5374. switch (get_pcvar_num(cvar_showactivity)) // show activity?
  5375. {
  5376. case 1: client_print(0, print_chat, "ADMIN - %L", LANG_PLAYER, "CMD_SWARM")
  5377. case 2: client_print(0, print_chat, "ADMIN %s - %L", name1, LANG_PLAYER, "CMD_SWARM")
  5378. }
  5379.  
  5380. if (get_pcvar_num(cvar_logcommands)) // Log to Zombie Plague log file?
  5381. {
  5382. static logdata[100]
  5383. formatex(logdata, sizeof logdata - 1, "ADMIN %s - %L (Players: %d/%d)", name1, LANG_SERVER, "CMD_SWARM", fnGetPlaying(), g_maxplayers)
  5384. log_to_file("zombieplague.log", logdata)
  5385. }
  5386.  
  5387. remove_task(MAKEZOMBIE_TASK)
  5388. make_a_zombie(MODE_SWARM, 0) // Call Swarm Mode
  5389. }
  5390.  
  5391. // Admin Command. zp_multi
  5392. command_multi(id)
  5393. {
  5394. static name1[32]
  5395. get_user_name(id, name1, sizeof name1 - 1)
  5396.  
  5397. switch (get_pcvar_num(cvar_showactivity)) // show activity?
  5398. {
  5399. case 1: client_print(0, print_chat, "ADMIN - %L", LANG_PLAYER, "CMD_MULTI")
  5400. case 2: client_print(0, print_chat, "ADMIN %s - %L", name1, LANG_PLAYER, "CMD_MULTI")
  5401. }
  5402.  
  5403. if (get_pcvar_num(cvar_logcommands)) // Log to Zombie Plague log file?
  5404. {
  5405. static logdata[100]
  5406. formatex(logdata, sizeof logdata - 1, "ADMIN %s - %L (Players: %d/%d)", name1, LANG_SERVER,"CMD_MULTI", fnGetPlaying(), g_maxplayers)
  5407. log_to_file("zombieplague.log", logdata)
  5408. }
  5409.  
  5410. remove_task(MAKEZOMBIE_TASK)
  5411. make_a_zombie(MODE_MULTI, 0) // Call Multi Infection
  5412. }
  5413.  
  5414. // Admin Command. zp_respawn
  5415. command_respawn(id, player)
  5416. {
  5417. static name1[32], name2[32]
  5418. get_user_name(id, name1, sizeof name1 - 1)
  5419. get_user_name(player, name2, sizeof name2 - 1)
  5420.  
  5421. switch (get_pcvar_num(cvar_showactivity)) // show activity?
  5422. {
  5423. case 1: client_print(0, print_chat, "ADMIN - %s %L", name2, LANG_PLAYER, "CMD_RESPAWN")
  5424. case 2: client_print(0, print_chat, "ADMIN %s - %s %L", name1, name2, LANG_PLAYER, "CMD_RESPAWN")
  5425. }
  5426.  
  5427. if (get_pcvar_num(cvar_logcommands)) // Log to Zombie Plague log file?
  5428. {
  5429. static logdata[100]
  5430. formatex(logdata, sizeof logdata - 1, "ADMIN %s - %s %L (Players: %d/%d)", name1, name2, LANG_SERVER, "CMD_RESPAWN", fnGetPlaying(), g_maxplayers)
  5431. log_to_file("zombieplague.log", logdata)
  5432. }
  5433.  
  5434. respawn_player(player+SPAWN_TASK);
  5435. }
  5436.  
  5437. /*================================================================================
  5438. [Custom Natives]
  5439. =================================================================================*/
  5440.  
  5441. // Native: zp_get_user_zombie
  5442. public native_get_user_zombie(id)
  5443. {
  5444. return g_zombie[id];
  5445. }
  5446.  
  5447. // Native: zp_get_user_nemesis
  5448. public native_get_user_nemesis(id)
  5449. {
  5450. return g_nemesis[id];
  5451. }
  5452.  
  5453. // Native: zp_get_user_survivor
  5454. public native_get_user_survivor(id)
  5455. {
  5456. return g_survivor[id];
  5457. }
  5458.  
  5459. public native_get_user_first_zombie(id)
  5460. {
  5461. return g_firstzombie[id];
  5462. }
  5463.  
  5464. // Native: zp_get_user_last_zombie
  5465. public native_get_user_last_zombie(id)
  5466. {
  5467. return g_lastzombie[id];
  5468. }
  5469.  
  5470. // Native: zp_get_user_last_human
  5471. public native_get_user_last_human(id)
  5472. {
  5473. return g_lasthuman[id];
  5474. }
  5475.  
  5476. // Native: zp_get_user_zombie_class
  5477. public native_get_user_zombie_class(id)
  5478. {
  5479. return g_zombieclass[id];
  5480. }
  5481.  
  5482. // Native: zp_get_user_ammo_packs
  5483. public native_get_user_ammo_packs(id)
  5484. {
  5485. return g_ammopacks[id];
  5486. }
  5487.  
  5488. // Native: zp_set_user_ammo_packs
  5489. public native_set_user_ammo_packs(id, amount)
  5490. {
  5491. g_ammopacks[id] = amount;
  5492. }
  5493.  
  5494. public native_get_zombie_maxhealth(id)
  5495. {
  5496. if (g_zombie[id] && !g_nemesis[id])
  5497. {
  5498. if (g_firstzombie[id])
  5499. return get_pcvar_num(cvar_zombiefirsthp)*zombie_multihp[g_zombieclass[id]]/100;
  5500. else
  5501. return get_pcvar_num(cvar_zombiehp)*zombie_multihp[g_zombieclass[id]]/100;
  5502. }
  5503. return -1;
  5504. }
  5505.  
  5506. // Native: zp_has_round_started
  5507. public native_has_round_started()
  5508. {
  5509. return !g_newround;
  5510. }
  5511.  
  5512. // Native: zp_is_nemesis_round
  5513. public native_is_nemesis_round()
  5514. {
  5515. return g_nemround;
  5516. }
  5517.  
  5518. // Native: zp_is_survivor_round
  5519. public native_is_survivor_round()
  5520. {
  5521. return g_survround;
  5522. }
  5523.  
  5524. // Native: zp_is_swarm_round
  5525. public native_is_swarm_round()
  5526. {
  5527. return g_swarmround;
  5528. }
  5529.  
  5530. /*================================================================================
  5531. [Custom Messages]
  5532. =================================================================================*/
  5533.  
  5534. // Custom Night Vision
  5535. public set_user_nvision(taskid)
  5536. {
  5537. // Not meant to have nvision or not enabled
  5538. if (!g_nvision[ID_NVISION] || !g_nvisionenabled[ID_NVISION])
  5539. {
  5540. // task not needed anymore
  5541. remove_task(taskid);
  5542. return;
  5543. }
  5544.  
  5545. // Get player origin
  5546. static origin[3], Float:originF[3]
  5547. pev(ID_NVISION, pev_origin, originF)
  5548. FVecIVec(originF, origin);
  5549.  
  5550. // Nightvision
  5551. message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, _, ID_NVISION);
  5552. write_byte(TE_DLIGHT);
  5553. write_coord(origin[0]); //x
  5554. write_coord(origin[1]); //y
  5555. write_coord(origin[2]); //z
  5556. write_byte(get_pcvar_num(cvar_nvgsize)); //visible distance
  5557. write_byte((g_nemround || g_nodamage[ID_NVISION]) ? get_pcvar_num(cvar_nemnvgcolor[0]) : get_pcvar_num(cvar_nvgcolor[0])); //red
  5558. write_byte((g_nemround || g_nodamage[ID_NVISION]) ? get_pcvar_num(cvar_nemnvgcolor[1]) : get_pcvar_num(cvar_nvgcolor[1])); //green
  5559. write_byte((g_nemround || g_nodamage[ID_NVISION]) ? get_pcvar_num(cvar_nemnvgcolor[2]) : get_pcvar_num(cvar_nvgcolor[2])); //blue
  5560. write_byte(2); //life
  5561. write_byte(0); //decay rate
  5562. message_end();
  5563. }
  5564.  
  5565. // Game Nightvision
  5566. set_user_gnvision(id, toggle)
  5567. {
  5568. message_begin(MSG_ONE, g_msgNVGToggle, _, id)
  5569. write_byte(toggle) // 1 On - 0 Off
  5570. message_end()
  5571. }
  5572.  
  5573. // Custom Flashlight
  5574. public set_user_flashlight(taskid)
  5575. {
  5576. // Not meant to have flashlight or not enabled
  5577. if (!get_pcvar_num(cvar_cflash) || !g_flashlight[ID_FLASH])
  5578. {
  5579. // task not needed anymore
  5580. remove_task(taskid);
  5581. return;
  5582. }
  5583.  
  5584. // Disable flashlight if it shouldn't be available
  5585. if (!is_user_alive(ID_FLASH) || g_zombie[ID_FLASH] || g_survivor[ID_FLASH])
  5586. {
  5587. // Turn it off
  5588. g_flashlight[ID_FLASH] = false;
  5589. g_flashbattery[ID_FLASH] = 0;
  5590.  
  5591. // Update flashlight HUD
  5592. message_begin(MSG_ONE, g_msgFlashlight, _, ID_FLASH);
  5593. write_byte(g_flashlight[ID_FLASH]);
  5594. write_byte(g_flashbattery[ID_FLASH]);
  5595. message_end();
  5596.  
  5597. // task not needed anymore
  5598. remove_task(taskid);
  5599. return;
  5600. }
  5601.  
  5602. // Get player and aiming origins
  5603. static origin[3], Float:originF[3], destorigin[3], Float:destoriginF[3]
  5604. pev(ID_FLASH, pev_origin, originF)
  5605. FVecIVec(originF, origin)
  5606. fm_get_aim_origin(ID_FLASH, destoriginF)
  5607. FVecIVec(destoriginF, destorigin)
  5608.  
  5609. // Make sure it doesn't exceed the max distance
  5610. if (get_distance(origin, destorigin) > get_pcvar_num(cvar_flashdist))
  5611. return;
  5612.  
  5613. // Flashlight
  5614. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  5615. write_byte(TE_DLIGHT);
  5616. write_coord(destorigin[0]); // X
  5617. write_coord(destorigin[1]); // Y
  5618. write_coord(destorigin[2]); // Z
  5619. write_byte(get_pcvar_num(cvar_flashsize)); // radius
  5620. write_byte(get_pcvar_num(cvar_flashcolor[0])); // R
  5621. write_byte(get_pcvar_num(cvar_flashcolor[1])); // G
  5622. write_byte(get_pcvar_num(cvar_flashcolor[2])); // B
  5623. write_byte(3); // life
  5624. write_byte(0); // decay rate
  5625. message_end();
  5626. }
  5627.  
  5628. // Infection special effects on victim
  5629. infectionFX1(id)
  5630. {
  5631. // screen fade
  5632. message_begin(MSG_ONE_UNRELIABLE, g_msgScreenFade, _, id)
  5633. write_short(4096) // Duration
  5634. write_short(0) // Hold time
  5635. write_short(0x0000) // Fade type
  5636. write_byte(g_nemesis[id] ? get_pcvar_num(cvar_nemnvgcolor[0]) : get_pcvar_num(cvar_nvgcolor[0])); // Red
  5637. write_byte(g_nemesis[id] ? get_pcvar_num(cvar_nemnvgcolor[1]) : get_pcvar_num(cvar_nvgcolor[1])); // Green
  5638. write_byte(g_nemesis[id] ? get_pcvar_num(cvar_nemnvgcolor[2]) : get_pcvar_num(cvar_nvgcolor[2])); // Blue
  5639. write_byte (255) // Alpha
  5640. message_end()
  5641.  
  5642. // infection icon
  5643. message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, _, id)
  5644. write_byte(0) // damage save
  5645. write_byte(0) // damage take
  5646. write_long(DMG_NERVEGAS) // damage type - DMG_RADIATION
  5647. write_coord(0) // x
  5648. write_coord(0) // y
  5649. write_coord(0) // z
  5650. message_end();
  5651. }
  5652.  
  5653. // Infection special effects or nemesis aura
  5654. public infectionFX2(id)
  5655. {
  5656. if (!is_user_alive(id)) // not alive
  5657. return;
  5658.  
  5659. // get player origin
  5660. static origin[3], Float:originF[3]
  5661. pev(id, pev_origin, originF)
  5662. FVecIVec(originF, origin)
  5663.  
  5664. // Colored Aura
  5665. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  5666. write_byte(TE_DLIGHT);
  5667. write_coord(origin[0]); //x
  5668. write_coord(origin[1]); //y
  5669. write_coord(origin[2]); //z
  5670. write_byte(20); //visible distance
  5671. write_byte((g_nemesis[id] || g_nodamage[id]) ? get_pcvar_num(cvar_nemnvgcolor[0]) : get_pcvar_num(cvar_nvgcolor[0])); //red
  5672. write_byte((g_nemesis[id] || g_nodamage[id]) ? get_pcvar_num(cvar_nemnvgcolor[1]) : get_pcvar_num(cvar_nvgcolor[1])); //green
  5673. write_byte((g_nemesis[id] || g_nodamage[id]) ? get_pcvar_num(cvar_nemnvgcolor[2]) : get_pcvar_num(cvar_nvgcolor[2])); //blue
  5674. write_byte(2); //life
  5675. write_byte(0); //decay rate
  5676. message_end();
  5677.  
  5678. // Keep calling back the task for nemesis/zombie madness aura
  5679. if (g_nodamage[id] || (g_nemesis[id] && get_pcvar_num(cvar_nemaura)))
  5680. {
  5681. set_task(0.1, "infectionFX2", id)
  5682. return;
  5683. }
  5684.  
  5685. // Tracers
  5686. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  5687. write_byte(TE_IMPLOSION);
  5688. write_coord(origin[0]); // x
  5689. write_coord(origin[1]); // y
  5690. write_coord(origin[2]); // z
  5691. write_byte(128); // radius
  5692. write_byte(20); // count
  5693. write_byte(3); // duration
  5694. message_end();
  5695.  
  5696. // Particle Burst
  5697. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  5698. write_byte(TE_PARTICLEBURST);
  5699. write_coord(origin[0]); // x
  5700. write_coord(origin[1]); // y
  5701. write_coord(origin[2]); // z
  5702. write_short(50); // radius
  5703. write_byte(70); // color
  5704. write_byte(3); // duration (will be randomized a bit)
  5705. message_end();
  5706. }
  5707.  
  5708. // Flare Lighting
  5709. public flare_lighting(args[5])
  5710. {
  5711. // args[0] = entity id
  5712. // args[1] = duration
  5713. // args[2] = r
  5714. // args[3] = g
  5715. // args[4] = b
  5716.  
  5717. static ent
  5718. ent = args[0]
  5719.  
  5720. // invalid entity
  5721. if (!pev_valid(ent)) return;
  5722.  
  5723. if (args[1] <= 0) // flare depleted -clean up the mess-
  5724. {
  5725. engfunc(EngFunc_RemoveEntity, ent)
  5726. return;
  5727. }
  5728.  
  5729. // get origin
  5730. static origin[3], Float:originF[3]
  5731. pev(ent, pev_origin, originF)
  5732. FVecIVec(originF, origin)
  5733.  
  5734. // lighting
  5735. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  5736. write_byte(TE_DLIGHT);
  5737. write_coord(origin[0]); //x
  5738. write_coord(origin[1]); //y
  5739. write_coord(origin[2]); //z
  5740. write_byte(get_pcvar_num(cvar_flaresize)); //visible distance
  5741. write_byte(args[2]); //red
  5742. write_byte(args[3]); //green
  5743. write_byte(args[4]); //blue
  5744. write_byte(51); //life
  5745. write_byte(args[1] < 2 ? 3 : 0); //decay rate
  5746. message_end();
  5747.  
  5748. // sparks
  5749. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  5750. write_byte(TE_SPARKS);
  5751. write_coord(origin[0]); // x
  5752. write_coord(origin[1]); // y
  5753. write_coord(origin[2]); // z
  5754. message_end();
  5755.  
  5756. // decrease task cycle count
  5757. args[1]--
  5758.  
  5759. // prevent smokegrenade from exploding
  5760. set_pev(ent, pev_nextthink, get_gametime()+10.0);
  5761.  
  5762. // keep sending flare messaegs
  5763. set_task(5.0, "flare_lighting", NADES_TASK, args, sizeof args)
  5764. }
  5765.  
  5766. // Burning Flames
  5767. public burning_flame(args[1], taskid)
  5768. {
  5769. // args[0] = cycles left (duration)
  5770.  
  5771. // get player origin
  5772. static origin[3], Float:originF[3]
  5773. pev(ID_BLOOD, pev_origin, originF)
  5774. FVecIVec(originF, origin)
  5775.  
  5776. // madness mode - in water - burning stopped
  5777. if (g_nodamage[ID_BLOOD] || pev(ID_BLOOD, pev_flags) & FL_INWATER || args[0] < 1)
  5778. {
  5779. // smoke sprite
  5780. message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
  5781. write_byte(TE_SMOKE)
  5782. write_coord(origin[0]) // x
  5783. write_coord(origin[1]) // y
  5784. write_coord(origin[2]-50) // z
  5785. write_short(g_smokeSpr) // sprite
  5786. write_byte(random_num(15, 20)) // scale
  5787. write_byte(random_num(10, 20)) // framerate
  5788. message_end()
  5789.  
  5790. return;
  5791. }
  5792.  
  5793. // randomly play burning zombie scream sounds (not for nemesis)
  5794. if (!random_num(0, 20) && !g_nemesis[ID_BLOOD])
  5795. engfunc(EngFunc_EmitSound, ID_BLOOD, CHAN_VOICE, grenade_fire_player[random_num(0, sizeof grenade_fire_player - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
  5796.  
  5797. // fire slow down (not for nemesis)
  5798. if (get_pcvar_float(cvar_fireslowdown) > 0.0 && !g_nemesis[ID_BLOOD] && (pev(ID_BLOOD, pev_flags) & FL_ONGROUND))
  5799. {
  5800. static Float:velocity[3]
  5801. pev(ID_BLOOD, pev_velocity, velocity)
  5802. xs_vec_mul_scalar(velocity, get_pcvar_float(cvar_fireslowdown), velocity)
  5803. set_pev(ID_BLOOD, pev_velocity, velocity)
  5804. }
  5805.  
  5806. // take damage from the fire
  5807. if (pev(ID_BLOOD, pev_health) > get_pcvar_num(cvar_firedamage))
  5808. fm_set_user_health(ID_BLOOD, pev(ID_BLOOD, pev_health) - get_pcvar_num(cvar_firedamage))
  5809.  
  5810. // flame sprite
  5811. message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
  5812. write_byte(TE_SPRITE);
  5813. write_coord(-5+origin[0]+random_num(0, 10)) // x
  5814. write_coord(-5+origin[1]+random_num(0, 10)) // y
  5815. write_coord(-10+origin[2]+random_num(0, 20)) // z
  5816. write_short(g_flameSpr) // sprite
  5817. write_byte(random_num(5, 10)) // scale
  5818. write_byte(200) // brightness
  5819. message_end()
  5820.  
  5821. // decrease task cycle count
  5822. args[0]--;
  5823.  
  5824. // keep sending flame messaegs
  5825. set_task(0.2, "burning_flame", taskid, args, sizeof args)
  5826. }
  5827.  
  5828. // Infection Grenade: Green Blast
  5829. create_blast(const origin[3])
  5830. {
  5831. // smallest ring
  5832. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  5833. write_byte(TE_BEAMCYLINDER);
  5834. write_coord(origin[0]); // start X
  5835. write_coord(origin[1]); // start Y
  5836. write_coord(origin[2]); // start Z
  5837. write_coord(origin[0]); // something X
  5838. write_coord(origin[1]); // something Y
  5839. write_coord(origin[2] + 385); // something Z
  5840. write_short(g_exploSpr); // sprite
  5841. write_byte(0); // startframe
  5842. write_byte(0); // framerate
  5843. write_byte(4); // life
  5844. write_byte(60); // width
  5845. write_byte(0); // noise
  5846. write_byte(0); // red
  5847. write_byte(200); // green
  5848. write_byte(0); // blue
  5849. write_byte(200); // brightness
  5850. write_byte(0); // speed
  5851. message_end();
  5852.  
  5853. // medium ring
  5854. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  5855. write_byte(TE_BEAMCYLINDER);
  5856. write_coord(origin[0]); // start X
  5857. write_coord(origin[1]); // start Y
  5858. write_coord(origin[2]); // start Z
  5859. write_coord(origin[0]); // something X
  5860. write_coord(origin[1]); // something Y
  5861. write_coord(origin[2] + 470); // something Z
  5862. write_short(g_exploSpr); // sprite
  5863. write_byte(0); // startframe
  5864. write_byte(0); // framerate
  5865. write_byte(4); // life
  5866. write_byte(60); // width
  5867. write_byte(0); // noise
  5868. write_byte(0); // red
  5869. write_byte(200); // green
  5870. write_byte(0); // blue
  5871. write_byte(200); // brightness
  5872. write_byte(0); // speed
  5873. message_end();
  5874.  
  5875. // largest ring
  5876. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  5877. write_byte(TE_BEAMCYLINDER);
  5878. write_coord(origin[0]); // start X
  5879. write_coord(origin[1]); // start Y
  5880. write_coord(origin[2]); // start Z
  5881. write_coord(origin[0]); // something X
  5882. write_coord(origin[1]); // something Y
  5883. write_coord(origin[2] + 555); // something Z
  5884. write_short(g_exploSpr); // sprite
  5885. write_byte(0); // startframe
  5886. write_byte(0); // framerate
  5887. write_byte(4); // life
  5888. write_byte(60); // width
  5889. write_byte(0); // noise
  5890. write_byte(0); // red
  5891. write_byte(200); // green
  5892. write_byte(0); // blue
  5893. write_byte(200); // brightness
  5894. write_byte(0); // speed
  5895. message_end();
  5896. }
  5897.  
  5898. // Fire Grenade: Fire Blast
  5899. create_blast2(const origin[3])
  5900. {
  5901. // smallest ring
  5902. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  5903. write_byte(TE_BEAMCYLINDER);
  5904. write_coord(origin[0]); // start X
  5905. write_coord(origin[1]); // start Y
  5906. write_coord(origin[2]); // start Z
  5907. write_coord(origin[0]); // something X
  5908. write_coord(origin[1]); // something Y
  5909. write_coord(origin[2] + 385); // something Z
  5910. write_short(g_exploSpr); // sprite
  5911. write_byte(0); // startframe
  5912. write_byte(0); // framerate
  5913. write_byte(4); // life
  5914. write_byte(60); // width
  5915. write_byte(0); // noise
  5916. write_byte(200); // red
  5917. write_byte(100); // green
  5918. write_byte(0); // blue
  5919. write_byte(200); // brightness
  5920. write_byte(0); // speed
  5921. message_end();
  5922.  
  5923. // medium ring
  5924. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  5925. write_byte(TE_BEAMCYLINDER);
  5926. write_coord(origin[0]); // start X
  5927. write_coord(origin[1]); // start Y
  5928. write_coord(origin[2]); // start Z
  5929. write_coord(origin[0]); // something X
  5930. write_coord(origin[1]); // something Y
  5931. write_coord(origin[2] + 470); // something Z
  5932. write_short(g_exploSpr); // sprite
  5933. write_byte(0); // startframe
  5934. write_byte(0); // framerate
  5935. write_byte(4); // life
  5936. write_byte(60); // width
  5937. write_byte(0); // noise
  5938. write_byte(200); // red
  5939. write_byte(50); // green
  5940. write_byte(0); // blue
  5941. write_byte(200); // brightness
  5942. write_byte(0); // speed
  5943. message_end();
  5944.  
  5945. // largest ring
  5946. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  5947. write_byte(TE_BEAMCYLINDER);
  5948. write_coord(origin[0]); // start X
  5949. write_coord(origin[1]); // start Y
  5950. write_coord(origin[2]); // start Z
  5951. write_coord(origin[0]); // something X
  5952. write_coord(origin[1]); // something Y
  5953. write_coord(origin[2] + 555); // something Z
  5954. write_short(g_exploSpr); // sprite
  5955. write_byte(0); // startframe
  5956. write_byte(0); // framerate
  5957. write_byte(4); // life
  5958. write_byte(60); // width
  5959. write_byte(0); // noise
  5960. write_byte(200); // red
  5961. write_byte(0); // green
  5962. write_byte(0); // blue
  5963. write_byte(200); // brightness
  5964. write_byte(0); // speed
  5965. message_end();
  5966. }
  5967.  
  5968. // Frost Grenade: Freeze Blast
  5969. create_blast3(const origin[3])
  5970. {
  5971. // smallest ring
  5972. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  5973. write_byte(TE_BEAMCYLINDER);
  5974. write_coord(origin[0]); // start X
  5975. write_coord(origin[1]); // start Y
  5976. write_coord(origin[2]); // start Z
  5977. write_coord(origin[0]); // something X
  5978. write_coord(origin[1]); // something Y
  5979. write_coord(origin[2] + 385); // something Z
  5980. write_short(g_exploSpr); // sprite
  5981. write_byte(0); // startframe
  5982. write_byte(0); // framerate
  5983. write_byte(4); // life
  5984. write_byte(60); // width
  5985. write_byte(0); // noise
  5986. write_byte(0); // red
  5987. write_byte(100); // green
  5988. write_byte(200); // blue
  5989. write_byte(200); // brightness
  5990. write_byte(0); // speed
  5991. message_end();
  5992.  
  5993. // medium ring
  5994. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  5995. write_byte(TE_BEAMCYLINDER);
  5996. write_coord(origin[0]); // start X
  5997. write_coord(origin[1]); // start Y
  5998. write_coord(origin[2]); // start Z
  5999. write_coord(origin[0]); // something X
  6000. write_coord(origin[1]); // something Y
  6001. write_coord(origin[2] + 470); // something Z
  6002. write_short(g_exploSpr); // sprite
  6003. write_byte(0); // startframe
  6004. write_byte(0); // framerate
  6005. write_byte(4); // life
  6006. write_byte(60); // width
  6007. write_byte(0); // noise
  6008. write_byte(0); // red
  6009. write_byte(100); // green
  6010. write_byte(200); // blue
  6011. write_byte(200); // brightness
  6012. write_byte(0); // speed
  6013. message_end();
  6014.  
  6015. // largest ring
  6016. message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
  6017. write_byte(TE_BEAMCYLINDER);
  6018. write_coord(origin[0]); // start X
  6019. write_coord(origin[1]); // start Y
  6020. write_coord(origin[2]); // start Z
  6021. write_coord(origin[0]); // something X
  6022. write_coord(origin[1]); // something Y
  6023. write_coord(origin[2] + 555); // something Z
  6024. write_short(g_exploSpr); // sprite
  6025. write_byte(0); // startframe
  6026. write_byte(0); // framerate
  6027. write_byte(4); // life
  6028. write_byte(60); // width
  6029. write_byte(0); // noise
  6030. write_byte(0); // red
  6031. write_byte(100); // green
  6032. write_byte(200); // blue
  6033. write_byte(200); // brightness
  6034. write_byte(0); // speed
  6035. message_end();
  6036. }
  6037.  
  6038. // Fix Dead Attrib on scoreboard
  6039. FixDeadAttrib(id)
  6040. {
  6041. message_begin(MSG_BROADCAST, g_msgScoreAttrib) // send message to everyone
  6042. write_byte(id) // target
  6043. write_byte(0) // 0 nothing - (1<<0) dead
  6044. message_end()
  6045. }
  6046.  
  6047. // Send Death Message for Zombies
  6048. SendDeathMsg(attacker, victim)
  6049. {
  6050. message_begin(MSG_BROADCAST, g_msgDeathMsg)
  6051. write_byte(attacker) // killer (0 - world)
  6052. write_byte(victim) // victim
  6053. write_byte(1) // headshot flag
  6054. write_string("infection") // killer's weapon
  6055. message_end()
  6056. }
  6057.  
  6058. // Update Player Frags
  6059. UpdateFrags(attacker, victim)
  6060. {
  6061. // set attacker frags
  6062. set_pev(attacker, pev_frags, float(pev(attacker, pev_frags) + 1))
  6063.  
  6064. // Update scoreboard with attacker info
  6065. message_begin(MSG_BROADCAST, g_msgScoreInfo)
  6066. write_byte(attacker)
  6067. write_short(pev(attacker, pev_frags))
  6068. write_short(fm_get_user_deaths(attacker))
  6069. write_short(0)
  6070. write_short(fm_get_user_team(attacker))
  6071. message_end()
  6072.  
  6073. // set victim deaths
  6074. fm_set_user_deaths(victim, fm_get_user_deaths(victim) + 1)
  6075.  
  6076. // Update scoreboard with victim info
  6077. message_begin(MSG_BROADCAST, g_msgScoreInfo)
  6078. write_byte(victim)
  6079. write_short(pev(victim, pev_frags))
  6080. write_short(fm_get_user_deaths(victim))
  6081. write_short(0)
  6082. write_short(fm_get_user_team(victim))
  6083. message_end()
  6084. }
  6085.  
  6086. // Remove Player Frags (when Nemesis/Survivor ignore_frags cvar is enabled)
  6087. RemoveFrags(attacker, victim)
  6088. {
  6089. // remove attacker frags
  6090. set_pev(attacker, pev_frags, float(pev(attacker, pev_frags) - 1))
  6091.  
  6092. // remove victim deaths
  6093. fm_set_user_deaths(victim, fm_get_user_deaths(victim) - 1)
  6094. }
  6095.  
  6096. // Play a sound on clients
  6097. PlaySound(const sound[])
  6098. {
  6099. message_begin(MSG_BROADCAST, g_msgSendAudio)
  6100. write_byte(0) // sender id
  6101. write_string(sound) // sound string
  6102. write_short(100) // pitch
  6103. message_end()
  6104. }
  6105.  
  6106. /*================================================================================
  6107. [Stocks]
  6108. =================================================================================*/
  6109.  
  6110. // Set an entity's key value (from fakemeta_util)
  6111. stock fm_set_kvd(entity, const key[], const value[], const classname[])
  6112. {
  6113. set_kvd(0, KV_ClassName, classname);
  6114. set_kvd(0, KV_KeyName, key);
  6115. set_kvd(0, KV_Value, value);
  6116. set_kvd(0, KV_fHandled, 0);
  6117.  
  6118. dllfunc(DLLFunc_KeyValue, entity, 0);
  6119. }
  6120.  
  6121. // Set entity's rendering type (from fakemeta_util)
  6122. stock fm_set_rendering(entity, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16)
  6123. {
  6124. static Float:color[3]
  6125. color[0] = float(r);
  6126. color[1] = float(g);
  6127. color[2] = float(b);
  6128.  
  6129. set_pev(entity, pev_renderfx, fx);
  6130. set_pev(entity, pev_rendercolor, color);
  6131. set_pev(entity, pev_rendermode, render);
  6132. set_pev(entity, pev_renderamt, float(amount));
  6133. }
  6134.  
  6135. // Get entity's speed (from fakemeta_util)
  6136. stock fm_get_speed(entity)
  6137. {
  6138. static Float:velocity[3]
  6139. pev(entity, pev_velocity, velocity);
  6140.  
  6141. return floatround(vector_length(velocity));
  6142. }
  6143.  
  6144. // Get entity's aim origins (from fakemeta_util)
  6145. stock fm_get_aim_origin(id, Float:origin[3])
  6146. {
  6147. static Float:origin1F[3], Float:origin2F[3]
  6148. pev(id, pev_origin, origin1F);
  6149. pev(id, pev_view_ofs, origin2F);
  6150. xs_vec_add(origin1F, origin2F, origin1F);
  6151.  
  6152. pev(id, pev_v_angle, origin2F);
  6153. engfunc(EngFunc_MakeVectors, origin2F);
  6154. global_get(glb_v_forward, origin2F);
  6155. xs_vec_mul_scalar(origin2F, 9999.0, origin2F);
  6156. xs_vec_add(origin1F, origin2F, origin2F);
  6157.  
  6158. engfunc(EngFunc_TraceLine, origin1F, origin2F, 0, id, 0);
  6159. get_tr2(0, TR_vecEndPos, origin);
  6160. }
  6161.  
  6162. // Find entity by its owner (from fakemeta_util)
  6163. stock fm_find_ent_by_owner(entity, const classname[], owner)
  6164. {
  6165. while ((entity = engfunc(EngFunc_FindEntityByString, entity, "classname", classname)) && pev(entity, pev_owner) != owner) {}
  6166.  
  6167. return entity;
  6168. }
  6169.  
  6170. // Set player's health (from fakemeta_util)
  6171. stock fm_set_user_health(id, health)
  6172. {
  6173. health > 0 ? set_pev(id, pev_health, float(health)) : dllfunc(DLLFunc_ClientKill, id);
  6174. }
  6175.  
  6176. // Give an item to a player (from fakemeta_util)
  6177. stock fm_give_item(id, const item[])
  6178. {
  6179. static ent
  6180. ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, item));
  6181. if (!pev_valid(ent)) return;
  6182.  
  6183. static Float:originF[3]
  6184. pev(id, pev_origin, originF);
  6185. set_pev(ent, pev_origin, originF);
  6186. set_pev(ent, pev_spawnflags, pev(ent, pev_spawnflags) | SF_NORESPAWN);
  6187. dllfunc(DLLFunc_Spawn, ent);
  6188.  
  6189. static save
  6190. save = pev(ent, pev_solid);
  6191. dllfunc(DLLFunc_Touch, ent, id);
  6192. if (pev(ent, pev_solid) != save)
  6193. return;
  6194.  
  6195. engfunc(EngFunc_RemoveEntity, ent);
  6196. }
  6197.  
  6198. // Strip user weapons (from fakemeta_util)
  6199. stock fm_strip_user_weapons(id)
  6200. {
  6201. static ent
  6202. ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "player_weaponstrip"))
  6203. if (!pev_valid(ent)) return;
  6204.  
  6205. dllfunc(DLLFunc_Spawn, ent);
  6206. dllfunc(DLLFunc_Use, ent, id);
  6207. engfunc(EngFunc_RemoveEntity, ent);
  6208. }
  6209.  
  6210. // Collect spawn points from entity origins
  6211. stock collect_spawns(const classname[])
  6212. {
  6213. static ent
  6214. ent = -1;
  6215.  
  6216. while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", classname)) != 0)
  6217. {
  6218. // get origin
  6219. static Float:originF[3]
  6220. pev(ent, pev_origin, originF);
  6221. g_spawns[g_spawnCount][0] = originF[0];
  6222. g_spawns[g_spawnCount][1] = originF[1];
  6223. g_spawns[g_spawnCount][2] = originF[2];
  6224.  
  6225. // increase spawn count
  6226. g_spawnCount++;
  6227. if(g_spawnCount >= sizeof g_spawns) break;
  6228. }
  6229. }
  6230.  
  6231. // Drop primary/secondary weapons
  6232. stock drop_weapons(id, dropwhat)
  6233. {
  6234. static weapons[32], num, i
  6235. num = 0 // reset passed weapons count (bugfix)
  6236. get_user_weapons(id, weapons, num)
  6237.  
  6238. for (i = 0; i < num; i++)
  6239. {
  6240. if ((dropwhat == 1 && ((1<<weapons[i]) & PRIMARY_WEAPONS_BIT_SUM)) || (dropwhat == 2 && ((1<<weapons[i]) & SECONDARY_WEAPONS_BIT_SUM)))
  6241. {
  6242. static wname[32], weapon_ent
  6243. get_weaponname(weapons[i], wname, sizeof wname - 1)
  6244. weapon_ent = fm_find_ent_by_owner(-1, wname, id); // get weapon entity
  6245.  
  6246. // hack: store weapon bpammo on pev_iuser1
  6247. set_pev(weapon_ent, pev_iuser1, fm_get_user_bpammo(id, weapons[i]))
  6248.  
  6249. engclient_cmd(id, "drop", wname) // player drops it
  6250. fm_set_user_bpammo(id, weapons[i], 0); // and looses his bpammo
  6251. }
  6252. }
  6253. }
  6254.  
  6255. // Stock by (probably) Twilight Suzuka -counts number of chars in a string
  6256. stock str_count(const str[], searchchar)
  6257. {
  6258. static count, i
  6259. count = 0
  6260.  
  6261. for (i = 0; i <= strlen(str); i++)
  6262. {
  6263. if(str[i] == searchchar)
  6264. count++
  6265. }
  6266.  
  6267. return count
  6268. }
  6269.  
  6270. // Checks if a space is vacant (credits to VEN)
  6271. stock is_hull_vacant(id, Float:origin[3])
  6272. {
  6273. engfunc(EngFunc_TraceHull, origin, origin, 0, pev(id, pev_flags) & FL_DUCKING ? HULL_HEAD : HULL_HUMAN, 0, 0);
  6274.  
  6275. if (!get_tr2(0, TR_StartSolid) && !get_tr2(0, TR_AllSolid) && get_tr2(0, TR_InOpen))
  6276. return true;
  6277.  
  6278. return false;
  6279. }
  6280.  
  6281. // Check if a player is stuck (credits to VEN)
  6282. stock is_player_stuck(id)
  6283. {
  6284. static Float:originF[3]
  6285. pev(id, pev_origin, originF)
  6286.  
  6287. engfunc(EngFunc_TraceHull, originF, originF, 0, pev(id, pev_flags) & FL_DUCKING ? HULL_HEAD : HULL_HUMAN, id, 0)
  6288.  
  6289. if (get_tr2(0, TR_StartSolid) || get_tr2(0, TR_AllSolid) || !get_tr2(0, TR_InOpen))
  6290. return true;
  6291.  
  6292. return false;
  6293. }
  6294.  
  6295. // Get User BP Ammo
  6296. stock fm_get_user_bpammo(id, weapon)
  6297. {
  6298. static offset
  6299.  
  6300. switch(weapon)
  6301. {
  6302. case CSW_AWP: offset = OFFSET_AWM_AMMO;
  6303. case CSW_SCOUT,CSW_AK47,CSW_G3SG1: offset = OFFSET_SCOUT_AMMO;
  6304. case CSW_M249: offset = OFFSET_PARA_AMMO;
  6305. case CSW_M4A1,CSW_FAMAS,CSW_AUG,CSW_SG550,CSW_GALI,CSW_SG552: offset = OFFSET_FAMAS_AMMO;
  6306. case CSW_M3,CSW_XM1014: offset = OFFSET_M3_AMMO;
  6307. case CSW_USP,CSW_UMP45,CSW_MAC10: offset = OFFSET_USP_AMMO;
  6308. case CSW_FIVESEVEN,CSW_P90: offset = OFFSET_FIVESEVEN_AMMO;
  6309. case CSW_DEAGLE: offset = OFFSET_DEAGLE_AMMO;
  6310. case CSW_P228: offset = OFFSET_P228_AMMO;
  6311. case CSW_GLOCK18,CSW_MP5NAVY,CSW_TMP,CSW_ELITE: offset = OFFSET_GLOCK_AMMO;
  6312. case CSW_FLASHBANG: offset = OFFSET_FLASH_AMMO;
  6313. case CSW_HEGRENADE: offset = OFFSET_HE_AMMO;
  6314. case CSW_SMOKEGRENADE: offset = OFFSET_SMOKE_AMMO;
  6315. case CSW_C4: offset = OFFSET_C4_AMMO;
  6316. default: return -1;
  6317. }
  6318.  
  6319. return get_pdata_int(id, offset, OFFSET_LINUX);
  6320. }
  6321.  
  6322. // Set User BP Ammo
  6323. stock fm_set_user_bpammo(id, weapon, amount)
  6324. {
  6325. static offset
  6326.  
  6327. switch(weapon)
  6328. {
  6329. case CSW_AWP: offset = OFFSET_AWM_AMMO;
  6330. case CSW_SCOUT,CSW_AK47,CSW_G3SG1: offset = OFFSET_SCOUT_AMMO;
  6331. case CSW_M249: offset = OFFSET_PARA_AMMO;
  6332. case CSW_M4A1,CSW_FAMAS,CSW_AUG,CSW_SG550,CSW_GALI,CSW_SG552: offset = OFFSET_FAMAS_AMMO;
  6333. case CSW_M3,CSW_XM1014: offset = OFFSET_M3_AMMO;
  6334. case CSW_USP,CSW_UMP45,CSW_MAC10: offset = OFFSET_USP_AMMO;
  6335. case CSW_FIVESEVEN,CSW_P90: offset = OFFSET_FIVESEVEN_AMMO;
  6336. case CSW_DEAGLE: offset = OFFSET_DEAGLE_AMMO;
  6337. case CSW_P228: offset = OFFSET_P228_AMMO;
  6338. case CSW_GLOCK18,CSW_MP5NAVY,CSW_TMP,CSW_ELITE: offset = OFFSET_GLOCK_AMMO;
  6339. case CSW_FLASHBANG: offset = OFFSET_FLASH_AMMO;
  6340. case CSW_HEGRENADE: offset = OFFSET_HE_AMMO;
  6341. case CSW_SMOKEGRENADE: offset = OFFSET_SMOKE_AMMO;
  6342. case CSW_C4: offset = OFFSET_C4_AMMO;
  6343. default: return;
  6344. }
  6345.  
  6346. set_pdata_int(id, offset, amount, OFFSET_LINUX);
  6347. }
  6348.  
  6349. // Set Weapon Clip Ammo
  6350. stock fm_set_weapon_ammo(entity, amount)
  6351. {
  6352. set_pdata_int(entity, OFFSET_CLIPAMMO, amount, OFFSET_LINUX_WEAPONS);
  6353. }
  6354.  
  6355. // Get Weapon Clip Ammo
  6356. stock fm_get_weapon_ammo(entity)
  6357. {
  6358. return get_pdata_int(entity, OFFSET_CLIPAMMO, OFFSET_LINUX_WEAPONS);
  6359. }
  6360.  
  6361. // Set User Zoom
  6362. stock fm_remove_user_zoom(id)
  6363. {
  6364. set_pdata_int(id, OFFSET_ZOOMTYPE, CS_NO_ZOOM, OFFSET_LINUX);
  6365. }
  6366.  
  6367. // Get User Deaths
  6368. stock fm_get_user_deaths(id)
  6369. {
  6370. return get_pdata_int(id, OFFSET_CSDEATHS, OFFSET_LINUX);
  6371. }
  6372.  
  6373. // Set User Deaths
  6374. stock fm_set_user_deaths(id, value)
  6375. {
  6376. set_pdata_int(id, OFFSET_CSDEATHS, value, OFFSET_LINUX);
  6377. }
  6378.  
  6379. // Set Bots NVG
  6380. stock fm_set_bot_nvg(id, value)
  6381. {
  6382. g_nvision[id] = true;
  6383.  
  6384. set_pdata_int(id, OFFSET_NVGOGGLES, value, OFFSET_LINUX);
  6385. }
  6386.  
  6387. // Get User Team
  6388. stock fm_get_user_team(id)
  6389. {
  6390. return get_pdata_int(id, OFFSET_CSTEAMS, OFFSET_LINUX);
  6391. }
  6392.  
  6393. // Set a Player's Team
  6394. stock fm_set_user_team(id, team)
  6395. {
  6396. set_pdata_int(id, OFFSET_CSTEAMS, team, OFFSET_LINUX);
  6397. }
  6398.  
  6399. // Send User Team Message
  6400. public fm_set_user_team_msg(taskid)
  6401. {
  6402. // Beware: this message can now be picked up by other metamod
  6403. // plugins (yeah, that includes AMXX plugins as well)
  6404.  
  6405. // Set the switching team flag
  6406. g_switchingteam[ID_TEAM] = true;
  6407.  
  6408. // Tell everyone my new team
  6409. emessage_begin(MSG_ALL, g_msgTeamInfo)
  6410. ewrite_byte(ID_TEAM)
  6411.  
  6412. switch (fm_get_user_team(ID_TEAM))
  6413. {
  6414. case CS_TEAM_UNASSIGNED: ewrite_string("UNASSIGNED");
  6415. case CS_TEAM_T: ewrite_string("TERRORIST");
  6416. case CS_TEAM_CT: ewrite_string("CT");
  6417. case CS_TEAM_SPECTATOR: ewrite_string("SPECTATOR");
  6418. }
  6419.  
  6420. emessage_end()
  6421.  
  6422. // Done switching team
  6423. g_switchingteam[ID_TEAM] = false;
  6424. }
  6425.  
  6426. #if defined HANDLE_MODELS_ON_SEPARATE_ENT
  6427. // Set User Model on Entity
  6428. stock fm_set_user_model_ent(id)
  6429. {
  6430. static model[100], ent
  6431.  
  6432. // format model string
  6433. formatex(model, sizeof model - 1, "models/player/%s/%s.mdl", g_playermodel[id], g_playermodel[id])
  6434.  
  6435. ent = fm_find_ent_by_owner(-1, "player_model", id) // get player_model entity
  6436.  
  6437. if (!ent) // doesn't exist, make a new one
  6438. {
  6439. ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
  6440. set_pev(ent, pev_classname, "player_model")
  6441. set_pev(ent, pev_movetype, MOVETYPE_FOLLOW)
  6442. engfunc(EngFunc_SetModel, ent, model)
  6443. set_pev(ent, pev_aiment, id)
  6444. set_pev(ent, pev_owner, id)
  6445. }
  6446. else
  6447. {
  6448. engfunc(EngFunc_SetModel, ent, model)
  6449. }
  6450. }
  6451.  
  6452. // Set Weapon Model on Entity
  6453. stock fm_set_weapon_model_ent(id, const model[])
  6454. {
  6455. static ent
  6456. ent = fm_find_ent_by_owner(-1, "weapon_model", id) // get weapon_model entity
  6457.  
  6458. if (!ent) // doesn't exist, make a new one
  6459. {
  6460. ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
  6461. set_pev(ent, pev_classname, "weapon_model")
  6462. set_pev(ent, pev_movetype, MOVETYPE_FOLLOW)
  6463. engfunc(EngFunc_SetModel, ent, model)
  6464. set_pev(ent, pev_aiment, id)
  6465. set_pev(ent, pev_owner, id)
  6466. }
  6467. else
  6468. {
  6469. engfunc(EngFunc_SetModel, ent, model)
  6470. }
  6471. }
  6472. #else
  6473. // Set User Model by ClientKeyValue
  6474. public fm_set_user_model(taskid)
  6475. {
  6476. engfunc(EngFunc_SetClientKeyValue, ID_MODEL, engfunc(EngFunc_GetInfoKeyBuffer, ID_MODEL), "model", g_playermodel[ID_MODEL])
  6477. }
  6478.  
  6479. // Get User Model -model passed byref-
  6480. stock fm_get_user_model(player, model[], len)
  6481. {
  6482. engfunc(EngFunc_InfoKeyValue, engfunc(EngFunc_GetInfoKeyBuffer, player), "model", model, len)
  6483. }
  6484. #endif
  6485. /* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
  6486. *{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang3082\\ f0\\ fs16 \n\\ par }
  6487. */
Add Comment
Please, Sign In to add comment