Guest User

Untitled

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