Guest User

Untitled

a guest
Aug 11th, 2012
204
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 336.95 KB | None | 0 0
  1. /*================================================================================
  2.  
  3. *****************************************************
  4. ************** [Zombie Plague Mod 4.3] **************
  5. *****************************************************
  6.  
  7. ----------------------
  8. -*- Licensing Info -*-
  9. ----------------------
  10.  
  11. Zombie Plague Mod
  12. Copyright (C) 2008-2009 by MeRcyLeZZ
  13.  
  14. This program is free software: you can redistribute it and/or modify
  15. it under the terms of the GNU General Public License as published by
  16. the Free Software Foundation, either version 3 of the License, or
  17. (at your option) any later version.
  18.  
  19. This program is distributed in the hope that it will be useful,
  20. but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. GNU General Public License for more details.
  23.  
  24. You should have received a copy of the GNU General Public License
  25. along with this program. If not, see <http://www.gnu.org/licenses/>.
  26.  
  27. In addition, as a special exception, the author gives permission to
  28. link the code of this program with the Half-Life Game Engine ("HL
  29. Engine") and Modified Game Libraries ("MODs") developed by Valve,
  30. L.L.C ("Valve"). You must obey the GNU General Public License in all
  31. respects for all of the code used other than the HL Engine and MODs
  32. from Valve. If you modify this file, you may extend this exception
  33. to your version of the file, but you are not obligated to do so. If
  34. you do not wish to do so, delete this exception statement from your
  35. version.
  36.  
  37. -------------------
  38. -*- Description -*-
  39. -------------------
  40.  
  41. Zombie Plague is a Counter-Strike server side modification, developed as
  42. an AMX Mod X plugin, which completely revamps the gameplay, turning the
  43. game into an intense "Humans vs Zombies" survival experience.
  44.  
  45. Even though it's strongly based on the classic zombie infection mods, it
  46. takes the concept to a new level by introducing:
  47.  
  48. * New Gameplay Modes: Nemesis, Survivor, Multi Infection, Swarm, Plague
  49. * Zombie Classes System: allows addding unlimited custom zombie classes
  50. * Ammo Packs: awarded to skilled players, can be exchanged for goods
  51. * Extra Items System: allows adding unlimited custom items to buy
  52. * Custom Grenades: Napalms, Frost Nades, Flares, and Infection Bombs
  53. * Deathmatch Mode: where zombies or humans can continually respawn
  54. * Admin Menus: to easily perform the included console commands
  55. * Special Effects: from the HL Engine, such as dynamic lighting and fog
  56.  
  57. There is plenty of customization as well, which enables you to create
  58. several different styles of gameplay. You can:
  59.  
  60. * Set zombies and humans' health, speed, models, rewards, and more
  61. * Toggle unlimited ammo and adjustable knockback for weapons
  62. * Separately enable and customize the new gameplay modes to your liking
  63. * Change overall map lighting (lightnings available for the dark settings)
  64. * Set different colors and sizes for flashlight and nightvision
  65. * Toggle leap (long jumping) and pain shock free (no damage slowdowns)
  66. * Toggle various infection effects, such as sparks and screen shakes
  67. * Enable random spawning (CSDM-spawn friendly)
  68. * Replace sounds or add some background themes
  69. * And many more...
  70.  
  71. -------------
  72. -*- Media -*-
  73. -------------
  74.  
  75. * Gameplay Video 1: http://www.youtube.com/watch?v=HFUyF7-_uzw
  76. * Gameplay Video 2: http://www.youtube.com/watch?v=XByif6Mti-w
  77.  
  78. --------------------
  79. -*- Requirements -*-
  80. --------------------
  81.  
  82. * Mods: Counter-Strike 1.6 or Condition-Zero
  83. * AMXX: Version 1.8.0 or later
  84.  
  85. --------------------
  86. -*- Installation -*-
  87. --------------------
  88.  
  89. Extract the contents from the .zip file to your server's mod directory
  90. ("cstrike" or "czero"). Make sure to keep folder structure.
  91.  
  92. -----------------------
  93. -*- Official Forums -*-
  94. -----------------------
  95.  
  96. For the official Zombie Plague forums visit:
  97. http://forums.alliedmods.net/forumdisplay.php?f=126
  98.  
  99. There you can:
  100.  
  101. * Get the latest releases and early betas
  102. * Discuss new features and suggestions
  103. * Share sub-plugins (expansions) for the mod
  104. * Find the support and help you need
  105. * Report any bugs you might find
  106. * And all that sort of stuff...
  107.  
  108. -------------------------------
  109. -*- CVARS and Customization -*-
  110. -------------------------------
  111.  
  112. For a complete and in-depth cvar list, look at the zombieplague.cfg file
  113. located in the amxmodx\configs directory.
  114.  
  115. Additionally, you can change player models, sounds, weather effects,
  116. and some other stuff from the configuration file zombieplague.ini.
  117.  
  118. As for editing attributes of zombie classes or custom extra items, you'll
  119. find a zp_zombieclasses.ini and zp_extraitems.ini. These files will be
  120. automatically updated as you install new custom classes or items with
  121. new entries for you to edit conveniently.
  122.  
  123. ---------------
  124. -*- History -*-
  125. ---------------
  126.  
  127. This project started back on late 2007, when the free infection mods
  128. around were quite buggy and I wanted to make one on my own. With little
  129. to no experience at AMXX scripting, I had to start from the very scratch.
  130.  
  131. Not after spending over a week looking at many plugins (mainly Zombie
  132. Swarm) and scarce tutorials, I somehow managed to have all the basic
  133. stuff working quite well (even though the code was a real mess). The
  134. following months were spent polishing things up and trying to fulfill
  135. new original ideas, most of them quite worth the hard work.
  136.  
  137. In the meantime, I got the chance to try the plugin out on a 32 man
  138. server. This meant a huge progress on development, and after lots of
  139. testing and bug fixing, the mod turned out to be more than the simple
  140. infection plugin I had originally planned it to be.
  141.  
  142. The project has come a long way since, and I'm glad to say I'm finally
  143. making it freely available. All I'm asking in return is to keep my
  144. name in the plugin.
  145.  
  146. -Enjoy!
  147.  
  148. ----------------------
  149. -*- Infection Mode -*-
  150. ----------------------
  151.  
  152. On every round players start out as humans, equip themselves with a few
  153. weapons and grenades, and head to the closest cover they find, knowing
  154. that one of them is infected with the T-Virus, and will suddenly turn
  155. into a vicious brain eating creature.
  156.  
  157. Only little time after, the battle for survival begins. The first zombie
  158. has to infect as many humans as possible to cluster a numerous zombie
  159. horde and take over the world.
  160.  
  161. Maps are set in the dark by default. Humans must use flashlights to light
  162. their way and spot any enemies. Zombies, on the other hand, have night
  163. vision but can only attack melee.
  164.  
  165. --------------------------
  166. -*- New Gameplay Modes -*-
  167. --------------------------
  168.  
  169. * Nemesis:
  170. The first zombie may turn into a Nemesis, a powerful fast-moving
  171. beast. His goal is to kill every human while sustaining the gunfire.
  172.  
  173. * Survivor:
  174. Everyone became a zombie except him. The survivor gets a machinegun
  175. with unlimited ammo and has to stop the never-ending army of undead.
  176.  
  177. * Multiple Infection:
  178. The round starts with many humans infected, so the remaining players
  179. will have to act quickly in order to control the situation.
  180.  
  181. * Swarm Mode:
  182. Half of the players turn into zombies, the rest become immune and
  183. cannot be infected. It's a battle to death.
  184.  
  185. * Plague Mode: [bonus]
  186. A full armed Survivor and his soldiers are to face Nemesis and
  187. his zombie minions. The future of the world is in their hands.
  188.  
  189. --------------------
  190. -*- In-Game Menu -*-
  191. --------------------
  192.  
  193. Players can access the mod menu by typing "zpmenu" on chat, or by
  194. pressing the M ("chooseteam") key. The menu allows players to choose
  195. their zombie class, buy extra items, get unstuck, or see the ingame
  196. help. Admins will find an additional option to easily perform all
  197. console commands.
  198.  
  199. ----------------------
  200. -*- Admin Commands -*-
  201. ----------------------
  202.  
  203. The following console commands are available:
  204.  
  205. * zp_zombie <target> - Turn someone into a Zombie
  206. * zp_human <target> - Turn someone back to Human
  207. * zp_nemesis <target> - Turn someone into a Nemesis
  208. * zp_survivor <target> - Turn someone into a Survivor
  209. * zp_respawn <target> - Respawn someone
  210. * zp_swarm - Start Swarm Mode (*)
  211. * zp_multi - Start Multi Infection (*)
  212. * zp_plague - Start Plague Mode (*)
  213.  
  214. (*) - These commands can only be used at round start, that is, when the
  215. T-Virus notice is shown on screen.
  216.  
  217. ------------------
  218. -*- Plugin API -*-
  219. ------------------
  220.  
  221. From version 3.6, some natives and forwards have been added to ease the
  222. development of sub-plugins, though you may also find them useful to work
  223. out compatibility issues with existing plugins.
  224.  
  225. Look for the zombieplague.inc file in your amxmodx\scripting\include
  226. folder for the full documented list.
  227.  
  228. ----------------------
  229. -*- Zombie Classes -*-
  230. ----------------------
  231.  
  232. From version 4.0 it is possible to create and add an unlimited number of
  233. zombie classes to the main mod. They can be made as separate plugins,
  234. by using the provided zombie class API, and easily distributed.
  235.  
  236. By default, five zombie classes are included:
  237.  
  238. * Classic Zombie: well balanced zombie for beginners.
  239. * Raptor Zombie: fast moving zombie, but also the weakest.
  240. * Poison Zombie: light weighed zombie, jumps higher.
  241. * Big Zombie: slow but strong zombie, with lots of hit points.
  242. * Leech Zombie: regains additional health when infecting.
  243.  
  244. -------------------
  245. -*- Extra Items -*-
  246. -------------------
  247.  
  248. From version 4.0 it is possible to add an unlimited number of items
  249. which can be purchased through the Extra Items menu. All you need
  250. to do is use the provided item registration natives on your custom
  251. plugins. You can set the name, the cost in ammo packs, and the team
  252. the extra item should be available for.
  253.  
  254. By default there is a number of items already included, listed here:
  255.  
  256. * Night Vision: makes you able to see in the dark for a single round [Human]
  257. * T-Virus Antidote: makes you turn back to your human form [Zombie]
  258. * Zombie Madness: you develop a powerful shield for a short time [Zombie]
  259. * Infection Bomb: infects anyone within its explosion radius [Zombie]
  260.  
  261. You are also able to choose some weapons to act as extra items, and change
  262. ammo packs costs in the customization file (zombieplague.ini).
  263.  
  264. ---------------
  265. -*- Credits -*-
  266. ---------------
  267.  
  268. * AMXX Dev Team: for all the hard work which made this possible
  269. * Imperio LNJ Community: for providing the first server where I
  270. could really test the plugin and for everyone's support
  271. * Mini_Midget: for his Zombie Swarm plugin which I used for reference
  272. on earliest stages of development
  273. * Avalanche: for the random spawning code I got from GunGame and the
  274. original Frostnades concept that I ported in here
  275. * cheap_suit: for some modelchange and knockback codes that I got from
  276. Biohazard
  277. * Simon Logic/ConnorMcLeod: for the Pain Shock Free feature
  278. * KRoT@L: for some code from Follow the Wounded, used to make the zombie
  279. bleeding feature
  280. * VEN: for Fakemeta Utilities and some useful stocks
  281. * RaaPuar and Goltark: for the custom grenade models
  282. * Orangutanz: for finding the precached modelindex offset
  283. * ML Translations: DKs/nunoabc/DarkMarcos (bp), JahMan/KWo (pl), DA (de),
  284. Zombie Lurker (ls), DoPe^ (da), k1nny (fr), NeWbiE' (cz), skymoon (tc),
  285. SUPER MATRIX/Shidla/zDemon/4eRT (ru), zsy314 (cn), lOlIl/Seehank (sk),
  286. Bridgestone (sv), crazyeffect.net/Mave/Wesley (nl), hleV/aaarnas (lt),
  287. darkbad945 (bg), decongamco (vn), beckham9224 (mn), TehGeorge (gr),
  288. shadoww_ro/tuty/georgik57/EastSider (ro)
  289. * Beta testers: for all the feedback, bug reports, and suggestions which
  290. constantly help improve this mod further
  291. * And to all zombie-mod supporters out there!
  292.  
  293. -----------------
  294. -*- Changelog -*-
  295. -----------------
  296.  
  297. * v1.0: (Dec 2007)
  298. - First Release: most of the basic stuff done.
  299. - Added: random spawning, HP display on hud, lighting setting,
  300. simple buy menu, custom nightvision, admin commands, Nemesis
  301. and Survivor modes, glow and leap settings for them.
  302.  
  303. * v2.2: (Jan 2008)
  304. - Added: zombie classes, ammo packs system, buying ammo for weapons,
  305. custom flashlight, admin skins setting, zombieplague.cfg file
  306. - Upgraded: weapons menu improved, flashlight and nightvision colors
  307. now customizable, HamSandwich module used to handle damage.
  308. - Fixed various bugs.
  309.  
  310. * v3.0: (Mar 2008)
  311. - Added: door removal setting, unstuck feature, human cvars, armor
  312. cvar for zombies, weapon knockback, zombie bleeding, flares,
  313. extra items (weapons, antidote, infection bomb), pain shock
  314. free setting, Multiple Infection and Swarm modes.
  315. - Upgraded: dumped Engine, Fun and Cstrike modules, code optimized,
  316. new model change method, new gfx effects for zombie infections.
  317. - Fixed a bunch of gameplay bugs.
  318.  
  319. * v3.5: (May 2008)
  320. - Added: deathmatch setting with spawn protection, unlimited ammo
  321. setting, fire and frost grenades, additional customization cvars,
  322. new extra items, help menu.
  323. - Upgraded: better objectives removal method, dropped weapons now
  324. keep their bpammo, code optimized a lot.
  325. - Fixed: no more game commencing bug when last zombie/human leaves,
  326. no more hegrenade infection bug, reduced svc_bad errors, and
  327. many more.
  328.  
  329. * v3.6: (Jun 2008)
  330. - Added: a few natives and forwards for sub-plugins support,
  331. zombie classes can now have their own models, additional
  332. knockback customization, bot support, various CVARs.
  333. - Upgraded: extra items now supporting grenades and pistols, changed
  334. bomb removal method, players can join on survivor/swarm rounds,
  335. extended lightnings support to other dark settings.
  336. - Fixed: a bunch of minor bugs, and a server crash with CZ bots.
  337.  
  338. * v4.0: (Aug 2008)
  339. - Added: new gameplay mode (Plague Mode), option to remember weapon
  340. selection, command to enable/disable the plugin, more CVARs.
  341. - Upgraded: redid all the menus, extra items and zombie classes now
  342. support external additions, survivor can now have its own model,
  343. upgraded model changing method.
  344. - Fixed: some bugs with bots, win sounds not being precached.
  345.  
  346. * v4.1: (Oct 2008)
  347. - Added: more CVARs, more customization, more natives, custom
  348. leap system, admin zombie models support, and more.
  349. - Upgraded: custom grenades compatible with Nade Modes, ambience
  350. sounds specific game mode support, optimized bandwidth usage
  351. for temp ents, admin commands logged with IP and SteamID.
  352. - Fixed: lots of bugs (some minor, some not)
  353.  
  354. * v4.2: (Feb 2009)
  355. - Added various CVARs for customization, improved prevention of
  356. svc_bad in some cases, optimized ammo handling code.
  357. - Fixed server crash with 'msg 35 has not been sent yet' error,
  358. fixed client overflow issues with ambience sounds, resolved
  359. many gameplay bugs.
  360.  
  361. * v4.3: (Apr 2009)
  362. - Customization settings can now be edited through external files,
  363. added support for global and multiple random zombie models,
  364. added even more CVARs for tweaking stuff, extended admin commands'
  365. functionality, greatly extended API capabilities, implemented a
  366. more efficient Pain Shock Free code, reworked some menus.
  367. - Fixed pretty much all reported bugs to the date.
  368.  
  369. =================================================================================*/
  370.  
  371. /*================================================================================
  372. [Plugin Customization]
  373. =================================================================================*/
  374.  
  375. // All customization settings have been moved
  376. // to external files to allow easier editing
  377. new const ZP_CUSTOMIZATION_FILE[] = "zombieplague.ini"
  378. new const ZP_EXTRAITEMS_FILE[] = "zp_extraitems.ini"
  379. new const ZP_ZOMBIECLASSES_FILE[] = "zp_zombieclasses.ini"
  380.  
  381. // Limiters for stuff not worth making dynamic arrays out of (increase if needed)
  382. const MAX_CSDM_SPAWNS = 128
  383. const MAX_STATS_SAVED = 64
  384.  
  385. /*================================================================================
  386. Customization ends here! Yes, that's it. Editing anything beyond
  387. here is not officially supported. Proceed at your own risk...
  388. =================================================================================*/
  389.  
  390. #include <amxmodx>
  391. #include <amxmisc>
  392. #include <cstrike>
  393. #include <fakemeta>
  394. #include <hamsandwich>
  395. #include <xs>
  396.  
  397. /*================================================================================
  398. [Constants, Offsets, Macros]
  399. =================================================================================*/
  400.  
  401. // Plugin Version
  402. new const PLUGIN_VERSION[] = "4.3"
  403.  
  404. // Customization file sections
  405. enum
  406. {
  407. SECTION_NONE = 0,
  408. SECTION_ACCESS_FLAGS,
  409. SECTION_PLAYER_MODELS,
  410. SECTION_WEAPON_MODELS,
  411. SECTION_GRENADE_SPRITES,
  412. SECTION_SOUNDS,
  413. SECTION_AMBIENCE_SOUNDS,
  414. SECTION_BUY_MENU_WEAPONS,
  415. SECTION_EXTRA_ITEMS_WEAPONS,
  416. SECTION_HARD_CODED_ITEMS_COSTS,
  417. SECTION_WEATHER_EFFECTS,
  418. SECTION_SKY,
  419. SECTION_LIGHTNING,
  420. SECTION_ZOMBIE_DECALS,
  421. SECTION_KNOCKBACK,
  422. SECTION_OBJECTIVE_ENTS,
  423. SECTION_SVC_BAD
  424. }
  425.  
  426. // Access flags
  427. enum
  428. {
  429. ACCESS_ENABLE_MOD = 0,
  430. ACCESS_ADMIN_MENU,
  431. ACCESS_MODE_INFECTION,
  432. ACCESS_MODE_NEMESIS,
  433. ACCESS_MODE_SURVIVOR,
  434. ACCESS_MODE_SWARM,
  435. ACCESS_MODE_MULTI,
  436. ACCESS_MODE_PLAGUE,
  437. ACCESS_MAKE_ZOMBIE,
  438. ACCESS_MAKE_HUMAN,
  439. ACCESS_MAKE_NEMESIS,
  440. ACCESS_MAKE_SURVIVOR,
  441. ACCESS_RESPAWN_PLAYERS,
  442. ACCESS_ADMIN_MODELS,
  443. MAX_ACCESS_FLAGS
  444. }
  445.  
  446. // Task offsets
  447. enum (+= 100)
  448. {
  449. TASK_MODEL = 2000,
  450. TASK_TEAM,
  451. TASK_SPAWN,
  452. TASK_BLOOD,
  453. TASK_AURA,
  454. TASK_BURN,
  455. TASK_NVISION,
  456. TASK_FLASH,
  457. TASK_CHARGE,
  458. TASK_SHOWHUD,
  459. TASK_MAKEZOMBIE,
  460. TASK_WELCOMEMSG,
  461. TASK_THUNDER_PRE,
  462. TASK_THUNDER,
  463. TASK_AMBIENCESOUNDS
  464. }
  465.  
  466. // IDs inside tasks
  467. #define ID_MODEL (taskid - TASK_MODEL)
  468. #define ID_TEAM (taskid - TASK_TEAM)
  469. #define ID_SPAWN (taskid - TASK_SPAWN)
  470. #define ID_BLOOD (taskid - TASK_BLOOD)
  471. #define ID_AURA (taskid - TASK_AURA)
  472. #define ID_BURN (taskid - TASK_BURN)
  473. #define ID_NVISION (taskid - TASK_NVISION)
  474. #define ID_FLASH (taskid - TASK_FLASH)
  475. #define ID_CHARGE (taskid - TASK_CHARGE)
  476. #define ID_SHOWHUD (taskid - TASK_SHOWHUD)
  477.  
  478. // BP Ammo Refill task
  479. #define REFILL_WEAPONID args[0]
  480.  
  481. // For weapon buy menu handlers
  482. #define WPN_STARTID g_menu_data[id][1]
  483. #define WPN_MAXIDS ArraySize(g_primary_items)
  484. #define WPN_SELECTION (g_menu_data[id][1]+key)
  485. #define WPN_AUTO_ON g_menu_data[id][2]
  486. #define WPN_AUTO_PRI g_menu_data[id][3]
  487. #define WPN_AUTO_SEC g_menu_data[id][4]
  488.  
  489. // For player list menu handlers
  490. #define PL_ACTION g_menu_data[id][0]
  491.  
  492. // For extra items menu handlers
  493. #define EXTRAS_CUSTOM_STARTID (EXTRA_WEAPONS_STARTID + ArraySize(g_extraweapon_names))
  494.  
  495. // Menu selections
  496. const MENU_KEY_AUTOSELECT = 7
  497. const MENU_KEY_BACK = 7
  498. const MENU_KEY_NEXT = 8
  499. const MENU_KEY_EXIT = 9
  500.  
  501. // Hard coded extra items
  502. enum
  503. {
  504. EXTRA_NVISION = 0,
  505. EXTRA_ANTIDOTE,
  506. EXTRA_MADNESS,
  507. EXTRA_INFBOMB,
  508. EXTRA_WEAPONS_STARTID
  509. }
  510.  
  511. // Game modes
  512. enum
  513. {
  514. MODE_NONE = 0,
  515. MODE_INFECTION,
  516. MODE_NEMESIS,
  517. MODE_SURVIVOR,
  518. MODE_SWARM,
  519. MODE_MULTI,
  520. MODE_PLAGUE
  521. }
  522.  
  523. // ZP Teams
  524. const ZP_TEAM_NO_ONE = 0
  525. const ZP_TEAM_ANY = 0
  526. const ZP_TEAM_ZOMBIE = (1<<0)
  527. const ZP_TEAM_HUMAN = (1<<1)
  528. const ZP_TEAM_NEMESIS = (1<<2)
  529. const ZP_TEAM_SURVIVOR = (1<<3)
  530. new const ZP_TEAM_NAMES[][] = { "ZOMBIE , HUMAN", "ZOMBIE", "HUMAN", "ZOMBIE , HUMAN", "NEMESIS",
  531. "ZOMBIE , NEMESIS", "HUMAN , NEMESIS", "ZOMBIE , HUMAN , NEMESIS",
  532. "SURVIVOR", "ZOMBIE , SURVIVOR", "HUMAN , SURVIVOR", "ZOMBIE , HUMAN , SURVIVOR",
  533. "NEMESIS , SURVIVOR", "ZOMBIE , NEMESIS , SURVIVOR", "HUMAN, NEMESIS, SURVIVOR",
  534. "ZOMBIE , HUMAN , NEMESIS , SURVIVOR" }
  535.  
  536. // Zombie classes
  537. const ZCLASS_NONE = -1
  538.  
  539. // HUD messages
  540. const Float:HUD_EVENT_X = -1.0
  541. const Float:HUD_EVENT_Y = 0.17
  542. const Float:HUD_INFECT_X = 0.05
  543. const Float:HUD_INFECT_Y = 0.45
  544. const Float:HUD_SPECT_X = 0.6
  545. const Float:HUD_SPECT_Y = 0.8
  546. const Float:HUD_STATS_X = 0.01
  547. const Float:HUD_STATS_Y = 0.25
  548.  
  549. // CS Player PData Offsets (win32)
  550. const OFFSET_PAINSHOCK = 108 // ConnorMcLeod
  551. const OFFSET_CSTEAMS = 114
  552. const OFFSET_CSMONEY = 115
  553. const OFFSET_FLASHLIGHT_BATTERY = 244
  554. const OFFSET_CSDEATHS = 444
  555. const OFFSET_MODELINDEX = 491 // Orangutanz
  556.  
  557. // CS Player CBase Offsets (win32)
  558. const OFFSET_ACTIVE_ITEM = 373
  559.  
  560. // CS Weapon CBase Offsets (win32)
  561. const OFFSET_WEAPONOWNER = 41
  562.  
  563. // Linux diff's
  564. const OFFSET_LINUX = 5 // offsets 5 higher in Linux builds
  565. const OFFSET_LINUX_WEAPONS = 4 // weapon offsets are only 4 steps higher on Linux
  566.  
  567. // CS Teams
  568. enum
  569. {
  570. FM_CS_TEAM_UNASSIGNED = 0,
  571. FM_CS_TEAM_T,
  572. FM_CS_TEAM_CT,
  573. FM_CS_TEAM_SPECTATOR
  574. }
  575. new const CS_TEAM_NAMES[][] = { "UNASSIGNED", "TERRORIST", "CT", "SPECTATOR" }
  576.  
  577. // Some constants
  578. const HIDE_MONEY = (1<<5)
  579. const UNIT_SECOND = (1<<12)
  580. const DMG_HEGRENADE = (1<<24)
  581. const IMPULSE_FLASHLIGHT = 100
  582. const USE_USING = 2
  583. const USE_STOPPED = 0
  584. const STEPTIME_SILENT = 999
  585. const BREAK_GLASS = 0x01
  586. const FFADE_IN = 0x0000
  587. const FFADE_STAYOUT = 0x0004
  588. const PEV_SPEC_TARGET = pev_iuser2
  589.  
  590. // Max BP ammo for weapons
  591. new const MAXBPAMMO[] = { -1, 52, -1, 90, 1, 32, 1, 100, 90, 1, 120, 100, 100, 90, 90, 90, 100, 120,
  592. 30, 120, 200, 32, 90, 120, 90, 2, 35, 90, 90, -1, 100 }
  593.  
  594. // Max Clip for weapons
  595. new const MAXCLIP[] = { -1, 13, -1, 10, -1, 7, -1, 30, 30, -1, 30, 20, 25, 30, 35, 25, 12, 20,
  596. 10, 30, 100, 8, 30, 30, 20, -1, 7, 30, 30, -1, 50 }
  597.  
  598. // Amount of ammo to give when buying additional clips for weapons
  599. new const BUYAMMO[] = { -1, 13, -1, 30, -1, 8, -1, 12, 30, -1, 30, 50, 12, 30, 30, 30, 12, 30,
  600. 10, 30, 30, 8, 30, 30, 30, -1, 7, 30, 30, -1, 50 }
  601.  
  602. // Ammo IDs for weapons
  603. new const AMMOID[] = { -1, 9, -1, 2, 12, 5, 14, 6, 4, 13, 10, 7, 6, 4, 4, 4, 6, 10,
  604. 1, 10, 3, 5, 4, 10, 2, 11, 8, 4, 2, -1, 7 }
  605.  
  606. // Ammo Type Names for weapons
  607. new const AMMOTYPE[][] = { "", "357sig", "", "762nato", "", "buckshot", "", "45acp", "556nato", "", "9mm", "57mm", "45acp",
  608. "556nato", "556nato", "556nato", "45acp", "9mm", "338magnum", "9mm", "556natobox", "buckshot",
  609. "556nato", "9mm", "762nato", "", "50ae", "556nato", "762nato", "", "57mm" }
  610.  
  611. // Weapon IDs for ammo types
  612. new const AMMOWEAPON[] = { 0, CSW_AWP, CSW_SCOUT, CSW_M249, CSW_AUG, CSW_XM1014, CSW_MAC10, CSW_FIVESEVEN, CSW_DEAGLE,
  613. CSW_P228, CSW_ELITE, CSW_FLASHBANG, CSW_HEGRENADE, CSW_SMOKEGRENADE, CSW_C4 }
  614.  
  615. // Primary and Secondary Weapon Names
  616. new const WEAPONNAMES[][] = { "", "\yP228 Compact", "", "\ySchmidt Scout", "", "\rXM1014 M4", "", "\rIngram MAC-10", "\rSteyr AUG A1",
  617. "", "\rDual Elite Berettas", "\rFiveseveN", "\rUMP 45", "\rSG-550 Auto-Sniper", "\rIMI Galil", "\rFamas",
  618. "\rUSP .45 ACP Tactical", "\rGlock 18C", "\rAWP Magnum Sniper", "\rMP5 Navy", "\rM249 Para Machinegun",
  619. "\rM3 Super 90", "\rM4A1 Carbine", "\rSchmidt TMP", "\rG3SG1 Auto-Sniper", "", "\rDesert Eagle .50 AE",
  620. "\rSG-552 Commando", "\rAK-47 Kalashnikov", "", "\rES P90" }
  621.  
  622. // Weapon entity names
  623. new const WEAPONENTNAMES[][] = { "", "weapon_p228", "", "weapon_scout", "weapon_hegrenade", "weapon_xm1014", "weapon_c4", "weapon_mac10",
  624. "weapon_aug", "weapon_smokegrenade", "weapon_elite", "weapon_fiveseven", "weapon_ump45", "weapon_sg550",
  625. "weapon_galil", "weapon_famas", "weapon_usp", "weapon_glock18", "weapon_awp", "weapon_mp5navy", "weapon_m249",
  626. "weapon_m3", "weapon_m4a1", "weapon_tmp", "weapon_g3sg1", "weapon_flashbang", "weapon_deagle", "weapon_sg552",
  627. "weapon_ak47", "weapon_knife", "weapon_p90" }
  628.  
  629. // CS sounds
  630. new const sound_flashlight[] = "items/flashlight1.wav"
  631. new const sound_buyammo[] = "items/9mmclip1.wav"
  632. new const sound_armorhit[] = "player/bhit_helmet-1.wav"
  633.  
  634. // Explosion radius for custom grenades
  635. const Float:NADE_EXPLOSION_RADIUS = 240.0
  636.  
  637. // HACK: pev_ field used to store additional ammo on weapons
  638. const PEV_ADDITIONAL_AMMO = pev_iuser1
  639.  
  640. // HACK: pev_ field used to store custom nade types and their values
  641. const PEV_NADE_TYPE = pev_flTimeStepSound
  642. const NADE_TYPE_INFECTION = 1111
  643. const NADE_TYPE_NAPALM = 2222
  644. const NADE_TYPE_FROST = 3333
  645. const NADE_TYPE_FLARE = 4444
  646. const PEV_FLARE_COLOR = pev_punchangle
  647. const PEV_FLARE_DURATION = pev_flSwimTime
  648.  
  649. // Weapon bitsums
  650. 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)
  651. const SECONDARY_WEAPONS_BIT_SUM = (1<<CSW_P228)|(1<<CSW_ELITE)|(1<<CSW_FIVESEVEN)|(1<<CSW_USP)|(1<<CSW_GLOCK18)|(1<<CSW_DEAGLE)
  652.  
  653. // Allowed weapons for zombies (added grenades/bomb for sub-plugin support, since they shouldn't be getting them anyway)
  654. const ZOMBIE_ALLOWED_WEAPONS_BITSUM = (1<<CSW_KNIFE)|(1<<CSW_HEGRENADE)|(1<<CSW_FLASHBANG)|(1<<CSW_SMOKEGRENADE)|(1<<CSW_C4)
  655.  
  656. // Classnames for separate model entities
  657. new const MODEL_ENT_CLASSNAME[] = "player_model"
  658. new const WEAPON_ENT_CLASSNAME[] = "weapon_model"
  659.  
  660. // Menu keys
  661. const KEYSMENU = MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4|MENU_KEY_5|MENU_KEY_6|MENU_KEY_7|MENU_KEY_8|MENU_KEY_9|MENU_KEY_0
  662.  
  663. // Ambience Sounds
  664. enum
  665. {
  666. AMBIENCE_SOUNDS_INFECTION = 0,
  667. AMBIENCE_SOUNDS_NEMESIS,
  668. AMBIENCE_SOUNDS_SURVIVOR,
  669. AMBIENCE_SOUNDS_SWARM,
  670. AMBIENCE_SOUNDS_PLAGUE,
  671. MAX_AMBIENCE_SOUNDS
  672. }
  673.  
  674. // Admin menu actions
  675. enum
  676. {
  677. ACTION_ZOMBIEFY_HUMANIZE = 0,
  678. ACTION_MAKE_NEMESIS,
  679. ACTION_MAKE_SURVIVOR,
  680. ACTION_RESPAWN_PLAYER,
  681. ACTION_MODE_SWARM,
  682. ACTION_MODE_MULTI,
  683. ACTION_MODE_PLAGUE
  684. }
  685.  
  686. // Custom forward return values
  687. const ZP_PLUGIN_HANDLED = 97
  688.  
  689. /*================================================================================
  690. [Global Variables]
  691. =================================================================================*/
  692.  
  693. // Player vars
  694. new g_zombie[33] // is zombie
  695. new g_nemesis[33] // is nemesis
  696. new g_survivor[33] // is survivor
  697. new g_firstzombie[33] // is first zombie
  698. new g_lastzombie[33] // is last zombie
  699. new g_lasthuman[33] // is last human
  700. new g_frozen[33] // is frozen (can't move)
  701. new g_nodamage[33] // has spawn protection/zombie madness
  702. new g_respawn_as_zombie[33] // should respawn as zombie
  703. new g_nvision[33] // has night vision
  704. new g_nvisionenabled[33] // has night vision turned on
  705. new g_zombieclass[33] // zombie class
  706. new g_zombieclassnext[33] // zombie class for next infection
  707. new g_flashlight[33] // has custom flashlight turned on
  708. new g_flashbattery[33] = { 100, ... } // custom flashlight battery
  709. new g_canbuy[33] // is allowed to buy a new weapon through the menu
  710. new g_ammopacks[33] // ammo pack count
  711. new g_damagedealt[33] // damage dealt to zombies (used to calculate ammo packs reward)
  712. new Float:g_lastleaptime[33] // time leap was last used
  713. new Float:g_lastflashtime[33] // time flashlight was last toggled
  714. new g_playermodel[33][32] // current model's short name [player][model]
  715. new g_menu_data[33][5] // data for some menu handlers
  716. new g_ent_playermodel[33] // player model entity
  717. new g_ent_weaponmodel[33] // weapon model entity
  718. new g_burning_duration[33] // burning task duration
  719.  
  720. // Game vars
  721. new g_pluginenabled // ZP enabled
  722. new g_newround // new round starting
  723. new g_endround // round ended
  724. new g_nemround // nemesis round
  725. new g_survround // survivor round
  726. new g_swarmround // swarm round
  727. new g_plagueround // plague round
  728. new g_modestarted // mode fully started
  729. new g_lastmode // last played mode
  730. new g_scorezombies, g_scorehumans // team scores
  731. new g_spawnCount, g_spawnCount2 // available spawn points counter
  732. new Float:g_spawns[MAX_CSDM_SPAWNS][3], Float:g_spawns2[MAX_CSDM_SPAWNS][3] // spawn points data
  733. new g_lights_i // lightning current lights counter
  734. new g_lights_cycle[32] // current lightning cycle
  735. new g_lights_cycle_len // lightning cycle length
  736. new Float:g_models_targettime // for adding delays between Model Change messages
  737. new Float:g_teams_targettime // for adding delays between Team Change messages
  738. new g_MsgSync, g_MsgSync2 // message sync objects
  739. new g_trailSpr, g_exploSpr, g_flameSpr, g_smokeSpr, g_glassSpr // grenade sprites
  740. new g_modname[32] // for formatting the mod name
  741. new g_freezetime // whether CS's freeze time is on
  742. new g_maxplayers // max players counter
  743. new g_czero // whether we are running on a CZ server
  744. new g_hamczbots // whether ham forwards are registered for CZ bots
  745. new g_fwSpawn, g_fwPrecacheSound // spawn and precache sound forward handles
  746. new g_infbombcounter, g_antidotecounter, g_madnesscounter // to limit buying some items
  747. new g_arrays_created // to prevent stuff from being registered before initializing arrays
  748. new g_lastplayerleaving // flag for whenever a player leaves and another takes his place
  749. new g_switchingteam // flag for whenever a player's team change emessage is sent
  750.  
  751. // Message IDs vars
  752. new g_msgScoreInfo, g_msgNVGToggle, g_msgScoreAttrib, g_msgAmmoPickup, g_msgScreenFade,
  753. g_msgDeathMsg, g_msgSetFOV, g_msgFlashlight, g_msgFlashBat, g_msgTeamInfo, g_msgDamage,
  754. g_msgHideWeapon, g_msgCrosshair, g_msgSayText, g_msgScreenShake, g_msgCurWeapon
  755.  
  756. // Some forward handlers
  757. new g_fwRoundStart, g_fwRoundEnd, g_fwUserInfected_pre, g_fwUserInfected_post,
  758. g_fwUserHumanized_pre, g_fwUserHumanized_post, g_fwUserInfect_attempt,
  759. g_fwUserHumanize_attempt, g_fwExtraItemSelected, g_fwUserUnfrozen,
  760. g_fwUserLastZombie, g_fwUserLastHuman, g_fwDummyResult
  761.  
  762. // Temporary Database vars (used to restore players stats in case they get disconnected)
  763. new db_name[MAX_STATS_SAVED][32] // player name
  764. new db_ammopacks[MAX_STATS_SAVED] // ammo pack count
  765. new db_zombieclass[MAX_STATS_SAVED] // zombie class
  766. new db_slot_i // additional saved slots counter (should start on maxplayers+1)
  767.  
  768. // Extra Items vars
  769. new Array:g_extraitem_name // caption
  770. new Array:g_extraitem_cost // cost
  771. new Array:g_extraitem_team // team
  772. new g_extraitem_i // loaded extra items counter
  773.  
  774. // For extra items file parsing
  775. new Array:g_extraitem2_realname, Array:g_extraitem2_name, Array:g_extraitem2_cost,
  776. Array:g_extraitem2_team, Array:g_extraitem_new
  777.  
  778. // Zombie Classes vars
  779. new Array:g_zclass_name // caption
  780. new Array:g_zclass_info // description
  781. new Array:g_zclass_modelsstart // start position in models array
  782. new Array:g_zclass_modelsend // end position in models array
  783. new Array:g_zclass_playermodel // player models array
  784. new Array:g_zclass_modelindex // model indices array
  785. new Array:g_zclass_clawmodel // claw model
  786. new Array:g_zclass_hp // health
  787. new Array:g_zclass_spd // speed
  788. new Array:g_zclass_grav // gravity
  789. new Array:g_zclass_kb // knockback
  790. new g_zclass_i // loaded zombie classes counter
  791.  
  792. // For zombie classes file parsing
  793. new Array:g_zclass2_realname, Array:g_zclass2_name, Array:g_zclass2_info,
  794. Array:g_zclass2_modelsstart, Array:g_zclass2_modelsend, Array:g_zclass2_playermodel,
  795. Array:g_zclass2_modelindex, Array:g_zclass2_clawmodel, Array:g_zclass2_hp,
  796. Array:g_zclass2_spd, Array:g_zclass2_grav, Array:g_zclass2_kb, Array:g_zclass_new
  797.  
  798. // Customization vars
  799. new g_access_flag[MAX_ACCESS_FLAGS], Array:model_nemesis, Array:model_survivor, Array:model_human,
  800. Array:model_admin_zombie, Array:model_admin_human, Array:g_modelindex_human,
  801. Array:g_modelindex_nemesis, Array:g_modelindex_survivor, g_same_models_for_all,
  802. Array:g_modelindex_admin_zombie, Array:g_modelindex_admin_human, model_vknife_human[64],
  803. model_vknife_nemesis[64], model_vm249_survivor[64], model_grenade_infect[64],
  804. model_grenade_fire[64], model_grenade_frost[64], model_grenade_flare[64],
  805. model_vknife_admin_human[64], model_vknife_admin_zombie[64],
  806. sprite_grenade_trail[64], sprite_grenade_ring[64], sprite_grenade_fire[64],
  807. sprite_grenade_smoke[64], sprite_grenade_glass[64], Array:sound_win_zombies,
  808. Array:sound_win_humans, Array:sound_win_no_one, Array:zombie_infect, Array:zombie_idle,
  809. Array:zombie_pain, Array:nemesis_pain, Array:zombie_die, Array:zombie_fall,
  810. Array:zombie_miss_wall, Array:zombie_hit_normal, Array:zombie_hit_stab, g_ambience_rain,
  811. Array:zombie_idle_last, Array:zombie_madness, Array:sound_nemesis, Array:sound_survivor,
  812. Array:sound_swarm, Array:sound_multi, Array:sound_plague, Array:grenade_infect,
  813. Array:grenade_infect_player, Array:grenade_fire, Array:grenade_fire_player,
  814. Array:grenade_frost, Array:grenade_frost_player, Array:grenade_frost_break,
  815. Array:grenade_flare, Array:sound_antidote, Array:sound_thunder, g_ambience_sounds[MAX_AMBIENCE_SOUNDS],
  816. Array:sound_ambience1, Array:sound_ambience2, Array:sound_ambience3, Array:sound_ambience4,
  817. Array:sound_ambience5, Array:sound_ambience1_duration, Array:sound_ambience2_duration,
  818. Array:sound_ambience3_duration, Array:sound_ambience4_duration,
  819. Array:sound_ambience5_duration, Array:sound_ambience1_ismp3, Array:sound_ambience2_ismp3,
  820. Array:sound_ambience3_ismp3, Array:sound_ambience4_ismp3, Array:sound_ambience5_ismp3,
  821. Array:g_primary_items, Array:g_secondary_items, Array:g_additional_items,
  822. Array:g_primary_weaponids, Array:g_secondary_weaponids, Array:g_extraweapon_names,
  823. Array:g_extraweapon_items, Array:g_extraweapon_costs, g_extra_costs2[EXTRA_WEAPONS_STARTID],
  824. g_ambience_snow, g_ambience_fog, g_fog_density[10], g_fog_color[12], g_sky_enable,
  825. Array:g_sky_names, Array:lights_thunder, Array:zombie_decals, Array:g_objective_ents,
  826. Float:g_modelchange_delay, g_set_modelindex_offset, g_handle_models_on_separate_ent,
  827. Float:kb_weapon_power[31] = { -1.0, ... }, Array:zombie_miss_slash, g_force_consistency
  828.  
  829. // CVAR pointers
  830. new cvar_lighting, cvar_zombiefov, cvar_plague, cvar_plaguechance, cvar_zombiefirsthp,
  831. cvar_removemoney, cvar_thunder, cvar_zombiebonushp, cvar_nemhp, cvar_nem, cvar_surv,
  832. cvar_nemchance, cvar_deathmatch, cvar_nemglow, cvar_customnvg, cvar_hitzones, cvar_humanhp,
  833. cvar_nemgravity, cvar_flashsize, cvar_ammodamage, cvar_zombiearmor, cvar_survpainfree,
  834. cvar_nempainfree, cvar_nemspd, cvar_survchance, cvar_survhp, cvar_survspd, cvar_humanspd,
  835. cvar_swarmchance, cvar_flashdrain, cvar_zombiebleeding, cvar_removedoors, cvar_customflash,
  836. cvar_randspawn, cvar_multi, cvar_multichance, cvar_infammo, cvar_swarm, cvar_ammoinfect,
  837. cvar_toggle, cvar_knockbackpower, cvar_freezeduration, cvar_triggered, cvar_flashcharge,
  838. cvar_firegrenades, cvar_frostgrenades, cvar_survgravity, cvar_logcommands, cvar_survglow,
  839. cvar_humangravity, cvar_spawnprotection, cvar_nvgsize, cvar_flareduration, cvar_zclasses,
  840. cvar_extraitems, cvar_showactivity, cvar_humanlasthp, cvar_nemignorefrags, cvar_warmup,
  841. cvar_flashdist, cvar_flarecolor, cvar_survignorefrags, cvar_fireduration, cvar_firedamage,
  842. cvar_flaregrenades, cvar_knockbackducking, cvar_knockbackdamage, cvar_knockbackzvel,
  843. cvar_multiratio, cvar_flaresize, cvar_spawndelay, cvar_extraantidote, cvar_extramadness,
  844. cvar_extraweapons, cvar_extranvision, cvar_nvggive, cvar_preventconsecutive, cvar_botquota,
  845. cvar_buycustom, cvar_zombiepainfree, cvar_fireslowdown, cvar_survbasehp, cvar_survaura,
  846. cvar_nemignoreammo, cvar_survignoreammo, cvar_nemaura, cvar_extrainfbomb, cvar_knockback,
  847. cvar_fragsinfect, cvar_fragskill, cvar_humanarmor, cvar_zombiesilent, cvar_removedropped,
  848. cvar_plagueratio, cvar_blocksuicide, cvar_knockbackdist, cvar_nemdamage, cvar_leapzombies,
  849. cvar_leapzombiesforce, cvar_leapzombiesheight, cvar_leapzombiescooldown, cvar_leapnemesis,
  850. cvar_leapnemesisforce, cvar_leapnemesisheight, cvar_leapnemesiscooldown, cvar_leapsurvivor,
  851. cvar_leapsurvivorforce, cvar_leapsurvivorheight, cvar_nemminplayers, cvar_survminplayers,
  852. cvar_respawnonsuicide, cvar_respawnafterlast, cvar_leapsurvivorcooldown, cvar_statssave,
  853. cvar_swarmminplayers, cvar_multiminplayers, cvar_plagueminplayers, cvar_adminmodelshuman,
  854. cvar_adminmodelszombie, cvar_nembasehp, cvar_blockpushables, cvar_respawnworldspawnkill,
  855. cvar_madnessduration, cvar_plaguenemnum, cvar_plaguenemhpmulti, cvar_plaguesurvhpmulti,
  856. cvar_survweapon, cvar_plaguesurvnum, cvar_infectionscreenfade, cvar_infectionscreenshake,
  857. cvar_infectionsparkle, cvar_infectiontracers, cvar_infectionparticles, cvar_infbomblimit,
  858. cvar_allowrespawnsurv, cvar_flashshowall, cvar_allowrespawninfection, cvar_allowrespawnnem,
  859. cvar_allowrespawnswarm, cvar_allowrespawnplague, cvar_survinfammo, cvar_nemknockback,
  860. cvar_nvgcolor[3], cvar_nemnvgcolor[3], cvar_humnvgcolor[3], cvar_flashcolor[3],
  861. cvar_hudicons, cvar_respawnzomb, cvar_respawnhum, cvar_respawnnem, cvar_respawnsurv,
  862. cvar_startammopacks, cvar_randweapons, cvar_antidotelimit, cvar_madnesslimit,
  863. cvar_adminknifemodelshuman, cvar_adminknifemodelszombie, cvar_keephealthondisconnect
  864.  
  865. // Cached stuff for players
  866. new g_isconnected[33] // whether player is connected
  867. new g_isalive[33] // whether player is alive
  868. new g_isbot[33] // whether player is a bot
  869. new g_currentweapon[33] // player's current weapon id
  870. new g_playername[33][32] // player's name
  871. new Float:g_zombie_spd[33] // zombie class speed
  872. new Float:g_zombie_knockback[33] // zombie class knockback
  873. new g_zombie_classname[33][32] // zombie class name
  874. #define is_user_valid_connected(%1) (1 <= %1 <= g_maxplayers && g_isconnected[%1])
  875. #define is_user_valid_alive(%1) (1 <= %1 <= g_maxplayers && g_isalive[%1])
  876.  
  877. // Cached CVARs
  878. new g_cached_customflash, g_cached_zombiesilent, Float:g_cached_humanspd, Float:g_cached_nemspd,
  879. Float:g_cached_survspd, g_cached_leapzombies, Float:g_cached_leapzombiescooldown, g_cached_leapnemesis,
  880. Float:g_cached_leapnemesiscooldown, g_cached_leapsurvivor, Float:g_cached_leapsurvivorcooldown
  881.  
  882. /*================================================================================
  883. [Natives, Precache and Init]
  884. =================================================================================*/
  885.  
  886. public plugin_natives()
  887. {
  888. // Player specific natives
  889. register_native("zp_get_user_zombie", "native_get_user_zombie", 1)
  890. register_native("zp_get_user_nemesis", "native_get_user_nemesis", 1)
  891. register_native("zp_get_user_survivor", "native_get_user_survivor", 1)
  892. register_native("zp_get_user_first_zombie", "native_get_user_first_zombie", 1)
  893. register_native("zp_get_user_last_zombie", "native_get_user_last_zombie", 1)
  894. register_native("zp_get_user_last_human", "native_get_user_last_human", 1)
  895. register_native("zp_get_user_zombie_class", "native_get_user_zombie_class", 1)
  896. register_native("zp_get_user_next_class", "native_get_user_next_class", 1)
  897. register_native("zp_set_user_zombie_class", "native_set_user_zombie_class", 1)
  898. register_native("zp_get_user_ammo_packs", "native_get_user_ammo_packs", 1)
  899. register_native("zp_set_user_ammo_packs", "native_set_user_ammo_packs", 1)
  900. register_native("zp_get_zombie_maxhealth", "native_get_zombie_maxhealth", 1)
  901. register_native("zp_get_user_batteries", "native_get_user_batteries", 1)
  902. register_native("zp_set_user_batteries", "native_set_user_batteries", 1)
  903. register_native("zp_get_user_nightvision", "native_get_user_nightvision", 1)
  904. register_native("zp_set_user_nightvision", "native_set_user_nightvision", 1)
  905. register_native("zp_infect_user", "native_infect_user", 1)
  906. register_native("zp_disinfect_user", "native_disinfect_user", 1)
  907. register_native("zp_make_user_nemesis", "native_make_user_nemesis", 1)
  908. register_native("zp_make_user_survivor", "native_make_user_survivor", 1)
  909. register_native("zp_respawn_user", "native_respawn_user", 1)
  910. register_native("zp_force_buy_extra_item", "native_force_buy_extra_item", 1)
  911.  
  912. // Round natives
  913. register_native("zp_has_round_started", "native_has_round_started", 1)
  914. register_native("zp_is_nemesis_round", "native_is_nemesis_round", 1)
  915. register_native("zp_is_survivor_round", "native_is_survivor_round", 1)
  916. register_native("zp_is_swarm_round", "native_is_swarm_round", 1)
  917. register_native("zp_is_plague_round", "native_is_plague_round", 1)
  918. register_native("zp_get_zombie_count", "native_get_zombie_count", 1)
  919. register_native("zp_get_human_count", "native_get_human_count", 1)
  920. register_native("zp_get_nemesis_count", "native_get_nemesis_count", 1)
  921. register_native("zp_get_survivor_count", "native_get_survivor_count", 1)
  922.  
  923. // External additions natives
  924. register_native("zp_register_extra_item", "native_register_extra_item", 1)
  925. register_native("zp_register_zombie_class", "native_register_zombie_class", 1)
  926. register_native("zp_get_extra_item_id", "native_get_extra_item_id", 1)
  927. register_native("zp_get_zombie_class_id", "native_get_zombie_class_id", 1)
  928. }
  929.  
  930. public plugin_precache()
  931. {
  932. // Register earlier to show up in plugins list properly after plugin disable/error at loading
  933. register_plugin("Zombie Plague", PLUGIN_VERSION, "MeRcyLeZZ")
  934.  
  935. // To switch plugin on/off
  936. register_concmd("zp_toggle", "cmd_toggle", _, "<1/0> - Enable/Disable Zombie Plague (will restart the current map)", 0)
  937. cvar_toggle = register_cvar("zp_on", "1")
  938.  
  939. // Plugin disabled?
  940. if (!get_pcvar_num(cvar_toggle)) return;
  941. g_pluginenabled = true
  942.  
  943. // Initialize a few dynamically sized arrays (alright, maybe more than just a few...)
  944. model_human = ArrayCreate(32, 1)
  945. model_nemesis = ArrayCreate(32, 1)
  946. model_survivor = ArrayCreate(32, 1)
  947. model_admin_human = ArrayCreate(32, 1)
  948. model_admin_zombie = ArrayCreate(32, 1)
  949. g_modelindex_human = ArrayCreate(1, 1)
  950. g_modelindex_nemesis = ArrayCreate(1, 1)
  951. g_modelindex_survivor = ArrayCreate(1, 1)
  952. g_modelindex_admin_human = ArrayCreate(1, 1)
  953. g_modelindex_admin_zombie = ArrayCreate(1, 1)
  954. sound_win_zombies = ArrayCreate(64, 1)
  955. sound_win_humans = ArrayCreate(64, 1)
  956. sound_win_no_one = ArrayCreate(64, 1)
  957. zombie_infect = ArrayCreate(64, 1)
  958. zombie_pain = ArrayCreate(64, 1)
  959. nemesis_pain = ArrayCreate(64, 1)
  960. zombie_die = ArrayCreate(64, 1)
  961. zombie_fall = ArrayCreate(64, 1)
  962. zombie_miss_slash = ArrayCreate(64, 1)
  963. zombie_miss_wall = ArrayCreate(64, 1)
  964. zombie_hit_normal = ArrayCreate(64, 1)
  965. zombie_hit_stab = ArrayCreate(64, 1)
  966. zombie_idle = ArrayCreate(64, 1)
  967. zombie_idle_last = ArrayCreate(64, 1)
  968. zombie_madness = ArrayCreate(64, 1)
  969. sound_nemesis = ArrayCreate(64, 1)
  970. sound_survivor = ArrayCreate(64, 1)
  971. sound_swarm = ArrayCreate(64, 1)
  972. sound_multi = ArrayCreate(64, 1)
  973. sound_plague = ArrayCreate(64, 1)
  974. grenade_infect = ArrayCreate(64, 1)
  975. grenade_infect_player = ArrayCreate(64, 1)
  976. grenade_fire = ArrayCreate(64, 1)
  977. grenade_fire_player = ArrayCreate(64, 1)
  978. grenade_frost = ArrayCreate(64, 1)
  979. grenade_frost_player = ArrayCreate(64, 1)
  980. grenade_frost_break = ArrayCreate(64, 1)
  981. grenade_flare = ArrayCreate(64, 1)
  982. sound_antidote = ArrayCreate(64, 1)
  983. sound_thunder = ArrayCreate(64, 1)
  984. sound_ambience1 = ArrayCreate(64, 1)
  985. sound_ambience2 = ArrayCreate(64, 1)
  986. sound_ambience3 = ArrayCreate(64, 1)
  987. sound_ambience4 = ArrayCreate(64, 1)
  988. sound_ambience5 = ArrayCreate(64, 1)
  989. sound_ambience1_duration = ArrayCreate(1, 1)
  990. sound_ambience2_duration = ArrayCreate(1, 1)
  991. sound_ambience3_duration = ArrayCreate(1, 1)
  992. sound_ambience4_duration = ArrayCreate(1, 1)
  993. sound_ambience5_duration = ArrayCreate(1, 1)
  994. sound_ambience1_ismp3 = ArrayCreate(1, 1)
  995. sound_ambience2_ismp3 = ArrayCreate(1, 1)
  996. sound_ambience3_ismp3 = ArrayCreate(1, 1)
  997. sound_ambience4_ismp3 = ArrayCreate(1, 1)
  998. sound_ambience5_ismp3 = ArrayCreate(1, 1)
  999. g_primary_items = ArrayCreate(32, 1)
  1000. g_secondary_items = ArrayCreate(32, 1)
  1001. g_additional_items = ArrayCreate(32, 1)
  1002. g_primary_weaponids = ArrayCreate(1, 1)
  1003. g_secondary_weaponids = ArrayCreate(1, 1)
  1004. g_extraweapon_names = ArrayCreate(32, 1)
  1005. g_extraweapon_items = ArrayCreate(32, 1)
  1006. g_extraweapon_costs = ArrayCreate(1, 1)
  1007. g_sky_names = ArrayCreate(32, 1)
  1008. lights_thunder = ArrayCreate(32, 1)
  1009. zombie_decals = ArrayCreate(1, 1)
  1010. g_objective_ents = ArrayCreate(32, 1)
  1011. g_extraitem_name = ArrayCreate(32, 1)
  1012. g_extraitem_cost = ArrayCreate(1, 1)
  1013. g_extraitem_team = ArrayCreate(1, 1)
  1014. g_extraitem2_realname = ArrayCreate(32, 1)
  1015. g_extraitem2_name = ArrayCreate(32, 1)
  1016. g_extraitem2_cost = ArrayCreate(1, 1)
  1017. g_extraitem2_team = ArrayCreate(1, 1)
  1018. g_extraitem_new = ArrayCreate(1, 1)
  1019. g_zclass_name = ArrayCreate(32, 1)
  1020. g_zclass_info = ArrayCreate(32, 1)
  1021. g_zclass_modelsstart = ArrayCreate(1, 1)
  1022. g_zclass_modelsend = ArrayCreate(1, 1)
  1023. g_zclass_playermodel = ArrayCreate(32, 1)
  1024. g_zclass_modelindex = ArrayCreate(1, 1)
  1025. g_zclass_clawmodel = ArrayCreate(32, 1)
  1026. g_zclass_hp = ArrayCreate(1, 1)
  1027. g_zclass_spd = ArrayCreate(1, 1)
  1028. g_zclass_grav = ArrayCreate(1, 1)
  1029. g_zclass_kb = ArrayCreate(1, 1)
  1030. g_zclass2_realname = ArrayCreate(32, 1)
  1031. g_zclass2_name = ArrayCreate(32, 1)
  1032. g_zclass2_info = ArrayCreate(32, 1)
  1033. g_zclass2_modelsstart = ArrayCreate(1, 1)
  1034. g_zclass2_modelsend = ArrayCreate(1, 1)
  1035. g_zclass2_playermodel = ArrayCreate(32, 1)
  1036. g_zclass2_modelindex = ArrayCreate(1, 1)
  1037. g_zclass2_clawmodel = ArrayCreate(32, 1)
  1038. g_zclass2_hp = ArrayCreate(1, 1)
  1039. g_zclass2_spd = ArrayCreate(1, 1)
  1040. g_zclass2_grav = ArrayCreate(1, 1)
  1041. g_zclass2_kb = ArrayCreate(1, 1)
  1042. g_zclass_new = ArrayCreate(1, 1)
  1043.  
  1044. // Allow registering stuff now
  1045. g_arrays_created = true
  1046.  
  1047. // Load customization data
  1048. load_customization_from_files()
  1049.  
  1050. new i, buffer[100]
  1051.  
  1052. // Load up the hard coded extra items
  1053. native_register_extra_item2("NightVision", g_extra_costs2[EXTRA_NVISION], ZP_TEAM_HUMAN)
  1054. native_register_extra_item2("T-Virus Antidote", g_extra_costs2[EXTRA_ANTIDOTE], ZP_TEAM_ZOMBIE)
  1055. native_register_extra_item2("Zombie Madness", g_extra_costs2[EXTRA_MADNESS], ZP_TEAM_ZOMBIE)
  1056. native_register_extra_item2("Infection Bomb", g_extra_costs2[EXTRA_INFBOMB], ZP_TEAM_ZOMBIE)
  1057.  
  1058. // Extra weapons
  1059. for (i = 0; i < ArraySize(g_extraweapon_names); i++)
  1060. {
  1061. ArrayGetString(g_extraweapon_names, i, buffer, charsmax(buffer))
  1062. native_register_extra_item2(buffer, ArrayGetCell(g_extraweapon_costs, i), ZP_TEAM_HUMAN)
  1063. }
  1064.  
  1065. // Custom player models
  1066. for (i = 0; i < ArraySize(model_human); i++)
  1067. {
  1068. ArrayGetString(model_human, i, buffer, charsmax(buffer))
  1069. format(buffer, charsmax(buffer), "models/player/%s/%s.mdl", buffer, buffer)
  1070. ArrayPushCell(g_modelindex_human, engfunc(EngFunc_PrecacheModel, buffer))
  1071. if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, buffer)
  1072. if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, buffer)
  1073. }
  1074. for (i = 0; i < ArraySize(model_nemesis); i++)
  1075. {
  1076. ArrayGetString(model_nemesis, i, buffer, charsmax(buffer))
  1077. format(buffer, charsmax(buffer), "models/player/%s/%s.mdl", buffer, buffer)
  1078. ArrayPushCell(g_modelindex_nemesis, engfunc(EngFunc_PrecacheModel, buffer))
  1079. if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, buffer)
  1080. if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, buffer)
  1081. }
  1082. for (i = 0; i < ArraySize(model_survivor); i++)
  1083. {
  1084. ArrayGetString(model_survivor, i, buffer, charsmax(buffer))
  1085. format(buffer, charsmax(buffer), "models/player/%s/%s.mdl", buffer, buffer)
  1086. ArrayPushCell(g_modelindex_survivor, engfunc(EngFunc_PrecacheModel, buffer))
  1087. if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, buffer)
  1088. if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, buffer)
  1089. }
  1090. for (i = 0; i < ArraySize(model_admin_zombie); i++)
  1091. {
  1092. ArrayGetString(model_admin_zombie, i, buffer, charsmax(buffer))
  1093. format(buffer, charsmax(buffer), "models/player/%s/%s.mdl", buffer, buffer)
  1094. ArrayPushCell(g_modelindex_admin_zombie, engfunc(EngFunc_PrecacheModel, buffer))
  1095. if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, buffer)
  1096. if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, buffer)
  1097. }
  1098. for (i = 0; i < ArraySize(model_admin_human); i++)
  1099. {
  1100. ArrayGetString(model_admin_human, i, buffer, charsmax(buffer))
  1101. format(buffer, charsmax(buffer), "models/player/%s/%s.mdl", buffer, buffer)
  1102. ArrayPushCell(g_modelindex_admin_human, engfunc(EngFunc_PrecacheModel, buffer))
  1103. if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, buffer)
  1104. if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, buffer)
  1105. }
  1106.  
  1107. // Custom weapon models
  1108. engfunc(EngFunc_PrecacheModel, model_vknife_human)
  1109. engfunc(EngFunc_PrecacheModel, model_vknife_nemesis)
  1110. engfunc(EngFunc_PrecacheModel, model_vm249_survivor)
  1111. engfunc(EngFunc_PrecacheModel, model_grenade_infect)
  1112. engfunc(EngFunc_PrecacheModel, model_grenade_fire)
  1113. engfunc(EngFunc_PrecacheModel, model_grenade_frost)
  1114. engfunc(EngFunc_PrecacheModel, model_grenade_flare)
  1115. engfunc(EngFunc_PrecacheModel, model_vknife_admin_human)
  1116. engfunc(EngFunc_PrecacheModel, model_vknife_admin_zombie)
  1117.  
  1118. // Custom sprites for grenades
  1119. g_trailSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_trail)
  1120. g_exploSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_ring)
  1121. g_flameSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_fire)
  1122. g_smokeSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_smoke)
  1123. g_glassSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_glass)
  1124.  
  1125. // Custom sounds
  1126. for (i = 0; i < ArraySize(sound_win_zombies); i++)
  1127. {
  1128. ArrayGetString(sound_win_zombies, i, buffer, charsmax(buffer))
  1129. engfunc(EngFunc_PrecacheSound, buffer)
  1130. }
  1131. for (i = 0; i < ArraySize(sound_win_humans); i++)
  1132. {
  1133. ArrayGetString(sound_win_humans, i, buffer, charsmax(buffer))
  1134. engfunc(EngFunc_PrecacheSound, buffer)
  1135. }
  1136. for (i = 0; i < ArraySize(sound_win_no_one); i++)
  1137. {
  1138. ArrayGetString(sound_win_no_one, i, buffer, charsmax(buffer))
  1139. engfunc(EngFunc_PrecacheSound, buffer)
  1140. }
  1141. for (i = 0; i < ArraySize(zombie_infect); i++)
  1142. {
  1143. ArrayGetString(zombie_infect, i, buffer, charsmax(buffer))
  1144. engfunc(EngFunc_PrecacheSound, buffer)
  1145. }
  1146. for (i = 0; i < ArraySize(zombie_pain); i++)
  1147. {
  1148. ArrayGetString(zombie_pain, i, buffer, charsmax(buffer))
  1149. engfunc(EngFunc_PrecacheSound, buffer)
  1150. }
  1151. for (i = 0; i < ArraySize(nemesis_pain); i++)
  1152. {
  1153. ArrayGetString(nemesis_pain, i, buffer, charsmax(buffer))
  1154. engfunc(EngFunc_PrecacheSound, buffer)
  1155. }
  1156. for (i = 0; i < ArraySize(zombie_die); i++)
  1157. {
  1158. ArrayGetString(zombie_die, i, buffer, charsmax(buffer))
  1159. engfunc(EngFunc_PrecacheSound, buffer)
  1160. }
  1161. for (i = 0; i < ArraySize(zombie_fall); i++)
  1162. {
  1163. ArrayGetString(zombie_fall, i, buffer, charsmax(buffer))
  1164. engfunc(EngFunc_PrecacheSound, buffer)
  1165. }
  1166. for (i = 0; i < ArraySize(zombie_miss_slash); i++)
  1167. {
  1168. ArrayGetString(zombie_miss_slash, i, buffer, charsmax(buffer))
  1169. engfunc(EngFunc_PrecacheSound, buffer)
  1170. }
  1171. for (i = 0; i < ArraySize(zombie_miss_wall); i++)
  1172. {
  1173. ArrayGetString(zombie_miss_wall, i, buffer, charsmax(buffer))
  1174. engfunc(EngFunc_PrecacheSound, buffer)
  1175. }
  1176. for (i = 0; i < ArraySize(zombie_hit_normal); i++)
  1177. {
  1178. ArrayGetString(zombie_hit_normal, i, buffer, charsmax(buffer))
  1179. engfunc(EngFunc_PrecacheSound, buffer)
  1180. }
  1181. for (i = 0; i < ArraySize(zombie_hit_stab); i++)
  1182. {
  1183. ArrayGetString(zombie_hit_stab, i, buffer, charsmax(buffer))
  1184. engfunc(EngFunc_PrecacheSound, buffer)
  1185. }
  1186. for (i = 0; i < ArraySize(zombie_idle); i++)
  1187. {
  1188. ArrayGetString(zombie_idle, i, buffer, charsmax(buffer))
  1189. engfunc(EngFunc_PrecacheSound, buffer)
  1190. }
  1191. for (i = 0; i < ArraySize(zombie_idle_last); i++)
  1192. {
  1193. ArrayGetString(zombie_idle_last, i, buffer, charsmax(buffer))
  1194. engfunc(EngFunc_PrecacheSound, buffer)
  1195. }
  1196. for (i = 0; i < ArraySize(zombie_madness); i++)
  1197. {
  1198. ArrayGetString(zombie_madness, i, buffer, charsmax(buffer))
  1199. engfunc(EngFunc_PrecacheSound, buffer)
  1200. }
  1201. for (i = 0; i < ArraySize(sound_nemesis); i++)
  1202. {
  1203. ArrayGetString(sound_nemesis, i, buffer, charsmax(buffer))
  1204. engfunc(EngFunc_PrecacheSound, buffer)
  1205. }
  1206. for (i = 0; i < ArraySize(sound_survivor); i++)
  1207. {
  1208. ArrayGetString(sound_survivor, i, buffer, charsmax(buffer))
  1209. engfunc(EngFunc_PrecacheSound, buffer)
  1210. }
  1211. for (i = 0; i < ArraySize(sound_swarm); i++)
  1212. {
  1213. ArrayGetString(sound_swarm, i, buffer, charsmax(buffer))
  1214. engfunc(EngFunc_PrecacheSound, buffer)
  1215. }
  1216. for (i = 0; i < ArraySize(sound_multi); i++)
  1217. {
  1218. ArrayGetString(sound_multi, i, buffer, charsmax(buffer))
  1219. engfunc(EngFunc_PrecacheSound, buffer)
  1220. }
  1221. for (i = 0; i < ArraySize(sound_plague); i++)
  1222. {
  1223. ArrayGetString(sound_plague, i, buffer, charsmax(buffer))
  1224. engfunc(EngFunc_PrecacheSound, buffer)
  1225. }
  1226. for (i = 0; i < ArraySize(grenade_infect); i++)
  1227. {
  1228. ArrayGetString(grenade_infect, i, buffer, charsmax(buffer))
  1229. engfunc(EngFunc_PrecacheSound, buffer)
  1230. }
  1231. for (i = 0; i < ArraySize(grenade_infect_player); i++)
  1232. {
  1233. ArrayGetString(grenade_infect_player, i, buffer, charsmax(buffer))
  1234. engfunc(EngFunc_PrecacheSound, buffer)
  1235. }
  1236. for (i = 0; i < ArraySize(grenade_fire); i++)
  1237. {
  1238. ArrayGetString(grenade_fire, i, buffer, charsmax(buffer))
  1239. engfunc(EngFunc_PrecacheSound, buffer)
  1240. }
  1241. for (i = 0; i < ArraySize(grenade_fire_player); i++)
  1242. {
  1243. ArrayGetString(grenade_fire_player, i, buffer, charsmax(buffer))
  1244. engfunc(EngFunc_PrecacheSound, buffer)
  1245. }
  1246. for (i = 0; i < ArraySize(grenade_frost); i++)
  1247. {
  1248. ArrayGetString(grenade_frost, i, buffer, charsmax(buffer))
  1249. engfunc(EngFunc_PrecacheSound, buffer)
  1250. }
  1251. for (i = 0; i < ArraySize(grenade_frost_player); i++)
  1252. {
  1253. ArrayGetString(grenade_frost_player, i, buffer, charsmax(buffer))
  1254. engfunc(EngFunc_PrecacheSound, buffer)
  1255. }
  1256. for (i = 0; i < ArraySize(grenade_frost_break); i++)
  1257. {
  1258. ArrayGetString(grenade_frost_break, i, buffer, charsmax(buffer))
  1259. engfunc(EngFunc_PrecacheSound, buffer)
  1260. }
  1261. for (i = 0; i < ArraySize(grenade_flare); i++)
  1262. {
  1263. ArrayGetString(grenade_flare, i, buffer, charsmax(buffer))
  1264. engfunc(EngFunc_PrecacheSound, buffer)
  1265. }
  1266. for (i = 0; i < ArraySize(sound_antidote); i++)
  1267. {
  1268. ArrayGetString(sound_antidote, i, buffer, charsmax(buffer))
  1269. engfunc(EngFunc_PrecacheSound, buffer)
  1270. }
  1271. for (i = 0; i < ArraySize(sound_thunder); i++)
  1272. {
  1273. ArrayGetString(sound_thunder, i, buffer, charsmax(buffer))
  1274. engfunc(EngFunc_PrecacheSound, buffer)
  1275. }
  1276.  
  1277. // Ambience Sounds
  1278. if (g_ambience_sounds[AMBIENCE_SOUNDS_INFECTION])
  1279. {
  1280. for (i = 0; i < ArraySize(sound_ambience1); i++)
  1281. {
  1282. ArrayGetString(sound_ambience1, i, buffer, charsmax(buffer))
  1283.  
  1284. if (ArrayGetCell(sound_ambience1_ismp3, i))
  1285. {
  1286. format(buffer, charsmax(buffer), "sound/%s", buffer)
  1287. engfunc(EngFunc_PrecacheGeneric, buffer)
  1288. }
  1289. else
  1290. {
  1291. engfunc(EngFunc_PrecacheSound, buffer)
  1292. }
  1293. }
  1294. }
  1295. if (g_ambience_sounds[AMBIENCE_SOUNDS_NEMESIS])
  1296. {
  1297. for (i = 0; i < ArraySize(sound_ambience2); i++)
  1298. {
  1299. ArrayGetString(sound_ambience2, i, buffer, charsmax(buffer))
  1300.  
  1301. if (ArrayGetCell(sound_ambience2_ismp3, i))
  1302. {
  1303. format(buffer, charsmax(buffer), "sound/%s", buffer)
  1304. engfunc(EngFunc_PrecacheGeneric, buffer)
  1305. }
  1306. else
  1307. {
  1308. engfunc(EngFunc_PrecacheSound, buffer)
  1309. }
  1310. }
  1311. }
  1312. if (g_ambience_sounds[AMBIENCE_SOUNDS_SURVIVOR])
  1313. {
  1314. for (i = 0; i < ArraySize(sound_ambience3); i++)
  1315. {
  1316. ArrayGetString(sound_ambience3, i, buffer, charsmax(buffer))
  1317.  
  1318. if (ArrayGetCell(sound_ambience3_ismp3, i))
  1319. {
  1320. format(buffer, charsmax(buffer), "sound/%s", buffer)
  1321. engfunc(EngFunc_PrecacheGeneric, buffer)
  1322. }
  1323. else
  1324. {
  1325. engfunc(EngFunc_PrecacheSound, buffer)
  1326. }
  1327. }
  1328. }
  1329. if (g_ambience_sounds[AMBIENCE_SOUNDS_SWARM])
  1330. {
  1331. for (i = 0; i < ArraySize(sound_ambience4); i++)
  1332. {
  1333. ArrayGetString(sound_ambience4, i, buffer, charsmax(buffer))
  1334.  
  1335. if (ArrayGetCell(sound_ambience4_ismp3, i))
  1336. {
  1337. format(buffer, charsmax(buffer), "sound/%s", buffer)
  1338. engfunc(EngFunc_PrecacheGeneric, buffer)
  1339. }
  1340. else
  1341. {
  1342. engfunc(EngFunc_PrecacheSound, buffer)
  1343. }
  1344. }
  1345. }
  1346. if (g_ambience_sounds[AMBIENCE_SOUNDS_PLAGUE])
  1347. {
  1348. for (i = 0; i < ArraySize(sound_ambience5); i++)
  1349. {
  1350. ArrayGetString(sound_ambience5, i, buffer, charsmax(buffer))
  1351.  
  1352. if (ArrayGetCell(sound_ambience5_ismp3, i))
  1353. {
  1354. format(buffer, charsmax(buffer), "sound/%s", buffer)
  1355. engfunc(EngFunc_PrecacheGeneric, buffer)
  1356. }
  1357. else
  1358. {
  1359. engfunc(EngFunc_PrecacheSound, buffer)
  1360. }
  1361. }
  1362. }
  1363.  
  1364. // CS sounds (just in case)
  1365. engfunc(EngFunc_PrecacheSound, sound_flashlight)
  1366. engfunc(EngFunc_PrecacheSound, sound_buyammo)
  1367. engfunc(EngFunc_PrecacheSound, sound_armorhit)
  1368.  
  1369. new ent
  1370.  
  1371. // Fake Hostage (to force round ending)
  1372. ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "hostage_entity"))
  1373. if (pev_valid(ent))
  1374. {
  1375. engfunc(EngFunc_SetOrigin, ent, Float:{8192.0,8192.0,8192.0})
  1376. dllfunc(DLLFunc_Spawn, ent)
  1377. }
  1378.  
  1379. // Weather/ambience effects
  1380. if (g_ambience_fog)
  1381. {
  1382. ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "env_fog"))
  1383. if (pev_valid(ent))
  1384. {
  1385. fm_set_kvd(ent, "density", g_fog_density, "env_fog")
  1386. fm_set_kvd(ent, "rendercolor", g_fog_color, "env_fog")
  1387. }
  1388. }
  1389. if (g_ambience_rain) engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "env_rain"))
  1390. if (g_ambience_snow) engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "env_snow"))
  1391.  
  1392. // Prevent some entities from spawning
  1393. g_fwSpawn = register_forward(FM_Spawn, "fw_Spawn")
  1394.  
  1395. // Prevent hostage sounds from being precached
  1396. g_fwPrecacheSound = register_forward(FM_PrecacheSound, "fw_PrecacheSound")
  1397. }
  1398.  
  1399. public plugin_init()
  1400. {
  1401. // Plugin disabled?
  1402. if (!g_pluginenabled) return;
  1403.  
  1404. // No zombie classes?
  1405. if (!g_zclass_i) set_fail_state("No zombie classes loaded!")
  1406.  
  1407. // Language files
  1408. register_dictionary("zombie_plague.txt")
  1409.  
  1410. // Events
  1411. register_event("HLTV", "event_round_start", "a", "1=0", "2=0")
  1412. register_logevent("logevent_round_start",2, "1=Round_Start")
  1413. register_logevent("logevent_round_end", 2, "1=Round_End")
  1414. register_event("AmmoX", "event_ammo_x", "be")
  1415. if (g_ambience_sounds[AMBIENCE_SOUNDS_INFECTION] || g_ambience_sounds[AMBIENCE_SOUNDS_NEMESIS] || g_ambience_sounds[AMBIENCE_SOUNDS_SURVIVOR] || g_ambience_sounds[AMBIENCE_SOUNDS_SWARM] || g_ambience_sounds[AMBIENCE_SOUNDS_PLAGUE])
  1416. register_event("30", "event_intermission", "a")
  1417.  
  1418. // HAM Forwards
  1419. RegisterHam(Ham_Spawn, "player", "fw_PlayerSpawn_Post", 1)
  1420. RegisterHam(Ham_Killed, "player", "fw_PlayerKilled")
  1421. RegisterHam(Ham_Killed, "player", "fw_PlayerKilled_Post", 1)
  1422. RegisterHam(Ham_TakeDamage, "player", "fw_TakeDamage")
  1423. RegisterHam(Ham_TakeDamage, "player", "fw_TakeDamage_Post", 1)
  1424. RegisterHam(Ham_TraceAttack, "player", "fw_TraceAttack")
  1425. RegisterHam(Ham_Use, "func_tank", "fw_UseStationary")
  1426. RegisterHam(Ham_Use, "func_tankmortar", "fw_UseStationary")
  1427. RegisterHam(Ham_Use, "func_tankrocket", "fw_UseStationary")
  1428. RegisterHam(Ham_Use, "func_tanklaser", "fw_UseStationary")
  1429. RegisterHam(Ham_Use, "func_tank", "fw_UseStationary_Post", 1)
  1430. RegisterHam(Ham_Use, "func_tankmortar", "fw_UseStationary_Post", 1)
  1431. RegisterHam(Ham_Use, "func_tankrocket", "fw_UseStationary_Post", 1)
  1432. RegisterHam(Ham_Use, "func_tanklaser", "fw_UseStationary_Post", 1)
  1433. RegisterHam(Ham_Use, "func_pushable", "fw_UsePushable")
  1434. RegisterHam(Ham_Touch, "weaponbox", "fw_TouchWeapon")
  1435. RegisterHam(Ham_Touch, "armoury_entity", "fw_TouchWeapon")
  1436. RegisterHam(Ham_Touch, "weapon_shield", "fw_TouchWeapon")
  1437. RegisterHam(Ham_AddPlayerItem, "player", "fw_AddPlayerItem")
  1438. for (new i = 1; i < sizeof WEAPONENTNAMES; i++)
  1439. if (WEAPONENTNAMES[i][0]) RegisterHam(Ham_Item_Deploy, WEAPONENTNAMES[i], "fw_Item_Deploy_Post", 1)
  1440.  
  1441. // FM Forwards
  1442. register_forward(FM_ClientDisconnect, "fw_ClientDisconnect")
  1443. register_forward(FM_ClientDisconnect, "fw_ClientDisconnect_Post", 1)
  1444. register_forward(FM_ClientKill, "fw_ClientKill")
  1445. register_forward(FM_EmitSound, "fw_EmitSound")
  1446. if (!g_handle_models_on_separate_ent) register_forward(FM_SetClientKeyValue, "fw_SetClientKeyValue")
  1447. register_forward(FM_ClientUserInfoChanged, "fw_ClientUserInfoChanged")
  1448. register_forward(FM_GetGameDescription, "fw_GetGameDescription")
  1449. register_forward(FM_SetModel, "fw_SetModel")
  1450. RegisterHam(Ham_Think, "grenade", "fw_ThinkGrenade")
  1451. register_forward(FM_CmdStart, "fw_CmdStart")
  1452. register_forward(FM_PlayerPreThink, "fw_PlayerPreThink")
  1453. unregister_forward(FM_Spawn, g_fwSpawn)
  1454. unregister_forward(FM_PrecacheSound, g_fwPrecacheSound)
  1455.  
  1456. // Client commands
  1457. register_clcmd("say zpmenu", "clcmd_saymenu")
  1458. register_clcmd("say /zpmenu", "clcmd_saymenu")
  1459. register_clcmd("say unstuck", "clcmd_sayunstuck")
  1460. register_clcmd("say /unstuck", "clcmd_sayunstuck")
  1461. register_clcmd("nightvision", "clcmd_nightvision")
  1462. register_clcmd("drop", "clcmd_drop")
  1463. register_clcmd("buyammo1", "clcmd_buyammo")
  1464. register_clcmd("buyammo2", "clcmd_buyammo")
  1465. register_clcmd("chooseteam", "clcmd_changeteam")
  1466. register_clcmd("jointeam", "clcmd_changeteam")
  1467.  
  1468. // Menus
  1469. register_menu("Game Menu", KEYSMENU, "menu_game")
  1470. register_menu("Buy Menu 1", KEYSMENU, "menu_buy1")
  1471. register_menu("Buy Menu 2", KEYSMENU, "menu_buy2")
  1472. register_menu("Mod Info", KEYSMENU, "menu_info")
  1473. register_menu("Admin Menu", KEYSMENU, "menu_admin")
  1474.  
  1475. // Admin commands
  1476. register_concmd("zp_zombie", "cmd_zombie", _, "<target> - Turn someone into a Zombie", 0)
  1477. register_concmd("zp_human", "cmd_human", _, "<target> - Turn someone back to Human", 0)
  1478. register_concmd("zp_nemesis", "cmd_nemesis", _, "<target> - Turn someone into a Nemesis", 0)
  1479. register_concmd("zp_survivor", "cmd_survivor", _, "<target> - Turn someone into a Survivor", 0)
  1480. register_concmd("zp_respawn", "cmd_respawn", _, "<target> - Respawn someone", 0)
  1481. register_concmd("zp_swarm", "cmd_swarm", _, " - Start Swarm Mode", 0)
  1482. register_concmd("zp_multi", "cmd_multi", _, " - Start Multi Infection", 0)
  1483. register_concmd("zp_plague", "cmd_plague", _, " - Start Plague Mode", 0)
  1484.  
  1485. // Message IDs
  1486. g_msgScoreInfo = get_user_msgid("ScoreInfo")
  1487. g_msgTeamInfo = get_user_msgid("TeamInfo")
  1488. g_msgDeathMsg = get_user_msgid("DeathMsg")
  1489. g_msgScoreAttrib = get_user_msgid("ScoreAttrib")
  1490. g_msgSetFOV = get_user_msgid("SetFOV")
  1491. g_msgScreenFade = get_user_msgid("ScreenFade")
  1492. g_msgScreenShake = get_user_msgid("ScreenShake")
  1493. g_msgNVGToggle = get_user_msgid("NVGToggle")
  1494. g_msgFlashlight = get_user_msgid("Flashlight")
  1495. g_msgFlashBat = get_user_msgid("FlashBat")
  1496. g_msgAmmoPickup = get_user_msgid("AmmoPickup")
  1497. g_msgDamage = get_user_msgid("Damage")
  1498. g_msgHideWeapon = get_user_msgid("HideWeapon")
  1499. g_msgCrosshair = get_user_msgid("Crosshair")
  1500. g_msgSayText = get_user_msgid("SayText")
  1501. g_msgCurWeapon = get_user_msgid("CurWeapon")
  1502.  
  1503. // Message hooks
  1504. register_message(g_msgCurWeapon, "message_cur_weapon")
  1505. register_message(get_user_msgid("Money"), "message_money")
  1506. register_message(get_user_msgid("Health"), "message_health")
  1507. register_message(g_msgFlashBat, "message_flashbat")
  1508. register_message(g_msgScreenFade, "message_screenfade")
  1509. register_message(g_msgNVGToggle, "message_nvgtoggle")
  1510. if (g_handle_models_on_separate_ent) register_message(get_user_msgid("ClCorpse"), "message_clcorpse")
  1511. register_message(get_user_msgid("WeapPickup"), "message_weappickup")
  1512. register_message(g_msgAmmoPickup, "message_ammopickup")
  1513. register_message(get_user_msgid("Scenario"), "message_scenario")
  1514. register_message(get_user_msgid("HostagePos"), "message_hostagepos")
  1515. register_message(get_user_msgid("TextMsg"), "message_textmsg")
  1516. register_message(get_user_msgid("SendAudio"), "message_sendaudio")
  1517. register_message(get_user_msgid("TeamScore"), "message_teamscore")
  1518. register_message(g_msgTeamInfo, "message_teaminfo")
  1519.  
  1520. // CVARS - General Purpose
  1521. cvar_warmup = register_cvar("zp_delay", "10")
  1522. cvar_lighting = register_cvar("zp_lighting", "a")
  1523. cvar_thunder = register_cvar("zp_thunderclap", "90")
  1524. cvar_triggered = register_cvar("zp_triggered_lights", "1")
  1525. cvar_removedoors = register_cvar("zp_remove_doors", "0")
  1526. cvar_blockpushables = register_cvar("zp_blockuse_pushables", "1")
  1527. cvar_blocksuicide = register_cvar("zp_block_suicide", "1")
  1528. cvar_randspawn = register_cvar("zp_random_spawn", "1")
  1529. cvar_respawnworldspawnkill = register_cvar("zp_respawn_on_worldspawn_kill", "1")
  1530. cvar_removedropped = register_cvar("zp_remove_dropped", "0")
  1531. cvar_removemoney = register_cvar("zp_remove_money", "1")
  1532. cvar_buycustom = register_cvar("zp_buy_custom", "1")
  1533. cvar_randweapons = register_cvar("zp_random_weapons", "0")
  1534. cvar_adminmodelshuman = register_cvar("zp_admin_models_human", "1")
  1535. cvar_adminknifemodelshuman = register_cvar("zp_admin_knife_models_human", "0")
  1536. cvar_adminmodelszombie = register_cvar("zp_admin_models_zombie", "1")
  1537. cvar_adminknifemodelszombie = register_cvar("zp_admin_knife_models_zombie", "0")
  1538. cvar_zclasses = register_cvar("zp_zombie_classes", "1")
  1539. cvar_statssave = register_cvar("zp_stats_save", "1")
  1540. cvar_startammopacks = register_cvar("zp_starting_ammo_packs", "5")
  1541. cvar_preventconsecutive = register_cvar("zp_prevent_consecutive_modes", "1")
  1542. cvar_keephealthondisconnect = register_cvar("zp_keep_health_on_disconnect", "1")
  1543.  
  1544. // CVARS - Deathmatch
  1545. cvar_deathmatch = register_cvar("zp_deathmatch", "0")
  1546. cvar_spawndelay = register_cvar("zp_spawn_delay", "5")
  1547. cvar_spawnprotection = register_cvar("zp_spawn_protection", "5")
  1548. cvar_respawnonsuicide = register_cvar("zp_respawn_on_suicide", "0")
  1549. cvar_respawnafterlast = register_cvar("zp_respawn_after_last_human", "1")
  1550. cvar_allowrespawninfection = register_cvar("zp_infection_allow_respawn", "1")
  1551. cvar_allowrespawnnem = register_cvar("zp_nem_allow_respawn", "0")
  1552. cvar_allowrespawnsurv = register_cvar("zp_surv_allow_respawn", "0")
  1553. cvar_allowrespawnswarm = register_cvar("zp_swarm_allow_respawn", "0")
  1554. cvar_allowrespawnplague = register_cvar("zp_plague_allow_respawn", "0")
  1555. cvar_respawnzomb = register_cvar("zp_respawn_zombies", "1")
  1556. cvar_respawnhum = register_cvar("zp_respawn_humans", "1")
  1557. cvar_respawnnem = register_cvar("zp_respawn_nemesis", "1")
  1558. cvar_respawnsurv = register_cvar("zp_respawn_survivors", "1")
  1559.  
  1560. // CVARS - Extra Items
  1561. cvar_extraitems = register_cvar("zp_extra_items", "1")
  1562. cvar_extraweapons = register_cvar("zp_extra_weapons", "1")
  1563. cvar_extranvision = register_cvar("zp_extra_nvision", "1")
  1564. cvar_extraantidote = register_cvar("zp_extra_antidote", "1")
  1565. cvar_antidotelimit = register_cvar("zp_extra_antidote_limit", "999")
  1566. cvar_extramadness = register_cvar("zp_extra_madness", "1")
  1567. cvar_madnesslimit = register_cvar("zp_extra_madness_limit", "999")
  1568. cvar_madnessduration = register_cvar("zp_extra_madness_duration", "5.0")
  1569. cvar_extrainfbomb = register_cvar("zp_extra_infbomb", "1")
  1570. cvar_infbomblimit = register_cvar("zp_extra_infbomb_limit", "999")
  1571.  
  1572. // CVARS - Flashlight and Nightvision
  1573. cvar_nvggive = register_cvar("zp_nvg_give", "1")
  1574. cvar_customnvg = register_cvar("zp_nvg_custom", "1")
  1575. cvar_nvgsize = register_cvar("zp_nvg_size", "80")
  1576. cvar_nvgcolor[0] = register_cvar("zp_nvg_color_R", "0")
  1577. cvar_nvgcolor[1] = register_cvar("zp_nvg_color_G", "150")
  1578. cvar_nvgcolor[2] = register_cvar("zp_nvg_color_B", "0")
  1579. cvar_humnvgcolor[0] = register_cvar("zp_nvg_hum_color_R", "0")
  1580. cvar_humnvgcolor[1] = register_cvar("zp_nvg_hum_color_G", "150")
  1581. cvar_humnvgcolor[2] = register_cvar("zp_nvg_hum_color_B", "0")
  1582. cvar_nemnvgcolor[0] = register_cvar("zp_nvg_nem_color_R", "150")
  1583. cvar_nemnvgcolor[1] = register_cvar("zp_nvg_nem_color_G", "0")
  1584. cvar_nemnvgcolor[2] = register_cvar("zp_nvg_nem_color_B", "0")
  1585. cvar_customflash = register_cvar("zp_flash_custom", "0")
  1586. cvar_flashsize = register_cvar("zp_flash_size", "10")
  1587. cvar_flashdrain = register_cvar("zp_flash_drain", "1")
  1588. cvar_flashcharge = register_cvar("zp_flash_charge", "5")
  1589. cvar_flashdist = register_cvar("zp_flash_distance", "1000")
  1590. cvar_flashcolor[0] = register_cvar("zp_flash_color_R", "100")
  1591. cvar_flashcolor[1] = register_cvar("zp_flash_color_G", "100")
  1592. cvar_flashcolor[2] = register_cvar("zp_flash_color_B", "100")
  1593. cvar_flashshowall = register_cvar("zp_flash_show_all", "1")
  1594.  
  1595. // CVARS - Knockback
  1596. cvar_knockback = register_cvar("zp_knockback", "0")
  1597. cvar_knockbackdamage = register_cvar("zp_knockback_damage", "1")
  1598. cvar_knockbackpower = register_cvar("zp_knockback_power", "1")
  1599. cvar_knockbackzvel = register_cvar("zp_knockback_zvel", "0")
  1600. cvar_knockbackducking = register_cvar("zp_knockback_ducking", "0.25")
  1601. cvar_knockbackdist = register_cvar("zp_knockback_distance", "500")
  1602. cvar_nemknockback = register_cvar("zp_knockback_nemesis", "0.25")
  1603.  
  1604. // CVARS - Leap
  1605. cvar_leapzombies = register_cvar("zp_leap_zombies", "0")
  1606. cvar_leapzombiesforce = register_cvar("zp_leap_zombies_force", "500")
  1607. cvar_leapzombiesheight = register_cvar("zp_leap_zombies_height", "300")
  1608. cvar_leapzombiescooldown = register_cvar("zp_leap_zombies_cooldown", "5.0")
  1609. cvar_leapnemesis = register_cvar("zp_leap_nemesis", "1")
  1610. cvar_leapnemesisforce = register_cvar("zp_leap_nemesis_force", "500")
  1611. cvar_leapnemesisheight = register_cvar("zp_leap_nemesis_height", "300")
  1612. cvar_leapnemesiscooldown = register_cvar("zp_leap_nemesis_cooldown", "5.0")
  1613. cvar_leapsurvivor = register_cvar("zp_leap_survivor", "0")
  1614. cvar_leapsurvivorforce = register_cvar("zp_leap_survivor_force", "500")
  1615. cvar_leapsurvivorheight = register_cvar("zp_leap_survivor_height", "300")
  1616. cvar_leapsurvivorcooldown = register_cvar("zp_leap_survivor_cooldown", "5.0")
  1617.  
  1618. // CVARS - Humans
  1619. cvar_humanhp = register_cvar("zp_human_health", "100")
  1620. cvar_humanlasthp = register_cvar("zp_human_last_extrahp", "0")
  1621. cvar_humanspd = register_cvar("zp_human_speed", "240")
  1622. cvar_humangravity = register_cvar("zp_human_gravity", "1.0")
  1623. cvar_humanarmor = register_cvar("zp_human_armor_protect", "1")
  1624. cvar_infammo = register_cvar("zp_human_unlimited_ammo", "0")
  1625. cvar_ammodamage = register_cvar("zp_human_damage_reward", "500")
  1626. cvar_fragskill = register_cvar("zp_human_frags_for_kill", "1")
  1627.  
  1628. // CVARS - Custom Grenades
  1629. cvar_firegrenades = register_cvar("zp_fire_grenades", "1")
  1630. cvar_fireduration = register_cvar("zp_fire_duration", "10")
  1631. cvar_firedamage = register_cvar("zp_fire_damage", "5")
  1632. cvar_fireslowdown = register_cvar("zp_fire_slowdown", "0.5")
  1633. cvar_frostgrenades = register_cvar("zp_frost_grenades", "1")
  1634. cvar_freezeduration = register_cvar("zp_frost_duration", "3")
  1635. cvar_flaregrenades = register_cvar("zp_flare_grenades","1")
  1636. cvar_flareduration = register_cvar("zp_flare_duration", "60")
  1637. cvar_flaresize = register_cvar("zp_flare_size", "25")
  1638. cvar_flarecolor = register_cvar("zp_flare_color", "0")
  1639.  
  1640. // CVARS - Zombies
  1641. cvar_zombiefirsthp = register_cvar("zp_zombie_first_hp", "2.0")
  1642. cvar_zombiearmor = register_cvar("zp_zombie_armor", "0.75")
  1643. cvar_hitzones = register_cvar("zp_zombie_hitzones", "0")
  1644. cvar_zombiebonushp = register_cvar("zp_zombie_infect_health", "100")
  1645. cvar_zombiefov = register_cvar("zp_zombie_fov", "110")
  1646. cvar_zombiesilent = register_cvar("zp_zombie_silent", "1")
  1647. cvar_zombiepainfree = register_cvar("zp_zombie_painfree", "2")
  1648. cvar_zombiebleeding = register_cvar("zp_zombie_bleeding", "1")
  1649. cvar_ammoinfect = register_cvar("zp_zombie_infect_reward", "1")
  1650. cvar_fragsinfect = register_cvar("zp_zombie_frags_for_infect", "1")
  1651.  
  1652. // CVARS - Special Effects
  1653. cvar_infectionscreenfade = register_cvar("zp_infection_screenfade", "1")
  1654. cvar_infectionscreenshake = register_cvar("zp_infection_screenshake", "1")
  1655. cvar_infectionsparkle = register_cvar("zp_infection_sparkle", "1")
  1656. cvar_infectiontracers = register_cvar("zp_infection_tracers", "1")
  1657. cvar_infectionparticles = register_cvar("zp_infection_particles", "1")
  1658. cvar_hudicons = register_cvar("zp_hud_icons", "1")
  1659.  
  1660. // CVARS - Nemesis
  1661. cvar_nem = register_cvar("zp_nem_enabled", "1")
  1662. cvar_nemchance = register_cvar("zp_nem_chance", "20")
  1663. cvar_nemminplayers = register_cvar("zp_nem_min_players", "0")
  1664. cvar_nemhp = register_cvar("zp_nem_health", "0")
  1665. cvar_nembasehp = register_cvar("zp_nem_base_health", "0")
  1666. cvar_nemspd = register_cvar("zp_nem_speed", "250")
  1667. cvar_nemgravity = register_cvar("zp_nem_gravity", "0.5")
  1668. cvar_nemdamage = register_cvar("zp_nem_damage", "250")
  1669. cvar_nemglow = register_cvar("zp_nem_glow", "1")
  1670. cvar_nemaura = register_cvar("zp_nem_aura", "1")
  1671. cvar_nempainfree = register_cvar("zp_nem_painfree", "0")
  1672. cvar_nemignorefrags = register_cvar("zp_nem_ignore_frags", "1")
  1673. cvar_nemignoreammo = register_cvar("zp_nem_ignore_rewards", "1")
  1674.  
  1675. // CVARS - Survivor
  1676. cvar_surv = register_cvar("zp_surv_enabled", "1")
  1677. cvar_survchance = register_cvar("zp_surv_chance", "20")
  1678. cvar_survminplayers = register_cvar("zp_surv_min_players", "0")
  1679. cvar_survhp = register_cvar("zp_surv_health", "0")
  1680. cvar_survbasehp = register_cvar("zp_surv_base_health", "0")
  1681. cvar_survspd = register_cvar("zp_surv_speed", "230")
  1682. cvar_survgravity = register_cvar("zp_surv_gravity", "1.25")
  1683. cvar_survglow = register_cvar("zp_surv_glow", "1")
  1684. cvar_survaura = register_cvar("zp_surv_aura", "1")
  1685. cvar_survpainfree = register_cvar("zp_surv_painfree", "1")
  1686. cvar_survignorefrags = register_cvar("zp_surv_ignore_frags", "1")
  1687. cvar_survignoreammo = register_cvar("zp_surv_ignore_rewards", "1")
  1688. cvar_survweapon = register_cvar("zp_surv_weapon", "weapon_m249")
  1689. cvar_survinfammo = register_cvar("zp_surv_unlimited_ammo", "2")
  1690.  
  1691. // CVARS - Swarm Mode
  1692. cvar_swarm = register_cvar("zp_swarm_enabled", "1")
  1693. cvar_swarmchance = register_cvar("zp_swarm_chance", "20")
  1694. cvar_swarmminplayers = register_cvar("zp_swarm_min_players", "0")
  1695.  
  1696. // CVARS - Multi Infection
  1697. cvar_multi = register_cvar("zp_multi_enabled", "1")
  1698. cvar_multichance = register_cvar("zp_multi_chance", "20")
  1699. cvar_multiminplayers = register_cvar("zp_multi_min_players", "0")
  1700. cvar_multiratio = register_cvar("zp_multi_ratio", "0.15")
  1701.  
  1702. // CVARS - Plague Mode
  1703. cvar_plague = register_cvar("zp_plague_enabled", "1")
  1704. cvar_plaguechance = register_cvar("zp_plague_chance", "30")
  1705. cvar_plagueminplayers = register_cvar("zp_plague_min_players", "0")
  1706. cvar_plagueratio = register_cvar("zp_plague_ratio", "0.5")
  1707. cvar_plaguenemnum = register_cvar("zp_plague_nem_number", "1")
  1708. cvar_plaguenemhpmulti = register_cvar("zp_plague_nem_hp_multi", "0.5")
  1709. cvar_plaguesurvnum = register_cvar("zp_plague_surv_number", "1")
  1710. cvar_plaguesurvhpmulti = register_cvar("zp_plague_surv_hp_multi", "0.5")
  1711.  
  1712. // CVARS - Others
  1713. cvar_logcommands = register_cvar("zp_logcommands", "1")
  1714. cvar_showactivity = get_cvar_pointer("amx_show_activity")
  1715. cvar_botquota = get_cvar_pointer("bot_quota")
  1716. register_cvar("zp_version", PLUGIN_VERSION, FCVAR_SERVER|FCVAR_SPONLY)
  1717. set_cvar_string("zp_version", PLUGIN_VERSION)
  1718.  
  1719. // Custom Forwards
  1720. g_fwRoundStart = CreateMultiForward("zp_round_started", ET_IGNORE, FP_CELL, FP_CELL)
  1721. g_fwRoundEnd = CreateMultiForward("zp_round_ended", ET_IGNORE, FP_CELL)
  1722. g_fwUserInfected_pre = CreateMultiForward("zp_user_infected_pre", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL)
  1723. g_fwUserInfected_post = CreateMultiForward("zp_user_infected_post", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL)
  1724. g_fwUserHumanized_pre = CreateMultiForward("zp_user_humanized_pre", ET_IGNORE, FP_CELL, FP_CELL)
  1725. g_fwUserHumanized_post = CreateMultiForward("zp_user_humanized_post", ET_IGNORE, FP_CELL, FP_CELL)
  1726. g_fwUserInfect_attempt = CreateMultiForward("zp_user_infect_attempt", ET_CONTINUE, FP_CELL, FP_CELL, FP_CELL)
  1727. g_fwUserHumanize_attempt = CreateMultiForward("zp_user_humanize_attempt", ET_CONTINUE, FP_CELL, FP_CELL)
  1728. g_fwExtraItemSelected = CreateMultiForward("zp_extra_item_selected", ET_CONTINUE, FP_CELL, FP_CELL)
  1729. g_fwUserUnfrozen = CreateMultiForward("zp_user_unfrozen", ET_IGNORE, FP_CELL)
  1730. g_fwUserLastZombie = CreateMultiForward("zp_user_last_zombie", ET_IGNORE, FP_CELL)
  1731. g_fwUserLastHuman = CreateMultiForward("zp_user_last_human", ET_IGNORE, FP_CELL)
  1732.  
  1733. // Collect random spawn points
  1734. load_spawns()
  1735.  
  1736. // Set a random skybox?
  1737. if (g_sky_enable)
  1738. {
  1739. new sky[32]
  1740. ArrayGetString(g_sky_names, random_num(0, ArraySize(g_sky_names) - 1), sky, charsmax(sky))
  1741. set_cvar_string("sv_skyname", sky)
  1742. }
  1743.  
  1744. // Disable sky lighting so it doesn't mess with our custom lighting
  1745. set_cvar_num("sv_skycolor_r", 0)
  1746. set_cvar_num("sv_skycolor_g", 0)
  1747. set_cvar_num("sv_skycolor_b", 0)
  1748.  
  1749. // Create the HUD Sync Objects
  1750. g_MsgSync = CreateHudSyncObj()
  1751. g_MsgSync2 = CreateHudSyncObj()
  1752.  
  1753. // Format mod name
  1754. formatex(g_modname, charsmax(g_modname), "Zombie Plague %s", PLUGIN_VERSION)
  1755.  
  1756. // Get Max Players
  1757. g_maxplayers = get_maxplayers()
  1758.  
  1759. // Reserved saving slots starts on maxplayers+1
  1760. db_slot_i = g_maxplayers+1
  1761.  
  1762. // Check if it's a CZ server
  1763. new mymod[6]
  1764. get_modname(mymod, charsmax(mymod))
  1765. if (equal(mymod, "czero")) g_czero = 1
  1766. }
  1767.  
  1768. public plugin_cfg()
  1769. {
  1770. // Plugin disabled?
  1771. if (!g_pluginenabled) return;
  1772.  
  1773. // Get configs dir
  1774. new cfgdir[32]
  1775. get_configsdir(cfgdir, charsmax(cfgdir))
  1776.  
  1777. // Execute config file (zombieplague.cfg)
  1778. server_cmd("exec %s/zombieplague.cfg", cfgdir)
  1779.  
  1780. // Prevent any more stuff from registering
  1781. g_arrays_created = false
  1782.  
  1783. // Save customization data
  1784. save_customization()
  1785.  
  1786. // Lighting task
  1787. set_task(5.0, "lighting_effects", _, _, _, "b")
  1788.  
  1789. // Cache CVARs after configs are loaded / call roundstart manually
  1790. set_task(0.5, "cache_cvars")
  1791. set_task(0.5, "event_round_start")
  1792. set_task(0.5, "logevent_round_start")
  1793. }
  1794.  
  1795. /*================================================================================
  1796. [Main Events]
  1797. =================================================================================*/
  1798.  
  1799. // Event Round Start
  1800. public event_round_start()
  1801. {
  1802. // Remove doors/lights?
  1803. set_task(0.1, "remove_stuff")
  1804.  
  1805. // New round starting
  1806. g_newround = true
  1807. g_endround = false
  1808. g_survround = false
  1809. g_nemround = false
  1810. g_swarmround = false
  1811. g_plagueround = false
  1812. g_modestarted = false
  1813.  
  1814. // Reset bought infection bombs counter
  1815. g_infbombcounter = 0
  1816. g_antidotecounter = 0
  1817. g_madnesscounter = 0
  1818.  
  1819. // Freezetime begins
  1820. g_freezetime = true
  1821.  
  1822. // Show welcome message and T-Virus notice
  1823. remove_task(TASK_WELCOMEMSG)
  1824. set_task(2.0, "welcome_msg", TASK_WELCOMEMSG)
  1825.  
  1826. // Set a new "Make Zombie Task"
  1827. remove_task(TASK_MAKEZOMBIE)
  1828. set_task(2.0 + get_pcvar_float(cvar_warmup), "make_zombie_task", TASK_MAKEZOMBIE)
  1829. }
  1830.  
  1831. // Log Event Round Start
  1832. public logevent_round_start()
  1833. {
  1834. // Freezetime ends
  1835. g_freezetime = false
  1836. }
  1837.  
  1838. // Log Event Round End
  1839. public logevent_round_end()
  1840. {
  1841. // Prevent this from getting called twice when restarting (bugfix)
  1842. static Float:lastendtime, Float:current_time
  1843. current_time = get_gametime()
  1844. if (current_time - lastendtime < 0.5) return;
  1845. lastendtime = current_time
  1846.  
  1847. // Temporarily save player stats?
  1848. if (get_pcvar_num(cvar_statssave))
  1849. {
  1850. static id, team
  1851. for (id = 1; id <= g_maxplayers; id++)
  1852. {
  1853. // Not connected
  1854. if (!g_isconnected[id])
  1855. continue;
  1856.  
  1857. team = fm_cs_get_user_team(id)
  1858.  
  1859. // Not playing
  1860. if (team == FM_CS_TEAM_SPECTATOR || team == FM_CS_TEAM_UNASSIGNED)
  1861. continue;
  1862.  
  1863. save_stats(id)
  1864. }
  1865. }
  1866.  
  1867. // Round ended
  1868. g_endround = true
  1869.  
  1870. // Stop old tasks (if any)
  1871. remove_task(TASK_WELCOMEMSG)
  1872. remove_task(TASK_MAKEZOMBIE)
  1873.  
  1874. // Stop ambience sounds
  1875. if ((g_ambience_sounds[AMBIENCE_SOUNDS_NEMESIS] && g_nemround) || (g_ambience_sounds[AMBIENCE_SOUNDS_SURVIVOR] && g_survround) || (g_ambience_sounds[AMBIENCE_SOUNDS_SWARM] && g_swarmround) || (g_ambience_sounds[AMBIENCE_SOUNDS_PLAGUE] && g_plagueround) || (g_ambience_sounds[AMBIENCE_SOUNDS_INFECTION] && !g_nemround && !g_survround && !g_swarmround && !g_plagueround))
  1876. {
  1877. remove_task(TASK_AMBIENCESOUNDS)
  1878. ambience_sound_stop()
  1879. }
  1880.  
  1881. // Show HUD notice, play win sound, update team scores...
  1882. static sound[64]
  1883. if (!fnGetZombies())
  1884. {
  1885. // Human team wins
  1886. set_hudmessage(0, 0, 200, HUD_EVENT_X, HUD_EVENT_Y, 0, 0.0, 3.0, 2.0, 1.0, -1)
  1887. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "WIN_HUMAN")
  1888.  
  1889. // Play win sound and increase score
  1890. ArrayGetString(sound_win_humans, random_num(0, ArraySize(sound_win_humans) - 1), sound, charsmax(sound))
  1891. PlaySound(sound)
  1892. g_scorehumans++
  1893.  
  1894. // Round end forward
  1895. ExecuteForward(g_fwRoundEnd, g_fwDummyResult, ZP_TEAM_HUMAN);
  1896. }
  1897. else if (!fnGetHumans())
  1898. {
  1899. // Zombie team wins
  1900. set_hudmessage(200, 0, 0, HUD_EVENT_X, HUD_EVENT_Y, 0, 0.0, 3.0, 2.0, 1.0, -1)
  1901. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "WIN_ZOMBIE")
  1902.  
  1903. // Play win sound and increase score
  1904. ArrayGetString(sound_win_zombies, random_num(0, ArraySize(sound_win_zombies) - 1), sound, charsmax(sound))
  1905. PlaySound(sound)
  1906. g_scorezombies++
  1907.  
  1908. // Round end forward
  1909. ExecuteForward(g_fwRoundEnd, g_fwDummyResult, ZP_TEAM_ZOMBIE);
  1910. }
  1911. else
  1912. {
  1913. // No one wins
  1914. set_hudmessage(0, 200, 0, HUD_EVENT_X, HUD_EVENT_Y, 0, 0.0, 3.0, 2.0, 1.0, -1)
  1915. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "WIN_NO_ONE")
  1916.  
  1917. // Play win sound
  1918. ArrayGetString(sound_win_no_one, random_num(0, ArraySize(sound_win_no_one) - 1), sound, charsmax(sound))
  1919. PlaySound(sound)
  1920.  
  1921. // Round end forward
  1922. ExecuteForward(g_fwRoundEnd, g_fwDummyResult, ZP_TEAM_NO_ONE);
  1923. }
  1924.  
  1925. // Balance the teams
  1926. balance_teams()
  1927. }
  1928.  
  1929. // Event Map Ended
  1930. public event_intermission()
  1931. {
  1932. // Remove ambience sounds task
  1933. remove_task(TASK_AMBIENCESOUNDS)
  1934. }
  1935.  
  1936. // BP Ammo update
  1937. public event_ammo_x(id)
  1938. {
  1939. // Humans only
  1940. if (g_zombie[id])
  1941. return;
  1942.  
  1943. // Get ammo type
  1944. static type
  1945. type = read_data(1)
  1946.  
  1947. // Unknown ammo type
  1948. if (type >= sizeof AMMOWEAPON)
  1949. return;
  1950.  
  1951. // Get weapon's id
  1952. static weapon
  1953. weapon = AMMOWEAPON[type]
  1954.  
  1955. // Primary and secondary only
  1956. if (MAXBPAMMO[weapon] <= 2)
  1957. return;
  1958.  
  1959. // Get ammo amount
  1960. static amount
  1961. amount = read_data(2)
  1962.  
  1963. // Unlimited BP Ammo?
  1964. if (g_survivor[id] ? get_pcvar_num(cvar_survinfammo) : get_pcvar_num(cvar_infammo))
  1965. {
  1966. if (amount < MAXBPAMMO[weapon])
  1967. {
  1968. // The BP Ammo refill code causes the engine to send a message, but we
  1969. // can't have that in this forward or we risk getting some recursion bugs.
  1970. // For more info see: https://bugs.alliedmods.net/show_bug.cgi?id=3664
  1971. static args[1]
  1972. args[0] = weapon
  1973. set_task(0.1, "refill_bpammo", id, args, sizeof args)
  1974. }
  1975. }
  1976. // Bots automatically buy ammo when needed
  1977. else if (g_isbot[id] && amount <= BUYAMMO[weapon])
  1978. {
  1979. // Task needed for the same reason as above
  1980. set_task(0.1, "clcmd_buyammo", id)
  1981. }
  1982. }
  1983.  
  1984. /*================================================================================
  1985. [Main Forwards]
  1986. =================================================================================*/
  1987.  
  1988. // Entity Spawn Forward
  1989. public fw_Spawn(entity)
  1990. {
  1991. // Invalid entity
  1992. if (!pev_valid(entity)) return FMRES_IGNORED;
  1993.  
  1994. // Get classname
  1995. new classname[32], objective[32], size = ArraySize(g_objective_ents)
  1996. pev(entity, pev_classname, classname, charsmax(classname))
  1997.  
  1998. // Check whether it needs to be removed
  1999. for (new i = 0; i < size; i++)
  2000. {
  2001. ArrayGetString(g_objective_ents, i, objective, charsmax(objective))
  2002.  
  2003. if (equal(classname, objective))
  2004. {
  2005. engfunc(EngFunc_RemoveEntity, entity)
  2006. return FMRES_SUPERCEDE;
  2007. }
  2008. }
  2009.  
  2010. return FMRES_IGNORED;
  2011. }
  2012.  
  2013. // Sound Precache Forward
  2014. public fw_PrecacheSound(const sound[])
  2015. {
  2016. // Block all those unneeeded hostage sounds
  2017. if (equal(sound, "hostage", 7))
  2018. return FMRES_SUPERCEDE;
  2019.  
  2020. return FMRES_IGNORED;
  2021. }
  2022.  
  2023. // Ham Player Spawn Post Forward
  2024. public fw_PlayerSpawn_Post(id)
  2025. {
  2026. // Not alive or didn't join a team yet
  2027. if (!is_user_alive(id) || !fm_cs_get_user_team(id))
  2028. return;
  2029.  
  2030. // Player spawned
  2031. g_isalive[id] = true
  2032.  
  2033. // Remove previous tasks
  2034. remove_task(id+TASK_SPAWN)
  2035. remove_task(id+TASK_MODEL)
  2036. remove_task(id+TASK_BLOOD)
  2037. remove_task(id+TASK_AURA)
  2038. remove_task(id+TASK_BURN)
  2039. remove_task(id+TASK_CHARGE)
  2040. remove_task(id+TASK_FLASH)
  2041. remove_task(id+TASK_NVISION)
  2042.  
  2043. // Spawn at a random location?
  2044. if (get_pcvar_num(cvar_randspawn)) do_random_spawn(id)
  2045.  
  2046. // Hide money?
  2047. if (get_pcvar_num(cvar_removemoney))
  2048. set_task(0.4, "task_hide_money", id+TASK_SPAWN)
  2049.  
  2050. // Respawn player if he dies because of a worldspawn kill?
  2051. if (get_pcvar_num(cvar_respawnworldspawnkill))
  2052. set_task(2.0, "respawn_player_task", id+TASK_SPAWN)
  2053.  
  2054. // Spawn as zombie?
  2055. if (g_respawn_as_zombie[id] && !g_newround)
  2056. {
  2057. reset_vars(id, 0) // reset player vars
  2058. zombieme(id, 0, 0, 0, 0) // make him zombie right away
  2059. return;
  2060. }
  2061.  
  2062. // Reset player vars
  2063. reset_vars(id, 0)
  2064.  
  2065. // Show custom buy menu?
  2066. if (get_pcvar_num(cvar_buycustom))
  2067. set_task(0.2, "show_menu_buy1", id+TASK_SPAWN)
  2068.  
  2069. // Set health and gravity
  2070. fm_set_user_health(id, get_pcvar_num(cvar_humanhp))
  2071. set_pev(id, pev_gravity, get_pcvar_float(cvar_humangravity))
  2072.  
  2073. // Switch to CT if spawning mid-round
  2074. if (!g_newround && fm_cs_get_user_team(id) != FM_CS_TEAM_CT) // need to change team?
  2075. {
  2076. remove_task(id+TASK_TEAM)
  2077. fm_cs_set_user_team(id, FM_CS_TEAM_CT)
  2078. fm_user_team_update(id)
  2079. }
  2080.  
  2081. // Custom models stuff
  2082. static currentmodel[32], tempmodel[32], already_has_model, i, iRand, size
  2083. already_has_model = false
  2084.  
  2085. if (g_handle_models_on_separate_ent)
  2086. {
  2087. // Set the right model
  2088. if (get_pcvar_num(cvar_adminmodelshuman) && (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS]))
  2089. {
  2090. iRand = random_num(0, ArraySize(model_admin_human) - 1)
  2091. ArrayGetString(model_admin_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  2092. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_admin_human, iRand))
  2093. }
  2094. else
  2095. {
  2096. iRand = random_num(0, ArraySize(model_human) - 1)
  2097. ArrayGetString(model_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  2098. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_human, iRand))
  2099. }
  2100.  
  2101. // Set model on player model entity
  2102. fm_set_playermodel_ent(id)
  2103.  
  2104. // Remove glow on player model entity
  2105. fm_set_rendering(g_ent_playermodel[id])
  2106. }
  2107. else
  2108. {
  2109. // Get current model for comparing it with the current one
  2110. fm_cs_get_user_model(id, currentmodel, charsmax(currentmodel))
  2111.  
  2112. // Set the right model, after checking that we don't already have it
  2113. if (get_pcvar_num(cvar_adminmodelshuman) && (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS]))
  2114. {
  2115. size = ArraySize(model_admin_human)
  2116. for (i = 0; i < size; i++)
  2117. {
  2118. ArrayGetString(model_admin_human, i, tempmodel, charsmax(tempmodel))
  2119. if (equal(currentmodel, tempmodel)) already_has_model = true
  2120. }
  2121.  
  2122. if (!already_has_model)
  2123. {
  2124. iRand = random_num(0, size - 1)
  2125. ArrayGetString(model_admin_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  2126. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_admin_human, iRand))
  2127. }
  2128. }
  2129. else
  2130. {
  2131. size = ArraySize(model_human)
  2132. for (i = 0; i < size; i++)
  2133. {
  2134. ArrayGetString(model_human, i, tempmodel, charsmax(tempmodel))
  2135. if (equal(currentmodel, tempmodel)) already_has_model = true
  2136. }
  2137.  
  2138. if (!already_has_model)
  2139. {
  2140. iRand = random_num(0, size - 1)
  2141. ArrayGetString(model_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  2142. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_human, iRand))
  2143. }
  2144. }
  2145.  
  2146. // Need to change the model?
  2147. if (!already_has_model)
  2148. {
  2149. // An additional delay is offset at round start
  2150. // since SVC_BAD is more likely to be triggered there
  2151. if (g_newround)
  2152. set_task(5.0 * g_modelchange_delay, "fm_user_model_update", id+TASK_MODEL)
  2153. else
  2154. fm_user_model_update(id+TASK_MODEL)
  2155. }
  2156.  
  2157. // Remove glow
  2158. fm_set_rendering(id)
  2159. }
  2160.  
  2161. // Bots stuff
  2162. if (g_isbot[id])
  2163. {
  2164. // Turn off NVG for bots
  2165. cs_set_user_nvg(id, 0)
  2166.  
  2167. // Automatically buy extra items/weapons after first zombie is chosen
  2168. if (get_pcvar_num(cvar_extraitems))
  2169. {
  2170. if (g_newround) set_task(10.0 + get_pcvar_float(cvar_warmup), "bot_buy_extras", id+TASK_SPAWN)
  2171. else set_task(10.0, "bot_buy_extras", id+TASK_SPAWN)
  2172. }
  2173. }
  2174.  
  2175. // Enable spawn protection for humans spawning mid-round
  2176. if (!g_newround && get_pcvar_float(cvar_spawnprotection) > 0.0)
  2177. {
  2178. // Do not take damage
  2179. g_nodamage[id] = true
  2180.  
  2181. // Make temporarily invisible
  2182. set_pev(id, pev_effects, pev(id, pev_effects) | EF_NODRAW)
  2183.  
  2184. // Set task to remove it
  2185. set_task(get_pcvar_float(cvar_spawnprotection), "remove_spawn_protection", id+TASK_SPAWN)
  2186. }
  2187.  
  2188. // Set the flashlight charge task to update battery status
  2189. if (g_cached_customflash)
  2190. set_task(1.0, "flashlight_charge", id+TASK_CHARGE, _, _, "b")
  2191.  
  2192. // Replace weapon models (bugfix)
  2193. static weapon_ent
  2194. weapon_ent = fm_cs_get_current_weapon_ent(id)
  2195. if (pev_valid(weapon_ent)) replace_weapon_models(id, cs_get_weapon_id(weapon_ent))
  2196.  
  2197. // Last Zombie Check
  2198. fnCheckLastZombie()
  2199. }
  2200.  
  2201. // Ham Player Killed Forward
  2202. public fw_PlayerKilled(victim, attacker, shouldgib)
  2203. {
  2204. // Player killed
  2205. g_isalive[victim] = false
  2206.  
  2207. // Enable dead players nightvision
  2208. set_task(0.1, "spec_nvision", victim)
  2209.  
  2210. // Disable nightvision when killed (bugfix)
  2211. if (get_pcvar_num(cvar_nvggive) == 0 && g_nvision[victim])
  2212. {
  2213. if (get_pcvar_num(cvar_customnvg)) remove_task(victim+TASK_NVISION)
  2214. else if (g_nvisionenabled[victim]) set_user_gnvision(victim, 0)
  2215. g_nvision[victim] = false
  2216. g_nvisionenabled[victim] = false
  2217. }
  2218.  
  2219. // Turn off nightvision when killed (bugfix)
  2220. if (get_pcvar_num(cvar_nvggive) == 2 && g_nvision[victim] && g_nvisionenabled[victim])
  2221. {
  2222. if (get_pcvar_num(cvar_customnvg)) remove_task(victim+TASK_NVISION)
  2223. else set_user_gnvision(victim, 0)
  2224. g_nvisionenabled[victim] = false
  2225. }
  2226.  
  2227. // Turn off custom flashlight when killed
  2228. if (g_cached_customflash)
  2229. {
  2230. // Turn it off
  2231. g_flashlight[victim] = false
  2232. g_flashbattery[victim] = 100
  2233.  
  2234. // Remove previous tasks
  2235. remove_task(victim+TASK_CHARGE)
  2236. remove_task(victim+TASK_FLASH)
  2237. }
  2238.  
  2239. // Stop bleeding/burning/aura when killed
  2240. if (g_zombie[victim])
  2241. {
  2242. remove_task(victim+TASK_BLOOD)
  2243. remove_task(victim+TASK_AURA)
  2244. remove_task(victim+TASK_BURN)
  2245. }
  2246.  
  2247. // Nemesis explodes!
  2248. if (g_nemesis[victim])
  2249. SetHamParamInteger(3, 2)
  2250.  
  2251. // Get deathmatch mode status and whether the player killed himself
  2252. static selfkill
  2253. selfkill = (victim == attacker || !is_user_valid_connected(attacker)) ? true : false
  2254.  
  2255. // Respawn if deathmatch is enabled
  2256. if (get_pcvar_num(cvar_deathmatch))
  2257. {
  2258. // Respawn on suicide?
  2259. if (selfkill && !get_pcvar_num(cvar_respawnonsuicide))
  2260. return;
  2261.  
  2262. // Respawn if only the last human is left?
  2263. if (!get_pcvar_num(cvar_respawnafterlast) && fnGetHumans() <= 1)
  2264. return;
  2265.  
  2266. // Respawn if human/zombie/nemesis/survivor?
  2267. if ((g_zombie[victim] && !g_nemesis[victim] && !get_pcvar_num(cvar_respawnzomb)) || (!g_zombie[victim] && !g_survivor[victim] && !get_pcvar_num(cvar_respawnhum)) || (g_nemesis[victim] && !get_pcvar_num(cvar_respawnnem)) || (g_survivor[victim] && !get_pcvar_num(cvar_respawnsurv)))
  2268. return;
  2269.  
  2270. // Respawn as zombie?
  2271. if (get_pcvar_num(cvar_deathmatch) == 2 || (get_pcvar_num(cvar_deathmatch) == 3 && random_num(0, 1)) || (get_pcvar_num(cvar_deathmatch) == 4 && fnGetZombies() < fnGetAlive()/2))
  2272. g_respawn_as_zombie[victim] = true
  2273.  
  2274. // Set the respawn task
  2275. set_task(get_pcvar_float(cvar_spawndelay), "respawn_player_task", victim+TASK_SPAWN)
  2276. }
  2277.  
  2278. // Killed by a non-player entity or self killed
  2279. if (selfkill) return;
  2280.  
  2281. // Ignore Nemesis/Survivor Frags?
  2282. if ((g_nemesis[attacker] && get_pcvar_num(cvar_nemignorefrags)) || (g_survivor[attacker] && get_pcvar_num(cvar_survignorefrags)))
  2283. RemoveFrags(attacker, victim)
  2284.  
  2285. // Zombie/nemesis killed human, reward ammo packs
  2286. if (g_zombie[attacker] && (!g_nemesis[attacker] || !get_pcvar_num(cvar_nemignoreammo)))
  2287. g_ammopacks[attacker] += get_pcvar_num(cvar_ammoinfect)
  2288.  
  2289. // Human killed zombie, add up the extra frags for kill
  2290. if (!g_zombie[attacker] && get_pcvar_num(cvar_fragskill) > 1)
  2291. UpdateFrags(attacker, victim, get_pcvar_num(cvar_fragskill) - 1, 0, 0)
  2292.  
  2293. // Zombie killed human, add up the extra frags for kill
  2294. if (g_zombie[attacker] && get_pcvar_num(cvar_fragsinfect) > 1)
  2295. UpdateFrags(attacker, victim, get_pcvar_num(cvar_fragsinfect) - 1, 0, 0)
  2296. }
  2297.  
  2298. // Ham Player Killed Post Forward
  2299. public fw_PlayerKilled_Post()
  2300. {
  2301. // Last Zombie Check
  2302. fnCheckLastZombie()
  2303. }
  2304.  
  2305. // Ham Take Damage Forward
  2306. public fw_TakeDamage(victim, inflictor, attacker, Float:damage, damage_type)
  2307. {
  2308. // Non-player damage or self damage
  2309. if (victim == attacker || !is_user_valid_connected(attacker))
  2310. return HAM_IGNORED;
  2311.  
  2312. // New round starting or round ended
  2313. if (g_newround || g_endround)
  2314. return HAM_SUPERCEDE;
  2315.  
  2316. // Victim shouldn't take damage or victim is frozen
  2317. if (g_nodamage[victim] || g_frozen[victim])
  2318. return HAM_SUPERCEDE;
  2319.  
  2320. // Prevent friendly fire
  2321. if (g_zombie[attacker] == g_zombie[victim])
  2322. return HAM_SUPERCEDE;
  2323.  
  2324. // Attacker is human...
  2325. if (!g_zombie[attacker])
  2326. {
  2327. // Armor multiplier for the final damage on normal zombies
  2328. if (!g_nemesis[victim])
  2329. {
  2330. damage *= get_pcvar_float(cvar_zombiearmor)
  2331. SetHamParamFloat(4, damage)
  2332. }
  2333.  
  2334. // Reward ammo packs
  2335. if (!g_survivor[attacker] || !get_pcvar_num(cvar_survignoreammo))
  2336. {
  2337. // Store damage dealt
  2338. g_damagedealt[attacker] += floatround(damage)
  2339.  
  2340. // Reward ammo packs for every [ammo damage] dealt
  2341. while (g_damagedealt[attacker] > get_pcvar_num(cvar_ammodamage))
  2342. {
  2343. g_ammopacks[attacker]++
  2344. g_damagedealt[attacker] -= get_pcvar_num(cvar_ammodamage)
  2345. }
  2346. }
  2347.  
  2348. return HAM_IGNORED;
  2349. }
  2350.  
  2351. // Attacker is zombie...
  2352.  
  2353. // Prevent infection/damage by HE grenade (bugfix)
  2354. if (damage_type & DMG_HEGRENADE)
  2355. return HAM_SUPERCEDE;
  2356.  
  2357. // Nemesis?
  2358. if (g_nemesis[attacker])
  2359. {
  2360. // Ignore nemesis damage override if damage comes from a 3rd party entity
  2361. // (to prevent this from affecting a sub-plugin's rockets e.g.)
  2362. if (inflictor == attacker)
  2363. {
  2364. // Set nemesis damage
  2365. SetHamParamFloat(4, get_pcvar_float(cvar_nemdamage))
  2366. }
  2367.  
  2368. return HAM_IGNORED;
  2369. }
  2370.  
  2371. // Last human or not an infection round
  2372. if (g_survround || g_nemround || g_swarmround || g_plagueround || fnGetHumans() == 1)
  2373. return HAM_IGNORED; // human is killed
  2374.  
  2375. // Does human armor need to be reduced before infecting?
  2376. if (get_pcvar_num(cvar_humanarmor))
  2377. {
  2378. // Get victim armor
  2379. static Float:armor
  2380. pev(victim, pev_armorvalue, armor)
  2381.  
  2382. // Block the attack if he has some
  2383. if (armor > 0.0)
  2384. {
  2385. emit_sound(victim, CHAN_BODY, sound_armorhit, 1.0, ATTN_NORM, 0, PITCH_NORM)
  2386. set_pev(victim, pev_armorvalue, floatmax(0.0, armor - damage))
  2387. return HAM_SUPERCEDE;
  2388. }
  2389. }
  2390.  
  2391. // Infection allowed
  2392. zombieme(victim, attacker, 0, 0, 1) // turn into zombie
  2393. return HAM_SUPERCEDE;
  2394. }
  2395.  
  2396. // Ham Take Damage Post Forward
  2397. public fw_TakeDamage_Post(victim)
  2398. {
  2399. // --- Check if victim should be Pain Shock Free ---
  2400.  
  2401. // Check if proper CVARs are enabled
  2402. if (g_zombie[victim])
  2403. {
  2404. if (g_nemesis[victim])
  2405. {
  2406. if (!get_pcvar_num(cvar_nempainfree)) return;
  2407. }
  2408. else
  2409. {
  2410. switch (get_pcvar_num(cvar_zombiepainfree))
  2411. {
  2412. case 0: return;
  2413. case 2: if (!g_lastzombie[victim]) return;
  2414. }
  2415. }
  2416. }
  2417. else
  2418. {
  2419. if (g_survivor[victim])
  2420. {
  2421. if (!get_pcvar_num(cvar_survpainfree)) return;
  2422. }
  2423. else return;
  2424. }
  2425.  
  2426. // Set pain shock free offset
  2427. set_pdata_float(victim, OFFSET_PAINSHOCK, 1.0, OFFSET_LINUX)
  2428. }
  2429.  
  2430. // Ham Trace Attack Forward
  2431. public fw_TraceAttack(victim, attacker, Float:damage, Float:direction[3], tracehandle, damage_type)
  2432. {
  2433. // Non-player damage or self damage
  2434. if (victim == attacker || !is_user_valid_connected(attacker))
  2435. return HAM_IGNORED;
  2436.  
  2437. // New round starting or round ended
  2438. if (g_newround || g_endround)
  2439. return HAM_SUPERCEDE;
  2440.  
  2441. // Victim shouldn't take damage or victim is frozen
  2442. if (g_nodamage[victim] || g_frozen[victim])
  2443. return HAM_SUPERCEDE;
  2444.  
  2445. // Prevent friendly fire
  2446. if (g_zombie[attacker] == g_zombie[victim])
  2447. return HAM_SUPERCEDE;
  2448.  
  2449. // Victim isn't a zombie or not bullet damage, nothing else to do here
  2450. if (!g_zombie[victim] || !(damage_type & DMG_BULLET))
  2451. return HAM_IGNORED;
  2452.  
  2453. // If zombie hitzones are enabled, check whether we hit an allowed one
  2454. if (get_pcvar_num(cvar_hitzones) && !g_nemesis[victim] && !(get_pcvar_num(cvar_hitzones) & (1<<get_tr2(tracehandle, TR_iHitgroup))))
  2455. return HAM_SUPERCEDE;
  2456.  
  2457. // Knockback disabled, nothing else to do here
  2458. if (!get_pcvar_num(cvar_knockback))
  2459. return HAM_IGNORED;
  2460.  
  2461. // Nemesis knockback disabled, nothing else to do here
  2462. if (g_nemesis[victim] && get_pcvar_float(cvar_nemknockback) == 0.0)
  2463. return HAM_IGNORED;
  2464.  
  2465. // Get whether the victim is in a crouch state
  2466. static ducking
  2467. ducking = pev(victim, pev_flags) & (FL_DUCKING | FL_ONGROUND) == (FL_DUCKING | FL_ONGROUND)
  2468.  
  2469. // Zombie knockback when ducking disabled
  2470. if (ducking && get_pcvar_float(cvar_knockbackducking) == 0.0)
  2471. return HAM_IGNORED;
  2472.  
  2473. // Get distance between players
  2474. static origin1[3], origin2[3]
  2475. get_user_origin(victim, origin1)
  2476. get_user_origin(attacker, origin2)
  2477.  
  2478. // Max distance exceeded
  2479. if (get_distance(origin1, origin2) > get_pcvar_num(cvar_knockbackdist))
  2480. return HAM_IGNORED;
  2481.  
  2482. // Get victim's velocity
  2483. static Float:velocity[3]
  2484. pev(victim, pev_velocity, velocity)
  2485.  
  2486. // Use damage on knockback calculation
  2487. if (get_pcvar_num(cvar_knockbackdamage))
  2488. xs_vec_mul_scalar(direction, damage, direction)
  2489.  
  2490. // Use weapon power on knockback calculation
  2491. if (get_pcvar_num(cvar_knockbackpower) && kb_weapon_power[g_currentweapon[attacker]] > 0.0)
  2492. xs_vec_mul_scalar(direction, kb_weapon_power[g_currentweapon[attacker]], direction)
  2493.  
  2494. // Apply ducking knockback multiplier
  2495. if (ducking)
  2496. xs_vec_mul_scalar(direction, get_pcvar_float(cvar_knockbackducking), direction)
  2497.  
  2498. // Apply zombie class/nemesis knockback multiplier
  2499. if (g_nemesis[victim])
  2500. xs_vec_mul_scalar(direction, get_pcvar_float(cvar_nemknockback), direction)
  2501. else
  2502. xs_vec_mul_scalar(direction, g_zombie_knockback[victim], direction)
  2503.  
  2504. // Add up the new vector
  2505. xs_vec_add(velocity, direction, direction)
  2506.  
  2507. // Should knockback also affect vertical velocity?
  2508. if (!get_pcvar_num(cvar_knockbackzvel))
  2509. direction[2] = velocity[2]
  2510.  
  2511. // Set the knockback'd victim's velocity
  2512. set_pev(victim, pev_velocity, direction)
  2513.  
  2514. return HAM_IGNORED;
  2515. }
  2516.  
  2517. // Ham Use Stationary Gun Forward
  2518. public fw_UseStationary(entity, caller, activator, use_type)
  2519. {
  2520. // Prevent zombies from using stationary guns
  2521. if (use_type == USE_USING && is_user_valid_connected(caller) && g_zombie[caller])
  2522. return HAM_SUPERCEDE;
  2523.  
  2524. return HAM_IGNORED;
  2525. }
  2526.  
  2527. // Ham Use Stationary Gun Post Forward
  2528. public fw_UseStationary_Post(entity, caller, activator, use_type)
  2529. {
  2530. // Someone stopped using a stationary gun
  2531. if (use_type == USE_STOPPED && is_user_valid_connected(caller))
  2532. replace_weapon_models(caller, g_currentweapon[caller]) // replace weapon models (bugfix)
  2533. }
  2534.  
  2535. // Ham Use Pushable Forward
  2536. public fw_UsePushable()
  2537. {
  2538. // Prevent speed bug with pushables?
  2539. if (get_pcvar_num(cvar_blockpushables))
  2540. return HAM_SUPERCEDE;
  2541.  
  2542. return HAM_IGNORED;
  2543. }
  2544.  
  2545. // Ham Weapon Touch Forward
  2546. public fw_TouchWeapon(weapon, id)
  2547. {
  2548. // Not a player
  2549. if (!is_user_valid_connected(id))
  2550. return HAM_IGNORED;
  2551.  
  2552. // Dont pickup weapons if zombie or survivor (+PODBot MM fix)
  2553. if (g_zombie[id] || (g_survivor[id] && !g_isbot[id]))
  2554. return HAM_SUPERCEDE;
  2555.  
  2556. return HAM_IGNORED;
  2557. }
  2558.  
  2559. // Ham Weapon Pickup Forward
  2560. public fw_AddPlayerItem(id, weapon_ent)
  2561. {
  2562. // HACK: Retrieve our custom extra ammo from the weapon
  2563. static extra_ammo
  2564. extra_ammo = pev(weapon_ent, PEV_ADDITIONAL_AMMO)
  2565.  
  2566. // If present
  2567. if (extra_ammo)
  2568. {
  2569. // Get weapon's id
  2570. static weaponid
  2571. weaponid = cs_get_weapon_id(weapon_ent)
  2572.  
  2573. // Add to player's bpammo
  2574. ExecuteHamB(Ham_GiveAmmo, id, extra_ammo, AMMOTYPE[weaponid], MAXBPAMMO[weaponid])
  2575. set_pev(weapon_ent, PEV_ADDITIONAL_AMMO, 0)
  2576. }
  2577. }
  2578.  
  2579. // Ham Weapon Deploy Forward
  2580. public fw_Item_Deploy_Post(weapon_ent)
  2581. {
  2582. // Get weapon's owner
  2583. static owner
  2584. owner = fm_cs_get_weapon_ent_owner(weapon_ent)
  2585.  
  2586. // Get weapon's id
  2587. static weaponid
  2588. weaponid = cs_get_weapon_id(weapon_ent)
  2589.  
  2590. // Store current weapon's id for reference
  2591. g_currentweapon[owner] = weaponid
  2592.  
  2593. // Replace weapon models with custom ones
  2594. replace_weapon_models(owner, weaponid)
  2595.  
  2596. // Zombie not holding an allowed weapon for some reason
  2597. if (g_zombie[owner] && !((1<<weaponid) & ZOMBIE_ALLOWED_WEAPONS_BITSUM))
  2598. {
  2599. // Switch to knife
  2600. g_currentweapon[owner] = CSW_KNIFE
  2601. engclient_cmd(owner, "weapon_knife")
  2602. }
  2603. }
  2604.  
  2605. // WeaponMod bugfix
  2606. //forward wpn_gi_reset_weapon(id);
  2607. public wpn_gi_reset_weapon(id)
  2608. {
  2609. // Replace knife model
  2610. replace_weapon_models(id, CSW_KNIFE)
  2611. }
  2612.  
  2613. // Client joins the game
  2614. public client_putinserver(id)
  2615. {
  2616. // Plugin disabled?
  2617. if (!g_pluginenabled) return;
  2618.  
  2619. // Player joined
  2620. g_isconnected[id] = true
  2621.  
  2622. // Cache player's name
  2623. get_user_name(id, g_playername[id], charsmax(g_playername[]))
  2624.  
  2625. // Initialize player vars
  2626. reset_vars(id, 1)
  2627.  
  2628. // Load player stats?
  2629. if (get_pcvar_num(cvar_statssave)) load_stats(id)
  2630.  
  2631. set_task( 3.0 , "respawn_welcome", id)
  2632.  
  2633. // Set some tasks for humans only
  2634. if (!is_user_bot(id))
  2635. {
  2636. // Set the custom HUD display task
  2637. set_task(1.0, "ShowHUD", id+TASK_SHOWHUD, _, _, "b")
  2638.  
  2639. // Disable minmodels for clients to see zombies properly
  2640. set_task(5.0, "disable_minmodels", id)
  2641. }
  2642. else
  2643. {
  2644. // Set bot flag
  2645. g_isbot[id] = true
  2646.  
  2647. // CZ bots seem to use a different "classtype" for player entities
  2648. // (or something like that) which needs to be hooked separately
  2649. if (!g_hamczbots && cvar_botquota)
  2650. {
  2651. // Set a task to let the private data initialize
  2652. set_task(0.1, "register_ham_czbots", id)
  2653. }
  2654. }
  2655. }
  2656. // Respawn check
  2657. public respawn_welcome(id)
  2658. {
  2659. static team
  2660. team = fm_cs_get_user_team(id)
  2661.  
  2662. if( id )
  2663. {
  2664. if( is_user_connected(id) && !is_user_connecting(id) )
  2665. {
  2666. if (team == FM_CS_TEAM_SPECTATOR || team == FM_CS_TEAM_UNASSIGNED)
  2667. {
  2668. set_task( 1.0 , "respawn_welcome", id)
  2669. }
  2670. else
  2671. {
  2672.  
  2673. set_task( 1.0 , "deadmau5_respawn_now", id)
  2674.  
  2675. }
  2676.  
  2677. }
  2678. else
  2679. {
  2680. set_task( 1.0 , "respawn_welcome", id)
  2681. }
  2682. }
  2683. else
  2684. {
  2685. new iPlayers[32], iNum
  2686. get_players(iPlayers, iNum, "c")
  2687.  
  2688. for(--iNum; iNum>=0; iNum--)
  2689. {
  2690. id = iPlayers[iNum]
  2691.  
  2692. if( !is_user_connecting(id) )
  2693. {
  2694. if (team == FM_CS_TEAM_SPECTATOR || team == FM_CS_TEAM_UNASSIGNED)
  2695. {
  2696. set_task( 1.0 , "respawn_welcome", id)
  2697. }
  2698. else
  2699. {
  2700. set_task( 1.0 , "deadmau5_respawn_now", id)
  2701.  
  2702. }
  2703.  
  2704. }
  2705. else
  2706. {
  2707. set_task( 1.0 , "respawn_welcome", id)
  2708. }
  2709. }
  2710. }
  2711. }
  2712.  
  2713. // Respawn now!
  2714. public deadmau5_respawn_now(id)
  2715. {
  2716.  
  2717. if (!is_user_alive(id))
  2718. {
  2719.  
  2720. if(g_nemround)
  2721. {
  2722. set_task( 7.5 , "deadmau5_welcome_text", id)
  2723. }
  2724. else if(g_survround)
  2725. {
  2726. set_task( 7.5 , "deadmau5_welcome_text", id)
  2727. }
  2728. else if(g_plagueround)
  2729. {
  2730. set_task( 7.5 , "deadmau5_welcome_text", id)
  2731. }
  2732. else
  2733. {
  2734. set_task( 7.5 , "deadmau5_welcome_text", id)
  2735.  
  2736. set_task(5.0, "respawn_player_task", id+TASK_SPAWN)
  2737. }
  2738. }
  2739. }
  2740.  
  2741. public deadmau5_welcome_text(id)
  2742. {
  2743. set_hudmessage(0, 125, 0, -1.0, 0.17, 1, 2.0, 2.0, 4.0, 2.0, -1)
  2744. ShowSyncHudMsg(id, g_MsgSync, "Sky Arena ZM vam zeli ugodnu igru!^n IP Servera: 193.192.59.74:27111")
  2745. }
  2746.  
  2747. // Client leaving
  2748. public fw_ClientDisconnect(id)
  2749. {
  2750. // Check that we still have both humans and zombies to keep the round going
  2751. if (g_isalive[id]) check_round(id)
  2752.  
  2753. // Temporarily save player stats?
  2754. if (get_pcvar_num(cvar_statssave)) save_stats(id)
  2755.  
  2756. // Remove previous tasks
  2757. remove_task(id+TASK_TEAM)
  2758. remove_task(id+TASK_MODEL)
  2759. remove_task(id+TASK_FLASH)
  2760. remove_task(id+TASK_CHARGE)
  2761. remove_task(id+TASK_SPAWN)
  2762. remove_task(id+TASK_BLOOD)
  2763. remove_task(id+TASK_AURA)
  2764. remove_task(id+TASK_BURN)
  2765. remove_task(id+TASK_NVISION)
  2766. remove_task(id+TASK_SHOWHUD)
  2767.  
  2768. if (g_handle_models_on_separate_ent)
  2769. {
  2770. // Remove custom model entities
  2771. fm_remove_model_ents(id)
  2772. }
  2773.  
  2774. // Player left, clear cached flags
  2775. g_isconnected[id] = false
  2776. g_isbot[id] = false
  2777. g_isalive[id] = false
  2778. }
  2779.  
  2780. // Client left
  2781. public fw_ClientDisconnect_Post()
  2782. {
  2783. // Last Zombie Check
  2784. fnCheckLastZombie()
  2785. }
  2786.  
  2787. // Client Kill Forward
  2788. public fw_ClientKill()
  2789. {
  2790. // Prevent players from killing themselves?
  2791. if (get_pcvar_num(cvar_blocksuicide))
  2792. return FMRES_SUPERCEDE;
  2793.  
  2794. return FMRES_IGNORED;
  2795. }
  2796.  
  2797. // Emit Sound Forward
  2798. public fw_EmitSound(id, channel, const sample[], Float:volume, Float:attn, flags, pitch)
  2799. {
  2800. // Block all those unneeeded hostage sounds
  2801. if (sample[0] == 'h' && sample[1] == 'o' && sample[2] == 's' && sample[3] == 't' && sample[4] == 'a' && sample[5] == 'g' && sample[6] == 'e')
  2802. return FMRES_SUPERCEDE;
  2803.  
  2804. // Replace these next sounds for zombies only
  2805. if (!is_user_valid_connected(id) || !g_zombie[id])
  2806. return FMRES_IGNORED;
  2807.  
  2808. static sound[64]
  2809.  
  2810. // Zombie being hit
  2811. if (sample[7] == 'b' && sample[8] == 'h' && sample[9] == 'i' && sample[10] == 't')
  2812. {
  2813. if (g_nemesis[id])
  2814. {
  2815. ArrayGetString(nemesis_pain, random_num(0, ArraySize(nemesis_pain) - 1), sound, charsmax(sound))
  2816. emit_sound(id, channel, sound, volume, attn, flags, pitch)
  2817. }
  2818. else
  2819. {
  2820. ArrayGetString(zombie_pain, random_num(0, ArraySize(zombie_pain) - 1), sound, charsmax(sound))
  2821. emit_sound(id, channel, sound, volume, attn, flags, pitch)
  2822. }
  2823. return FMRES_SUPERCEDE;
  2824. }
  2825.  
  2826. // Zombie attacks with knife
  2827. if (sample[8] == 'k' && sample[9] == 'n' && sample[10] == 'i')
  2828. {
  2829. if (sample[14] == 's' && sample[15] == 'l' && sample[16] == 'a') // slash
  2830. {
  2831. ArrayGetString(zombie_miss_slash, random_num(0, ArraySize(zombie_miss_slash) - 1), sound, charsmax(sound))
  2832. emit_sound(id, channel, sound, volume, attn, flags, pitch)
  2833. return FMRES_SUPERCEDE;
  2834. }
  2835. if (sample[14] == 'h' && sample[15] == 'i' && sample[16] == 't') // hit
  2836. {
  2837. if (sample[17] == 'w') // wall
  2838. {
  2839. ArrayGetString(zombie_miss_wall, random_num(0, ArraySize(zombie_miss_wall) - 1), sound, charsmax(sound))
  2840. emit_sound(id, channel, sound, volume, attn, flags, pitch)
  2841. return FMRES_SUPERCEDE;
  2842. }
  2843. else
  2844. {
  2845. ArrayGetString(zombie_hit_normal, random_num(0, ArraySize(zombie_hit_normal) - 1), sound, charsmax(sound))
  2846. emit_sound(id, channel, sound, volume, attn, flags, pitch)
  2847. return FMRES_SUPERCEDE;
  2848. }
  2849. }
  2850. if (sample[14] == 's' && sample[15] == 't' && sample[16] == 'a') // stab
  2851. {
  2852. ArrayGetString(zombie_hit_stab, random_num(0, ArraySize(zombie_hit_stab) - 1), sound, charsmax(sound))
  2853. emit_sound(id, channel, sound, volume, attn, flags, pitch)
  2854. return FMRES_SUPERCEDE;
  2855. }
  2856. }
  2857.  
  2858. // Zombie dies
  2859. if (sample[7] == 'd' && ((sample[8] == 'i' && sample[9] == 'e') || (sample[8] == 'e' && sample[9] == 'a')))
  2860. {
  2861. ArrayGetString(zombie_die, random_num(0, ArraySize(zombie_die) - 1), sound, charsmax(sound))
  2862. emit_sound(id, channel, sound, volume, attn, flags, pitch)
  2863. return FMRES_SUPERCEDE;
  2864. }
  2865.  
  2866. // Zombie falls off
  2867. if (sample[10] == 'f' && sample[11] == 'a' && sample[12] == 'l' && sample[13] == 'l')
  2868. {
  2869. ArrayGetString(zombie_fall, random_num(0, ArraySize(zombie_fall) - 1), sound, charsmax(sound))
  2870. emit_sound(id, channel, sound, volume, attn, flags, pitch)
  2871. return FMRES_SUPERCEDE;
  2872. }
  2873.  
  2874. return FMRES_IGNORED;
  2875. }
  2876.  
  2877. // Forward Set ClientKey Value -prevent CS from changing player models-
  2878. public fw_SetClientKeyValue(id, const infobuffer[], const key[])
  2879. {
  2880. // Block CS model changes
  2881. if (key[0] == 'm' && key[1] == 'o' && key[2] == 'd' && key[3] == 'e' && key[4] == 'l')
  2882. return FMRES_SUPERCEDE;
  2883.  
  2884. return FMRES_IGNORED;
  2885. }
  2886.  
  2887. // Forward Client User Info Changed -prevent players from changing models-
  2888. public fw_ClientUserInfoChanged(id)
  2889. {
  2890. // Cache player's name
  2891. get_user_name(id, g_playername[id], charsmax(g_playername[]))
  2892.  
  2893. if (!g_handle_models_on_separate_ent)
  2894. {
  2895. // Get current model
  2896. static currentmodel[32]
  2897. fm_cs_get_user_model(id, currentmodel, charsmax(currentmodel))
  2898.  
  2899. // If they're different, set model again
  2900. if (!equal(currentmodel, g_playermodel[id]) && !task_exists(id+TASK_MODEL))
  2901. fm_cs_set_user_model(id+TASK_MODEL)
  2902. }
  2903. }
  2904.  
  2905. // Forward Get Game Description
  2906. public fw_GetGameDescription()
  2907. {
  2908. // Return the mod name so it can be easily identified
  2909. forward_return(FMV_STRING, g_modname)
  2910.  
  2911. return FMRES_SUPERCEDE;
  2912. }
  2913.  
  2914. // Forward Set Model
  2915. public fw_SetModel(entity, const model[])
  2916. {
  2917. // We don't care
  2918. if (strlen(model) < 8)
  2919. return;
  2920.  
  2921. // Remove weapons?
  2922. if (get_pcvar_float(cvar_removedropped) > 0.0)
  2923. {
  2924. // Get entity's classname
  2925. static classname[10]
  2926. pev(entity, pev_classname, classname, charsmax(classname))
  2927.  
  2928. // Check if it's a weapon box
  2929. if (equal(classname, "weaponbox"))
  2930. {
  2931. // They get automatically removed when thinking
  2932. set_pev(entity, pev_nextthink, get_gametime() + get_pcvar_float(cvar_removedropped))
  2933. return;
  2934. }
  2935. }
  2936.  
  2937. // Narrow down our matches a bit
  2938. if (model[7] != 'w' || model[8] != '_')
  2939. return;
  2940.  
  2941. // Get damage time of grenade
  2942. static Float:dmgtime
  2943. pev(entity, pev_dmgtime, dmgtime)
  2944.  
  2945. // Grenade not yet thrown
  2946. if (dmgtime == 0.0)
  2947. return;
  2948.  
  2949. // Get whether grenade's owner is a zombie
  2950. if (g_zombie[pev(entity, pev_owner)])
  2951. {
  2952. if (model[9] == 'h' && model[10] == 'e' && get_pcvar_num(cvar_extrainfbomb)) // Infection Bomb
  2953. {
  2954. // Give it a glow
  2955. fm_set_rendering(entity, kRenderFxGlowShell, 0, 200, 0, kRenderNormal, 16);
  2956.  
  2957. // And a colored trail
  2958. message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
  2959. write_byte(TE_BEAMFOLLOW) // TE id
  2960. write_short(entity) // entity
  2961. write_short(g_trailSpr) // sprite
  2962. write_byte(10) // life
  2963. write_byte(10) // width
  2964. write_byte(0) // r
  2965. write_byte(200) // g
  2966. write_byte(0) // b
  2967. write_byte(200) // brightness
  2968. message_end()
  2969.  
  2970. // Set grenade type on the thrown grenade entity
  2971. set_pev(entity, PEV_NADE_TYPE, NADE_TYPE_INFECTION)
  2972. }
  2973. }
  2974. else if (model[9] == 'h' && model[10] == 'e' && get_pcvar_num(cvar_firegrenades)) // Napalm Grenade
  2975. {
  2976. // Give it a glow
  2977. fm_set_rendering(entity, kRenderFxGlowShell, 200, 0, 0, kRenderNormal, 16);
  2978.  
  2979. // And a colored trail
  2980. message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
  2981. write_byte(TE_BEAMFOLLOW) // TE id
  2982. write_short(entity) // entity
  2983. write_short(g_trailSpr) // sprite
  2984. write_byte(10) // life
  2985. write_byte(10) // width
  2986. write_byte(200) // r
  2987. write_byte(0) // g
  2988. write_byte(0) // b
  2989. write_byte(200) // brightness
  2990. message_end()
  2991.  
  2992. // Set grenade type on the thrown grenade entity
  2993. set_pev(entity, PEV_NADE_TYPE, NADE_TYPE_NAPALM)
  2994. }
  2995. else if (model[9] == 'f' && model[10] == 'l' && get_pcvar_num(cvar_frostgrenades)) // Frost Grenade
  2996. {
  2997. // Give it a glow
  2998. fm_set_rendering(entity, kRenderFxGlowShell, 0, 100, 200, kRenderNormal, 16);
  2999.  
  3000. // And a colored trail
  3001. message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
  3002. write_byte(TE_BEAMFOLLOW) // TE id
  3003. write_short(entity) // entity
  3004. write_short(g_trailSpr) // sprite
  3005. write_byte(10) // life
  3006. write_byte(10) // width
  3007. write_byte(0) // r
  3008. write_byte(100) // g
  3009. write_byte(200) // b
  3010. write_byte(200) // brightness
  3011. message_end()
  3012.  
  3013. // Set grenade type on the thrown grenade entity
  3014. set_pev(entity, PEV_NADE_TYPE, NADE_TYPE_FROST)
  3015. }
  3016. else if (model[9] == 's' && model[10] == 'm' && get_pcvar_num(cvar_flaregrenades)) // Flare
  3017. {
  3018. // Build flare's color
  3019. static rgb[3]
  3020. switch (get_pcvar_num(cvar_flarecolor))
  3021. {
  3022. case 0: // white
  3023. {
  3024. rgb[0] = 255 // r
  3025. rgb[1] = 255 // g
  3026. rgb[2] = 255 // b
  3027. }
  3028. case 1: // red
  3029. {
  3030. rgb[0] = random_num(50,255) // r
  3031. rgb[1] = 0 // g
  3032. rgb[2] = 0 // b
  3033. }
  3034. case 2: // green
  3035. {
  3036. rgb[0] = 0 // r
  3037. rgb[1] = random_num(50,255) // g
  3038. rgb[2] = 0 // b
  3039. }
  3040. case 3: // blue
  3041. {
  3042. rgb[0] = 0 // r
  3043. rgb[1] = 0 // g
  3044. rgb[2] = random_num(50,255) // b
  3045. }
  3046. case 4: // random (all colors)
  3047. {
  3048. rgb[0] = random_num(50,200) // r
  3049. rgb[1] = random_num(50,200) // g
  3050. rgb[2] = random_num(50,200) // b
  3051. }
  3052. case 5: // random (r,g,b)
  3053. {
  3054. switch (random_num(1, 3))
  3055. {
  3056. case 1: // red
  3057. {
  3058. rgb[0] = random_num(50,255) // r
  3059. rgb[1] = 0 // g
  3060. rgb[2] = 0 // b
  3061. }
  3062. case 2: // green
  3063. {
  3064. rgb[0] = 0 // r
  3065. rgb[1] = random_num(50,255) // g
  3066. rgb[2] = 0 // b
  3067. }
  3068. case 3: // blue
  3069. {
  3070. rgb[0] = 0 // r
  3071. rgb[1] = 0 // g
  3072. rgb[2] = random_num(50,255) // b
  3073. }
  3074. }
  3075. }
  3076. }
  3077.  
  3078. // Give it a glow
  3079. fm_set_rendering(entity, kRenderFxGlowShell, rgb[0], rgb[1], rgb[2], kRenderNormal, 16);
  3080.  
  3081. // And a colored trail
  3082. message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
  3083. write_byte(TE_BEAMFOLLOW) // TE id
  3084. write_short(entity) // entity
  3085. write_short(g_trailSpr) // sprite
  3086. write_byte(10) // life
  3087. write_byte(10) // width
  3088. write_byte(rgb[0]) // r
  3089. write_byte(rgb[1]) // g
  3090. write_byte(rgb[2]) // b
  3091. write_byte(200) // brightness
  3092. message_end()
  3093.  
  3094. // Set grenade type on the thrown grenade entity
  3095. set_pev(entity, PEV_NADE_TYPE, NADE_TYPE_FLARE)
  3096.  
  3097. // Set flare color on the thrown grenade entity
  3098. set_pev(entity, PEV_FLARE_COLOR, rgb)
  3099. }
  3100. }
  3101.  
  3102. // Ham Grenade Think Forward
  3103. public fw_ThinkGrenade(entity)
  3104. {
  3105. // Invalid entity
  3106. if (!pev_valid(entity)) return HAM_IGNORED;
  3107.  
  3108. // Get damage time of grenade
  3109. static Float:dmgtime, Float:current_time
  3110. pev(entity, pev_dmgtime, dmgtime)
  3111. current_time = get_gametime()
  3112.  
  3113. // Check if it's time to go off
  3114. if (dmgtime > current_time)
  3115. return HAM_IGNORED;
  3116.  
  3117. // Check if it's one of our custom nades
  3118. switch (pev(entity, PEV_NADE_TYPE))
  3119. {
  3120. case NADE_TYPE_INFECTION: // Infection Bomb
  3121. {
  3122. infection_explode(entity)
  3123. return HAM_SUPERCEDE;
  3124. }
  3125. case NADE_TYPE_NAPALM: // Napalm Grenade
  3126. {
  3127. fire_explode(entity)
  3128. return HAM_SUPERCEDE;
  3129. }
  3130. case NADE_TYPE_FROST: // Frost Grenade
  3131. {
  3132. frost_explode(entity)
  3133. return HAM_SUPERCEDE;
  3134. }
  3135. case NADE_TYPE_FLARE: // Flare
  3136. {
  3137. // Get its duration
  3138. static duration
  3139. duration = pev(entity, PEV_FLARE_DURATION)
  3140.  
  3141. // Already went off, do lighting loop for the duration of PEV_FLARE_DURATION
  3142. if (duration > 0)
  3143. {
  3144. // Check whether this is the last loop
  3145. if (duration == 1)
  3146. {
  3147. // Get rid of the flare entity
  3148. engfunc(EngFunc_RemoveEntity, entity)
  3149. return HAM_SUPERCEDE;
  3150. }
  3151.  
  3152. // Light it up!
  3153. flare_lighting(entity, duration)
  3154.  
  3155. // Set time for next loop
  3156. set_pev(entity, PEV_FLARE_DURATION, --duration)
  3157. set_pev(entity, pev_dmgtime, current_time + 5.0)
  3158. }
  3159. // Light up when it's stopped on ground
  3160. else if ((pev(entity, pev_flags) & FL_ONGROUND) && fm_get_speed(entity) < 10)
  3161. {
  3162. // Flare sound
  3163. static sound[64]
  3164. ArrayGetString(grenade_flare, random_num(0, ArraySize(grenade_flare) - 1), sound, charsmax(sound))
  3165. emit_sound(entity, CHAN_WEAPON, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  3166.  
  3167. // Set duration and start lightning loop on next think
  3168. set_pev(entity, PEV_FLARE_DURATION, 1 + get_pcvar_num(cvar_flareduration)/5)
  3169. set_pev(entity, pev_dmgtime, current_time + 0.1)
  3170. }
  3171. else
  3172. {
  3173. // Delay explosion until we hit ground
  3174. set_pev(entity, pev_dmgtime, current_time + 0.5)
  3175. }
  3176. }
  3177. }
  3178.  
  3179. return HAM_IGNORED;
  3180. }
  3181.  
  3182. // Forward CmdStart
  3183. public fw_CmdStart(id, handle)
  3184. {
  3185. // Not alive
  3186. if (!g_isalive[id])
  3187. return;
  3188.  
  3189. // This logic looks kinda weird, but it should work in theory...
  3190. // p = g_zombie[id], q = g_survivor[id], r = g_cached_customflash
  3191. // ¬(p v q v (¬p ^ r)) <==> ¬p ^ ¬q ^ (p v ¬r)
  3192. if (!g_zombie[id] && !g_survivor[id] && (g_zombie[id] || !g_cached_customflash))
  3193. return;
  3194.  
  3195. // Check if it's a flashlight impulse
  3196. if (get_uc(handle, UC_Impulse) != IMPULSE_FLASHLIGHT)
  3197. return;
  3198.  
  3199. // Block it I say!
  3200. set_uc(handle, UC_Impulse, 0)
  3201.  
  3202. // Should human's custom flashlight be turned on?
  3203. if (!g_zombie[id] && !g_survivor[id] && g_flashbattery[id] > 2 && get_gametime() - g_lastflashtime[id] > 1.2)
  3204. {
  3205. // Prevent calling flashlight too quickly (bugfix)
  3206. g_lastflashtime[id] = get_gametime()
  3207.  
  3208. // Toggle custom flashlight
  3209. g_flashlight[id] = !(g_flashlight[id])
  3210.  
  3211. // Play flashlight toggle sound
  3212. emit_sound(id, CHAN_ITEM, sound_flashlight, 1.0, ATTN_NORM, 0, PITCH_NORM)
  3213.  
  3214. // Update flashlight status on the HUD
  3215. message_begin(MSG_ONE, g_msgFlashlight, _, id)
  3216. write_byte(g_flashlight[id]) // toggle
  3217. write_byte(g_flashbattery[id]) // battery
  3218. message_end()
  3219.  
  3220. // Remove previous tasks
  3221. remove_task(id+TASK_CHARGE)
  3222. remove_task(id+TASK_FLASH)
  3223.  
  3224. // Set the flashlight charge task
  3225. set_task(1.0, "flashlight_charge", id+TASK_CHARGE, _, _, "b")
  3226.  
  3227. // Call our custom flashlight task if enabled
  3228. if (g_flashlight[id]) set_task(0.1, "set_user_flashlight", id+TASK_FLASH, _, _, "b")
  3229. }
  3230. }
  3231.  
  3232. // Forward Player PreThink
  3233. public fw_PlayerPreThink(id)
  3234. {
  3235. // Not alive
  3236. if (!g_isalive[id])
  3237. return;
  3238.  
  3239. // Silent footsteps for zombies?
  3240. if (g_cached_zombiesilent && g_zombie[id] && !g_nemesis[id])
  3241. set_pev(id, pev_flTimeStepSound, STEPTIME_SILENT)
  3242.  
  3243. // Set Player MaxSpeed
  3244. if (g_frozen[id])
  3245. {
  3246. set_pev(id, pev_velocity, Float:{0.0,0.0,0.0}) // stop motion
  3247. set_pev(id, pev_maxspeed, 1.0) // prevent from moving
  3248. return; // shouldn't leap while frozen
  3249. }
  3250. else if (g_freezetime)
  3251. {
  3252. return; // shouldn't leap while in freezetime
  3253. }
  3254. else
  3255. {
  3256. if (g_zombie[id])
  3257. {
  3258. if (g_nemesis[id])
  3259. set_pev(id, pev_maxspeed, g_cached_nemspd)
  3260. else
  3261. set_pev(id, pev_maxspeed, g_zombie_spd[id])
  3262. }
  3263. else
  3264. {
  3265. if (g_survivor[id])
  3266. set_pev(id, pev_maxspeed, g_cached_survspd)
  3267. else
  3268. set_pev(id, pev_maxspeed, g_cached_humanspd)
  3269. }
  3270. }
  3271.  
  3272. // --- Check if player should leap ---
  3273.  
  3274. // Check if proper CVARs are enabled and retrieve leap settings
  3275. static Float:cooldown, Float:current_time
  3276. if (g_zombie[id])
  3277. {
  3278. if (g_nemesis[id])
  3279. {
  3280. if (!g_cached_leapnemesis) return;
  3281. cooldown = g_cached_leapnemesiscooldown
  3282. }
  3283. else
  3284. {
  3285. switch (g_cached_leapzombies)
  3286. {
  3287. case 0: return;
  3288. case 2: if (!g_firstzombie[id]) return;
  3289. case 3: if (!g_lastzombie[id]) return;
  3290. }
  3291. cooldown = g_cached_leapzombiescooldown
  3292. }
  3293. }
  3294. else
  3295. {
  3296. if (g_survivor[id])
  3297. {
  3298. if (!g_cached_leapsurvivor) return;
  3299. cooldown = g_cached_leapsurvivorcooldown
  3300. }
  3301. else return;
  3302. }
  3303.  
  3304. current_time = get_gametime()
  3305.  
  3306. // Cooldown not over yet
  3307. if (current_time - g_lastleaptime[id] < cooldown)
  3308. return;
  3309.  
  3310. // Not doing a longjump (don't perform check for bots, they leap automatically)
  3311. if (!g_isbot[id] && !(pev(id, pev_button) & (IN_JUMP | IN_DUCK) == (IN_JUMP | IN_DUCK)))
  3312. return;
  3313.  
  3314. // Not on ground or not enough speed
  3315. if (!(pev(id, pev_flags) & FL_ONGROUND) || fm_get_speed(id) < 80)
  3316. return;
  3317.  
  3318. static Float:velocity[3]
  3319.  
  3320. // Make velocity vector
  3321. velocity_by_aim(id, g_survivor[id] ? get_pcvar_num(cvar_leapsurvivorforce) : g_nemesis[id] ? get_pcvar_num(cvar_leapnemesisforce) : get_pcvar_num(cvar_leapzombiesforce), velocity)
  3322.  
  3323. // Set custom height
  3324. velocity[2] = g_survivor[id] ? get_pcvar_float(cvar_leapsurvivorheight) : g_nemesis[id] ? get_pcvar_float(cvar_leapnemesisheight) : get_pcvar_float(cvar_leapzombiesheight)
  3325.  
  3326. // Apply the new velocity
  3327. set_pev(id, pev_velocity, velocity)
  3328.  
  3329. // Update last leap time
  3330. g_lastleaptime[id] = current_time
  3331. }
  3332.  
  3333. /*================================================================================
  3334. [Client Commands]
  3335. =================================================================================*/
  3336.  
  3337. // Say "/zpmenu"
  3338. public clcmd_saymenu(id)
  3339. {
  3340. show_menu_game(id) // show game menu
  3341. }
  3342.  
  3343. // Say "/unstuck"
  3344. public clcmd_sayunstuck(id)
  3345. {
  3346. menu_game(id, 3) // try to get unstuck
  3347. }
  3348.  
  3349. // Nightvision toggle
  3350. public clcmd_nightvision(id)
  3351. {
  3352. if (g_nvision[id])
  3353. {
  3354. // Enable-disable
  3355. g_nvisionenabled[id] = !(g_nvisionenabled[id])
  3356.  
  3357. // Custom nvg?
  3358. if (get_pcvar_num(cvar_customnvg))
  3359. {
  3360. remove_task(id+TASK_NVISION)
  3361. if (g_nvisionenabled[id]) set_task(0.1, "set_user_nvision", id+TASK_NVISION, _, _, "b")
  3362. }
  3363. else
  3364. set_user_gnvision(id, g_nvisionenabled[id])
  3365. }
  3366.  
  3367. return PLUGIN_HANDLED;
  3368. }
  3369.  
  3370. // Weapon Drop
  3371. public clcmd_drop(id)
  3372. {
  3373. // Survivor should stick with its weapon
  3374. if (g_survivor[id])
  3375. return PLUGIN_HANDLED;
  3376.  
  3377. return PLUGIN_CONTINUE;
  3378. }
  3379.  
  3380. // Buy BP Ammo
  3381. public clcmd_buyammo(id)
  3382. {
  3383. // Not alive or infinite ammo setting enabled
  3384. if (!g_isalive[id] || get_pcvar_num(cvar_infammo))
  3385. return PLUGIN_HANDLED;
  3386.  
  3387. // Not human
  3388. if (g_zombie[id])
  3389. {
  3390. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_HUMAN_ONLY")
  3391. return PLUGIN_HANDLED;
  3392. }
  3393.  
  3394. // Not enough ammo packs
  3395. if (g_ammopacks[id] < 1)
  3396. {
  3397. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "NOT_ENOUGH_AMMO")
  3398. return PLUGIN_HANDLED;
  3399. }
  3400.  
  3401. // Get user weapons
  3402. static weapons[32], num, i, currentammo, weaponid, refilled
  3403. num = 0 // reset passed weapons count (bugfix)
  3404. refilled = false
  3405. get_user_weapons(id, weapons, num)
  3406.  
  3407. // Loop through them and give the right ammo type
  3408. for (i = 0; i < num; i++)
  3409. {
  3410. // Prevents re-indexing the array
  3411. weaponid = weapons[i]
  3412.  
  3413. // Primary and secondary only
  3414. if (MAXBPAMMO[weaponid] > 2)
  3415. {
  3416. // Get current ammo of the weapon
  3417. currentammo = cs_get_user_bpammo(id, weaponid)
  3418.  
  3419. // Give additional ammo
  3420. ExecuteHamB(Ham_GiveAmmo, id, BUYAMMO[weaponid], AMMOTYPE[weaponid], MAXBPAMMO[weaponid])
  3421.  
  3422. // Check whether we actually refilled the weapon's ammo
  3423. if (cs_get_user_bpammo(id, weaponid) - currentammo > 0) refilled = true
  3424. }
  3425. }
  3426.  
  3427. // Weapons already have full ammo
  3428. if (!refilled) return PLUGIN_HANDLED;
  3429.  
  3430. // Deduce ammo packs, play clip purchase sound, and notify player
  3431. g_ammopacks[id]--
  3432. emit_sound(id, CHAN_ITEM, sound_buyammo, 1.0, ATTN_NORM, 0, PITCH_NORM)
  3433. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "AMMO_BOUGHT")
  3434.  
  3435. return PLUGIN_HANDLED;
  3436. }
  3437.  
  3438. // Block Team Change
  3439. public clcmd_changeteam(id)
  3440. {
  3441. static team
  3442. team = fm_cs_get_user_team(id)
  3443.  
  3444. // Unless it's a spectator joining the game
  3445. if (team == FM_CS_TEAM_SPECTATOR || team == FM_CS_TEAM_UNASSIGNED)
  3446. return PLUGIN_CONTINUE;
  3447.  
  3448. // Pressing 'M' (chooseteam) ingame should show the main menu instead
  3449. show_menu_game(id)
  3450. return PLUGIN_HANDLED;
  3451. }
  3452.  
  3453. /*================================================================================
  3454. [Menus]
  3455. =================================================================================*/
  3456.  
  3457. // Game Menu
  3458. show_menu_game(id)
  3459. {
  3460. static menu[250], len, userflags
  3461. len = 0
  3462. userflags = get_user_flags(id)
  3463.  
  3464. // Title
  3465. len += formatex(menu[len], charsmax(menu) - len, "\r%s^n^n", g_modname)
  3466.  
  3467. // 1. Buy weapons
  3468. if (get_pcvar_num(cvar_buycustom))
  3469. len += formatex(menu[len], charsmax(menu) - len, "\r1.\y %L^n", id, "MENU_BUY")
  3470. else
  3471. len += formatex(menu[len], charsmax(menu) - len, "\d1. %L^n", id, "MENU_BUY")
  3472.  
  3473. // 2. Extra items
  3474. if (get_pcvar_num(cvar_extraitems) && g_isalive[id])
  3475. len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L^n", id, "MENU_EXTRABUY")
  3476. else
  3477. len += formatex(menu[len], charsmax(menu) - len, "\d2. %L^n", id, "MENU_EXTRABUY")
  3478.  
  3479. // 3. Zombie class
  3480. if (get_pcvar_num(cvar_zclasses))
  3481. len += formatex(menu[len], charsmax(menu) - len, "\r3.\r %L^n", id,"MENU_ZCLASS")
  3482. else
  3483. len += formatex(menu[len], charsmax(menu) - len, "\d3. %L^n", id,"MENU_ZCLASS")
  3484.  
  3485. // 4. Unstuck
  3486. if (g_isalive[id])
  3487. len += formatex(menu[len], charsmax(menu) - len, "\r4.\w %L^n", id, "MENU_UNSTUCK")
  3488. else
  3489. len += formatex(menu[len], charsmax(menu) - len, "\d4. %L^n", id, "MENU_UNSTUCK")
  3490.  
  3491. // 5. Help
  3492. len += formatex(menu[len], charsmax(menu) - len, "\r5.\y %L^n^n", id, "MENU_INFO")
  3493.  
  3494. // 6. Join spec
  3495. if (!g_isalive[id] || !get_pcvar_num(cvar_blocksuicide) || (userflags & g_access_flag[ACCESS_ADMIN_MENU]))
  3496. len += formatex(menu[len], charsmax(menu) - len, "\r6.\w %L^n^n", id, "MENU_SPECTATOR")
  3497. else
  3498. len += formatex(menu[len], charsmax(menu) - len, "\d6. %L^n^n", id, "MENU_SPECTATOR")
  3499.  
  3500. //7. Vip menu
  3501. if (g_isalive[id])
  3502. len += formatex(menu[len], charsmax(menu) - len, "\y7.\r VIP Menu^n^n")
  3503. else
  3504. len += formatex(menu[len], charsmax(menu) - len, "\r7.\d VIP Menu^n^n")
  3505.  
  3506. // 9. Admin menu
  3507. if (userflags & g_access_flag[ACCESS_ADMIN_MENU])
  3508. len += formatex(menu[len], charsmax(menu) - len, "\r9.\r %L", id, "MENU_ADMIN")
  3509. else
  3510. len += formatex(menu[len], charsmax(menu) - len, "\d9. %L", id, "MENU_ADMIN")
  3511.  
  3512. // 0. Exit
  3513. len += formatex(menu[len], charsmax(menu) - len, "^n^n\r0.\w %L", id, "MENU_EXIT")
  3514.  
  3515. show_menu(id, KEYSMENU, menu, -1, "Game Menu")
  3516. }
  3517.  
  3518. // Buy Menu 1
  3519. public show_menu_buy1(taskid)
  3520. {
  3521. // Get player's id
  3522. static id
  3523. (taskid > g_maxplayers) ? (id = ID_SPAWN) : (id = taskid);
  3524.  
  3525. // Zombies or survivors get no guns
  3526. if (!g_isalive[id] || g_zombie[id] || g_survivor[id])
  3527. return;
  3528.  
  3529. // Bots pick their weapons randomly / Random weapons setting enabled
  3530. if (get_pcvar_num(cvar_randweapons) || g_isbot[id])
  3531. {
  3532. buy_primary_weapon(id, random_num(0, ArraySize(g_primary_items) - 1))
  3533. menu_buy2(id, random_num(0, ArraySize(g_secondary_items) - 1))
  3534. return;
  3535. }
  3536.  
  3537. // Automatic selection enabled for player and menu called on spawn event
  3538. if (WPN_AUTO_ON && taskid > g_maxplayers)
  3539. {
  3540. buy_primary_weapon(id, WPN_AUTO_PRI)
  3541. menu_buy2(id, WPN_AUTO_SEC)
  3542. return;
  3543. }
  3544.  
  3545. static menu[300], len, weap, maxloops
  3546. len = 0
  3547. maxloops = min(WPN_STARTID+7, WPN_MAXIDS)
  3548.  
  3549. // Title
  3550. len += formatex(menu[len], charsmax(menu) - len, "\y%L \r[%d-%d]^n^n", id, "MENU_BUY1_TITLE", WPN_STARTID+1, min(WPN_STARTID+7, WPN_MAXIDS))
  3551.  
  3552. // 1-7. Weapon List
  3553. for (weap = WPN_STARTID; weap < maxloops; weap++)
  3554. len += formatex(menu[len], charsmax(menu) - len, "\r%d.\w %s^n", weap-WPN_STARTID+1, WEAPONNAMES[ArrayGetCell(g_primary_weaponids, weap)])
  3555.  
  3556. // 8. Auto Select
  3557. len += formatex(menu[len], charsmax(menu) - len, "^n\r8.\w %L \y[%L]", id, "MENU_AUTOSELECT", id, (WPN_AUTO_ON) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  3558.  
  3559. // 9. Next/Back - 0. Exit
  3560. len += formatex(menu[len], charsmax(menu) - len, "^n^n\r9.\w %L/%L^n^n\r0.\w %L", id, "MENU_NEXT", id, "MENU_BACK", id, "MENU_EXIT")
  3561.  
  3562. show_menu(id, KEYSMENU, menu, -1, "Buy Menu 1")
  3563. }
  3564.  
  3565. // Buy Menu 2
  3566. show_menu_buy2(id)
  3567. {
  3568. static menu[250], len, weap, maxloops
  3569. len = 0
  3570. maxloops = ArraySize(g_secondary_items)
  3571.  
  3572. // Title
  3573. len += formatex(menu[len], charsmax(menu) - len, "\y%L^n", id, "MENU_BUY2_TITLE")
  3574.  
  3575. // 1-6. Weapon List
  3576. for (weap = 0; weap < maxloops; weap++)
  3577. len += formatex(menu[len], charsmax(menu) - len, "^n\r%d.\w %s", weap+1, WEAPONNAMES[ArrayGetCell(g_secondary_weaponids, weap)])
  3578.  
  3579. // 8. Auto Select
  3580. len += formatex(menu[len], charsmax(menu) - len, "^n^n\r8.\w %L \y[%L]", id, "MENU_AUTOSELECT", id, (WPN_AUTO_ON) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  3581.  
  3582. // 0. Exit
  3583. len += formatex(menu[len], charsmax(menu) - len, "^n^n\r0.\w %L", id, "MENU_EXIT")
  3584.  
  3585. show_menu(id, KEYSMENU, menu, -1, "Buy Menu 2")
  3586. }
  3587.  
  3588. // Extra Items Menu
  3589. show_menu_extras(id)
  3590. {
  3591. static menuid, menu[128], item, team, buffer[32]
  3592.  
  3593. // Title
  3594. formatex(menu, charsmax(menu), "%L [%L]\r", id, "MENU_EXTRA_TITLE", id, g_zombie[id] ? g_nemesis[id] ? "CLASS_NEMESIS" : "CLASS_ZOMBIE" : g_survivor[id] ? "CLASS_SURVIVOR" : "CLASS_HUMAN")
  3595. menuid = menu_create(menu, "menu_extras")
  3596.  
  3597. // Item List
  3598. for (item = 0; item < g_extraitem_i; item++)
  3599. {
  3600. // Retrieve item's team
  3601. team = ArrayGetCell(g_extraitem_team, item)
  3602.  
  3603. // Item not available to player's team/class
  3604. if ((g_zombie[id] && !g_nemesis[id] && !(team & ZP_TEAM_ZOMBIE)) || (!g_zombie[id] && !g_survivor[id] && !(team & ZP_TEAM_HUMAN)) || (g_nemesis[id] && !(team & ZP_TEAM_NEMESIS)) || (g_survivor[id] && !(team & ZP_TEAM_SURVIVOR)))
  3605. continue;
  3606.  
  3607. // Check if it's one of the hardcoded items, check availability, set translated caption
  3608. switch (item)
  3609. {
  3610. case EXTRA_NVISION:
  3611. {
  3612. if (!get_pcvar_num(cvar_extranvision)) continue;
  3613. formatex(buffer, charsmax(buffer), "%L", id, "MENU_EXTRA1")
  3614. }
  3615. case EXTRA_ANTIDOTE:
  3616. {
  3617. if (!get_pcvar_num(cvar_extraantidote) || g_antidotecounter >= get_pcvar_num(cvar_antidotelimit)) continue;
  3618. formatex(buffer, charsmax(buffer), "%L", id, "MENU_EXTRA2")
  3619. }
  3620. case EXTRA_MADNESS:
  3621. {
  3622. if (!get_pcvar_num(cvar_extramadness) || g_madnesscounter >= get_pcvar_num(cvar_madnesslimit)) continue;
  3623. formatex(buffer, charsmax(buffer), "%L", id, "MENU_EXTRA3")
  3624. }
  3625. case EXTRA_INFBOMB:
  3626. {
  3627. if (!get_pcvar_num(cvar_extrainfbomb) || g_infbombcounter >= get_pcvar_num(cvar_infbomblimit)) continue;
  3628. formatex(buffer, charsmax(buffer), "%L", id, "MENU_EXTRA4")
  3629. }
  3630. default:
  3631. {
  3632. if (item >= EXTRA_WEAPONS_STARTID && item <= EXTRAS_CUSTOM_STARTID-1 && !get_pcvar_num(cvar_extraweapons)) continue;
  3633. ArrayGetString(g_extraitem_name, item, buffer, charsmax(buffer))
  3634. }
  3635. }
  3636.  
  3637. // Add Item Name and Cost
  3638. formatex(menu, charsmax(menu), "%s \y%d %L", buffer, ArrayGetCell(g_extraitem_cost, item), id, "AMMO_PACKS2")
  3639. buffer[0] = item
  3640. buffer[1] = 0
  3641. menu_additem(menuid, menu, buffer)
  3642. }
  3643.  
  3644. // No items to display?
  3645. if (menu_items(menuid) <= 0)
  3646. {
  3647. zp_colored_print(id, "^x04[ZP]^x01 %L", id ,"CMD_NOT_EXTRAS")
  3648. menu_destroy(menuid)
  3649. return;
  3650. }
  3651.  
  3652. // Back - Next - Exit
  3653. formatex(menu, charsmax(menu), "%L", id, "MENU_BACK")
  3654. menu_setprop(menuid, MPROP_BACKNAME, menu)
  3655. formatex(menu, charsmax(menu), "%L", id, "MENU_NEXT")
  3656. menu_setprop(menuid, MPROP_NEXTNAME, menu)
  3657. formatex(menu, charsmax(menu), "%L", id, "MENU_EXIT")
  3658. menu_setprop(menuid, MPROP_EXITNAME, menu)
  3659.  
  3660. menu_display(id, menuid)
  3661. }
  3662.  
  3663. // Zombie Class Menu
  3664. public show_menu_zclass(id)
  3665. {
  3666. // Player disconnected
  3667. if (!g_isconnected[id])
  3668. return;
  3669.  
  3670. // Bots pick their zombie class randomly
  3671. if (g_isbot[id])
  3672. {
  3673. g_zombieclassnext[id] = random_num(0, g_zclass_i - 1)
  3674. return;
  3675. }
  3676.  
  3677. static menuid, menu[128], class, buffer[32], buffer2[32]
  3678.  
  3679. // Title
  3680. formatex(menu, charsmax(menu), "%L\r", id, "MENU_ZCLASS_TITLE")
  3681. menuid = menu_create(menu, "menu_zclass")
  3682.  
  3683. // Class List
  3684. for (class = 0; class < g_zclass_i; class++)
  3685. {
  3686. // Retrieve name and info
  3687. ArrayGetString(g_zclass_name, class, buffer, charsmax(buffer))
  3688. ArrayGetString(g_zclass_info, class, buffer2, charsmax(buffer2))
  3689.  
  3690. // Add to menu
  3691. if (class == g_zombieclassnext[id])
  3692. formatex(menu, charsmax(menu), "\d%s %s", buffer, buffer2)
  3693. else
  3694. formatex(menu, charsmax(menu), "%s \y%s", buffer, buffer2)
  3695.  
  3696. buffer[0] = class
  3697. buffer[1] = 0
  3698. menu_additem(menuid, menu, buffer)
  3699. }
  3700.  
  3701. // Back - Next - Exit
  3702. formatex(menu, charsmax(menu), "%L", id, "MENU_BACK")
  3703. menu_setprop(menuid, MPROP_BACKNAME, menu)
  3704. formatex(menu, charsmax(menu), "%L", id, "MENU_NEXT")
  3705. menu_setprop(menuid, MPROP_NEXTNAME, menu)
  3706. formatex(menu, charsmax(menu), "%L", id, "MENU_EXIT")
  3707. menu_setprop(menuid, MPROP_EXITNAME, menu)
  3708.  
  3709. menu_display(id, menuid)
  3710. }
  3711.  
  3712. // Help Menu
  3713. show_menu_info(id)
  3714. {
  3715. static menu[150]
  3716.  
  3717. formatex(menu, charsmax(menu), "\y%L^n^n\r1.\w %L^n\r2.\w %L^n\r3.\w %L^n\r4.\w %L^n^n\r0.\w %L", id, "MENU_INFO_TITLE", id, "MENU_INFO1", id,"MENU_INFO2", id,"MENU_INFO3", id,"MENU_INFO4", id, "MENU_EXIT")
  3718. show_menu(id, KEYSMENU, menu, -1, "Mod Info")
  3719. }
  3720.  
  3721. // Admin Menu
  3722. show_menu_admin(id)
  3723. {
  3724. static menu[250], len, userflags
  3725. len = 0
  3726. userflags = get_user_flags(id)
  3727.  
  3728. // Title
  3729. len += formatex(menu[len], charsmax(menu) - len, "\y%L^n^n", id, "MENU_ADMIN_TITLE")
  3730.  
  3731. // 1. Zombiefy/Humanize command
  3732. if (userflags & (g_access_flag[ACCESS_MODE_INFECTION] | g_access_flag[ACCESS_MAKE_ZOMBIE] | g_access_flag[ACCESS_MAKE_HUMAN]))
  3733. len += formatex(menu[len], charsmax(menu) - len, "\r1.\w %L^n", id, "MENU_ADMIN1")
  3734. else
  3735. len += formatex(menu[len], charsmax(menu) - len, "\d1. %L^n", id, "MENU_ADMIN1")
  3736.  
  3737. // 2. Nemesis command
  3738. if (userflags & (g_access_flag[ACCESS_MODE_NEMESIS] | g_access_flag[ACCESS_MAKE_NEMESIS]))
  3739. len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L^n", id, "MENU_ADMIN2")
  3740. else
  3741. len += formatex(menu[len], charsmax(menu) - len, "\d2. %L^n", id, "MENU_ADMIN2")
  3742.  
  3743. // 3. Survivor command
  3744. if (userflags & (g_access_flag[ACCESS_MODE_SURVIVOR] | g_access_flag[ACCESS_MAKE_SURVIVOR]))
  3745. len += formatex(menu[len], charsmax(menu) - len, "\r3.\w %L^n", id, "MENU_ADMIN3")
  3746. else
  3747. len += formatex(menu[len], charsmax(menu) - len, "\d3. %L^n", id, "MENU_ADMIN3")
  3748.  
  3749. // 4. Respawn command
  3750. if (userflags & g_access_flag[ACCESS_RESPAWN_PLAYERS])
  3751. len += formatex(menu[len], charsmax(menu) - len, "\r4.\w %L^n", id, "MENU_ADMIN4")
  3752. else
  3753. len += formatex(menu[len], charsmax(menu) - len, "\d4. %L^n", id, "MENU_ADMIN4")
  3754.  
  3755. // 5. Swarm mode command
  3756. if ((userflags & g_access_flag[ACCESS_MODE_SWARM]) && allowed_swarm())
  3757. len += formatex(menu[len], charsmax(menu) - len, "\r5.\w %L^n", id, "MENU_ADMIN5")
  3758. else
  3759. len += formatex(menu[len], charsmax(menu) - len, "\d5. %L^n", id, "MENU_ADMIN5")
  3760.  
  3761. // 6. Multi infection command
  3762. if ((userflags & g_access_flag[ACCESS_MODE_MULTI]) && allowed_multi())
  3763. len += formatex(menu[len], charsmax(menu) - len, "\r6.\w %L^n", id, "MENU_ADMIN6")
  3764. else
  3765. len += formatex(menu[len], charsmax(menu) - len, "\d6. %L^n", id, "MENU_ADMIN6")
  3766.  
  3767. // 7. Plague mode command
  3768. if ((userflags & g_access_flag[ACCESS_MODE_PLAGUE]) && allowed_plague())
  3769. len += formatex(menu[len], charsmax(menu) - len, "\r7.\w %L^n", id, "MENU_ADMIN7")
  3770. else
  3771. len += formatex(menu[len], charsmax(menu) - len, "\d7. %L^n", id, "MENU_ADMIN7")
  3772.  
  3773. // 0. Exit
  3774. len += formatex(menu[len], charsmax(menu) - len, "^n\r0.\w %L", id, "MENU_EXIT")
  3775.  
  3776. show_menu(id, KEYSMENU, menu, -1, "Admin Menu")
  3777. }
  3778.  
  3779. // Player List Menu
  3780. show_menu_player_list(id)
  3781. {
  3782. static menuid, menu[128], player, userflags, buffer[2]
  3783. userflags = get_user_flags(id)
  3784.  
  3785. // Title
  3786. switch (PL_ACTION)
  3787. {
  3788. case ACTION_ZOMBIEFY_HUMANIZE: formatex(menu, charsmax(menu), "%L\r", id, "MENU_ADMIN1")
  3789. case ACTION_MAKE_NEMESIS: formatex(menu, charsmax(menu), "%L\r", id, "MENU_ADMIN2")
  3790. case ACTION_MAKE_SURVIVOR: formatex(menu, charsmax(menu), "%L\r", id, "MENU_ADMIN3")
  3791. case ACTION_RESPAWN_PLAYER: formatex(menu, charsmax(menu), "%L\r", id, "MENU_ADMIN4")
  3792. }
  3793. menuid = menu_create(menu, "menu_player_list")
  3794.  
  3795. // Player List
  3796. for (player = 0; player <= g_maxplayers; player++)
  3797. {
  3798. // Skip if not connected
  3799. if (!g_isconnected[player])
  3800. continue;
  3801.  
  3802. // Format text depending on the action to take
  3803. switch (PL_ACTION)
  3804. {
  3805. case ACTION_ZOMBIEFY_HUMANIZE: // Zombiefy/Humanize command
  3806. {
  3807. if (g_zombie[player])
  3808. {
  3809. if (allowed_human(player) && (userflags & g_access_flag[ACCESS_MAKE_HUMAN]))
  3810. formatex(menu, charsmax(menu), "%s \r[%L]", g_playername[player], id, g_nemesis[player] ? "CLASS_NEMESIS" : "CLASS_ZOMBIE")
  3811. else
  3812. formatex(menu, charsmax(menu), "\d%s [%L]", g_playername[player], id, g_nemesis[player] ? "CLASS_NEMESIS" : "CLASS_ZOMBIE")
  3813. }
  3814. else
  3815. {
  3816. if (allowed_zombie(player) && (g_newround ? (userflags & g_access_flag[ACCESS_MODE_INFECTION]) : (userflags & g_access_flag[ACCESS_MAKE_ZOMBIE])))
  3817. formatex(menu, charsmax(menu), "%s \y[%L]", g_playername[player], id, g_survivor[player] ? "CLASS_SURVIVOR" : "CLASS_HUMAN")
  3818. else
  3819. formatex(menu, charsmax(menu), "\d%s [%L]", g_playername[player], id, g_survivor[player] ? "CLASS_SURVIVOR" : "CLASS_HUMAN")
  3820. }
  3821. }
  3822. case ACTION_MAKE_NEMESIS: // Nemesis command
  3823. {
  3824. if (allowed_nemesis(player) && (g_newround ? (userflags & g_access_flag[ACCESS_MODE_NEMESIS]) : (userflags & g_access_flag[ACCESS_MAKE_NEMESIS])))
  3825. {
  3826. if (g_zombie[player])
  3827. formatex(menu, charsmax(menu), "%s \r[%L]", g_playername[player], id, g_nemesis[player] ? "CLASS_NEMESIS" : "CLASS_ZOMBIE")
  3828. else
  3829. formatex(menu, charsmax(menu), "%s \y[%L]", g_playername[player], id, g_survivor[player] ? "CLASS_SURVIVOR" : "CLASS_HUMAN")
  3830. }
  3831. else
  3832. formatex(menu, charsmax(menu), "\d%s [%L]", g_playername[player], id, g_zombie[player] ? g_nemesis[player] ? "CLASS_NEMESIS" : "CLASS_ZOMBIE" : g_survivor[player] ? "CLASS_SURVIVOR" : "CLASS_HUMAN")
  3833. }
  3834. case ACTION_MAKE_SURVIVOR: // Survivor command
  3835. {
  3836. if (allowed_survivor(player) && (g_newround ? (userflags & g_access_flag[ACCESS_MODE_SURVIVOR]) : (userflags & g_access_flag[ACCESS_MAKE_SURVIVOR])))
  3837. {
  3838. if (g_zombie[player])
  3839. formatex(menu, charsmax(menu), "%s \r[%L]", g_playername[player], id, g_nemesis[player] ? "CLASS_NEMESIS" : "CLASS_ZOMBIE")
  3840. else
  3841. formatex(menu, charsmax(menu), "%s \y[%L]", g_playername[player], id, g_survivor[player] ? "CLASS_SURVIVOR" : "CLASS_HUMAN")
  3842. }
  3843. else
  3844. formatex(menu, charsmax(menu), "\d%s [%L]", g_playername[player], id, g_zombie[player] ? g_nemesis[player] ? "CLASS_NEMESIS" : "CLASS_ZOMBIE" : g_survivor[player] ? "CLASS_SURVIVOR" : "CLASS_HUMAN")
  3845. }
  3846. case ACTION_RESPAWN_PLAYER: // Respawn command
  3847. {
  3848. if (allowed_respawn(player) && (userflags & g_access_flag[ACCESS_RESPAWN_PLAYERS]))
  3849. formatex(menu, charsmax(menu), "%s", g_playername[player])
  3850. else
  3851. formatex(menu, charsmax(menu), "\d%s", g_playername[player])
  3852. }
  3853. }
  3854.  
  3855. // Add player
  3856. buffer[0] = player
  3857. buffer[1] = 0
  3858. menu_additem(menuid, menu, buffer)
  3859. }
  3860.  
  3861. // Back - Next - Exit
  3862. formatex(menu, charsmax(menu), "%L", id, "MENU_BACK")
  3863. menu_setprop(menuid, MPROP_BACKNAME, menu)
  3864. formatex(menu, charsmax(menu), "%L", id, "MENU_NEXT")
  3865. menu_setprop(menuid, MPROP_NEXTNAME, menu)
  3866. formatex(menu, charsmax(menu), "%L", id, "MENU_EXIT")
  3867. menu_setprop(menuid, MPROP_EXITNAME, menu)
  3868.  
  3869. menu_display(id, menuid)
  3870. }
  3871.  
  3872. /*================================================================================
  3873. [Menu Handlers]
  3874. =================================================================================*/
  3875.  
  3876. // Game Menu
  3877. public menu_game(id, key)
  3878. {
  3879. switch (key)
  3880. {
  3881. case 0: // Buy Weapons
  3882. {
  3883. // Custom buy menus enabled?
  3884. if (get_pcvar_num(cvar_buycustom))
  3885. {
  3886. // Disable the remember selection setting
  3887. WPN_AUTO_ON = 0
  3888. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "BUY_ENABLED")
  3889.  
  3890. // Show menu if player hasn't yet bought anything
  3891. if (g_canbuy[id]) show_menu_buy1(id)
  3892. }
  3893. else
  3894. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")
  3895. }
  3896. case 1: // Extra Items
  3897. {
  3898. // Extra items enabled?
  3899. if (get_pcvar_num(cvar_extraitems))
  3900. {
  3901. // Check whether the player is able to buy anything
  3902. if (g_isalive[id])
  3903. show_menu_extras(id)
  3904. else
  3905. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")
  3906. }
  3907. else
  3908. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_EXTRAS")
  3909. }
  3910. case 2: // Zombie Classes
  3911. {
  3912. // Zombie classes enabled?
  3913. if (get_pcvar_num(cvar_zclasses))
  3914. show_menu_zclass(id)
  3915. else
  3916. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ZCLASSES")
  3917. }
  3918. case 3: // Unstuck
  3919. {
  3920. // Check if player is stuck
  3921. if (g_isalive[id])
  3922. {
  3923. if (is_player_stuck(id))
  3924. {
  3925. // Move to an initial spawn
  3926. if (get_pcvar_num(cvar_randspawn))
  3927. do_random_spawn(id) // random spawn (including CSDM)
  3928. else
  3929. do_random_spawn(id, 1) // regular spawn
  3930. }
  3931. else
  3932. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_STUCK")
  3933. }
  3934. else
  3935. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")
  3936. }
  3937. case 4: // Help Menu
  3938. {
  3939. show_menu_info(id)
  3940. }
  3941. case 5: // Join Spectator
  3942. {
  3943. // Player alive?
  3944. if (g_isalive[id])
  3945. {
  3946. // Prevent abuse by non-admins if block suicide setting is enabled
  3947. if (get_pcvar_num(cvar_blocksuicide) && !(get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MENU]))
  3948. {
  3949. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")
  3950. return PLUGIN_HANDLED;
  3951. }
  3952.  
  3953. // Check that we still have both humans and zombies to keep the round going
  3954. check_round(id)
  3955.  
  3956. // Kill him before he switches team
  3957. dllfunc(DLLFunc_ClientKill, id)
  3958. }
  3959.  
  3960. // Temporarily save player stats?
  3961. if (get_pcvar_num(cvar_statssave)) save_stats(id)
  3962.  
  3963. // Remove previous tasks
  3964. remove_task(id+TASK_TEAM)
  3965. remove_task(id+TASK_MODEL)
  3966. remove_task(id+TASK_FLASH)
  3967. remove_task(id+TASK_CHARGE)
  3968. remove_task(id+TASK_SPAWN)
  3969. remove_task(id+TASK_BLOOD)
  3970. remove_task(id+TASK_AURA)
  3971. remove_task(id+TASK_BURN)
  3972.  
  3973. // Then move him to the spectator team
  3974. fm_cs_set_user_team(id, FM_CS_TEAM_SPECTATOR)
  3975. fm_user_team_update(id)
  3976.  
  3977. }
  3978. case 6: {
  3979. if (g_isalive[id])
  3980. client_cmd(id, "say /vm"); // VIP menu
  3981. else
  3982. zp_colored_print(id, "^x03[VIP Menu]^x01 %L", id, "CMD_NOT")
  3983. }
  3984. case 8: // Admin Menu
  3985. {
  3986. // Check if player has the required access
  3987. if (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MENU])
  3988. show_menu_admin(id)
  3989. else
  3990. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")
  3991. }
  3992. }
  3993.  
  3994. return PLUGIN_HANDLED;
  3995. }
  3996.  
  3997. // Buy Menu 1
  3998. public menu_buy1(id, key)
  3999. {
  4000. // Zombies or survivors get no guns
  4001. if (!g_isalive[id] || g_zombie[id] || g_survivor[id])
  4002. return PLUGIN_HANDLED;
  4003.  
  4004. // Special keys / weapon list exceeded
  4005. if (key >= MENU_KEY_AUTOSELECT || WPN_SELECTION >= WPN_MAXIDS)
  4006. {
  4007. switch (key)
  4008. {
  4009. case MENU_KEY_AUTOSELECT: // toggle auto select
  4010. {
  4011. WPN_AUTO_ON = 1 - WPN_AUTO_ON
  4012. }
  4013. case MENU_KEY_NEXT: // next/back
  4014. {
  4015. if (WPN_STARTID+7 < WPN_MAXIDS)
  4016. WPN_STARTID += 7
  4017. else
  4018. WPN_STARTID = 0
  4019. }
  4020. case MENU_KEY_EXIT: // exit
  4021. {
  4022. return PLUGIN_HANDLED;
  4023. }
  4024. }
  4025.  
  4026. // Show buy menu again
  4027. show_menu_buy1(id)
  4028. return PLUGIN_HANDLED;
  4029. }
  4030.  
  4031. // Store selected weapon id
  4032. WPN_AUTO_PRI = WPN_SELECTION
  4033.  
  4034. // Buy primary weapon
  4035. buy_primary_weapon(id, WPN_AUTO_PRI)
  4036.  
  4037. // Show pistols menu
  4038. show_menu_buy2(id)
  4039.  
  4040. return PLUGIN_HANDLED;
  4041. }
  4042.  
  4043. // Buy Primary Weapon
  4044. buy_primary_weapon(id, selection)
  4045. {
  4046. // Drop previous weapons
  4047. drop_weapons(id, 1)
  4048. drop_weapons(id, 2)
  4049.  
  4050. // Strip off from weapons
  4051. fm_strip_user_weapons(id)
  4052. fm_give_item(id, "weapon_knife")
  4053.  
  4054. // Get weapon's id and name
  4055. static weaponid, wname[32]
  4056. weaponid = ArrayGetCell(g_primary_weaponids, selection)
  4057. ArrayGetString(g_primary_items, selection, wname, charsmax(wname))
  4058.  
  4059. // Give the new weapon and full ammo
  4060. fm_give_item(id, wname)
  4061. ExecuteHamB(Ham_GiveAmmo, id, MAXBPAMMO[weaponid], AMMOTYPE[weaponid], MAXBPAMMO[weaponid])
  4062.  
  4063. // Weapons bought
  4064. g_canbuy[id] = false
  4065.  
  4066. // Give additional items
  4067. static i
  4068. for (i = 0; i < ArraySize(g_additional_items); i++)
  4069. {
  4070. ArrayGetString(g_additional_items, i, wname, charsmax(wname))
  4071. fm_give_item(id, wname)
  4072. }
  4073. }
  4074.  
  4075. // Buy Menu 2
  4076. public menu_buy2(id, key)
  4077. {
  4078. // Zombies or survivors get no guns
  4079. if (!g_isalive[id] || g_zombie[id] || g_survivor[id])
  4080. return PLUGIN_HANDLED;
  4081.  
  4082. // Special keys / weapon list exceeded
  4083. if (key >= ArraySize(g_secondary_items))
  4084. {
  4085. // Toggle autoselect
  4086. if (key == MENU_KEY_AUTOSELECT)
  4087. WPN_AUTO_ON = 1 - WPN_AUTO_ON
  4088.  
  4089. // Reshow menu unless user exited
  4090. if (key != MENU_KEY_EXIT)
  4091. show_menu_buy2(id)
  4092.  
  4093. return PLUGIN_HANDLED;
  4094. }
  4095.  
  4096. // Store selected weapon
  4097. WPN_AUTO_SEC = key
  4098.  
  4099. // Drop secondary gun again, in case we picked another (bugfix)
  4100. drop_weapons(id, 2)
  4101.  
  4102. // Get weapon's id
  4103. static weaponid, wname[32]
  4104. weaponid = ArrayGetCell(g_secondary_weaponids, key)
  4105. ArrayGetString(g_secondary_items, key, wname, charsmax(wname))
  4106.  
  4107. // Give the new weapon and full ammo
  4108. fm_give_item(id, wname)
  4109. ExecuteHamB(Ham_GiveAmmo, id, MAXBPAMMO[weaponid], AMMOTYPE[weaponid], MAXBPAMMO[weaponid])
  4110.  
  4111. return PLUGIN_HANDLED;
  4112. }
  4113.  
  4114. // Extra Items Menu
  4115. public menu_extras(id, menuid, item)
  4116. {
  4117. // Menu was closed
  4118. if (item == MENU_EXIT)
  4119. {
  4120. menu_destroy(menuid)
  4121. return PLUGIN_HANDLED;
  4122. }
  4123.  
  4124. // Dead players are not allowed to buy items
  4125. if (!g_isalive[id])
  4126. {
  4127. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")
  4128. menu_destroy(menuid)
  4129. return PLUGIN_HANDLED;
  4130. }
  4131.  
  4132. // Retrieve extra item id
  4133. static buffer[2], dummy, itemid
  4134. menu_item_getinfo(menuid, item, dummy, buffer, charsmax(buffer), _, _, dummy)
  4135. itemid = buffer[0]
  4136.  
  4137. // Attempt to buy the item
  4138. buy_extra_item(id, itemid)
  4139. menu_destroy(menuid)
  4140. return PLUGIN_HANDLED;
  4141. }
  4142.  
  4143. // Buy Extra Item
  4144. buy_extra_item(id, itemid, ignorecost = 0)
  4145. {
  4146. // Retrieve item's team
  4147. static team
  4148. team = ArrayGetCell(g_extraitem_team, itemid)
  4149.  
  4150. // Check for team/class specific items
  4151. if ((g_zombie[id] && !g_nemesis[id] && !(team & ZP_TEAM_ZOMBIE)) || (!g_zombie[id] && !g_survivor[id] && !(team & ZP_TEAM_HUMAN)) || (g_nemesis[id] && !(team & ZP_TEAM_NEMESIS)) || (g_survivor[id] && !(team & ZP_TEAM_SURVIVOR)))
  4152. {
  4153. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")
  4154. return;
  4155. }
  4156.  
  4157. // Check for unavailable items
  4158. if ((itemid == EXTRA_NVISION && !get_pcvar_num(cvar_extranvision))
  4159. || (itemid == EXTRA_ANTIDOTE && (!get_pcvar_num(cvar_extraantidote) || g_antidotecounter >= get_pcvar_num(cvar_antidotelimit)))
  4160. || (itemid == EXTRA_MADNESS && (!get_pcvar_num(cvar_extramadness) || g_madnesscounter >= get_pcvar_num(cvar_madnesslimit)))
  4161. || (itemid == EXTRA_INFBOMB && (!get_pcvar_num(cvar_extrainfbomb) || g_infbombcounter >= get_pcvar_num(cvar_infbomblimit)))
  4162. || (itemid >= EXTRA_WEAPONS_STARTID && itemid <= EXTRAS_CUSTOM_STARTID-1 && !get_pcvar_num(cvar_extraweapons)))
  4163. {
  4164. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")
  4165. return;
  4166. }
  4167.  
  4168. // Check for hard coded items with special conditions
  4169. if ((itemid == EXTRA_ANTIDOTE && (g_endround || g_swarmround || g_nemround || g_survround || g_plagueround || fnGetZombies() <= 1 || (get_pcvar_num(cvar_deathmatch) && !get_pcvar_num(cvar_respawnafterlast) && fnGetHumans() == 1)))
  4170. || (itemid == EXTRA_MADNESS && g_nodamage[id]) || (itemid == EXTRA_INFBOMB && (g_endround || g_swarmround || g_nemround || g_survround || g_plagueround)))
  4171. {
  4172. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_CANTUSE")
  4173. return;
  4174. }
  4175.  
  4176. // Ignore item's cost?
  4177. if (!ignorecost)
  4178. {
  4179. // Check that we have enough ammo packs
  4180. if (g_ammopacks[id] < ArrayGetCell(g_extraitem_cost, itemid))
  4181. {
  4182. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "NOT_ENOUGH_AMMO")
  4183. return;
  4184. }
  4185.  
  4186. // Deduce item cost
  4187. g_ammopacks[id] -= ArrayGetCell(g_extraitem_cost, itemid)
  4188. }
  4189.  
  4190. // Check which kind of item we're buying
  4191. switch (itemid)
  4192. {
  4193. case EXTRA_NVISION: // Night Vision
  4194. {
  4195. g_nvision[id] = true
  4196.  
  4197. if (!g_isbot[id])
  4198. {
  4199. g_nvisionenabled[id] = true
  4200.  
  4201. // Custom nvg?
  4202. if (get_pcvar_num(cvar_customnvg))
  4203. {
  4204. remove_task(id+TASK_NVISION)
  4205. set_task(0.1, "set_user_nvision", id+TASK_NVISION, _, _, "b")
  4206. }
  4207. else
  4208. set_user_gnvision(id, 1)
  4209. }
  4210. else
  4211. cs_set_user_nvg(id, 1)
  4212. }
  4213. case EXTRA_ANTIDOTE: // Antidote
  4214. {
  4215. // Increase antidote purchase count for this round
  4216. g_antidotecounter++
  4217.  
  4218. humanme(id, 0, 0)
  4219. }
  4220. case EXTRA_MADNESS: // Zombie Madness
  4221. {
  4222. // Increase madness purchase count for this round
  4223. g_madnesscounter++
  4224.  
  4225. g_nodamage[id] = true
  4226. set_task(0.1, "zombie_aura", id+TASK_AURA, _, _, "b")
  4227. set_task(get_pcvar_float(cvar_madnessduration), "madness_over", id+TASK_BLOOD)
  4228.  
  4229. static sound[64]
  4230. ArrayGetString(zombie_madness, random_num(0, ArraySize(zombie_madness) - 1), sound, charsmax(sound))
  4231. emit_sound(id, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  4232. }
  4233. case EXTRA_INFBOMB: // Infection Bomb
  4234. {
  4235. // Increase infection bomb purchase count for this round
  4236. g_infbombcounter++
  4237.  
  4238. // Already own one
  4239. if (user_has_weapon(id, CSW_HEGRENADE))
  4240. {
  4241. // Increase BP ammo on it instead
  4242. cs_set_user_bpammo(id, CSW_HEGRENADE, cs_get_user_bpammo(id, CSW_HEGRENADE) + 1)
  4243.  
  4244. // Flash ammo in hud
  4245. message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoPickup, _, id)
  4246. write_byte(AMMOID[CSW_HEGRENADE]) // ammo id
  4247. write_byte(1) // ammo amount
  4248. message_end()
  4249.  
  4250. // Play clip purchase sound
  4251. emit_sound(id, CHAN_ITEM, sound_buyammo, 1.0, ATTN_NORM, 0, PITCH_NORM)
  4252.  
  4253. return; // stop here
  4254. }
  4255.  
  4256. // Give weapon to the player
  4257. fm_give_item(id, "weapon_hegrenade")
  4258. }
  4259. default:
  4260. {
  4261. if (itemid >= EXTRA_WEAPONS_STARTID && itemid <= EXTRAS_CUSTOM_STARTID-1) // Weapons
  4262. {
  4263. // Get weapon's id and name
  4264. static weaponid, wname[32]
  4265. ArrayGetString(g_extraweapon_items, itemid - EXTRA_WEAPONS_STARTID, wname, charsmax(wname))
  4266. weaponid = cs_weapon_name_to_id(wname)
  4267.  
  4268. // If we are giving a primary/secondary weapon
  4269. if (MAXBPAMMO[weaponid] > 2)
  4270. {
  4271. // Make user drop the previous one
  4272. if ((1<<weaponid) & PRIMARY_WEAPONS_BIT_SUM)
  4273. drop_weapons(id, 1)
  4274. else
  4275. drop_weapons(id, 2)
  4276.  
  4277. // Give full BP ammo for the new one
  4278. ExecuteHamB(Ham_GiveAmmo, id, MAXBPAMMO[weaponid], AMMOTYPE[weaponid], MAXBPAMMO[weaponid])
  4279. }
  4280. // If we are giving a grenade which the user already owns
  4281. else if (user_has_weapon(id, weaponid))
  4282. {
  4283. // Increase BP ammo on it instead
  4284. cs_set_user_bpammo(id, weaponid, cs_get_user_bpammo(id, weaponid) + 1)
  4285.  
  4286. // Flash ammo in hud
  4287. message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoPickup, _, id)
  4288. write_byte(AMMOID[weaponid]) // ammo id
  4289. write_byte(1) // ammo amount
  4290. message_end()
  4291.  
  4292. // Play clip purchase sound
  4293. emit_sound(id, CHAN_ITEM, sound_buyammo, 1.0, ATTN_NORM, 0, PITCH_NORM)
  4294.  
  4295. return; // stop here
  4296. }
  4297.  
  4298. // Give weapon to the player
  4299. fm_give_item(id, wname)
  4300. }
  4301. else // Custom additions
  4302. {
  4303. // Item selected forward
  4304. ExecuteForward(g_fwExtraItemSelected, g_fwDummyResult, id, itemid);
  4305.  
  4306. // Item purchase blocked, restore buyer's ammo packs
  4307. if (g_fwDummyResult >= ZP_PLUGIN_HANDLED && !ignorecost)
  4308. g_ammopacks[id] += ArrayGetCell(g_extraitem_cost, itemid)
  4309. }
  4310. }
  4311. }
  4312. }
  4313.  
  4314. // Zombie Class Menu
  4315. public menu_zclass(id, menuid, item)
  4316. {
  4317. // Menu was closed
  4318. if (item == MENU_EXIT)
  4319. {
  4320. menu_destroy(menuid)
  4321. return PLUGIN_HANDLED;
  4322. }
  4323.  
  4324. // Retrieve zombie class id
  4325. static buffer[2], dummy, classid
  4326. menu_item_getinfo(menuid, item, dummy, buffer, charsmax(buffer), _, _, dummy)
  4327. classid = buffer[0]
  4328.  
  4329. // Store selection for the next infection
  4330. g_zombieclassnext[id] = classid
  4331.  
  4332. static name[32]
  4333. ArrayGetString(g_zclass_name, g_zombieclassnext[id], name, charsmax(name))
  4334.  
  4335. // Show selected zombie class info and stats
  4336. zp_colored_print(id, "^x04[ZP]^x01 %L: %s", id, "ZOMBIE_SELECT", name)
  4337. zp_colored_print(id, "^x04[ZP]^x01 %L: %d %L: %d %L: %d %L: %d%%", id, "ZOMBIE_ATTRIB1", ArrayGetCell(g_zclass_hp, g_zombieclassnext[id]), id, "ZOMBIE_ATTRIB2", ArrayGetCell(g_zclass_spd, g_zombieclassnext[id]),
  4338. id, "ZOMBIE_ATTRIB3", floatround(Float:ArrayGetCell(g_zclass_grav, g_zombieclassnext[id]) * 800.0), id, "ZOMBIE_ATTRIB4", floatround(Float:ArrayGetCell(g_zclass_kb, g_zombieclassnext[id]) * 100.0))
  4339.  
  4340. menu_destroy(menuid)
  4341. return PLUGIN_HANDLED;
  4342. }
  4343.  
  4344. // Info Menu
  4345. public menu_info(id, key)
  4346. {
  4347. static motd[1500], len
  4348. len = 0
  4349.  
  4350. switch (key)
  4351. {
  4352. case 0: // General
  4353. {
  4354. static weather, lighting[2]
  4355. weather = 0
  4356. get_pcvar_string(cvar_lighting, lighting, charsmax(lighting))
  4357. strtolower(lighting)
  4358.  
  4359. len += formatex(motd[len], charsmax(motd) - len, "%L ", id, "MOTD_INFO11", "Zombie Plague", PLUGIN_VERSION, "MeRcyLeZZ")
  4360. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO12")
  4361. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_A")
  4362.  
  4363. if (g_ambience_fog)
  4364. {
  4365. len += formatex(motd[len], charsmax(motd) - len, (weather < 1) ? " %L" : ". %L", id, "MOTD_FOG")
  4366. weather++
  4367. }
  4368. if (g_ambience_rain)
  4369. {
  4370. len += formatex(motd[len], charsmax(motd) - len, (weather < 1) ? " %L" : ". %L", id, "MOTD_RAIN")
  4371. weather++
  4372. }
  4373. if (g_ambience_snow)
  4374. {
  4375. len += formatex(motd[len], charsmax(motd) - len, (weather < 1) ? " %L" : ". %L", id, "MOTD_SNOW")
  4376. weather++
  4377. }
  4378. if (weather < 1) len += formatex(motd[len], charsmax(motd) - len, " %L", id, "MOTD_DISABLED")
  4379.  
  4380. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_B", lighting)
  4381. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_C", id, get_pcvar_num(cvar_triggered) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4382. if (lighting[0] >= 'a' && lighting[0] <= 'd' && get_pcvar_float(cvar_thunder) > 0.0) len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_D", floatround(get_pcvar_float(cvar_thunder)))
  4383. len += formatex(motd[len], charsmax(motd) - 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")
  4384. len += formatex(motd[len], charsmax(motd) - 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")
  4385. if (get_pcvar_num(cvar_deathmatch)) len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_G", floatround(get_pcvar_float(cvar_spawnprotection)))
  4386. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_H", id, get_pcvar_num(cvar_randspawn) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4387. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_I", id, get_pcvar_num(cvar_extraitems) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4388. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_J", id, get_pcvar_num(cvar_zclasses) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4389. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_K", id, get_pcvar_num(cvar_customnvg) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4390. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_L", id, g_cached_customflash ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4391.  
  4392. show_motd(id, motd)
  4393. }
  4394. case 1: // Humans
  4395. {
  4396. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2")
  4397. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_A", get_pcvar_num(cvar_humanhp))
  4398. if (get_pcvar_num(cvar_humanlasthp) > 0) len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_B", get_pcvar_num(cvar_humanlasthp))
  4399. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_C", floatround(g_cached_humanspd))
  4400. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_D", floatround(get_pcvar_float(cvar_humangravity) * 800.0))
  4401. len += formatex(motd[len], charsmax(motd) - 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")
  4402. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_F", get_pcvar_num(cvar_ammodamage))
  4403. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_G", id, get_pcvar_num(cvar_firegrenades) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4404. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_H", id, get_pcvar_num(cvar_frostgrenades) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4405. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_I", id, get_pcvar_num(cvar_flaregrenades) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4406. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_J", id, get_pcvar_num(cvar_knockback) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4407.  
  4408. show_motd(id, motd)
  4409. }
  4410. case 2: // Zombies
  4411. {
  4412. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3")
  4413. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_A", ArrayGetCell(g_zclass_hp, 0))
  4414. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_B", floatround(float(ArrayGetCell(g_zclass_hp, 0)) * get_pcvar_float(cvar_zombiefirsthp)))
  4415. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_C", floatround(get_pcvar_float(cvar_zombiearmor) * 100.0))
  4416. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_D", ArrayGetCell(g_zclass_spd, 0))
  4417. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_E", floatround(Float:ArrayGetCell(g_zclass_grav, 0) * 800.0))
  4418. if (get_pcvar_num(cvar_zombiebonushp)) len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_F", get_pcvar_num(cvar_zombiebonushp))
  4419. len += formatex(motd[len], charsmax(motd) - 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")
  4420. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_H", id, get_pcvar_num(cvar_zombiebleeding) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4421. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_I", get_pcvar_num(cvar_ammoinfect))
  4422.  
  4423. show_motd(id, motd)
  4424. }
  4425. case 3: // Gameplay Modes
  4426. {
  4427. static nemhp[5], survhp[5]
  4428.  
  4429. // Get nemesis and survivor health
  4430. num_to_str(get_pcvar_num(cvar_nemhp), nemhp, charsmax(nemhp))
  4431. num_to_str(get_pcvar_num(cvar_survhp), survhp, charsmax(survhp))
  4432.  
  4433. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4")
  4434. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_A", id, get_pcvar_num(cvar_nem) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4435. if (get_pcvar_num(cvar_nem))
  4436. {
  4437. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_B", get_pcvar_num(cvar_nemchance))
  4438. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_C", get_pcvar_num(cvar_nemhp) > 0 ? nemhp : "[Auto]")
  4439. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_D", floatround(g_cached_nemspd))
  4440. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_E", floatround(get_pcvar_float(cvar_nemgravity) * 800.0))
  4441. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_F", id, g_cached_leapnemesis ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4442. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_G", id, get_pcvar_num(cvar_nempainfree) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4443. }
  4444. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_H", id, get_pcvar_num(cvar_surv) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4445. if (get_pcvar_num(cvar_surv))
  4446. {
  4447. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_I", get_pcvar_num(cvar_survchance))
  4448. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_J", get_pcvar_num(cvar_survhp) > 0 ? survhp : "[Auto]")
  4449. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_K", floatround(g_cached_survspd))
  4450. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_L", floatround(get_pcvar_float(cvar_survgravity) * 800.0))
  4451. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_M", id, g_cached_leapsurvivor ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4452. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_N", id, get_pcvar_num(cvar_survpainfree) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4453. }
  4454. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_O", id, get_pcvar_num(cvar_swarm) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4455. if (get_pcvar_num(cvar_swarm)) len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_P", get_pcvar_num(cvar_swarmchance))
  4456. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_Q", id, get_pcvar_num(cvar_multi) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4457. if (get_pcvar_num(cvar_multi))
  4458. {
  4459. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_R", get_pcvar_num(cvar_multichance))
  4460. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_S", floatround(get_pcvar_float(cvar_multiratio) * 100.0))
  4461. }
  4462. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_T", id, get_pcvar_num(cvar_plague) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4463. if (get_pcvar_num(cvar_plague))
  4464. {
  4465. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_U", get_pcvar_num(cvar_plaguechance))
  4466. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_V", floatround(get_pcvar_float(cvar_plagueratio) * 100.0))
  4467. }
  4468.  
  4469. show_motd(id, motd)
  4470. }
  4471. default: return PLUGIN_HANDLED;
  4472. }
  4473.  
  4474. // Show help menu again if user wishes to read another topic
  4475. show_menu_info(id)
  4476.  
  4477. return PLUGIN_HANDLED;
  4478. }
  4479.  
  4480. // Admin Menu
  4481. public menu_admin(id, key)
  4482. {
  4483. static userflags
  4484. userflags = get_user_flags(id)
  4485.  
  4486. switch (key)
  4487. {
  4488. case ACTION_ZOMBIEFY_HUMANIZE: // Zombiefy/Humanize command
  4489. {
  4490. if (userflags & (g_access_flag[ACCESS_MODE_INFECTION] | g_access_flag[ACCESS_MAKE_ZOMBIE] | g_access_flag[ACCESS_MAKE_HUMAN]))
  4491. {
  4492. // Show player list for admin to pick a target
  4493. PL_ACTION = ACTION_ZOMBIEFY_HUMANIZE
  4494. show_menu_player_list(id)
  4495. }
  4496. else
  4497. {
  4498. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")
  4499. show_menu_admin(id)
  4500. }
  4501. }
  4502. case ACTION_MAKE_NEMESIS: // Nemesis command
  4503. {
  4504. if (userflags & (g_access_flag[ACCESS_MODE_NEMESIS] | g_access_flag[ACCESS_MAKE_NEMESIS]))
  4505. {
  4506. // Show player list for admin to pick a target
  4507. PL_ACTION = ACTION_MAKE_NEMESIS
  4508. show_menu_player_list(id)
  4509. }
  4510. else
  4511. {
  4512. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")
  4513. show_menu_admin(id)
  4514. }
  4515. }
  4516. case ACTION_MAKE_SURVIVOR: // Survivor command
  4517. {
  4518. if (userflags & (g_access_flag[ACCESS_MODE_SURVIVOR] | g_access_flag[ACCESS_MAKE_SURVIVOR]))
  4519. {
  4520. // Show player list for admin to pick a target
  4521. PL_ACTION = ACTION_MAKE_SURVIVOR
  4522. show_menu_player_list(id)
  4523. }
  4524. else
  4525. {
  4526. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")
  4527. show_menu_admin(id)
  4528. }
  4529. }
  4530. case ACTION_RESPAWN_PLAYER: // Respawn command
  4531. {
  4532. if (userflags & g_access_flag[ACCESS_RESPAWN_PLAYERS])
  4533. {
  4534. // Show player list for admin to pick a target
  4535. PL_ACTION = ACTION_RESPAWN_PLAYER
  4536. show_menu_player_list(id)
  4537. }
  4538. else
  4539. {
  4540. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")
  4541. show_menu_admin(id)
  4542. }
  4543. }
  4544. case ACTION_MODE_SWARM: // Swarm Mode command
  4545. {
  4546. if (userflags & g_access_flag[ACCESS_MODE_SWARM])
  4547. {
  4548. if (allowed_swarm())
  4549. command_swarm(id)
  4550. else
  4551. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")
  4552. }
  4553. else
  4554. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")
  4555.  
  4556. show_menu_admin(id)
  4557. }
  4558. case ACTION_MODE_MULTI: // Multiple Infection command
  4559. {
  4560. if (userflags & g_access_flag[ACCESS_MODE_MULTI])
  4561. {
  4562. if (allowed_multi())
  4563. command_multi(id)
  4564. else
  4565. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")
  4566. }
  4567. else
  4568. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")
  4569.  
  4570. show_menu_admin(id)
  4571. }
  4572. case ACTION_MODE_PLAGUE: // Plague Mode command
  4573. {
  4574. if (userflags & g_access_flag[ACCESS_MODE_PLAGUE])
  4575. {
  4576. if (allowed_plague())
  4577. command_plague(id)
  4578. else
  4579. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")
  4580. }
  4581. else
  4582. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")
  4583.  
  4584. show_menu_admin(id)
  4585. }
  4586. }
  4587.  
  4588. return PLUGIN_HANDLED;
  4589. }
  4590.  
  4591. // Player List Menu
  4592. public menu_player_list(id, menuid, item)
  4593. {
  4594. // Menu was closed
  4595. if (item == MENU_EXIT)
  4596. {
  4597. menu_destroy(menuid)
  4598. show_menu_admin(id)
  4599. return PLUGIN_HANDLED;
  4600. }
  4601.  
  4602. // Retrieve player id
  4603. static buffer[2], dummy, playerid
  4604. menu_item_getinfo(menuid, item, dummy, buffer, charsmax(buffer), _, _, dummy)
  4605. playerid = buffer[0]
  4606.  
  4607. // Perform action on player
  4608.  
  4609. // Get admin flags
  4610. static userflags
  4611. userflags = get_user_flags(id)
  4612.  
  4613. // Make sure it's still connected
  4614. if (g_isconnected[playerid])
  4615. {
  4616. // Perform the right action if allowed
  4617. switch (PL_ACTION)
  4618. {
  4619. case ACTION_ZOMBIEFY_HUMANIZE: // Zombiefy/Humanize command
  4620. {
  4621. if (g_zombie[playerid])
  4622. {
  4623. if (userflags & g_access_flag[ACCESS_MAKE_HUMAN])
  4624. {
  4625. if (allowed_human(playerid))
  4626. command_human(id, playerid)
  4627. else
  4628. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")
  4629. }
  4630. else
  4631. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")
  4632. }
  4633. else
  4634. {
  4635. if (g_newround ? (userflags & g_access_flag[ACCESS_MODE_INFECTION]) : (userflags & g_access_flag[ACCESS_MAKE_ZOMBIE]))
  4636. {
  4637. if (allowed_zombie(playerid))
  4638. command_zombie(id, playerid)
  4639. else
  4640. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")
  4641. }
  4642. else
  4643. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")
  4644. }
  4645. }
  4646. case ACTION_MAKE_NEMESIS: // Nemesis command
  4647. {
  4648. if (g_newround ? (userflags & g_access_flag[ACCESS_MODE_NEMESIS]) : (userflags & g_access_flag[ACCESS_MAKE_NEMESIS]))
  4649. {
  4650. if (allowed_nemesis(playerid))
  4651. command_nemesis(id, playerid)
  4652. else
  4653. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")
  4654. }
  4655. else
  4656. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")
  4657. }
  4658. case ACTION_MAKE_SURVIVOR: // Survivor command
  4659. {
  4660. if (g_newround ? (userflags & g_access_flag[ACCESS_MODE_SURVIVOR]) : (userflags & g_access_flag[ACCESS_MAKE_SURVIVOR]))
  4661. {
  4662. if (allowed_survivor(playerid))
  4663. command_survivor(id, playerid)
  4664. else
  4665. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")
  4666. }
  4667. else
  4668. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")
  4669. }
  4670. case ACTION_RESPAWN_PLAYER: // Respawn command
  4671. {
  4672. if (userflags & g_access_flag[ACCESS_RESPAWN_PLAYERS])
  4673. {
  4674. if (allowed_respawn(playerid))
  4675. command_respawn(id, playerid)
  4676. else
  4677. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")
  4678. }
  4679. else
  4680. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")
  4681. }
  4682. }
  4683. }
  4684. else
  4685. zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")
  4686.  
  4687. menu_destroy(menuid)
  4688. show_menu_player_list(id)
  4689. return PLUGIN_HANDLED;
  4690. }
  4691.  
  4692. /*================================================================================
  4693. [Admin Commands]
  4694. =================================================================================*/
  4695.  
  4696. // zp_toggle [1/0]
  4697. public cmd_toggle(id, level, cid)
  4698. {
  4699. // Check for access flag - Enable/Disable Mod
  4700. if (!cmd_access(id, g_access_flag[ACCESS_ENABLE_MOD], cid, 2))
  4701. return PLUGIN_HANDLED;
  4702.  
  4703. // Retrieve arguments
  4704. new arg[2]
  4705. read_argv(1, arg, charsmax(arg))
  4706.  
  4707. // Mod already enabled/disabled
  4708. if (str_to_num(arg) == g_pluginenabled)
  4709. return PLUGIN_HANDLED;
  4710.  
  4711. // Set toggle cvar
  4712. set_pcvar_num(cvar_toggle, str_to_num(arg))
  4713. client_print(id, print_console, "Zombie Plague %L.", id, str_to_num(arg) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4714.  
  4715. // Retrieve map name
  4716. new mapname[32]
  4717. get_mapname(mapname, charsmax(mapname))
  4718.  
  4719. // Restart current map
  4720. server_cmd("changelevel %s", mapname)
  4721.  
  4722. return PLUGIN_HANDLED;
  4723. }
  4724.  
  4725. // zp_zombie [target]
  4726. public cmd_zombie(id, level, cid)
  4727. {
  4728. // Check for access flag depending on the resulting action
  4729. if (g_newround)
  4730. {
  4731. // Start Mode Infection
  4732. if (!cmd_access(id, g_access_flag[ACCESS_MODE_INFECTION], cid, 2))
  4733. return PLUGIN_HANDLED;
  4734. }
  4735. else
  4736. {
  4737. // Make Zombie
  4738. if (!cmd_access(id, g_access_flag[ACCESS_MAKE_ZOMBIE], cid, 2))
  4739. return PLUGIN_HANDLED;
  4740. }
  4741.  
  4742. // Retrieve arguments
  4743. static arg[32], player
  4744. read_argv(1, arg, charsmax(arg))
  4745. player = cmd_target(id, arg, (CMDTARGET_ONLY_ALIVE | CMDTARGET_ALLOW_SELF))
  4746.  
  4747. // Invalid target
  4748. if (!player) return PLUGIN_HANDLED;
  4749.  
  4750. // Target not allowed to be zombie
  4751. if (!allowed_zombie(player))
  4752. {
  4753. client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")
  4754. return PLUGIN_HANDLED
  4755. }
  4756.  
  4757. command_zombie(id, player)
  4758.  
  4759. return PLUGIN_HANDLED;
  4760. }
  4761.  
  4762. // zp_human [target]
  4763. public cmd_human(id, level, cid)
  4764. {
  4765. // Check for access flag - Make Human
  4766. if (!cmd_access(id, g_access_flag[ACCESS_MAKE_HUMAN], cid, 2))
  4767. return PLUGIN_HANDLED;
  4768.  
  4769. // Retrieve arguments
  4770. static arg[32], player
  4771. read_argv(1, arg, charsmax(arg))
  4772. player = cmd_target(id, arg, (CMDTARGET_ONLY_ALIVE | CMDTARGET_ALLOW_SELF))
  4773.  
  4774. // Invalid target
  4775. if (!player) return PLUGIN_HANDLED;
  4776.  
  4777. // Target not allowed to be human
  4778. if (!allowed_human(player))
  4779. {
  4780. client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")
  4781. return PLUGIN_HANDLED;
  4782. }
  4783.  
  4784. command_human(id, player)
  4785.  
  4786. return PLUGIN_HANDLED;
  4787. }
  4788.  
  4789. // zp_survivor [target]
  4790. public cmd_survivor(id, level, cid)
  4791. {
  4792. // Check for access flag depending on the resulting action
  4793. if (g_newround)
  4794. {
  4795. // Start Mode Survivor
  4796. if (!cmd_access(id, g_access_flag[ACCESS_MODE_SURVIVOR], cid, 2))
  4797. return PLUGIN_HANDLED;
  4798. }
  4799. else
  4800. {
  4801. // Make Survivor
  4802. if (!cmd_access(id, g_access_flag[ACCESS_MAKE_SURVIVOR], cid, 2))
  4803. return PLUGIN_HANDLED;
  4804. }
  4805.  
  4806. // Retrieve arguments
  4807. static arg[32], player
  4808. read_argv(1, arg, charsmax(arg))
  4809. player = cmd_target(id, arg, (CMDTARGET_ONLY_ALIVE | CMDTARGET_ALLOW_SELF))
  4810.  
  4811. // Invalid target
  4812. if (!player) return PLUGIN_HANDLED;
  4813.  
  4814. // Target not allowed to be survivor
  4815. if (!allowed_survivor(player))
  4816. {
  4817. client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")
  4818. return PLUGIN_HANDLED;
  4819. }
  4820.  
  4821. command_survivor(id, player)
  4822.  
  4823. return PLUGIN_HANDLED;
  4824. }
  4825.  
  4826. // zp_nemesis [target]
  4827. public cmd_nemesis(id, level, cid)
  4828. {
  4829. // Check for access flag depending on the resulting action
  4830. if (g_newround)
  4831. {
  4832. // Start Mode Nemesis
  4833. if (!cmd_access(id, g_access_flag[ACCESS_MODE_NEMESIS], cid, 2))
  4834. return PLUGIN_HANDLED;
  4835. }
  4836. else
  4837. {
  4838. // Make Nemesis
  4839. if (!cmd_access(id, g_access_flag[ACCESS_MAKE_NEMESIS], cid, 2))
  4840. return PLUGIN_HANDLED;
  4841. }
  4842.  
  4843. // Retrieve arguments
  4844. static arg[32], player
  4845. read_argv(1, arg, charsmax(arg))
  4846. player = cmd_target(id, arg, (CMDTARGET_ONLY_ALIVE | CMDTARGET_ALLOW_SELF))
  4847.  
  4848. // Invalid target
  4849. if (!player) return PLUGIN_HANDLED;
  4850.  
  4851. // Target not allowed to be nemesis
  4852. if (!allowed_nemesis(player))
  4853. {
  4854. client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")
  4855. return PLUGIN_HANDLED;
  4856. }
  4857.  
  4858. command_nemesis(id, player)
  4859.  
  4860. return PLUGIN_HANDLED;
  4861. }
  4862.  
  4863. // zp_respawn [target]
  4864. public cmd_respawn(id, level, cid)
  4865. {
  4866. // Check for access flag - Respawn
  4867. if (!cmd_access(id, g_access_flag[ACCESS_RESPAWN_PLAYERS], cid, 2))
  4868. return PLUGIN_HANDLED;
  4869.  
  4870. // Retrieve arguments
  4871. static arg[32], player
  4872. read_argv(1, arg, charsmax(arg))
  4873. player = cmd_target(id, arg, CMDTARGET_ALLOW_SELF)
  4874.  
  4875. // Invalid target
  4876. if (!player) return PLUGIN_HANDLED;
  4877.  
  4878. // Target not allowed to be respawned
  4879. if (!allowed_respawn(player))
  4880. {
  4881. client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")
  4882. return PLUGIN_HANDLED;
  4883. }
  4884.  
  4885. command_respawn(id, player)
  4886.  
  4887. return PLUGIN_HANDLED;
  4888. }
  4889.  
  4890. // zp_swarm
  4891. public cmd_swarm(id, level, cid)
  4892. {
  4893. // Check for access flag - Mode Swarm
  4894. if (!cmd_access(id, g_access_flag[ACCESS_MODE_SWARM], cid, 2))
  4895. return PLUGIN_HANDLED;
  4896.  
  4897. // Swarm mode not allowed
  4898. if (!allowed_swarm())
  4899. {
  4900. client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")
  4901. return PLUGIN_HANDLED;
  4902. }
  4903.  
  4904. command_swarm(id)
  4905.  
  4906. return PLUGIN_HANDLED;
  4907. }
  4908.  
  4909. // zp_multi
  4910. public cmd_multi(id, level, cid)
  4911. {
  4912. // Check for access flag - Mode Multi
  4913. if (!cmd_access(id, g_access_flag[ACCESS_MODE_MULTI], cid, 2))
  4914. return PLUGIN_HANDLED;
  4915.  
  4916. // Multi infection mode not allowed
  4917. if (!allowed_multi())
  4918. {
  4919. client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")
  4920. return PLUGIN_HANDLED;
  4921. }
  4922.  
  4923. command_multi(id)
  4924.  
  4925. return PLUGIN_HANDLED;
  4926. }
  4927.  
  4928. // zp_plague
  4929. public cmd_plague(id, level, cid)
  4930. {
  4931. // Check for access flag - Mode Plague
  4932. if (!cmd_access(id, g_access_flag[ACCESS_MODE_PLAGUE], cid, 2))
  4933. return PLUGIN_HANDLED;
  4934.  
  4935. // Plague mode not allowed
  4936. if (!allowed_plague())
  4937. {
  4938. client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")
  4939. return PLUGIN_HANDLED;
  4940. }
  4941.  
  4942. command_plague(id)
  4943.  
  4944. return PLUGIN_HANDLED;
  4945. }
  4946.  
  4947. /*================================================================================
  4948. [Message Hooks]
  4949. =================================================================================*/
  4950.  
  4951. // Current Weapon info
  4952. public message_cur_weapon(msg_id, msg_dest, msg_entity)
  4953. {
  4954. // Not alive or zombie
  4955. if (!g_isalive[msg_entity] || g_zombie[msg_entity])
  4956. return;
  4957.  
  4958. // Not an active weapon
  4959. if (get_msg_arg_int(1) != 1)
  4960. return;
  4961.  
  4962. // Unlimited clip disabled for class
  4963. if (g_survivor[msg_entity] ? get_pcvar_num(cvar_survinfammo) <= 1 : get_pcvar_num(cvar_infammo) <= 1)
  4964. return;
  4965.  
  4966. // Get weapon's id
  4967. static weapon
  4968. weapon = get_msg_arg_int(2)
  4969.  
  4970. // Unlimited Clip Ammo for this weapon?
  4971. if (MAXBPAMMO[weapon] > 2)
  4972. {
  4973. // Max out clip ammo
  4974. cs_set_weapon_ammo(fm_cs_get_current_weapon_ent(msg_entity), MAXCLIP[weapon])
  4975.  
  4976. // HUD should show full clip all the time
  4977. set_msg_arg_int(3, get_msg_argtype(3), MAXCLIP[weapon])
  4978. }
  4979. }
  4980.  
  4981. // Take off player's money
  4982. public message_money(msg_id, msg_dest, msg_entity)
  4983. {
  4984. // Remove money setting enabled?
  4985. if (!get_pcvar_num(cvar_removemoney))
  4986. return PLUGIN_CONTINUE;
  4987.  
  4988. fm_cs_set_user_money(msg_entity, 0)
  4989. return PLUGIN_HANDLED;
  4990. }
  4991.  
  4992. // Fix for the HL engine bug when HP is multiples of 256
  4993. public message_health(msg_id, msg_dest, msg_entity)
  4994. {
  4995. // Get player's health
  4996. static health
  4997. health = get_msg_arg_int(1)
  4998.  
  4999. // Don't bother
  5000. if (health < 256) return;
  5001.  
  5002. // Check if we need to fix it
  5003. if (health % 256 == 0)
  5004. fm_set_user_health(msg_entity, pev(msg_entity, pev_health) + 1)
  5005.  
  5006. // HUD can only show as much as 255 hp
  5007. set_msg_arg_int(1, get_msg_argtype(1), 255)
  5008. }
  5009.  
  5010. // Block flashlight battery messages if custom flashlight is enabled instead
  5011. public message_flashbat()
  5012. {
  5013. if (g_cached_customflash)
  5014. return PLUGIN_HANDLED;
  5015.  
  5016. return PLUGIN_CONTINUE;
  5017. }
  5018.  
  5019. // Flashbangs should only affect zombies
  5020. public message_screenfade(msg_id, msg_dest, msg_entity)
  5021. {
  5022. 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)
  5023. return PLUGIN_CONTINUE;
  5024.  
  5025. // Nemesis shouldn't be FBed
  5026. if (g_zombie[msg_entity] && !g_nemesis[msg_entity])
  5027. {
  5028. // Set flash color to nighvision's
  5029. set_msg_arg_int(4, get_msg_argtype(4), get_pcvar_num(cvar_nvgcolor[0]))
  5030. set_msg_arg_int(5, get_msg_argtype(5), get_pcvar_num(cvar_nvgcolor[1]))
  5031. set_msg_arg_int(6, get_msg_argtype(6), get_pcvar_num(cvar_nvgcolor[2]))
  5032. return PLUGIN_CONTINUE;
  5033. }
  5034.  
  5035. return PLUGIN_HANDLED;
  5036. }
  5037.  
  5038. // Prevent spectators' nightvision from being turned off when switching targets, etc.
  5039. public message_nvgtoggle()
  5040. {
  5041. return PLUGIN_HANDLED;
  5042. }
  5043.  
  5044. // Set correct model on player corpses
  5045. public message_clcorpse()
  5046. {
  5047. set_msg_arg_string(1, g_playermodel[get_msg_arg_int(12)])
  5048. }
  5049.  
  5050. // Prevent zombies from seeing any weapon pickup icon
  5051. public message_weappickup(msg_id, msg_dest, msg_entity)
  5052. {
  5053. if (g_zombie[msg_entity])
  5054. return PLUGIN_HANDLED;
  5055.  
  5056. return PLUGIN_CONTINUE;
  5057. }
  5058.  
  5059. // Prevent zombies from seeing any ammo pickup icon
  5060. public message_ammopickup(msg_id, msg_dest, msg_entity)
  5061. {
  5062. if (g_zombie[msg_entity])
  5063. return PLUGIN_HANDLED;
  5064.  
  5065. return PLUGIN_CONTINUE;
  5066. }
  5067.  
  5068. // Block hostage HUD display
  5069. public message_scenario()
  5070. {
  5071. if (get_msg_args() > 1)
  5072. {
  5073. static sprite[8]
  5074. get_msg_arg_string(2, sprite, charsmax(sprite))
  5075.  
  5076. if (equal(sprite, "hostage"))
  5077. return PLUGIN_HANDLED;
  5078. }
  5079.  
  5080. return PLUGIN_CONTINUE;
  5081. }
  5082.  
  5083. // Block hostages from appearing on radar
  5084. public message_hostagepos()
  5085. {
  5086. return PLUGIN_HANDLED;
  5087. }
  5088.  
  5089. // Block some text messages
  5090. public message_textmsg()
  5091. {
  5092. static textmsg[22]
  5093. get_msg_arg_string(2, textmsg, charsmax(textmsg))
  5094.  
  5095. // Game restarting, reset scores and call round end to balance the teams
  5096. if (equal(textmsg, "#Game_will_restart_in"))
  5097. {
  5098. g_scorehumans = 0
  5099. g_scorezombies = 0
  5100. logevent_round_end()
  5101. }
  5102. // Block round end related messages
  5103. else if (equal(textmsg, "#Hostages_Not_Rescued") || equal(textmsg, "#Round_Draw") || equal(textmsg, "#Terrorists_Win") || equal(textmsg, "#CTs_Win"))
  5104. {
  5105. return PLUGIN_HANDLED;
  5106. }
  5107.  
  5108. return PLUGIN_CONTINUE;
  5109. }
  5110.  
  5111. // Block CS round win audio messages, since we're playing our own instead
  5112. public message_sendaudio()
  5113. {
  5114. static audio[17]
  5115. get_msg_arg_string(2, audio, charsmax(audio))
  5116.  
  5117. if(equal(audio[7], "terwin") || equal(audio[7], "ctwin") || equal(audio[7], "rounddraw"))
  5118. return PLUGIN_HANDLED;
  5119.  
  5120. return PLUGIN_CONTINUE;
  5121. }
  5122.  
  5123. // Send actual team scores (T = zombies // CT = humans)
  5124. public message_teamscore()
  5125. {
  5126. static team[2]
  5127. get_msg_arg_string(1, team, charsmax(team))
  5128.  
  5129. switch (team[0])
  5130. {
  5131. // CT
  5132. case 'C': set_msg_arg_int(2, get_msg_argtype(2), g_scorehumans)
  5133. // Terrorist
  5134. case 'T': set_msg_arg_int(2, get_msg_argtype(2), g_scorezombies)
  5135. }
  5136. }
  5137.  
  5138. // Team Switch (or player joining a team for first time)
  5139. public message_teaminfo(msg_id, msg_dest)
  5140. {
  5141. // Only hook global messages
  5142. if (msg_dest != MSG_ALL && msg_dest != MSG_BROADCAST) return;
  5143.  
  5144. // Don't pick up our own TeamInfo messages for this player (bugfix)
  5145. if (g_switchingteam) return;
  5146.  
  5147. // Get player's id
  5148. static id
  5149. id = get_msg_arg_int(1)
  5150.  
  5151. // Enable spectators' nightvision if not spawning right away
  5152. set_task(0.2, "spec_nvision", id)
  5153.  
  5154. // Round didn't start yet, nothing to worry about
  5155. if (g_newround) return;
  5156.  
  5157. // Get his new team
  5158. static team[2]
  5159. get_msg_arg_string(2, team, charsmax(team))
  5160.  
  5161. // Perform some checks to see if they should join a different team instead
  5162. switch (team[0])
  5163. {
  5164. case 'C': // CT
  5165. {
  5166. if (g_survround && fnGetHumans()) // survivor alive --> switch to T and spawn as zombie
  5167. {
  5168. g_respawn_as_zombie[id] = true;
  5169. remove_task(id+TASK_TEAM)
  5170. fm_cs_set_user_team(id, FM_CS_TEAM_T)
  5171. set_msg_arg_string(2, "TERRORIST")
  5172. }
  5173. else if (!fnGetZombies()) // no zombies alive --> switch to T and spawn as zombie
  5174. {
  5175. g_respawn_as_zombie[id] = true;
  5176. remove_task(id+TASK_TEAM)
  5177. fm_cs_set_user_team(id, FM_CS_TEAM_T)
  5178. set_msg_arg_string(2, "TERRORIST")
  5179. }
  5180. }
  5181. case 'T': // Terrorist
  5182. {
  5183. if ((g_swarmround || g_survround) && fnGetHumans()) // survivor alive or swarm round w/ humans --> spawn as zombie
  5184. {
  5185. g_respawn_as_zombie[id] = true;
  5186. }
  5187. else if (fnGetZombies()) // zombies alive --> switch to CT
  5188. {
  5189. remove_task(id+TASK_TEAM)
  5190. fm_cs_set_user_team(id, FM_CS_TEAM_CT)
  5191. set_msg_arg_string(2, "CT")
  5192. }
  5193. }
  5194. }
  5195. }
  5196.  
  5197. /*================================================================================
  5198. [Main Functions]
  5199. =================================================================================*/
  5200.  
  5201. // Make Zombie Task
  5202. public make_zombie_task()
  5203. {
  5204. // Call make a zombie with no specific mode
  5205. make_a_zombie(MODE_NONE, 0)
  5206. }
  5207.  
  5208. // Make a Zombie Function
  5209. make_a_zombie(mode, id)
  5210. {
  5211. // Get alive players count
  5212. static iPlayersnum
  5213. iPlayersnum = fnGetAlive()
  5214.  
  5215. // Not enough players, come back later!
  5216. if (iPlayersnum < 1)
  5217. {
  5218. set_task(2.0, "make_zombie_task", TASK_MAKEZOMBIE)
  5219. return;
  5220. }
  5221.  
  5222. // Round started!
  5223. g_newround = false
  5224.  
  5225. // Set up some common vars
  5226. static forward_id, sound[64], iZombies, iMaxZombies
  5227.  
  5228. if ((mode == MODE_NONE && (!get_pcvar_num(cvar_preventconsecutive) || g_lastmode != MODE_SURVIVOR) && random_num(1, get_pcvar_num(cvar_survchance)) == get_pcvar_num(cvar_surv) && iPlayersnum >= get_pcvar_num(cvar_survminplayers)) || mode == MODE_SURVIVOR)
  5229. {
  5230. // Survivor Mode
  5231. g_survround = true
  5232. g_lastmode = MODE_SURVIVOR
  5233.  
  5234. // Choose player randomly?
  5235. if (mode == MODE_NONE)
  5236. id = fnGetRandomAlive(random_num(1, iPlayersnum))
  5237.  
  5238. // Remember id for calling our forward later
  5239. forward_id = id
  5240.  
  5241. // Turn player into a survivor
  5242. humanme(id, 1, 0)
  5243.  
  5244. // Turn the remaining players into zombies
  5245. for (id = 1; id <= g_maxplayers; id++)
  5246. {
  5247. // Not alive
  5248. if (!g_isalive[id])
  5249. continue;
  5250.  
  5251. // Survivor or already a zombie
  5252. if (g_survivor[id] || g_zombie[id])
  5253. continue;
  5254.  
  5255. // Turn into a zombie
  5256. zombieme(id, 0, 0, 1, 0)
  5257. }
  5258.  
  5259. // Play survivor sound
  5260. ArrayGetString(sound_survivor, random_num(0, ArraySize(sound_survivor) - 1), sound, charsmax(sound))
  5261. PlaySound(sound);
  5262.  
  5263. // Show Survivor HUD notice
  5264. set_hudmessage(20, 20, 255, HUD_EVENT_X, HUD_EVENT_Y, 1, 0.0, 5.0, 1.0, 1.0, -1)
  5265. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_SURVIVOR", g_playername[forward_id])
  5266.  
  5267. // Mode fully started!
  5268. g_modestarted = true
  5269.  
  5270. // Round start forward
  5271. ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_SURVIVOR, forward_id);
  5272. }
  5273. else if ((mode == MODE_NONE && (!get_pcvar_num(cvar_preventconsecutive) || g_lastmode != MODE_SWARM) && random_num(1, get_pcvar_num(cvar_swarmchance)) == get_pcvar_num(cvar_swarm) && iPlayersnum >= get_pcvar_num(cvar_swarmminplayers)) || mode == MODE_SWARM)
  5274. {
  5275. // Swarm Mode
  5276. g_swarmround = true
  5277. g_lastmode = MODE_SWARM
  5278.  
  5279. // Make sure there are alive players on both teams (BUGFIX)
  5280. if (!fnGetAliveTs())
  5281. {
  5282. // Move random player to T team
  5283. id = fnGetRandomAlive(random_num(1, iPlayersnum))
  5284. remove_task(id+TASK_TEAM)
  5285. fm_cs_set_user_team(id, FM_CS_TEAM_T)
  5286. fm_user_team_update(id)
  5287. }
  5288. else if (!fnGetAliveCTs())
  5289. {
  5290. // Move random player to CT team
  5291. id = fnGetRandomAlive(random_num(1, iPlayersnum))
  5292. remove_task(id+TASK_TEAM)
  5293. fm_cs_set_user_team(id, FM_CS_TEAM_CT)
  5294. fm_user_team_update(id)
  5295. }
  5296.  
  5297. // Turn every T into a zombie
  5298. for (id = 1; id <= g_maxplayers; id++)
  5299. {
  5300. // Not alive
  5301. if (!g_isalive[id])
  5302. continue;
  5303.  
  5304. // Not a Terrorist
  5305. if (fm_cs_get_user_team(id) != FM_CS_TEAM_T)
  5306. continue;
  5307.  
  5308. // Turn into a zombie
  5309. zombieme(id, 0, 0, 1, 0)
  5310. }
  5311.  
  5312. // Play swarm sound
  5313. ArrayGetString(sound_swarm, random_num(0, ArraySize(sound_swarm) - 1), sound, charsmax(sound))
  5314. PlaySound(sound);
  5315.  
  5316. // Show Swarm HUD notice
  5317. set_hudmessage(20, 255, 20, HUD_EVENT_X, HUD_EVENT_Y, 1, 0.0, 5.0, 1.0, 1.0, -1)
  5318. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_SWARM")
  5319.  
  5320. // Mode fully started!
  5321. g_modestarted = true
  5322.  
  5323. // Round start forward
  5324. ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_SWARM, 0);
  5325. }
  5326. else if ((mode == MODE_NONE && (!get_pcvar_num(cvar_preventconsecutive) || g_lastmode != MODE_MULTI) && random_num(1, get_pcvar_num(cvar_multichance)) == get_pcvar_num(cvar_multi) && floatround(iPlayersnum*get_pcvar_float(cvar_multiratio), floatround_ceil) >= 2 && floatround(iPlayersnum*get_pcvar_float(cvar_multiratio), floatround_ceil) < iPlayersnum && iPlayersnum >= get_pcvar_num(cvar_multiminplayers)) || mode == MODE_MULTI)
  5327. {
  5328. // Multi Infection Mode
  5329. g_lastmode = MODE_MULTI
  5330.  
  5331. // iMaxZombies is rounded up, in case there aren't enough players
  5332. iMaxZombies = floatround(iPlayersnum*get_pcvar_float(cvar_multiratio), floatround_ceil)
  5333. iZombies = 0
  5334.  
  5335. // Randomly turn iMaxZombies players into zombies
  5336. while (iZombies < iMaxZombies)
  5337. {
  5338. // Keep looping through all players
  5339. if (++id > g_maxplayers) id = 1
  5340.  
  5341. // Dead or already a zombie
  5342. if (!g_isalive[id] || g_zombie[id])
  5343. continue;
  5344.  
  5345. // Random chance
  5346. if (random_num(0, 1))
  5347. {
  5348. // Turn into a zombie
  5349. zombieme(id, 0, 0, 1, 0)
  5350. iZombies++
  5351. }
  5352. }
  5353.  
  5354. // Turn the remaining players into humans
  5355. for (id = 1; id <= g_maxplayers; id++)
  5356. {
  5357. // Only those of them who aren't zombies
  5358. if (!g_isalive[id] || g_zombie[id])
  5359. continue;
  5360.  
  5361. // Switch to CT
  5362. if (fm_cs_get_user_team(id) != FM_CS_TEAM_CT) // need to change team?
  5363. {
  5364. remove_task(id+TASK_TEAM)
  5365. fm_cs_set_user_team(id, FM_CS_TEAM_CT)
  5366. fm_user_team_update(id)
  5367. }
  5368. }
  5369.  
  5370. // Play multi infection sound
  5371. ArrayGetString(sound_multi, random_num(0, ArraySize(sound_multi) - 1), sound, charsmax(sound))
  5372. PlaySound(sound);
  5373.  
  5374. // Show Multi Infection HUD notice
  5375. set_hudmessage(200, 50, 0, HUD_EVENT_X, HUD_EVENT_Y, 1, 0.0, 5.0, 1.0, 1.0, -1)
  5376. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_MULTI")
  5377.  
  5378. // Mode fully started!
  5379. g_modestarted = true
  5380.  
  5381. // Round start forward
  5382. ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_MULTI, 0);
  5383. }
  5384. else if ((mode == MODE_NONE && (!get_pcvar_num(cvar_preventconsecutive) || g_lastmode != MODE_PLAGUE) && random_num(1, get_pcvar_num(cvar_plaguechance)) == get_pcvar_num(cvar_plague) && floatround((iPlayersnum-(get_pcvar_num(cvar_plaguenemnum)+get_pcvar_num(cvar_plaguesurvnum)))*get_pcvar_float(cvar_plagueratio), floatround_ceil) >= 1
  5385. && iPlayersnum-(get_pcvar_num(cvar_plaguesurvnum)+get_pcvar_num(cvar_plaguenemnum)+floatround((iPlayersnum-(get_pcvar_num(cvar_plaguenemnum)+get_pcvar_num(cvar_plaguesurvnum)))*get_pcvar_float(cvar_plagueratio), floatround_ceil)) >= 1 && iPlayersnum >= get_pcvar_num(cvar_plagueminplayers)) || mode == MODE_PLAGUE)
  5386. {
  5387. // Plague Mode
  5388. g_plagueround = true
  5389. g_lastmode = MODE_PLAGUE
  5390.  
  5391. // Turn specified amount of players into Survivors
  5392. static iSurvivors, iMaxSurvivors
  5393. iMaxSurvivors = get_pcvar_num(cvar_plaguesurvnum)
  5394. iSurvivors = 0
  5395.  
  5396. while (iSurvivors < iMaxSurvivors)
  5397. {
  5398. // Choose random guy
  5399. id = fnGetRandomAlive(random_num(1, iPlayersnum))
  5400.  
  5401. // Already a survivor?
  5402. if (g_survivor[id])
  5403. continue;
  5404.  
  5405. // If not, turn him into one
  5406. humanme(id, 1, 0)
  5407. iSurvivors++
  5408.  
  5409. // Apply survivor health multiplier
  5410. fm_set_user_health(id, floatround(float(pev(id, pev_health)) * get_pcvar_float(cvar_plaguesurvhpmulti)))
  5411. }
  5412.  
  5413. // Turn specified amount of players into Nemesis
  5414. static iNemesis, iMaxNemesis
  5415. iMaxNemesis = get_pcvar_num(cvar_plaguenemnum)
  5416. iNemesis = 0
  5417.  
  5418. while (iNemesis < iMaxNemesis)
  5419. {
  5420. // Choose random guy
  5421. id = fnGetRandomAlive(random_num(1, iPlayersnum))
  5422.  
  5423. // Already a survivor or nemesis?
  5424. if (g_survivor[id] || g_nemesis[id])
  5425. continue;
  5426.  
  5427. // If not, turn him into one
  5428. zombieme(id, 0, 1, 0, 0)
  5429. iNemesis++
  5430.  
  5431. // Apply nemesis health multiplier
  5432. fm_set_user_health(id, floatround(float(pev(id, pev_health)) * get_pcvar_float(cvar_plaguenemhpmulti)))
  5433. }
  5434.  
  5435. // iMaxZombies is rounded up, in case there aren't enough players
  5436. iMaxZombies = floatround((iPlayersnum-(get_pcvar_num(cvar_plaguenemnum)+get_pcvar_num(cvar_plaguesurvnum)))*get_pcvar_float(cvar_plagueratio), floatround_ceil)
  5437. iZombies = 0
  5438.  
  5439. // Randomly turn iMaxZombies players into zombies
  5440. while (iZombies < iMaxZombies)
  5441. {
  5442. // Keep looping through all players
  5443. if (++id > g_maxplayers) id = 1
  5444.  
  5445. // Dead or already a zombie or survivor
  5446. if (!g_isalive[id] || g_zombie[id] || g_survivor[id])
  5447. continue;
  5448.  
  5449. // Random chance
  5450. if (random_num(0, 1))
  5451. {
  5452. // Turn into a zombie
  5453. zombieme(id, 0, 0, 1, 0)
  5454. iZombies++
  5455. }
  5456. }
  5457.  
  5458. // Turn the remaining players into humans
  5459. for (id = 1; id <= g_maxplayers; id++)
  5460. {
  5461. // Only those of them who arent zombies or survivor
  5462. if (!g_isalive[id] || g_zombie[id] || g_survivor[id])
  5463. continue;
  5464.  
  5465. // Switch to CT
  5466. if (fm_cs_get_user_team(id) != FM_CS_TEAM_CT) // need to change team?
  5467. {
  5468. remove_task(id+TASK_TEAM)
  5469. fm_cs_set_user_team(id, FM_CS_TEAM_CT)
  5470. fm_user_team_update(id)
  5471. }
  5472. }
  5473.  
  5474. // Play plague sound
  5475. ArrayGetString(sound_plague, random_num(0, ArraySize(sound_plague) - 1), sound, charsmax(sound))
  5476. PlaySound(sound);
  5477.  
  5478. // Show Plague HUD notice
  5479. set_hudmessage(0, 50, 200, HUD_EVENT_X, HUD_EVENT_Y, 1, 0.0, 5.0, 1.0, 1.0, -1)
  5480. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_PLAGUE")
  5481.  
  5482. // Mode fully started!
  5483. g_modestarted = true
  5484.  
  5485. // Round start forward
  5486. ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_PLAGUE, 0);
  5487. }
  5488. else
  5489. {
  5490. // Single Infection Mode or Nemesis Mode
  5491.  
  5492. // Choose player randomly?
  5493. if (mode == MODE_NONE)
  5494. id = fnGetRandomAlive(random_num(1, iPlayersnum))
  5495.  
  5496. // Remember id for calling our forward later
  5497. forward_id = id
  5498.  
  5499. if ((mode == MODE_NONE && (!get_pcvar_num(cvar_preventconsecutive) || g_lastmode != MODE_NEMESIS) && random_num(1, get_pcvar_num(cvar_nemchance)) == get_pcvar_num(cvar_nem) && iPlayersnum >= get_pcvar_num(cvar_nemminplayers)) || mode == MODE_NEMESIS)
  5500. {
  5501. // Nemesis Mode
  5502. g_nemround = true
  5503. g_lastmode = MODE_NEMESIS
  5504.  
  5505. // Turn player into nemesis
  5506. zombieme(id, 0, 1, 0, 0)
  5507. }
  5508. else
  5509. {
  5510. // Single Infection Mode
  5511. g_lastmode = MODE_INFECTION
  5512.  
  5513. // Turn player into the first zombie
  5514. zombieme(id, 0, 0, 0, 0)
  5515. }
  5516.  
  5517. // Remaining players should be humans (CTs)
  5518. for (id = 1; id <= g_maxplayers; id++)
  5519. {
  5520. // Not alive
  5521. if (!g_isalive[id])
  5522. continue;
  5523.  
  5524. // First zombie/nemesis
  5525. if (g_zombie[id])
  5526. continue;
  5527.  
  5528. // Switch to CT
  5529. if (fm_cs_get_user_team(id) != FM_CS_TEAM_CT) // need to change team?
  5530. {
  5531. remove_task(id+TASK_TEAM)
  5532. fm_cs_set_user_team(id, FM_CS_TEAM_CT)
  5533. fm_user_team_update(id)
  5534. }
  5535. }
  5536.  
  5537. if (g_nemround)
  5538. {
  5539. // Play Nemesis sound
  5540. ArrayGetString(sound_nemesis, random_num(0, ArraySize(sound_nemesis) - 1), sound, charsmax(sound))
  5541. PlaySound(sound);
  5542.  
  5543. // Show Nemesis HUD notice
  5544. set_hudmessage(255, 20, 20, HUD_EVENT_X, HUD_EVENT_Y, 1, 0.0, 5.0, 1.0, 1.0, -1)
  5545. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_NEMESIS", g_playername[forward_id])
  5546.  
  5547. // Mode fully started!
  5548. g_modestarted = true
  5549.  
  5550. // Round start forward
  5551. ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_NEMESIS, forward_id);
  5552. }
  5553. else
  5554. {
  5555. // Show First Zombie HUD notice
  5556. set_hudmessage(255, 0, 0, HUD_EVENT_X, HUD_EVENT_Y, 0, 0.0, 5.0, 1.0, 1.0, -1)
  5557. ShowSyncHudMsg(0, g_MsgSync, "%L",LANG_PLAYER, "NOTICE_FIRST", g_playername[forward_id])
  5558.  
  5559. // Mode fully started!
  5560. g_modestarted = true
  5561.  
  5562. // Round start forward
  5563. ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_INFECTION, forward_id);
  5564. }
  5565. }
  5566.  
  5567. // Start ambience sounds after a mode begins
  5568. if ((g_ambience_sounds[AMBIENCE_SOUNDS_NEMESIS] && g_nemround) || (g_ambience_sounds[AMBIENCE_SOUNDS_SURVIVOR] && g_survround) || (g_ambience_sounds[AMBIENCE_SOUNDS_SWARM] && g_swarmround) || (g_ambience_sounds[AMBIENCE_SOUNDS_PLAGUE] && g_plagueround) || (g_ambience_sounds[AMBIENCE_SOUNDS_INFECTION] && !g_nemround && !g_survround && !g_swarmround && !g_plagueround))
  5569. {
  5570. remove_task(TASK_AMBIENCESOUNDS)
  5571. set_task(2.0, "ambience_sound_effects", TASK_AMBIENCESOUNDS)
  5572. }
  5573. }
  5574.  
  5575. // Zombie Me Function (player id, infector, turn into a nemesis, silent mode, deathmsg and rewards)
  5576. zombieme(id, infector, nemesis, silentmode, rewards)
  5577. {
  5578. // User infect attempt forward
  5579. ExecuteForward(g_fwUserInfect_attempt, g_fwDummyResult, id, infector, nemesis)
  5580.  
  5581. // One or more plugins blocked the infection. Only allow this after making sure it's
  5582. // not going to leave us with no zombies. Take into account a last player leaving case.
  5583. // BUGFIX: only allow after a mode has started, to prevent blocking first zombie e.g.
  5584. if (g_fwDummyResult >= ZP_PLUGIN_HANDLED && g_modestarted && fnGetZombies() > g_lastplayerleaving)
  5585. return;
  5586.  
  5587. // Pre user infect forward
  5588. ExecuteForward(g_fwUserInfected_pre, g_fwDummyResult, id, infector, nemesis)
  5589.  
  5590. // Show zombie class menu if they haven't chosen any (e.g. just connected)
  5591. if (g_zombieclassnext[id] == ZCLASS_NONE && get_pcvar_num(cvar_zclasses))
  5592. set_task(0.2, "show_menu_zclass", id)
  5593.  
  5594. // Set selected zombie class
  5595. g_zombieclass[id] = g_zombieclassnext[id]
  5596. // If no class selected yet, use the first (default) one
  5597. if (g_zombieclass[id] == ZCLASS_NONE) g_zombieclass[id] = 0
  5598.  
  5599. // Way to go...
  5600. g_zombie[id] = true
  5601. g_nemesis[id] = false
  5602. g_survivor[id] = false
  5603. g_firstzombie[id] = false
  5604.  
  5605. // Remove survivor's aura (bugfix)
  5606. set_pev(id, pev_effects, pev(id, pev_effects) &~ EF_BRIGHTLIGHT)
  5607.  
  5608. // Remove spawn protection (bugfix)
  5609. g_nodamage[id] = false
  5610. set_pev(id, pev_effects, pev(id, pev_effects) &~ EF_NODRAW)
  5611.  
  5612. // Reset burning duration counter (bugfix)
  5613. g_burning_duration[id] = 0
  5614.  
  5615. // Show deathmsg and reward infector?
  5616. if (rewards && infector)
  5617. {
  5618. // Send death notice and fix the "dead" attrib on scoreboard
  5619. SendDeathMsg(infector, id)
  5620. FixDeadAttrib(id)
  5621.  
  5622. // Reward frags, deaths, health, and ammo packs
  5623. UpdateFrags(infector, id, get_pcvar_num(cvar_fragsinfect), 1, 1)
  5624. g_ammopacks[infector] += get_pcvar_num(cvar_ammoinfect)
  5625. fm_set_user_health(infector, pev(infector, pev_health) + get_pcvar_num(cvar_zombiebonushp))
  5626. }
  5627.  
  5628. // Cache speed, knockback, and name for player's class
  5629. g_zombie_spd[id] = float(ArrayGetCell(g_zclass_spd, g_zombieclass[id]))
  5630. g_zombie_knockback[id] = Float:ArrayGetCell(g_zclass_kb, g_zombieclass[id])
  5631. ArrayGetString(g_zclass_name, g_zombieclass[id], g_zombie_classname[id], charsmax(g_zombie_classname[]))
  5632.  
  5633. // Set zombie attributes based on the mode
  5634. static sound[64]
  5635. if (!silentmode)
  5636. {
  5637. if (nemesis)
  5638. {
  5639. // Nemesis
  5640. g_nemesis[id] = true
  5641.  
  5642. // Set health [0 = auto]
  5643. if (get_pcvar_num(cvar_nemhp) == 0)
  5644. {
  5645. if (get_pcvar_num(cvar_nembasehp) == 0)
  5646. fm_set_user_health(id, ArrayGetCell(g_zclass_hp, 0) * fnGetAlive())
  5647. else
  5648. fm_set_user_health(id, get_pcvar_num(cvar_nembasehp) * fnGetAlive())
  5649. }
  5650. else
  5651. fm_set_user_health(id, get_pcvar_num(cvar_nemhp))
  5652.  
  5653. // Set gravity, unless frozen
  5654. if (!g_frozen[id]) set_pev(id, pev_gravity, get_pcvar_float(cvar_nemgravity))
  5655. }
  5656. else if (fnGetZombies() == 1)
  5657. {
  5658. // First zombie
  5659. g_firstzombie[id] = true
  5660.  
  5661. // Set health and gravity, unless frozen
  5662. fm_set_user_health(id, floatround(float(ArrayGetCell(g_zclass_hp, g_zombieclass[id])) * get_pcvar_float(cvar_zombiefirsthp)))
  5663. if (!g_frozen[id]) set_pev(id, pev_gravity, Float:ArrayGetCell(g_zclass_grav, g_zombieclass[id]))
  5664.  
  5665. // Infection sound
  5666. ArrayGetString(zombie_infect, random_num(0, ArraySize(zombie_infect) - 1), sound, charsmax(sound))
  5667. emit_sound(id, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  5668. }
  5669. else
  5670. {
  5671. // Infected by someone
  5672.  
  5673. // Set health and gravity, unless frozen
  5674. fm_set_user_health(id, ArrayGetCell(g_zclass_hp, g_zombieclass[id]))
  5675. if (!g_frozen[id]) set_pev(id, pev_gravity, Float:ArrayGetCell(g_zclass_grav, g_zombieclass[id]))
  5676.  
  5677. // Infection sound
  5678. ArrayGetString(zombie_infect, random_num(0, ArraySize(zombie_infect) - 1), sound, charsmax(sound))
  5679. emit_sound(id, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  5680.  
  5681. // Show Infection HUD notice
  5682. set_hudmessage(255, 0, 0, HUD_INFECT_X, HUD_INFECT_Y, 0, 0.0, 5.0, 1.0, 1.0, -1)
  5683.  
  5684. if (infector) // infected by someone?
  5685. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_INFECT2", g_playername[id], g_playername[infector])
  5686. else
  5687. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_INFECT", g_playername[id])
  5688. }
  5689. }
  5690. else
  5691. {
  5692. // Silent mode, no HUD messages, no infection sounds
  5693.  
  5694. // Set health and gravity, unless frozen
  5695. fm_set_user_health(id, ArrayGetCell(g_zclass_hp, g_zombieclass[id]))
  5696. if (!g_frozen[id]) set_pev(id, pev_gravity, Float:ArrayGetCell(g_zclass_grav, g_zombieclass[id]))
  5697. }
  5698.  
  5699. // Remove previous tasks
  5700. remove_task(id+TASK_MODEL)
  5701. remove_task(id+TASK_BLOOD)
  5702. remove_task(id+TASK_AURA)
  5703. remove_task(id+TASK_BURN)
  5704.  
  5705. // Switch to T
  5706. if (fm_cs_get_user_team(id) != FM_CS_TEAM_T) // need to change team?
  5707. {
  5708. remove_task(id+TASK_TEAM)
  5709. fm_cs_set_user_team(id, FM_CS_TEAM_T)
  5710. fm_user_team_update(id)
  5711. }
  5712.  
  5713. // Custom models stuff
  5714. static currentmodel[32], tempmodel[32], already_has_model, i, iRand, size
  5715. already_has_model = false
  5716.  
  5717. if (g_handle_models_on_separate_ent)
  5718. {
  5719. // Set the right model
  5720. if (g_nemesis[id])
  5721. {
  5722. iRand = random_num(0, ArraySize(model_nemesis) - 1)
  5723. ArrayGetString(model_nemesis, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  5724. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_nemesis, iRand))
  5725. }
  5726. else
  5727. {
  5728. if (get_pcvar_num(cvar_adminmodelszombie) && (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS]))
  5729. {
  5730. iRand = random_num(0, ArraySize(model_admin_zombie) - 1)
  5731. ArrayGetString(model_admin_zombie, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  5732. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_admin_zombie, iRand))
  5733. }
  5734. else
  5735. {
  5736. iRand = random_num(ArrayGetCell(g_zclass_modelsstart, g_zombieclass[id]), ArrayGetCell(g_zclass_modelsend, g_zombieclass[id]) - 1)
  5737. ArrayGetString(g_zclass_playermodel, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  5738. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_zclass_modelindex, iRand))
  5739. }
  5740. }
  5741.  
  5742. // Set model on player model entity
  5743. fm_set_playermodel_ent(id)
  5744.  
  5745. // Nemesis glow / remove glow on player model entity, unless frozen
  5746. if (!g_frozen[id])
  5747. {
  5748. if (g_nemesis[id] && get_pcvar_num(cvar_nemglow))
  5749. fm_set_rendering(g_ent_playermodel[id], kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 25)
  5750. else
  5751. fm_set_rendering(g_ent_playermodel[id])
  5752. }
  5753. }
  5754. else
  5755. {
  5756. // Get current model for comparing it with the current one
  5757. fm_cs_get_user_model(id, currentmodel, charsmax(currentmodel))
  5758.  
  5759. // Set the right model, after checking that we don't already have it
  5760. if (g_nemesis[id])
  5761. {
  5762. size = ArraySize(model_nemesis)
  5763. for (i = 0; i < size; i++)
  5764. {
  5765. ArrayGetString(model_nemesis, i, tempmodel, charsmax(tempmodel))
  5766. if (equal(currentmodel, tempmodel)) already_has_model = true
  5767. }
  5768.  
  5769. if (!already_has_model)
  5770. {
  5771. iRand = random_num(0, size - 1)
  5772. ArrayGetString(model_nemesis, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  5773. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_nemesis, iRand))
  5774. }
  5775. }
  5776. else
  5777. {
  5778. if (get_pcvar_num(cvar_adminmodelszombie) && (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS]))
  5779. {
  5780. size = ArraySize(model_admin_zombie)
  5781. for (i = 0; i < size; i++)
  5782. {
  5783. ArrayGetString(model_admin_zombie, i, tempmodel, charsmax(tempmodel))
  5784. if (equal(currentmodel, tempmodel)) already_has_model = true
  5785. }
  5786.  
  5787. if (!already_has_model)
  5788. {
  5789. iRand = random_num(0, size - 1)
  5790. ArrayGetString(model_admin_zombie, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  5791. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_admin_zombie, iRand))
  5792. }
  5793. }
  5794. else
  5795. {
  5796. for (i = ArrayGetCell(g_zclass_modelsstart, g_zombieclass[id]); i < ArrayGetCell(g_zclass_modelsend, g_zombieclass[id]); i++)
  5797. {
  5798. ArrayGetString(g_zclass_playermodel, i, tempmodel, charsmax(tempmodel))
  5799. if (equal(currentmodel, tempmodel)) already_has_model = true
  5800. }
  5801.  
  5802. if (!already_has_model)
  5803. {
  5804. iRand = random_num(ArrayGetCell(g_zclass_modelsstart, g_zombieclass[id]), ArrayGetCell(g_zclass_modelsend, g_zombieclass[id]) - 1)
  5805. ArrayGetString(g_zclass_playermodel, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  5806. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_zclass_modelindex, iRand))
  5807. }
  5808. }
  5809. }
  5810.  
  5811. // Need to change the model?
  5812. if (!already_has_model)
  5813. {
  5814. // An additional delay is offset at round start
  5815. // since SVC_BAD is more likely to be triggered there
  5816. if (g_newround)
  5817. set_task(5.0 * g_modelchange_delay, "fm_user_model_update", id+TASK_MODEL)
  5818. else
  5819. fm_user_model_update(id+TASK_MODEL)
  5820. }
  5821.  
  5822. // Nemesis glow / remove glow, unless frozen
  5823. if (!g_frozen[id])
  5824. {
  5825. if (g_nemesis[id] && get_pcvar_num(cvar_nemglow))
  5826. fm_set_rendering(id, kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 25)
  5827. else
  5828. fm_set_rendering(id)
  5829. }
  5830. }
  5831.  
  5832. // Remove any zoom (bugfix)
  5833. cs_set_user_zoom(id, CS_RESET_ZOOM, 1)
  5834.  
  5835. // Remove armor
  5836. set_pev(id, pev_armorvalue, 0.0)
  5837.  
  5838. // Drop weapons when infected
  5839. drop_weapons(id, 1)
  5840. drop_weapons(id, 2)
  5841.  
  5842. // Strip zombies from guns and give them a knife
  5843. fm_strip_user_weapons(id)
  5844. fm_give_item(id, "weapon_knife")
  5845.  
  5846. // Fancy effects
  5847. infection_effects(id)
  5848.  
  5849. // Nemesis aura task
  5850. if (g_nemesis[id] && get_pcvar_num(cvar_nemaura))
  5851. set_task(0.1, "zombie_aura", id+TASK_AURA, _, _, "b")
  5852.  
  5853. // Give Zombies Night Vision?
  5854. if (get_pcvar_num(cvar_nvggive))
  5855. {
  5856. g_nvision[id] = true
  5857.  
  5858. if (!g_isbot[id])
  5859. {
  5860. // Turn on Night Vision automatically?
  5861. if (get_pcvar_num(cvar_nvggive) == 1)
  5862. {
  5863. g_nvisionenabled[id] = true
  5864.  
  5865. // Custom nvg?
  5866. if (get_pcvar_num(cvar_customnvg))
  5867. {
  5868. remove_task(id+TASK_NVISION)
  5869. set_task(0.1, "set_user_nvision", id+TASK_NVISION, _, _, "b")
  5870. }
  5871. else
  5872. set_user_gnvision(id, 1)
  5873. }
  5874. // Turn off nightvision when infected (bugfix)
  5875. else if (g_nvisionenabled[id])
  5876. {
  5877. if (get_pcvar_num(cvar_customnvg)) remove_task(id+TASK_NVISION)
  5878. else set_user_gnvision(id, 0)
  5879. g_nvisionenabled[id] = false
  5880. }
  5881. }
  5882. else
  5883. cs_set_user_nvg(id, 1); // turn on NVG for bots
  5884. }
  5885. // Disable nightvision when infected (bugfix)
  5886. else if (g_nvision[id])
  5887. {
  5888. if (g_isbot[id]) cs_set_user_nvg(id, 0) // Turn off NVG for bots
  5889. if (get_pcvar_num(cvar_customnvg)) remove_task(id+TASK_NVISION)
  5890. else if (g_nvisionenabled[id]) set_user_gnvision(id, 0)
  5891. g_nvision[id] = false
  5892. g_nvisionenabled[id] = false
  5893. }
  5894.  
  5895. // Set custom FOV?
  5896. if (get_pcvar_num(cvar_zombiefov) != 90 && get_pcvar_num(cvar_zombiefov) != 0)
  5897. {
  5898. message_begin(MSG_ONE, g_msgSetFOV, _, id)
  5899. write_byte(get_pcvar_num(cvar_zombiefov)) // fov angle
  5900. message_end()
  5901. }
  5902.  
  5903. // Call the bloody task
  5904. if (!g_nemesis[id] && get_pcvar_num(cvar_zombiebleeding))
  5905. set_task(0.7, "make_blood", id+TASK_BLOOD, _, _, "b")
  5906.  
  5907. // Idle sounds task
  5908. if (!g_nemesis[id])
  5909. set_task(random_float(50.0, 70.0), "zombie_play_idle", id+TASK_BLOOD, _, _, "b")
  5910.  
  5911. // Turn off zombie's flashlight
  5912. turn_off_flashlight(id)
  5913.  
  5914. // Post user infect forward
  5915. ExecuteForward(g_fwUserInfected_post, g_fwDummyResult, id, infector, nemesis)
  5916.  
  5917. // Last Zombie Check
  5918. fnCheckLastZombie()
  5919. }
  5920.  
  5921. // Function Human Me (player id, turn into a survivor, silent mode)
  5922. humanme(id, survivor, silentmode)
  5923. {
  5924. // User humanize attempt forward
  5925. ExecuteForward(g_fwUserHumanize_attempt, g_fwDummyResult, id, survivor)
  5926.  
  5927. // One or more plugins blocked the "humanization". Only allow this after making sure it's
  5928. // not going to leave us with no humans. Take into account a last player leaving case.
  5929. // BUGFIX: only allow after a mode has started, to prevent blocking first survivor e.g.
  5930. if (g_fwDummyResult >= ZP_PLUGIN_HANDLED && g_modestarted && fnGetHumans() > g_lastplayerleaving)
  5931. return;
  5932.  
  5933. // Pre user humanize forward
  5934. ExecuteForward(g_fwUserHumanized_pre, g_fwDummyResult, id, survivor)
  5935.  
  5936. // Remove previous tasks
  5937. remove_task(id+TASK_MODEL)
  5938. remove_task(id+TASK_BLOOD)
  5939. remove_task(id+TASK_AURA)
  5940. remove_task(id+TASK_BURN)
  5941. remove_task(id+TASK_NVISION)
  5942.  
  5943. // Reset some vars
  5944. g_zombie[id] = false
  5945. g_nemesis[id] = false
  5946. g_survivor[id] = false
  5947. g_firstzombie[id] = false
  5948. g_canbuy[id] = true
  5949. g_nvision[id] = false
  5950. g_nvisionenabled[id] = false
  5951.  
  5952. // Remove survivor's aura (bugfix)
  5953. set_pev(id, pev_effects, pev(id, pev_effects) &~ EF_BRIGHTLIGHT)
  5954.  
  5955. // Remove spawn protection (bugfix)
  5956. g_nodamage[id] = false
  5957. set_pev(id, pev_effects, pev(id, pev_effects) &~ EF_NODRAW)
  5958.  
  5959. // Reset burning duration counter (bugfix)
  5960. g_burning_duration[id] = 0
  5961.  
  5962. // Drop previous weapons
  5963. drop_weapons(id, 1)
  5964. drop_weapons(id, 2)
  5965.  
  5966. // Strip off from weapons
  5967. fm_strip_user_weapons(id)
  5968. fm_give_item(id, "weapon_knife")
  5969.  
  5970. // Set human attributes based on the mode
  5971. if (survivor)
  5972. {
  5973. // Survivor
  5974. g_survivor[id] = true
  5975.  
  5976. // Set Health [0 = auto]
  5977. if (get_pcvar_num(cvar_survhp) == 0)
  5978. {
  5979. if (get_pcvar_num(cvar_survbasehp) == 0)
  5980. fm_set_user_health(id, get_pcvar_num(cvar_humanhp) * fnGetAlive())
  5981. else
  5982. fm_set_user_health(id, get_pcvar_num(cvar_survbasehp) * fnGetAlive())
  5983. }
  5984. else
  5985. fm_set_user_health(id, get_pcvar_num(cvar_survhp))
  5986.  
  5987. // Set gravity, unless frozen
  5988. if (!g_frozen[id]) set_pev(id, pev_gravity, get_pcvar_float(cvar_survgravity))
  5989.  
  5990. // Give survivor his own weapon
  5991. static survweapon[32]
  5992. get_pcvar_string(cvar_survweapon, survweapon, charsmax(survweapon))
  5993. fm_give_item(id, survweapon)
  5994. ExecuteHamB(Ham_GiveAmmo, id, MAXBPAMMO[cs_weapon_name_to_id(survweapon)], AMMOTYPE[cs_weapon_name_to_id(survweapon)], MAXBPAMMO[cs_weapon_name_to_id(survweapon)])
  5995.  
  5996. // Turn off his flashlight
  5997. turn_off_flashlight(id)
  5998.  
  5999. // Give the survivor a bright light
  6000. if (get_pcvar_num(cvar_survaura)) set_pev(id, pev_effects, pev(id, pev_effects) | EF_BRIGHTLIGHT)
  6001.  
  6002. // Survivor bots will also need nightvision to see in the dark
  6003. if (g_isbot[id])
  6004. {
  6005. g_nvision[id] = true
  6006. cs_set_user_nvg(id, 1)
  6007. }
  6008. }
  6009. else
  6010. {
  6011. // Human taking an antidote
  6012.  
  6013. // Set health
  6014. fm_set_user_health(id, get_pcvar_num(cvar_humanhp))
  6015.  
  6016. // Set gravity, unless frozen
  6017. if (!g_frozen[id]) set_pev(id, pev_gravity, get_pcvar_float(cvar_humangravity))
  6018.  
  6019. // Show custom buy menu?
  6020. if (get_pcvar_num(cvar_buycustom))
  6021. set_task(0.2, "show_menu_buy1", id+TASK_SPAWN)
  6022.  
  6023. // Silent mode = no HUD messages, no antidote sound
  6024. if (!silentmode)
  6025. {
  6026. // Antidote sound
  6027. static sound[64]
  6028. ArrayGetString(sound_antidote, random_num(0, ArraySize(sound_antidote) - 1), sound, charsmax(sound))
  6029. emit_sound(id, CHAN_ITEM, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  6030.  
  6031. // Show Antidote HUD notice
  6032. set_hudmessage(0, 0, 255, HUD_INFECT_X, HUD_INFECT_Y, 0, 0.0, 5.0, 1.0, 1.0, -1)
  6033. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_ANTIDOTE", g_playername[id])
  6034. }
  6035. }
  6036.  
  6037. // Switch to CT
  6038. if (fm_cs_get_user_team(id) != FM_CS_TEAM_CT) // need to change team?
  6039. {
  6040. remove_task(id+TASK_TEAM)
  6041. fm_cs_set_user_team(id, FM_CS_TEAM_CT)
  6042. fm_user_team_update(id)
  6043. }
  6044.  
  6045. // Custom models stuff
  6046. static currentmodel[32], tempmodel[32], already_has_model, i, iRand, size
  6047. already_has_model = false
  6048.  
  6049. if (g_handle_models_on_separate_ent)
  6050. {
  6051. // Set the right model
  6052. if (g_survivor[id])
  6053. {
  6054. iRand = random_num(0, ArraySize(model_survivor) - 1)
  6055. ArrayGetString(model_survivor, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  6056. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_survivor, iRand))
  6057. }
  6058. else
  6059. {
  6060. if (get_pcvar_num(cvar_adminmodelshuman) && (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS]))
  6061. {
  6062. iRand = random_num(0, ArraySize(model_admin_human) - 1)
  6063. ArrayGetString(model_admin_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  6064. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_admin_human, iRand))
  6065. }
  6066. else
  6067. {
  6068. iRand = random_num(0, ArraySize(model_human) - 1)
  6069. ArrayGetString(model_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  6070. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_human, iRand))
  6071. }
  6072. }
  6073.  
  6074. // Set model on player model entity
  6075. fm_set_playermodel_ent(id)
  6076.  
  6077. // Set survivor glow / remove glow on player model entity, unless frozen
  6078. if (!g_frozen[id])
  6079. {
  6080. if (g_survivor[id] && get_pcvar_num(cvar_survglow))
  6081. fm_set_rendering(g_ent_playermodel[id], kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 25)
  6082. else
  6083. fm_set_rendering(g_ent_playermodel[id])
  6084. }
  6085. }
  6086. else
  6087. {
  6088. // Get current model for comparing it with the current one
  6089. fm_cs_get_user_model(id, currentmodel, charsmax(currentmodel))
  6090.  
  6091. // Set the right model, after checking that we don't already have it
  6092. if (g_survivor[id])
  6093. {
  6094. size = ArraySize(model_survivor)
  6095. for (i = 0; i < size; i++)
  6096. {
  6097. ArrayGetString(model_survivor, i, tempmodel, charsmax(tempmodel))
  6098. if (equal(currentmodel, tempmodel)) already_has_model = true
  6099. }
  6100.  
  6101. if (!already_has_model)
  6102. {
  6103. iRand = random_num(0, size - 1)
  6104. ArrayGetString(model_survivor, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  6105. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_survivor, iRand))
  6106. }
  6107. }
  6108. else
  6109. {
  6110. if (get_pcvar_num(cvar_adminmodelshuman) && (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS]))
  6111. {
  6112. size = ArraySize(model_admin_human)
  6113. for (i = 0; i < size; i++)
  6114. {
  6115. ArrayGetString(model_admin_human, i, tempmodel, charsmax(tempmodel))
  6116. if (equal(currentmodel, tempmodel)) already_has_model = true
  6117. }
  6118.  
  6119. if (!already_has_model)
  6120. {
  6121. iRand = random_num(0, size - 1)
  6122. ArrayGetString(model_admin_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  6123. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_admin_human, iRand))
  6124. }
  6125. }
  6126. else
  6127. {
  6128. size = ArraySize(model_human)
  6129. for (i = 0; i < size; i++)
  6130. {
  6131. ArrayGetString(model_human, i, tempmodel, charsmax(tempmodel))
  6132. if (equal(currentmodel, tempmodel)) already_has_model = true
  6133. }
  6134.  
  6135. if (!already_has_model)
  6136. {
  6137. iRand = random_num(0, size - 1)
  6138. ArrayGetString(model_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  6139. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_human, iRand))
  6140. }
  6141. }
  6142. }
  6143.  
  6144. // Need to change the model?
  6145. if (!already_has_model)
  6146. {
  6147. // An additional delay is offset at round start
  6148. // since SVC_BAD is more likely to be triggered there
  6149. if (g_newround)
  6150. set_task(5.0 * g_modelchange_delay, "fm_user_model_update", id+TASK_MODEL)
  6151. else
  6152. fm_user_model_update(id+TASK_MODEL)
  6153. }
  6154.  
  6155. // Set survivor glow / remove glow, unless frozen
  6156. if (!g_frozen[id])
  6157. {
  6158. if (g_survivor[id] && get_pcvar_num(cvar_survglow))
  6159. fm_set_rendering(id, kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 25)
  6160. else
  6161. fm_set_rendering(id)
  6162. }
  6163. }
  6164.  
  6165. // Restore FOV?
  6166. if (get_pcvar_num(cvar_zombiefov) != 90 && get_pcvar_num(cvar_zombiefov) != 0)
  6167. {
  6168. message_begin(MSG_ONE, g_msgSetFOV, _, id)
  6169. write_byte(90) // angle
  6170. message_end()
  6171. }
  6172.  
  6173. // Disable nightvision
  6174. if (g_isbot[id]) cs_set_user_nvg(id, 0)
  6175. else if (!get_pcvar_num(cvar_customnvg) && g_nvisionenabled[id]) set_user_gnvision(id, 0)
  6176.  
  6177. // Post user humanize forward
  6178. ExecuteForward(g_fwUserHumanized_post, g_fwDummyResult, id, survivor)
  6179.  
  6180. // Last Zombie Check
  6181. fnCheckLastZombie()
  6182. }
  6183.  
  6184. /*================================================================================
  6185. [Other Functions and Tasks]
  6186. =================================================================================*/
  6187.  
  6188. public cache_cvars()
  6189. {
  6190. g_cached_zombiesilent = get_pcvar_num(cvar_zombiesilent)
  6191. g_cached_customflash = get_pcvar_num(cvar_customflash)
  6192. g_cached_humanspd = get_pcvar_float(cvar_humanspd)
  6193. g_cached_nemspd = get_pcvar_float(cvar_nemspd)
  6194. g_cached_survspd = get_pcvar_float(cvar_survspd)
  6195. g_cached_leapzombies = get_pcvar_num(cvar_leapzombies)
  6196. g_cached_leapzombiescooldown = get_pcvar_float(cvar_leapzombiescooldown)
  6197. g_cached_leapnemesis = get_pcvar_num(cvar_leapnemesis)
  6198. g_cached_leapnemesiscooldown = get_pcvar_float(cvar_leapnemesiscooldown)
  6199. g_cached_leapsurvivor = get_pcvar_num(cvar_leapsurvivor)
  6200. g_cached_leapsurvivorcooldown = get_pcvar_float(cvar_leapsurvivorcooldown)
  6201. }
  6202.  
  6203. load_customization_from_files()
  6204. {
  6205. // Build customization file path
  6206. new path[64]
  6207. get_configsdir(path, charsmax(path))
  6208. format(path, charsmax(path), "%s/%s", path, ZP_CUSTOMIZATION_FILE)
  6209.  
  6210. // File not present
  6211. if (!file_exists(path))
  6212. {
  6213. new error[100]
  6214. formatex(error, charsmax(error), "Cannot load customization file %s!", path)
  6215. set_fail_state(error)
  6216. return;
  6217. }
  6218.  
  6219. // Set up some vars to hold parsing info
  6220. new linedata[1024], key[64], value[960], section, teams
  6221.  
  6222. // Open customization file for reading
  6223. new file = fopen(path, "rt")
  6224.  
  6225. while (file && !feof(file))
  6226. {
  6227. // Read one line at a time
  6228. fgets(file, linedata, charsmax(linedata))
  6229.  
  6230. // Replace newlines with a null character to prevent headaches
  6231. replace(linedata, charsmax(linedata), "^n", "")
  6232.  
  6233. // Blank line or comment
  6234. if (!linedata[0] || linedata[0] == ';') continue;
  6235.  
  6236. // New section starting
  6237. if (linedata[0] == '[')
  6238. {
  6239. section++
  6240. continue;
  6241. }
  6242.  
  6243. // Get key and value(s)
  6244. strtok(linedata, key, charsmax(key), value, charsmax(value), '=')
  6245.  
  6246. // Trim spaces
  6247. trim(key)
  6248. trim(value)
  6249.  
  6250. switch (section)
  6251. {
  6252. case SECTION_ACCESS_FLAGS:
  6253. {
  6254. if (equal(key, "ENABLE/DISABLE MOD"))
  6255. g_access_flag[ACCESS_ENABLE_MOD] = read_flags(value)
  6256. else if (equal(key, "ADMIN MENU"))
  6257. g_access_flag[ACCESS_ADMIN_MENU] = read_flags(value)
  6258. else if (equal(key, "START MODE INFECTION"))
  6259. g_access_flag[ACCESS_MODE_INFECTION] = read_flags(value)
  6260. else if (equal(key, "START MODE NEMESIS"))
  6261. g_access_flag[ACCESS_MODE_NEMESIS] = read_flags(value)
  6262. else if (equal(key, "START MODE SURVIVOR"))
  6263. g_access_flag[ACCESS_MODE_SURVIVOR] = read_flags(value)
  6264. else if (equal(key, "START MODE SWARM"))
  6265. g_access_flag[ACCESS_MODE_SWARM] = read_flags(value)
  6266. else if (equal(key, "START MODE MULTI"))
  6267. g_access_flag[ACCESS_MODE_MULTI] = read_flags(value)
  6268. else if (equal(key, "START MODE PLAGUE"))
  6269. g_access_flag[ACCESS_MODE_PLAGUE] = read_flags(value)
  6270. else if (equal(key, "MAKE ZOMBIE"))
  6271. g_access_flag[ACCESS_MAKE_ZOMBIE] = read_flags(value)
  6272. else if (equal(key, "MAKE HUMAN"))
  6273. g_access_flag[ACCESS_MAKE_HUMAN] = read_flags(value)
  6274. else if (equal(key, "MAKE NEMESIS"))
  6275. g_access_flag[ACCESS_MAKE_NEMESIS] = read_flags(value)
  6276. else if (equal(key, "MAKE SURVIVOR"))
  6277. g_access_flag[ACCESS_MAKE_SURVIVOR] = read_flags(value)
  6278. else if (equal(key, "RESPAWN PLAYERS"))
  6279. g_access_flag[ACCESS_RESPAWN_PLAYERS] = read_flags(value)
  6280. else if (equal(key, "ADMIN MODELS"))
  6281. g_access_flag[ACCESS_ADMIN_MODELS] = read_flags(value)
  6282. }
  6283. case SECTION_PLAYER_MODELS:
  6284. {
  6285. if (equal(key, "HUMAN"))
  6286. {
  6287. // Parse models
  6288. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6289. {
  6290. // Trim spaces
  6291. trim(key)
  6292. trim(value)
  6293.  
  6294. // Add to models array
  6295. ArrayPushString(model_human, key)
  6296. }
  6297. }
  6298. else if (equal(key, "NEMESIS"))
  6299. {
  6300. // Parse models
  6301. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6302. {
  6303. // Trim spaces
  6304. trim(key)
  6305. trim(value)
  6306.  
  6307. // Add to models array
  6308. ArrayPushString(model_nemesis, key)
  6309. }
  6310. }
  6311. else if (equal(key, "SURVIVOR"))
  6312. {
  6313. // Parse models
  6314. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6315. {
  6316. // Trim spaces
  6317. trim(key)
  6318. trim(value)
  6319.  
  6320. // Add to models array
  6321. ArrayPushString(model_survivor, key)
  6322. }
  6323. }
  6324. else if (equal(key, "ADMIN ZOMBIE"))
  6325. {
  6326. // Parse models
  6327. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6328. {
  6329. // Trim spaces
  6330. trim(key)
  6331. trim(value)
  6332.  
  6333. // Add to models array
  6334. ArrayPushString(model_admin_zombie, key)
  6335. }
  6336. }
  6337. else if (equal(key, "ADMIN HUMAN"))
  6338. {
  6339. // Parse models
  6340. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6341. {
  6342. // Trim spaces
  6343. trim(key)
  6344. trim(value)
  6345.  
  6346. // Add to models array
  6347. ArrayPushString(model_admin_human, key)
  6348. }
  6349. }
  6350. else if (equal(key, "FORCE CONSISTENCY"))
  6351. g_force_consistency = str_to_num(value)
  6352. else if (equal(key, "SAME MODELS FOR ALL"))
  6353. g_same_models_for_all = str_to_num(value)
  6354. else if (g_same_models_for_all && equal(key, "ZOMBIE"))
  6355. {
  6356. // Parse models
  6357. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6358. {
  6359. // Trim spaces
  6360. trim(key)
  6361. trim(value)
  6362.  
  6363. // Add to models array
  6364. ArrayPushString(g_zclass_playermodel, key)
  6365.  
  6366. // Precache model and retrieve its modelindex
  6367. formatex(linedata, charsmax(linedata), "models/player/%s/%s.mdl", key, key)
  6368. ArrayPushCell(g_zclass_modelindex, engfunc(EngFunc_PrecacheModel, linedata))
  6369. if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, linedata)
  6370. if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, linedata)
  6371. }
  6372. }
  6373. }
  6374. case SECTION_WEAPON_MODELS:
  6375. {
  6376. if (equal(key, "V_KNIFE HUMAN"))
  6377. copy(model_vknife_human, charsmax(model_vknife_human), value)
  6378. else if (equal(key, "V_KNIFE NEMESIS"))
  6379. copy(model_vknife_nemesis, charsmax(model_vknife_nemesis), value)
  6380. else if (equal(key, "V_M249 SURVIVOR"))
  6381. copy(model_vm249_survivor, charsmax(model_vm249_survivor), value)
  6382. else if (equal(key, "GRENADE INFECT"))
  6383. copy(model_grenade_infect, charsmax(model_grenade_infect), value)
  6384. else if (equal(key, "GRENADE FIRE"))
  6385. copy(model_grenade_fire, charsmax(model_grenade_fire), value)
  6386. else if (equal(key, "GRENADE FROST"))
  6387. copy(model_grenade_frost, charsmax(model_grenade_frost), value)
  6388. else if (equal(key, "GRENADE FLARE"))
  6389. copy(model_grenade_flare, charsmax(model_grenade_flare), value)
  6390. else if (equal(key, "V_KNIFE ADMIN HUMAN"))
  6391. copy(model_vknife_admin_human, charsmax(model_vknife_admin_human), value)
  6392. else if (equal(key, "V_KNIFE ADMIN ZOMBIE"))
  6393. copy(model_vknife_admin_zombie, charsmax(model_vknife_admin_zombie), value)
  6394. }
  6395. case SECTION_GRENADE_SPRITES:
  6396. {
  6397. if (equal(key, "TRAIL"))
  6398. copy(sprite_grenade_trail, charsmax(sprite_grenade_trail), value)
  6399. else if (equal(key, "RING"))
  6400. copy(sprite_grenade_ring, charsmax(sprite_grenade_ring), value)
  6401. else if (equal(key, "FIRE"))
  6402. copy(sprite_grenade_fire, charsmax(sprite_grenade_fire), value)
  6403. else if (equal(key, "SMOKE"))
  6404. copy(sprite_grenade_smoke, charsmax(sprite_grenade_smoke), value)
  6405. else if (equal(key, "GLASS"))
  6406. copy(sprite_grenade_glass, charsmax(sprite_grenade_glass), value)
  6407. }
  6408. case SECTION_SOUNDS:
  6409. {
  6410. if (equal(key, "WIN ZOMBIES"))
  6411. {
  6412. // Parse sounds
  6413. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6414. {
  6415. // Trim spaces
  6416. trim(key)
  6417. trim(value)
  6418.  
  6419. // Add to sounds array
  6420. ArrayPushString(sound_win_zombies, key)
  6421. }
  6422. }
  6423. else if (equal(key, "WIN HUMANS"))
  6424. {
  6425. // Parse sounds
  6426. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6427. {
  6428. // Trim spaces
  6429. trim(key)
  6430. trim(value)
  6431.  
  6432. // Add to sounds array
  6433. ArrayPushString(sound_win_humans, key)
  6434. }
  6435. }
  6436. else if (equal(key, "WIN NO ONE"))
  6437. {
  6438. // Parse sounds
  6439. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6440. {
  6441. // Trim spaces
  6442. trim(key)
  6443. trim(value)
  6444.  
  6445. // Add to sounds array
  6446. ArrayPushString(sound_win_no_one, key)
  6447. }
  6448. }
  6449. else if (equal(key, "ZOMBIE INFECT"))
  6450. {
  6451. // Parse sounds
  6452. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6453. {
  6454. // Trim spaces
  6455. trim(key)
  6456. trim(value)
  6457.  
  6458. // Add to sounds array
  6459. ArrayPushString(zombie_infect, key)
  6460. }
  6461. }
  6462. else if (equal(key, "ZOMBIE PAIN"))
  6463. {
  6464. // Parse sounds
  6465. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6466. {
  6467. // Trim spaces
  6468. trim(key)
  6469. trim(value)
  6470.  
  6471. // Add to sounds array
  6472. ArrayPushString(zombie_pain, key)
  6473. }
  6474. }
  6475. else if (equal(key, "NEMESIS PAIN"))
  6476. {
  6477. // Parse sounds
  6478. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6479. {
  6480. // Trim spaces
  6481. trim(key)
  6482. trim(value)
  6483.  
  6484. // Add to sounds array
  6485. ArrayPushString(nemesis_pain, key)
  6486. }
  6487. }
  6488. else if (equal(key, "ZOMBIE DIE"))
  6489. {
  6490. // Parse sounds
  6491. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6492. {
  6493. // Trim spaces
  6494. trim(key)
  6495. trim(value)
  6496.  
  6497. // Add to sounds array
  6498. ArrayPushString(zombie_die, key)
  6499. }
  6500. }
  6501. else if (equal(key, "ZOMBIE FALL"))
  6502. {
  6503. // Parse sounds
  6504. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6505. {
  6506. // Trim spaces
  6507. trim(key)
  6508. trim(value)
  6509.  
  6510. // Add to sounds array
  6511. ArrayPushString(zombie_fall, key)
  6512. }
  6513. }
  6514. else if (equal(key, "ZOMBIE MISS SLASH"))
  6515. {
  6516. // Parse sounds
  6517. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6518. {
  6519. // Trim spaces
  6520. trim(key)
  6521. trim(value)
  6522.  
  6523. // Add to sounds array
  6524. ArrayPushString(zombie_miss_slash, key)
  6525. }
  6526. }
  6527. else if (equal(key, "ZOMBIE MISS WALL"))
  6528. {
  6529. // Parse sounds
  6530. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6531. {
  6532. // Trim spaces
  6533. trim(key)
  6534. trim(value)
  6535.  
  6536. // Add to sounds array
  6537. ArrayPushString(zombie_miss_wall, key)
  6538. }
  6539. }
  6540. else if (equal(key, "ZOMBIE HIT NORMAL"))
  6541. {
  6542. // Parse sounds
  6543. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6544. {
  6545. // Trim spaces
  6546. trim(key)
  6547. trim(value)
  6548.  
  6549. // Add to sounds array
  6550. ArrayPushString(zombie_hit_normal, key)
  6551. }
  6552. }
  6553. else if (equal(key, "ZOMBIE HIT STAB"))
  6554. {
  6555. // Parse sounds
  6556. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6557. {
  6558. // Trim spaces
  6559. trim(key)
  6560. trim(value)
  6561.  
  6562. // Add to sounds array
  6563. ArrayPushString(zombie_hit_stab, key)
  6564. }
  6565. }
  6566. else if (equal(key, "ZOMBIE IDLE"))
  6567. {
  6568. // Parse sounds
  6569. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6570. {
  6571. // Trim spaces
  6572. trim(key)
  6573. trim(value)
  6574.  
  6575. // Add to sounds array
  6576. ArrayPushString(zombie_idle, key)
  6577. }
  6578. }
  6579. else if (equal(key, "ZOMBIE IDLE LAST"))
  6580. {
  6581. // Parse sounds
  6582. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6583. {
  6584. // Trim spaces
  6585. trim(key)
  6586. trim(value)
  6587.  
  6588. // Add to sounds array
  6589. ArrayPushString(zombie_idle_last, key)
  6590. }
  6591. }
  6592. else if (equal(key, "ZOMBIE MADNESS"))
  6593. {
  6594. // Parse sounds
  6595. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6596. {
  6597. // Trim spaces
  6598. trim(key)
  6599. trim(value)
  6600.  
  6601. // Add to sounds array
  6602. ArrayPushString(zombie_madness, key)
  6603. }
  6604. }
  6605. else if (equal(key, "ROUND NEMESIS"))
  6606. {
  6607. // Parse sounds
  6608. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6609. {
  6610. // Trim spaces
  6611. trim(key)
  6612. trim(value)
  6613.  
  6614. // Add to sounds array
  6615. ArrayPushString(sound_nemesis, key)
  6616. }
  6617. }
  6618. else if (equal(key, "ROUND SURVIVOR"))
  6619. {
  6620. // Parse sounds
  6621. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6622. {
  6623. // Trim spaces
  6624. trim(key)
  6625. trim(value)
  6626.  
  6627. // Add to sounds array
  6628. ArrayPushString(sound_survivor, key)
  6629. }
  6630. }
  6631. else if (equal(key, "ROUND SWARM"))
  6632. {
  6633. // Parse sounds
  6634. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6635. {
  6636. // Trim spaces
  6637. trim(key)
  6638. trim(value)
  6639.  
  6640. // Add to sounds array
  6641. ArrayPushString(sound_swarm, key)
  6642. }
  6643. }
  6644. else if (equal(key, "ROUND MULTI"))
  6645. {
  6646. // Parse sounds
  6647. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6648. {
  6649. // Trim spaces
  6650. trim(key)
  6651. trim(value)
  6652.  
  6653. // Add to sounds array
  6654. ArrayPushString(sound_multi, key)
  6655. }
  6656. }
  6657. else if (equal(key, "ROUND PLAGUE"))
  6658. {
  6659. // Parse sounds
  6660. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6661. {
  6662. // Trim spaces
  6663. trim(key)
  6664. trim(value)
  6665.  
  6666. // Add to sounds array
  6667. ArrayPushString(sound_plague, key)
  6668. }
  6669. }
  6670. else if (equal(key, "GRENADE INFECT EXPLODE"))
  6671. {
  6672. // Parse sounds
  6673. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6674. {
  6675. // Trim spaces
  6676. trim(key)
  6677. trim(value)
  6678.  
  6679. // Add to sounds array
  6680. ArrayPushString(grenade_infect, key)
  6681. }
  6682. }
  6683. else if (equal(key, "GRENADE INFECT PLAYER"))
  6684. {
  6685. // Parse sounds
  6686. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6687. {
  6688. // Trim spaces
  6689. trim(key)
  6690. trim(value)
  6691.  
  6692. // Add to sounds array
  6693. ArrayPushString(grenade_infect_player, key)
  6694. }
  6695. }
  6696. else if (equal(key, "GRENADE FIRE EXPLODE"))
  6697. {
  6698. // Parse sounds
  6699. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6700. {
  6701. // Trim spaces
  6702. trim(key)
  6703. trim(value)
  6704.  
  6705. // Add to sounds array
  6706. ArrayPushString(grenade_fire, key)
  6707. }
  6708. }
  6709. else if (equal(key, "GRENADE FIRE PLAYER"))
  6710. {
  6711. // Parse sounds
  6712. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6713. {
  6714. // Trim spaces
  6715. trim(key)
  6716. trim(value)
  6717.  
  6718. // Add to sounds array
  6719. ArrayPushString(grenade_fire_player, key)
  6720. }
  6721. }
  6722. else if (equal(key, "GRENADE FROST EXPLODE"))
  6723. {
  6724. // Parse sounds
  6725. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6726. {
  6727. // Trim spaces
  6728. trim(key)
  6729. trim(value)
  6730.  
  6731. // Add to sounds array
  6732. ArrayPushString(grenade_frost, key)
  6733. }
  6734. }
  6735. else if (equal(key, "GRENADE FROST PLAYER"))
  6736. {
  6737. // Parse sounds
  6738. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6739. {
  6740. // Trim spaces
  6741. trim(key)
  6742. trim(value)
  6743.  
  6744. // Add to sounds array
  6745. ArrayPushString(grenade_frost_player, key)
  6746. }
  6747. }
  6748. else if (equal(key, "GRENADE FROST BREAK"))
  6749. {
  6750. // Parse sounds
  6751. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6752. {
  6753. // Trim spaces
  6754. trim(key)
  6755. trim(value)
  6756.  
  6757. // Add to sounds array
  6758. ArrayPushString(grenade_frost_break, key)
  6759. }
  6760. }
  6761. else if (equal(key, "GRENADE FLARE"))
  6762. {
  6763. // Parse sounds
  6764. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6765. {
  6766. // Trim spaces
  6767. trim(key)
  6768. trim(value)
  6769.  
  6770. // Add to sounds array
  6771. ArrayPushString(grenade_flare, key)
  6772. }
  6773. }
  6774. else if (equal(key, "ANTIDOTE"))
  6775. {
  6776. // Parse sounds
  6777. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6778. {
  6779. // Trim spaces
  6780. trim(key)
  6781. trim(value)
  6782.  
  6783. // Add to sounds array
  6784. ArrayPushString(sound_antidote, key)
  6785. }
  6786. }
  6787. else if (equal(key, "THUNDER"))
  6788. {
  6789. // Parse sounds
  6790. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6791. {
  6792. // Trim spaces
  6793. trim(key)
  6794. trim(value)
  6795.  
  6796. // Add to sounds array
  6797. ArrayPushString(sound_thunder, key)
  6798. }
  6799. }
  6800. }
  6801. case SECTION_AMBIENCE_SOUNDS:
  6802. {
  6803. if (equal(key, "INFECTION ENABLE"))
  6804. g_ambience_sounds[AMBIENCE_SOUNDS_INFECTION] = str_to_num(value)
  6805. else if (g_ambience_sounds[AMBIENCE_SOUNDS_INFECTION] && equal(key, "INFECTION SOUNDS"))
  6806. {
  6807. // Parse sounds
  6808. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6809. {
  6810. // Trim spaces
  6811. trim(key)
  6812. trim(value)
  6813.  
  6814. // Add to sounds array
  6815. ArrayPushString(sound_ambience1, key)
  6816. ArrayPushCell(sound_ambience1_ismp3, equal(key[strlen(key)-4], ".mp3") ? 1 : 0)
  6817. }
  6818. }
  6819. else if (g_ambience_sounds[AMBIENCE_SOUNDS_INFECTION] && equal(key, "INFECTION DURATIONS"))
  6820. {
  6821. // Parse sounds
  6822. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6823. {
  6824. // Trim spaces
  6825. trim(key)
  6826. trim(value)
  6827.  
  6828. // Add to sounds array
  6829. ArrayPushCell(sound_ambience1_duration, str_to_num(key))
  6830. }
  6831. }
  6832. else if (equal(key, "NEMESIS ENABLE"))
  6833. g_ambience_sounds[AMBIENCE_SOUNDS_NEMESIS] = str_to_num(value)
  6834. else if (g_ambience_sounds[AMBIENCE_SOUNDS_NEMESIS] && equal(key, "NEMESIS SOUNDS"))
  6835. {
  6836. // Parse sounds
  6837. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6838. {
  6839. // Trim spaces
  6840. trim(key)
  6841. trim(value)
  6842.  
  6843. // Add to sounds array
  6844. ArrayPushString(sound_ambience2, key)
  6845. ArrayPushCell(sound_ambience2_ismp3, equal(key[strlen(key)-4], ".mp3") ? 1 : 0)
  6846. }
  6847. }
  6848. else if (g_ambience_sounds[AMBIENCE_SOUNDS_NEMESIS] && equal(key, "NEMESIS DURATIONS"))
  6849. {
  6850. // Parse sounds
  6851. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6852. {
  6853. // Trim spaces
  6854. trim(key)
  6855. trim(value)
  6856.  
  6857. // Add to sounds array
  6858. ArrayPushCell(sound_ambience2_duration, str_to_num(key))
  6859. }
  6860. }
  6861. else if (equal(key, "SURVIVOR ENABLE"))
  6862. g_ambience_sounds[AMBIENCE_SOUNDS_SURVIVOR] = str_to_num(value)
  6863. else if (g_ambience_sounds[AMBIENCE_SOUNDS_SURVIVOR] && equal(key, "SURVIVOR SOUNDS"))
  6864. {
  6865. // Parse sounds
  6866. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6867. {
  6868. // Trim spaces
  6869. trim(key)
  6870. trim(value)
  6871.  
  6872. // Add to sounds array
  6873. ArrayPushString(sound_ambience3, key)
  6874. ArrayPushCell(sound_ambience3_ismp3, equal(key[strlen(key)-4], ".mp3") ? 1 : 0)
  6875. }
  6876. }
  6877. else if (g_ambience_sounds[AMBIENCE_SOUNDS_SURVIVOR] && equal(key, "SURVIVOR DURATIONS"))
  6878. {
  6879. // Parse sounds
  6880. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6881. {
  6882. // Trim spaces
  6883. trim(key)
  6884. trim(value)
  6885.  
  6886. // Add to sounds array
  6887. ArrayPushCell(sound_ambience3_duration, str_to_num(key))
  6888. }
  6889. }
  6890. else if (equal(key, "SWARM ENABLE"))
  6891. g_ambience_sounds[AMBIENCE_SOUNDS_SWARM] = str_to_num(value)
  6892. else if (g_ambience_sounds[AMBIENCE_SOUNDS_SWARM] && equal(key, "SWARM SOUNDS"))
  6893. {
  6894. // Parse sounds
  6895. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6896. {
  6897. // Trim spaces
  6898. trim(key)
  6899. trim(value)
  6900.  
  6901. // Add to sounds array
  6902. ArrayPushString(sound_ambience4, key)
  6903. ArrayPushCell(sound_ambience4_ismp3, equal(key[strlen(key)-4], ".mp3") ? 1 : 0)
  6904. }
  6905. }
  6906. else if (g_ambience_sounds[AMBIENCE_SOUNDS_SWARM] && equal(key, "SWARM DURATIONS"))
  6907. {
  6908. // Parse sounds
  6909. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6910. {
  6911. // Trim spaces
  6912. trim(key)
  6913. trim(value)
  6914.  
  6915. // Add to sounds array
  6916. ArrayPushCell(sound_ambience4_duration, str_to_num(key))
  6917. }
  6918. }
  6919. else if (equal(key, "PLAGUE ENABLE"))
  6920. g_ambience_sounds[AMBIENCE_SOUNDS_PLAGUE] = str_to_num(value)
  6921. else if (g_ambience_sounds[AMBIENCE_SOUNDS_PLAGUE] && equal(key, "PLAGUE SOUNDS"))
  6922. {
  6923. // Parse sounds
  6924. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6925. {
  6926. // Trim spaces
  6927. trim(key)
  6928. trim(value)
  6929.  
  6930. // Add to sounds array
  6931. ArrayPushString(sound_ambience5, key)
  6932. ArrayPushCell(sound_ambience5_ismp3, equal(key[strlen(key)-4], ".mp3") ? 1 : 0)
  6933. }
  6934. }
  6935. else if (g_ambience_sounds[AMBIENCE_SOUNDS_PLAGUE] && equal(key, "PLAGUE DURATIONS"))
  6936. {
  6937. // Parse sounds
  6938. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6939. {
  6940. // Trim spaces
  6941. trim(key)
  6942. trim(value)
  6943.  
  6944. // Add to sounds array
  6945. ArrayPushCell(sound_ambience5_duration, str_to_num(key))
  6946. }
  6947. }
  6948. }
  6949. case SECTION_BUY_MENU_WEAPONS:
  6950. {
  6951. if (equal(key, "PRIMARY"))
  6952. {
  6953. // Parse weapons
  6954. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6955. {
  6956. // Trim spaces
  6957. trim(key)
  6958. trim(value)
  6959.  
  6960. // Add to weapons array
  6961. ArrayPushString(g_primary_items, key)
  6962. ArrayPushCell(g_primary_weaponids, cs_weapon_name_to_id(key))
  6963. }
  6964. }
  6965. else if (equal(key, "SECONDARY"))
  6966. {
  6967. // Parse weapons
  6968. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6969. {
  6970. // Trim spaces
  6971. trim(key)
  6972. trim(value)
  6973.  
  6974. // Add to weapons array
  6975. ArrayPushString(g_secondary_items, key)
  6976. ArrayPushCell(g_secondary_weaponids, cs_weapon_name_to_id(key))
  6977. }
  6978. }
  6979. else if (equal(key, "ADDITIONAL ITEMS"))
  6980. {
  6981. // Parse weapons
  6982. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6983. {
  6984. // Trim spaces
  6985. trim(key)
  6986. trim(value)
  6987.  
  6988. // Add to weapons array
  6989. ArrayPushString(g_additional_items, key)
  6990. }
  6991. }
  6992. }
  6993. case SECTION_EXTRA_ITEMS_WEAPONS:
  6994. {
  6995. if (equal(key, "NAMES"))
  6996. {
  6997. // Parse weapon items
  6998. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6999. {
  7000. // Trim spaces
  7001. trim(key)
  7002. trim(value)
  7003.  
  7004. // Add to weapons array
  7005. ArrayPushString(g_extraweapon_names, key)
  7006. }
  7007. }
  7008. else if (equal(key, "ITEMS"))
  7009. {
  7010. // Parse weapon items
  7011. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  7012. {
  7013. // Trim spaces
  7014. trim(key)
  7015. trim(value)
  7016.  
  7017. // Add to weapons array
  7018. ArrayPushString(g_extraweapon_items, key)
  7019. }
  7020. }
  7021. else if (equal(key, "COSTS"))
  7022. {
  7023. // Parse weapon items
  7024. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  7025. {
  7026. // Trim spaces
  7027. trim(key)
  7028. trim(value)
  7029.  
  7030. // Add to weapons array
  7031. ArrayPushCell(g_extraweapon_costs, str_to_num(key))
  7032. }
  7033. }
  7034. }
  7035. case SECTION_HARD_CODED_ITEMS_COSTS:
  7036. {
  7037. if (equal(key, "NIGHT VISION"))
  7038. g_extra_costs2[EXTRA_NVISION] = str_to_num(value)
  7039. else if (equal(key, "ANTIDOTE"))
  7040. g_extra_costs2[EXTRA_ANTIDOTE] = str_to_num(value)
  7041. else if (equal(key, "ZOMBIE MADNESS"))
  7042. g_extra_costs2[EXTRA_MADNESS] = str_to_num(value)
  7043. else if (equal(key, "INFECTION BOMB"))
  7044. g_extra_costs2[EXTRA_INFBOMB] = str_to_num(value)
  7045. }
  7046. case SECTION_WEATHER_EFFECTS:
  7047. {
  7048. if (equal(key, "RAIN"))
  7049. g_ambience_rain = str_to_num(value)
  7050. else if (equal(key, "SNOW"))
  7051. g_ambience_snow = str_to_num(value)
  7052. else if (equal(key, "FOG"))
  7053. g_ambience_fog = str_to_num(value)
  7054. else if (equal(key, "FOG DENSITY"))
  7055. copy(g_fog_density, charsmax(g_fog_density), value)
  7056. else if (equal(key, "FOG COLOR"))
  7057. copy(g_fog_color, charsmax(g_fog_color), value)
  7058. }
  7059. case SECTION_SKY:
  7060. {
  7061. if (equal(key, "ENABLE"))
  7062. g_sky_enable = str_to_num(value)
  7063. else if (equal(key, "SKY NAMES"))
  7064. {
  7065. // Parse sky names
  7066. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  7067. {
  7068. // Trim spaces
  7069. trim(key)
  7070. trim(value)
  7071.  
  7072. // Add to skies array
  7073. ArrayPushString(g_sky_names, key)
  7074.  
  7075. // Preache custom sky files
  7076. formatex(linedata, charsmax(linedata), "gfx/env/%sbk.tga", key)
  7077. engfunc(EngFunc_PrecacheGeneric, linedata)
  7078. formatex(linedata, charsmax(linedata), "gfx/env/%sdn.tga", key)
  7079. engfunc(EngFunc_PrecacheGeneric, linedata)
  7080. formatex(linedata, charsmax(linedata), "gfx/env/%sft.tga", key)
  7081. engfunc(EngFunc_PrecacheGeneric, linedata)
  7082. formatex(linedata, charsmax(linedata), "gfx/env/%slf.tga", key)
  7083. engfunc(EngFunc_PrecacheGeneric, linedata)
  7084. formatex(linedata, charsmax(linedata), "gfx/env/%srt.tga", key)
  7085. engfunc(EngFunc_PrecacheGeneric, linedata)
  7086. formatex(linedata, charsmax(linedata), "gfx/env/%sup.tga", key)
  7087. engfunc(EngFunc_PrecacheGeneric, linedata)
  7088. }
  7089. }
  7090. }
  7091. case SECTION_LIGHTNING:
  7092. {
  7093. if (equal(key, "LIGHTS"))
  7094. {
  7095. // Parse lights
  7096. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  7097. {
  7098. // Trim spaces
  7099. trim(key)
  7100. trim(value)
  7101.  
  7102. // Add to lightning array
  7103. ArrayPushString(lights_thunder, key)
  7104. }
  7105. }
  7106. }
  7107. case SECTION_ZOMBIE_DECALS:
  7108. {
  7109. if (equal(key, "DECALS"))
  7110. {
  7111. // Parse decals
  7112. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  7113. {
  7114. // Trim spaces
  7115. trim(key)
  7116. trim(value)
  7117.  
  7118. // Add to zombie decals array
  7119. ArrayPushCell(zombie_decals, str_to_num(key))
  7120. }
  7121. }
  7122. }
  7123. case SECTION_KNOCKBACK:
  7124. {
  7125. // Format weapon entity name
  7126. strtolower(key)
  7127. format(key, charsmax(key), "weapon_%s", key)
  7128.  
  7129. // Add value to knockback power array
  7130. kb_weapon_power[cs_weapon_name_to_id(key)] = str_to_float(value)
  7131. }
  7132. case SECTION_OBJECTIVE_ENTS:
  7133. {
  7134. if (equal(key, "CLASSNAMES"))
  7135. {
  7136. // Parse classnames
  7137. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  7138. {
  7139. // Trim spaces
  7140. trim(key)
  7141. trim(value)
  7142.  
  7143. // Add to objective ents array
  7144. ArrayPushString(g_objective_ents, key)
  7145. }
  7146. }
  7147. }
  7148. case SECTION_SVC_BAD:
  7149. {
  7150. if (equal(key, "MODELCHANGE DELAY"))
  7151. g_modelchange_delay = str_to_float(value)
  7152. else if (equal(key, "HANDLE MODELS ON SEPARATE ENT"))
  7153. g_handle_models_on_separate_ent = str_to_num(value)
  7154. else if (equal(key, "SET MODELINDEX OFFSET"))
  7155. g_set_modelindex_offset = str_to_num(value)
  7156. }
  7157. }
  7158. }
  7159. if (file) fclose(file)
  7160.  
  7161. // Build zombie classes file path
  7162. get_configsdir(path, charsmax(path))
  7163. format(path, charsmax(path), "%s/%s", path, ZP_ZOMBIECLASSES_FILE)
  7164.  
  7165. // Parse if present
  7166. if (file_exists(path))
  7167. {
  7168. // Open zombie classes file for reading
  7169. file = fopen(path, "rt")
  7170.  
  7171. while (file && !feof(file))
  7172. {
  7173. // Read one line at a time
  7174. fgets(file, linedata, charsmax(linedata))
  7175.  
  7176. // Replace newlines with a null character to prevent headaches
  7177. replace(linedata, charsmax(linedata), "^n", "")
  7178.  
  7179. // Blank line or comment
  7180. if (!linedata[0] || linedata[0] == ';') continue;
  7181.  
  7182. // New class starting
  7183. if (linedata[0] == '[')
  7184. {
  7185. // Remove first and last characters (braces)
  7186. linedata[strlen(linedata) - 1] = 0
  7187. copy(linedata, charsmax(linedata), linedata[1])
  7188.  
  7189. // Store its real name for future reference
  7190. ArrayPushString(g_zclass2_realname, linedata)
  7191. continue;
  7192. }
  7193.  
  7194. // Get key and value(s)
  7195. strtok(linedata, key, charsmax(key), value, charsmax(value), '=')
  7196.  
  7197. // Trim spaces
  7198. trim(key)
  7199. trim(value)
  7200.  
  7201. if (equal(key, "NAME"))
  7202. ArrayPushString(g_zclass2_name, value)
  7203. else if (equal(key, "INFO"))
  7204. ArrayPushString(g_zclass2_info, value)
  7205. else if (equal(key, "MODELS"))
  7206. {
  7207. // Set models start index
  7208. ArrayPushCell(g_zclass2_modelsstart, ArraySize(g_zclass2_playermodel))
  7209.  
  7210. // Parse class models
  7211. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  7212. {
  7213. // Trim spaces
  7214. trim(key)
  7215. trim(value)
  7216.  
  7217. // Add to class models array
  7218. ArrayPushString(g_zclass2_playermodel, key)
  7219. ArrayPushCell(g_zclass2_modelindex, -1)
  7220. }
  7221.  
  7222. // Set models end index
  7223. ArrayPushCell(g_zclass2_modelsend, ArraySize(g_zclass2_playermodel))
  7224. }
  7225. else if (equal(key, "CLAWMODEL"))
  7226. ArrayPushString(g_zclass2_clawmodel, value)
  7227. else if (equal(key, "HEALTH"))
  7228. ArrayPushCell(g_zclass2_hp, str_to_num(value))
  7229. else if (equal(key, "SPEED"))
  7230. ArrayPushCell(g_zclass2_spd, str_to_num(value))
  7231. else if (equal(key, "GRAVITY"))
  7232. ArrayPushCell(g_zclass2_grav, str_to_float(value))
  7233. else if (equal(key, "KNOCKBACK"))
  7234. ArrayPushCell(g_zclass2_kb, str_to_float(value))
  7235. }
  7236. if (file) fclose(file)
  7237. }
  7238.  
  7239. // Build extra items file path
  7240. get_configsdir(path, charsmax(path))
  7241. format(path, charsmax(path), "%s/%s", path, ZP_EXTRAITEMS_FILE)
  7242.  
  7243. // Parse if present
  7244. if (file_exists(path))
  7245. {
  7246. // Open extra items file for reading
  7247. file = fopen(path, "rt")
  7248.  
  7249. while (file && !feof(file))
  7250. {
  7251. // Read one line at a time
  7252. fgets(file, linedata, charsmax(linedata))
  7253.  
  7254. // Replace newlines with a null character to prevent headaches
  7255. replace(linedata, charsmax(linedata), "^n", "")
  7256.  
  7257. // Blank line or comment
  7258. if (!linedata[0] || linedata[0] == ';') continue;
  7259.  
  7260. // New item starting
  7261. if (linedata[0] == '[')
  7262. {
  7263. // Remove first and last characters (braces)
  7264. linedata[strlen(linedata) - 1] = 0
  7265. copy(linedata, charsmax(linedata), linedata[1])
  7266.  
  7267. // Store its real name for future reference
  7268. ArrayPushString(g_extraitem2_realname, linedata)
  7269. continue;
  7270. }
  7271.  
  7272. // Get key and value(s)
  7273. strtok(linedata, key, charsmax(key), value, charsmax(value), '=')
  7274.  
  7275. // Trim spaces
  7276. trim(key)
  7277. trim(value)
  7278.  
  7279. if (equal(key, "NAME"))
  7280. ArrayPushString(g_extraitem2_name, value)
  7281. else if (equal(key, "COST"))
  7282. ArrayPushCell(g_extraitem2_cost, str_to_num(value))
  7283. else if (equal(key, "TEAMS"))
  7284. {
  7285. // Clear teams bitsum
  7286. teams = 0
  7287.  
  7288. // Parse teams
  7289. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  7290. {
  7291. // Trim spaces
  7292. trim(key)
  7293. trim(value)
  7294.  
  7295. if (equal(key, ZP_TEAM_NAMES[ZP_TEAM_ZOMBIE]))
  7296. teams |= ZP_TEAM_ZOMBIE
  7297. else if (equal(key, ZP_TEAM_NAMES[ZP_TEAM_HUMAN]))
  7298. teams |= ZP_TEAM_HUMAN
  7299. else if (equal(key, ZP_TEAM_NAMES[ZP_TEAM_NEMESIS]))
  7300. teams |= ZP_TEAM_NEMESIS
  7301. else if (equal(key, ZP_TEAM_NAMES[ZP_TEAM_SURVIVOR]))
  7302. teams |= ZP_TEAM_SURVIVOR
  7303. }
  7304.  
  7305. // Add to teams array
  7306. ArrayPushCell(g_extraitem2_team, teams)
  7307. }
  7308. }
  7309. if (file) fclose(file)
  7310. }
  7311. }
  7312.  
  7313. save_customization()
  7314. {
  7315. new i, k, buffer[512]
  7316.  
  7317. // Build zombie classes file path
  7318. new path[64]
  7319. get_configsdir(path, charsmax(path))
  7320. format(path, charsmax(path), "%s/%s", path, ZP_ZOMBIECLASSES_FILE)
  7321.  
  7322. // Open zombie classes file for appending data
  7323. new file = fopen(path, "at"), size = ArraySize(g_zclass_name)
  7324.  
  7325. // Add any new zombie classes data at the end if needed
  7326. for (i = 0; i < size; i++)
  7327. {
  7328. if (ArrayGetCell(g_zclass_new, i))
  7329. {
  7330. // Add real name
  7331. ArrayGetString(g_zclass_name, i, buffer, charsmax(buffer))
  7332. format(buffer, charsmax(buffer), "^n[%s]", buffer)
  7333. fputs(file, buffer)
  7334.  
  7335. // Add caption
  7336. ArrayGetString(g_zclass_name, i, buffer, charsmax(buffer))
  7337. format(buffer, charsmax(buffer), "^nNAME = %s", buffer)
  7338. fputs(file, buffer)
  7339.  
  7340. // Add info
  7341. ArrayGetString(g_zclass_info, i, buffer, charsmax(buffer))
  7342. format(buffer, charsmax(buffer), "^nINFO = %s", buffer)
  7343. fputs(file, buffer)
  7344.  
  7345. // Add models
  7346. for (k = ArrayGetCell(g_zclass_modelsstart, i); k < ArrayGetCell(g_zclass_modelsend, i); k++)
  7347. {
  7348. if (k == ArrayGetCell(g_zclass_modelsstart, i))
  7349. {
  7350. // First model, overwrite buffer
  7351. ArrayGetString(g_zclass_playermodel, k, buffer, charsmax(buffer))
  7352. }
  7353. else
  7354. {
  7355. // Successive models, append to buffer
  7356. ArrayGetString(g_zclass_playermodel, k, path, charsmax(path))
  7357. format(buffer, charsmax(buffer), "%s , %s", buffer, path)
  7358. }
  7359. }
  7360. format(buffer, charsmax(buffer), "^nMODELS = %s", buffer)
  7361. fputs(file, buffer)
  7362.  
  7363. // Add clawmodel
  7364. ArrayGetString(g_zclass_clawmodel, i, buffer, charsmax(buffer))
  7365. format(buffer, charsmax(buffer), "^nCLAWMODEL = %s", buffer)
  7366. fputs(file, buffer)
  7367.  
  7368. // Add health
  7369. formatex(buffer, charsmax(buffer), "^nHEALTH = %d", ArrayGetCell(g_zclass_hp, i))
  7370. fputs(file, buffer)
  7371.  
  7372. // Add speed
  7373. formatex(buffer, charsmax(buffer), "^nSPEED = %d", ArrayGetCell(g_zclass_spd, i))
  7374. fputs(file, buffer)
  7375.  
  7376. // Add gravity
  7377. formatex(buffer, charsmax(buffer), "^nGRAVITY = %.2f", Float:ArrayGetCell(g_zclass_grav, i))
  7378. fputs(file, buffer)
  7379.  
  7380. // Add knockback
  7381. formatex(buffer, charsmax(buffer), "^nKNOCKBACK = %.2f^n", Float:ArrayGetCell(g_zclass_kb, i))
  7382. fputs(file, buffer)
  7383. }
  7384. }
  7385. fclose(file)
  7386.  
  7387. // Build extra items file path
  7388. get_configsdir(path, charsmax(path))
  7389. format(path, charsmax(path), "%s/%s", path, ZP_EXTRAITEMS_FILE)
  7390.  
  7391. // Open extra items file for appending data
  7392. file = fopen(path, "at")
  7393. size = ArraySize(g_extraitem_name)
  7394.  
  7395. // Add any new extra items data at the end if needed
  7396. for (i = EXTRAS_CUSTOM_STARTID; i < size; i++)
  7397. {
  7398. if (ArrayGetCell(g_extraitem_new, i))
  7399. {
  7400. // Add real name
  7401. ArrayGetString(g_extraitem_name, i, buffer, charsmax(buffer))
  7402. format(buffer, charsmax(buffer), "^n[%s]", buffer)
  7403. fputs(file, buffer)
  7404.  
  7405. // Add caption
  7406. ArrayGetString(g_extraitem_name, i, buffer, charsmax(buffer))
  7407. format(buffer, charsmax(buffer), "^nNAME = %s", buffer)
  7408. fputs(file, buffer)
  7409.  
  7410. // Add cost
  7411. formatex(buffer, charsmax(buffer), "^nCOST = %d", ArrayGetCell(g_extraitem_cost, i))
  7412. fputs(file, buffer)
  7413.  
  7414. // Add team
  7415. formatex(buffer, charsmax(buffer), "^nTEAMS = %s^n", ZP_TEAM_NAMES[ArrayGetCell(g_extraitem_team, i)])
  7416. fputs(file, buffer)
  7417. }
  7418. }
  7419. fclose(file)
  7420.  
  7421. // Free arrays containing class/item overrides
  7422. ArrayDestroy(g_zclass2_realname)
  7423. ArrayDestroy(g_zclass2_name)
  7424. ArrayDestroy(g_zclass2_info)
  7425. ArrayDestroy(g_zclass2_modelsstart)
  7426. ArrayDestroy(g_zclass2_modelsend)
  7427. ArrayDestroy(g_zclass2_playermodel)
  7428. ArrayDestroy(g_zclass2_modelindex)
  7429. ArrayDestroy(g_zclass2_clawmodel)
  7430. ArrayDestroy(g_zclass2_hp)
  7431. ArrayDestroy(g_zclass2_spd)
  7432. ArrayDestroy(g_zclass2_grav)
  7433. ArrayDestroy(g_zclass2_kb)
  7434. ArrayDestroy(g_zclass_new)
  7435. ArrayDestroy(g_extraitem2_realname)
  7436. ArrayDestroy(g_extraitem2_name)
  7437. ArrayDestroy(g_extraitem2_cost)
  7438. ArrayDestroy(g_extraitem2_team)
  7439. ArrayDestroy(g_extraitem_new)
  7440. }
  7441.  
  7442. // Register Ham Forwards for CZ bots
  7443. public register_ham_czbots(id)
  7444. {
  7445. // Make sure it's a CZ bot and it's still connected
  7446. if (g_hamczbots || !g_isconnected[id] || !get_pcvar_num(cvar_botquota))
  7447. return;
  7448.  
  7449. RegisterHamFromEntity(Ham_Spawn, id, "fw_PlayerSpawn_Post", 1)
  7450. RegisterHamFromEntity(Ham_Killed, id, "fw_PlayerKilled")
  7451. RegisterHamFromEntity(Ham_Killed, id, "fw_PlayerKilled_Post", 1)
  7452. RegisterHamFromEntity(Ham_TakeDamage, id, "fw_TakeDamage")
  7453. RegisterHamFromEntity(Ham_TakeDamage, id, "fw_TakeDamage_Post", 1)
  7454. RegisterHamFromEntity(Ham_TraceAttack, id, "fw_TraceAttack")
  7455.  
  7456. // Ham forwards for CZ bots succesfully registered
  7457. g_hamczbots = true
  7458.  
  7459. // If the bot has already spawned, call the forward manually for him
  7460. if (is_user_alive(id)) fw_PlayerSpawn_Post(id)
  7461. }
  7462.  
  7463. // Disable minmodels task
  7464. public disable_minmodels(id)
  7465. {
  7466. if (!g_isconnected[id]) return;
  7467. client_cmd(id, "cl_minmodels 0")
  7468. }
  7469.  
  7470. // Bots automatically buy extra items
  7471. public bot_buy_extras(taskid)
  7472. {
  7473. // Nemesis or Survivor bots have nothing to buy by default
  7474. if (!g_isalive[ID_SPAWN] || g_survivor[ID_SPAWN] || g_nemesis[ID_SPAWN])
  7475. return;
  7476.  
  7477. if (!g_zombie[ID_SPAWN]) // human bots
  7478. {
  7479. // Attempt to buy Night Vision
  7480. buy_extra_item(ID_SPAWN, EXTRA_NVISION)
  7481.  
  7482. // Attempt to buy a weapon
  7483. buy_extra_item(ID_SPAWN, random_num(EXTRA_WEAPONS_STARTID, EXTRAS_CUSTOM_STARTID-1))
  7484. }
  7485. else // zombie bots
  7486. {
  7487. // Attempt to buy an Antidote
  7488. buy_extra_item(ID_SPAWN, EXTRA_ANTIDOTE)
  7489. }
  7490. }
  7491.  
  7492. // Refill BP Ammo Task
  7493. public refill_bpammo(const args[], id)
  7494. {
  7495. // Player died or turned into a zombie
  7496. if (!g_isalive[id] || g_zombie[id])
  7497. return;
  7498.  
  7499. set_msg_block(g_msgAmmoPickup, BLOCK_ONCE)
  7500. ExecuteHamB(Ham_GiveAmmo, id, MAXBPAMMO[REFILL_WEAPONID], AMMOTYPE[REFILL_WEAPONID], MAXBPAMMO[REFILL_WEAPONID])
  7501. }
  7502.  
  7503. // Balance Teams Task
  7504. balance_teams()
  7505. {
  7506. // Get amount of users playing
  7507. static iPlayersnum
  7508. iPlayersnum = fnGetPlaying()
  7509.  
  7510. // No players, don't bother
  7511. if (iPlayersnum < 1) return;
  7512.  
  7513. // Split players evenly
  7514. static iTerrors, iMaxTerrors, id, team[33]
  7515. iMaxTerrors = iPlayersnum/2
  7516. iTerrors = 0
  7517.  
  7518. // First, set everyone to CT
  7519. for (id = 1; id <= g_maxplayers; id++)
  7520. {
  7521. // Skip if not connected
  7522. if (!g_isconnected[id])
  7523. continue;
  7524.  
  7525. team[id] = fm_cs_get_user_team(id)
  7526.  
  7527. // Skip if not playing
  7528. if (team[id] == FM_CS_TEAM_SPECTATOR || team[id] == FM_CS_TEAM_UNASSIGNED)
  7529. continue;
  7530.  
  7531. // Set team
  7532. remove_task(id+TASK_TEAM)
  7533. fm_cs_set_user_team(id, FM_CS_TEAM_CT)
  7534. team[id] = FM_CS_TEAM_CT
  7535. }
  7536.  
  7537. // Then randomly set half of the players to Terrorists
  7538. while (iTerrors < iMaxTerrors)
  7539. {
  7540. // Keep looping through all players
  7541. if (++id > g_maxplayers) id = 1
  7542.  
  7543. // Skip if not connected
  7544. if (!g_isconnected[id])
  7545. continue;
  7546.  
  7547. // Skip if not playing or already a Terrorist
  7548. if (team[id] != FM_CS_TEAM_CT)
  7549. continue;
  7550.  
  7551. // Random chance
  7552. if (random_num(0, 1))
  7553. {
  7554. fm_cs_set_user_team(id, FM_CS_TEAM_T)
  7555. team[id] = FM_CS_TEAM_T
  7556. iTerrors++
  7557. }
  7558. }
  7559. }
  7560.  
  7561. // Welcome Message Task
  7562. public welcome_msg()
  7563. {
  7564. // Show mod info
  7565. zp_colored_print(0, "^x01**** ^x04%s^x01 ****", g_modname)
  7566. zp_colored_print(0, "^x04[ZP]^x01 %L", LANG_PLAYER, "NOTICE_INFO1")
  7567. if (!get_pcvar_num(cvar_infammo)) zp_colored_print(0, "^x04[ZP]^x01 %L", LANG_PLAYER, "NOTICE_INFO2")
  7568.  
  7569. // Show T-virus HUD notice
  7570. set_hudmessage(0, 125, 200, HUD_EVENT_X, HUD_EVENT_Y, 0, 0.0, 3.0, 2.0, 1.0, -1)
  7571. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_VIRUS_FREE")
  7572. }
  7573.  
  7574. // Respawn Player Task
  7575. public respawn_player_task(taskid)
  7576. {
  7577. // Get player's team
  7578. static team
  7579. team = fm_cs_get_user_team(ID_SPAWN)
  7580.  
  7581. // Respawn player automatically if allowed on current round
  7582. if (!g_endround && team != FM_CS_TEAM_SPECTATOR && team != FM_CS_TEAM_UNASSIGNED && !g_isalive[ID_SPAWN] && (!g_survround || get_pcvar_num(cvar_allowrespawnsurv)) && (!g_swarmround || get_pcvar_num(cvar_allowrespawnswarm)) && (!g_nemround || get_pcvar_num(cvar_allowrespawnnem)) && (!g_plagueround || get_pcvar_num(cvar_allowrespawnplague)))
  7583. {
  7584. // Infection rounds = none of the above
  7585. if (!get_pcvar_num(cvar_allowrespawninfection) && !g_survround && !g_nemround && !g_swarmround && !g_plagueround)
  7586. return;
  7587.  
  7588. // Override respawn as zombie setting on nemesis and survivor rounds
  7589. if (g_survround) g_respawn_as_zombie[ID_SPAWN] = true
  7590. else if (g_nemround) g_respawn_as_zombie[ID_SPAWN] = false
  7591.  
  7592. respawn_player_manually(ID_SPAWN)
  7593. }
  7594. }
  7595.  
  7596. // Respawn Player Manually (called after respawn checks are done)
  7597. respawn_player_manually(id)
  7598. {
  7599. // Set proper team before respawning, so that the TeamInfo message that's sent doesn't confuse PODBots
  7600. if (g_respawn_as_zombie[id])
  7601. fm_cs_set_user_team(id, FM_CS_TEAM_T)
  7602. else
  7603. fm_cs_set_user_team(id, FM_CS_TEAM_CT)
  7604.  
  7605. // Respawning a player has never been so easy
  7606. ExecuteHamB(Ham_CS_RoundRespawn, id)
  7607. }
  7608.  
  7609. // Check Round Task -check that we still have both zombies and humans on a round-
  7610. check_round(leaving_player)
  7611. {
  7612. // Round ended or make_a_zombie task still active
  7613. if (g_endround || task_exists(TASK_MAKEZOMBIE))
  7614. return;
  7615.  
  7616. // Get alive players count
  7617. static iPlayersnum, id
  7618. iPlayersnum = fnGetAlive()
  7619.  
  7620. // Last alive player, don't bother
  7621. if (iPlayersnum < 2)
  7622. return;
  7623.  
  7624. // Last zombie disconnecting
  7625. if (g_zombie[leaving_player] && fnGetZombies() == 1)
  7626. {
  7627. // Only one CT left, don't bother
  7628. if (fnGetHumans() == 1 && fnGetCTs() == 1)
  7629. return;
  7630.  
  7631. // Pick a random one to take his place
  7632. while ((id = fnGetRandomAlive(random_num(1, iPlayersnum))) == leaving_player ) { /* keep looping */ }
  7633.  
  7634. // Show last zombie left notice
  7635. zp_colored_print(0, "^x04[ZP]^x01 %L", LANG_PLAYER, "LAST_ZOMBIE_LEFT", g_playername[id])
  7636.  
  7637. // Set player leaving flag
  7638. g_lastplayerleaving = true
  7639.  
  7640. // Turn into a Nemesis or just a zombie?
  7641. if (g_nemesis[leaving_player])
  7642. zombieme(id, 0, 1, 0, 0)
  7643. else
  7644. zombieme(id, 0, 0, 0, 0)
  7645.  
  7646. // Remove player leaving flag
  7647. g_lastplayerleaving = false
  7648.  
  7649. // If Nemesis, set chosen player's health to that of the one who's leaving
  7650. if (get_pcvar_num(cvar_keephealthondisconnect) && g_nemesis[leaving_player])
  7651. fm_set_user_health(id, pev(leaving_player, pev_health))
  7652. }
  7653.  
  7654. // Last human disconnecting
  7655. else if (!g_zombie[leaving_player] && fnGetHumans() == 1)
  7656. {
  7657. // Only one T left, don't bother
  7658. if (fnGetZombies() == 1 && fnGetTs() == 1)
  7659. return;
  7660.  
  7661. // Pick a random one to take his place
  7662. while ((id = fnGetRandomAlive(random_num(1, iPlayersnum))) == leaving_player ) { /* keep looping */ }
  7663.  
  7664. // Show last human left notice
  7665. zp_colored_print(0, "^x04[ZP]^x01 %L", LANG_PLAYER, "LAST_HUMAN_LEFT", g_playername[id])
  7666.  
  7667. // Set player leaving flag
  7668. g_lastplayerleaving = true
  7669.  
  7670. // Turn into a Survivor or just a human?
  7671. if (g_survivor[leaving_player])
  7672. humanme(id, 1, 0)
  7673. else
  7674. humanme(id, 0, 0)
  7675.  
  7676. // Remove player leaving flag
  7677. g_lastplayerleaving = false
  7678.  
  7679. // If Survivor, set chosen player's health to that of the one who's leaving
  7680. if (get_pcvar_num(cvar_keephealthondisconnect) && g_survivor[leaving_player])
  7681. fm_set_user_health(id, pev(leaving_player, pev_health))
  7682. }
  7683. }
  7684.  
  7685. // Lighting Effects Task
  7686. public lighting_effects()
  7687. {
  7688. // Cache some CVAR values at every 5 secs
  7689. cache_cvars()
  7690.  
  7691. // Get lighting style
  7692. static lighting[2]
  7693. get_pcvar_string(cvar_lighting, lighting, charsmax(lighting))
  7694. strtolower(lighting)
  7695.  
  7696. // Lighting disabled? ["0"]
  7697. if (lighting[0] == '0')
  7698. return;
  7699.  
  7700. // Darkest light settings?
  7701. if (lighting[0] >= 'a' && lighting[0] <= 'd')
  7702. {
  7703. static thunderclap_in_progress, Float:thunder
  7704. thunderclap_in_progress = task_exists(TASK_THUNDER)
  7705. thunder = get_pcvar_float(cvar_thunder)
  7706.  
  7707. // Set thunderclap tasks if not existant
  7708. if (thunder > 0.0 && !task_exists(TASK_THUNDER_PRE) && !thunderclap_in_progress)
  7709. {
  7710. g_lights_i = 0
  7711. ArrayGetString(lights_thunder, random_num(0, ArraySize(lights_thunder) - 1), g_lights_cycle, charsmax(g_lights_cycle))
  7712. g_lights_cycle_len = strlen(g_lights_cycle)
  7713. set_task(thunder, "thunderclap", TASK_THUNDER_PRE)
  7714. }
  7715.  
  7716. // Set lighting only when no thunderclaps are going on
  7717. if (!thunderclap_in_progress) engfunc(EngFunc_LightStyle, 0, lighting)
  7718. }
  7719. else
  7720. {
  7721. // Remove thunderclap tasks
  7722. remove_task(TASK_THUNDER_PRE)
  7723. remove_task(TASK_THUNDER)
  7724.  
  7725. // Set lighting
  7726. engfunc(EngFunc_LightStyle, 0, lighting)
  7727. }
  7728. }
  7729.  
  7730. // Thunderclap task
  7731. public thunderclap()
  7732. {
  7733. // Play thunder sound
  7734. if (g_lights_i == 0)
  7735. {
  7736. static sound[64]
  7737. ArrayGetString(sound_thunder, random_num(0, ArraySize(sound_thunder) - 1), sound, charsmax(sound))
  7738. PlaySound(sound)
  7739. }
  7740.  
  7741. // Set lighting
  7742. static light[2]
  7743. light[0] = g_lights_cycle[g_lights_i]
  7744. engfunc(EngFunc_LightStyle, 0, light)
  7745.  
  7746. g_lights_i++
  7747.  
  7748. // Lighting cycle end?
  7749. if (g_lights_i >= g_lights_cycle_len)
  7750. {
  7751. remove_task(TASK_THUNDER)
  7752. lighting_effects()
  7753. }
  7754. // Lighting cycle start?
  7755. else if (!task_exists(TASK_THUNDER))
  7756. set_task(0.1, "thunderclap", TASK_THUNDER, _, _, "b")
  7757. }
  7758.  
  7759. // Ambience Sound Effects Task
  7760. public ambience_sound_effects(taskid)
  7761. {
  7762. // Play a random sound depending on the round
  7763. static sound[64], iRand, duration, ismp3
  7764.  
  7765. if (g_nemround) // Nemesis Mode
  7766. {
  7767. iRand = random_num(0, ArraySize(sound_ambience2) - 1)
  7768. ArrayGetString(sound_ambience2, iRand, sound, charsmax(sound))
  7769. duration = ArrayGetCell(sound_ambience2_duration, iRand)
  7770. ismp3 = ArrayGetCell(sound_ambience2_ismp3, iRand)
  7771. }
  7772. else if (g_survround) // Survivor Mode
  7773. {
  7774. iRand = random_num(0, ArraySize(sound_ambience3) - 1)
  7775. ArrayGetString(sound_ambience3, iRand, sound, charsmax(sound))
  7776. duration = ArrayGetCell(sound_ambience3_duration, iRand)
  7777. ismp3 = ArrayGetCell(sound_ambience3_ismp3, iRand)
  7778. }
  7779. else if (g_swarmround) // Swarm Mode
  7780. {
  7781. iRand = random_num(0, ArraySize(sound_ambience4) - 1)
  7782. ArrayGetString(sound_ambience4, iRand, sound, charsmax(sound))
  7783. duration = ArrayGetCell(sound_ambience4_duration, iRand)
  7784. ismp3 = ArrayGetCell(sound_ambience4_ismp3, iRand)
  7785. }
  7786. else if (g_plagueround) // Plague Mode
  7787. {
  7788. iRand = random_num(0, ArraySize(sound_ambience5) - 1)
  7789. ArrayGetString(sound_ambience5, iRand, sound, charsmax(sound))
  7790. duration = ArrayGetCell(sound_ambience5_duration, iRand)
  7791. ismp3 = ArrayGetCell(sound_ambience5_ismp3, iRand)
  7792. }
  7793. else // Infection Mode
  7794. {
  7795. iRand = random_num(0, ArraySize(sound_ambience1) - 1)
  7796. ArrayGetString(sound_ambience1, iRand, sound, charsmax(sound))
  7797. duration = ArrayGetCell(sound_ambience1_duration, iRand)
  7798. ismp3 = ArrayGetCell(sound_ambience1_ismp3, iRand)
  7799. }
  7800.  
  7801. // Play it on clients
  7802. if (ismp3)
  7803. client_cmd(0, "mp3 play ^"sound/%s^"", sound)
  7804. else
  7805. PlaySound(sound)
  7806.  
  7807. // Set the task for when the sound is done playing
  7808. set_task(float(duration), "ambience_sound_effects", TASK_AMBIENCESOUNDS)
  7809. }
  7810.  
  7811. // Ambience Sounds Stop Task
  7812. ambience_sound_stop()
  7813. {
  7814. client_cmd(0, "mp3 stop; stopsound")
  7815. }
  7816.  
  7817. // Flashlight Charge Task
  7818. public flashlight_charge(taskid)
  7819. {
  7820. // Drain or charge?
  7821. if (g_flashlight[ID_CHARGE])
  7822. g_flashbattery[ID_CHARGE] -= get_pcvar_num(cvar_flashdrain)
  7823. else
  7824. g_flashbattery[ID_CHARGE] += get_pcvar_num(cvar_flashcharge)
  7825.  
  7826. // Battery fully charged
  7827. if (g_flashbattery[ID_CHARGE] >= 100)
  7828. {
  7829. // Don't exceed 100%
  7830. g_flashbattery[ID_CHARGE] = 100
  7831.  
  7832. // Update flashlight battery on HUD
  7833. message_begin(MSG_ONE, g_msgFlashBat, _, ID_CHARGE)
  7834. write_byte(100) // battery
  7835. message_end()
  7836.  
  7837. // Task not needed anymore
  7838. remove_task(taskid);
  7839. return;
  7840. }
  7841.  
  7842. // Battery depleted
  7843. if (g_flashbattery[ID_CHARGE] <= 0)
  7844. {
  7845. // Turn it off
  7846. g_flashlight[ID_CHARGE] = false
  7847. g_flashbattery[ID_CHARGE] = 0
  7848.  
  7849. // Play flashlight toggle sound
  7850. emit_sound(ID_CHARGE, CHAN_ITEM, sound_flashlight, 1.0, ATTN_NORM, 0, PITCH_NORM)
  7851.  
  7852. // Update flashlight status on HUD
  7853. message_begin(MSG_ONE, g_msgFlashlight, _, ID_CHARGE)
  7854. write_byte(0) // toggle
  7855. write_byte(0) // battery
  7856. message_end()
  7857.  
  7858. // Remove flashlight task for this player
  7859. remove_task(ID_CHARGE+TASK_FLASH)
  7860. }
  7861. else
  7862. {
  7863. // Update flashlight battery on HUD
  7864. message_begin(MSG_ONE_UNRELIABLE, g_msgFlashBat, _, ID_CHARGE)
  7865. write_byte(g_flashbattery[ID_CHARGE]) // battery
  7866. message_end()
  7867. }
  7868. }
  7869.  
  7870. // Remove Spawn Protection Task
  7871. public remove_spawn_protection(taskid)
  7872. {
  7873. // Not alive
  7874. if (!g_isalive[ID_SPAWN])
  7875. return;
  7876.  
  7877. // Remove spawn protection
  7878. g_nodamage[ID_SPAWN] = false
  7879. set_pev(ID_SPAWN, pev_effects, pev(ID_SPAWN, pev_effects) & ~EF_NODRAW)
  7880. }
  7881.  
  7882. // Hide Player's Money Task
  7883. public task_hide_money(taskid)
  7884. {
  7885. // Not alive
  7886. if (!g_isalive[ID_SPAWN])
  7887. return;
  7888.  
  7889. // Hide money
  7890. message_begin(MSG_ONE, g_msgHideWeapon, _, ID_SPAWN)
  7891. write_byte(HIDE_MONEY) // what to hide bitsum
  7892. message_end()
  7893.  
  7894. // Hide the HL crosshair that's drawn
  7895. message_begin(MSG_ONE, g_msgCrosshair, _, ID_SPAWN)
  7896. write_byte(0) // toggle
  7897. message_end()
  7898. }
  7899.  
  7900. // Turn Off Flashlight and Restore Batteries
  7901. turn_off_flashlight(id)
  7902. {
  7903. // Restore batteries for the next use
  7904. fm_cs_set_user_batteries(id, 100)
  7905.  
  7906. // Check if flashlight is on
  7907. if (pev(id, pev_effects) & EF_DIMLIGHT)
  7908. {
  7909. // Turn it off
  7910. set_pev(id, pev_impulse, IMPULSE_FLASHLIGHT)
  7911. }
  7912. else
  7913. {
  7914. // Clear any stored flashlight impulse (bugfix)
  7915. set_pev(id, pev_impulse, 0)
  7916. }
  7917.  
  7918. // Turn off custom flashlight
  7919. if (g_cached_customflash)
  7920. {
  7921. // Turn it off
  7922. g_flashlight[id] = false
  7923. g_flashbattery[id] = 100
  7924.  
  7925. // Update flashlight HUD
  7926. message_begin(MSG_ONE, g_msgFlashlight, _, id)
  7927. write_byte(0) // toggle
  7928. write_byte(100) // battery
  7929. message_end()
  7930.  
  7931. // Remove previous tasks
  7932. remove_task(id+TASK_CHARGE)
  7933. remove_task(id+TASK_FLASH)
  7934. }
  7935. }
  7936.  
  7937. // Infection Bomb Explosion
  7938. infection_explode(ent)
  7939. {
  7940. // Round ended (bugfix)
  7941. if (g_endround) return;
  7942.  
  7943. // Get origin
  7944. static Float:originF[3]
  7945. pev(ent, pev_origin, originF)
  7946.  
  7947. // Make the explosion
  7948. create_blast(originF)
  7949.  
  7950. // Infection nade explode sound
  7951. static sound[64]
  7952. ArrayGetString(grenade_infect, random_num(0, ArraySize(grenade_infect) - 1), sound, charsmax(sound))
  7953. emit_sound(ent, CHAN_WEAPON, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  7954.  
  7955. // Get attacker
  7956. static attacker
  7957. attacker = pev(ent, pev_owner)
  7958.  
  7959. // Collisions
  7960. static victim
  7961. victim = -1
  7962.  
  7963. while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, NADE_EXPLOSION_RADIUS)) != 0)
  7964. {
  7965. // Only effect alive non-spawnprotected humans
  7966. if (!is_user_valid_alive(victim) || g_zombie[victim] || g_nodamage[victim])
  7967. continue;
  7968.  
  7969. // Last human is killed
  7970. if (fnGetHumans() == 1)
  7971. {
  7972. ExecuteHamB(Ham_Killed, victim, attacker, 0)
  7973. continue;
  7974. }
  7975.  
  7976. // Infected victim's sound
  7977. ArrayGetString(grenade_infect_player, random_num(0, ArraySize(grenade_infect_player) - 1), sound, charsmax(sound))
  7978. emit_sound(victim, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  7979.  
  7980. // Turn into zombie
  7981. zombieme(victim, attacker, 0, 1, 1)
  7982. }
  7983.  
  7984. // Get rid of the grenade
  7985. engfunc(EngFunc_RemoveEntity, ent)
  7986. }
  7987.  
  7988. // Fire Grenade Explosion
  7989. fire_explode(ent)
  7990. {
  7991. // Get origin
  7992. static Float:originF[3]
  7993. pev(ent, pev_origin, originF)
  7994.  
  7995. // Make the explosion
  7996. create_blast2(originF)
  7997.  
  7998. // Fire nade explode sound
  7999. static sound[64]
  8000. ArrayGetString(grenade_fire, random_num(0, ArraySize(grenade_fire) - 1), sound, charsmax(sound))
  8001. emit_sound(ent, CHAN_WEAPON, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  8002.  
  8003. // Collisions
  8004. static victim
  8005. victim = -1
  8006.  
  8007. while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, NADE_EXPLOSION_RADIUS)) != 0)
  8008. {
  8009. // Only effect alive zombies
  8010. if (!is_user_valid_alive(victim) || !g_zombie[victim] || g_nodamage[victim])
  8011. continue;
  8012.  
  8013. // Heat icon?
  8014. if (get_pcvar_num(cvar_hudicons))
  8015. {
  8016. message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, _, victim)
  8017. write_byte(0) // damage save
  8018. write_byte(0) // damage take
  8019. write_long(DMG_BURN) // damage type
  8020. write_coord(0) // x
  8021. write_coord(0) // y
  8022. write_coord(0) // z
  8023. message_end()
  8024. }
  8025.  
  8026. if (g_nemesis[victim]) // fire duration (nemesis is fire resistant)
  8027. g_burning_duration[victim] += get_pcvar_num(cvar_fireduration)
  8028. else
  8029. g_burning_duration[victim] += get_pcvar_num(cvar_fireduration) * 5
  8030.  
  8031. // Set burning task on victim if not present
  8032. if (!task_exists(victim+TASK_BURN))
  8033. set_task(0.2, "burning_flame", victim+TASK_BURN, _, _, "b")
  8034. }
  8035.  
  8036. // Get rid of the grenade
  8037. engfunc(EngFunc_RemoveEntity, ent)
  8038. }
  8039.  
  8040. // Frost Grenade Explosion
  8041. frost_explode(ent)
  8042. {
  8043. // Get origin
  8044. static Float:originF[3]
  8045. pev(ent, pev_origin, originF)
  8046.  
  8047. // Make the explosion
  8048. create_blast3(originF)
  8049.  
  8050. // Frost nade explode sound
  8051. static sound[64]
  8052. ArrayGetString(grenade_frost, random_num(0, ArraySize(grenade_frost) - 1), sound, charsmax(sound))
  8053. emit_sound(ent, CHAN_WEAPON, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  8054.  
  8055. // Collisions
  8056. static victim
  8057. victim = -1
  8058.  
  8059. while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, NADE_EXPLOSION_RADIUS)) != 0)
  8060. {
  8061. // Only effect alive unfrozen zombies
  8062. if (!is_user_valid_alive(victim) || !g_zombie[victim] || g_frozen[victim] || g_nodamage[victim])
  8063. continue;
  8064.  
  8065. // Nemesis shouldn't be frozen
  8066. if (g_nemesis[victim])
  8067. {
  8068. // Get player's origin
  8069. static origin2[3]
  8070. get_user_origin(victim, origin2)
  8071.  
  8072. // Broken glass sound
  8073. ArrayGetString(grenade_frost_break, random_num(0, ArraySize(grenade_frost_break) - 1), sound, charsmax(sound))
  8074. emit_sound(victim, CHAN_BODY, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  8075.  
  8076. // Glass shatter
  8077. message_begin(MSG_PVS, SVC_TEMPENTITY, origin2)
  8078. write_byte(TE_BREAKMODEL) // TE id
  8079. write_coord(origin2[0]) // x
  8080. write_coord(origin2[1]) // y
  8081. write_coord(origin2[2]+24) // z
  8082. write_coord(16) // size x
  8083. write_coord(16) // size y
  8084. write_coord(16) // size z
  8085. write_coord(random_num(-50, 50)) // velocity x
  8086. write_coord(random_num(-50, 50)) // velocity y
  8087. write_coord(25) // velocity z
  8088. write_byte(10) // random velocity
  8089. write_short(g_glassSpr) // model
  8090. write_byte(10) // count
  8091. write_byte(25) // life
  8092. write_byte(BREAK_GLASS) // flags
  8093. message_end()
  8094.  
  8095. continue;
  8096. }
  8097.  
  8098. // Freeze icon?
  8099. if (get_pcvar_num(cvar_hudicons))
  8100. {
  8101. message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, _, victim)
  8102. write_byte(0) // damage save
  8103. write_byte(0) // damage take
  8104. write_long(DMG_DROWN) // damage type - DMG_FREEZE
  8105. write_coord(0) // x
  8106. write_coord(0) // y
  8107. write_coord(0) // z
  8108. message_end()
  8109. }
  8110.  
  8111. // Light blue glow while frozen
  8112. if (g_handle_models_on_separate_ent)
  8113. fm_set_rendering(g_ent_playermodel[victim], kRenderFxGlowShell, 0, 100, 200, kRenderNormal, 25)
  8114. else
  8115. fm_set_rendering(victim, kRenderFxGlowShell, 0, 100, 200, kRenderNormal, 25)
  8116.  
  8117. // Freeze sound
  8118. ArrayGetString(grenade_frost_player, random_num(0, ArraySize(grenade_frost_player) - 1), sound, charsmax(sound))
  8119. emit_sound(victim, CHAN_BODY, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  8120.  
  8121. // Add a blue tint to their screen
  8122. message_begin(MSG_ONE, g_msgScreenFade, _, victim)
  8123. write_short(0) // duration
  8124. write_short(0) // hold time
  8125. write_short(FFADE_STAYOUT) // fade type
  8126. write_byte(0) // red
  8127. write_byte(50) // green
  8128. write_byte(200) // blue
  8129. write_byte(100) // alpha
  8130. message_end()
  8131.  
  8132. // Prevent from jumping
  8133. if (pev(victim, pev_flags) & FL_ONGROUND)
  8134. set_pev(victim, pev_gravity, 999999.9) // set really high
  8135. else
  8136. set_pev(victim, pev_gravity, 0.000001) // no gravity
  8137.  
  8138. // Set a task to remove the freeze
  8139. g_frozen[victim] = true;
  8140. set_task(get_pcvar_float(cvar_freezeduration), "remove_freeze", victim)
  8141. }
  8142.  
  8143. // Get rid of the grenade
  8144. engfunc(EngFunc_RemoveEntity, ent)
  8145. }
  8146.  
  8147. // Remove freeze task
  8148. public remove_freeze(id)
  8149. {
  8150. // Not alive or not frozen anymore
  8151. if (!g_isalive[id] || !g_frozen[id])
  8152. return;
  8153.  
  8154. // Unfreeze
  8155. g_frozen[id] = false;
  8156.  
  8157. // Restore gravity
  8158. if (g_zombie[id])
  8159. {
  8160. if (g_nemesis[id])
  8161. set_pev(id, pev_gravity, get_pcvar_float(cvar_nemgravity))
  8162. else
  8163. set_pev(id, pev_gravity, Float:ArrayGetCell(g_zclass_grav, g_zombieclass[id]))
  8164. }
  8165. else
  8166. {
  8167. if (g_survivor[id])
  8168. set_pev(id, pev_gravity, get_pcvar_float(cvar_survgravity))
  8169. else
  8170. set_pev(id, pev_gravity, get_pcvar_float(cvar_humangravity))
  8171. }
  8172.  
  8173. // Restore rendering
  8174. if (g_handle_models_on_separate_ent)
  8175. {
  8176. // Nemesis or Survivor glow / remove glow on player model entity
  8177. if (g_nemesis[id] && get_pcvar_num(cvar_nemglow))
  8178. fm_set_rendering(g_ent_playermodel[id], kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 25)
  8179. else if (g_survivor[id] && get_pcvar_num(cvar_survglow))
  8180. fm_set_rendering(g_ent_playermodel[id], kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 25)
  8181. else
  8182. fm_set_rendering(g_ent_playermodel[id])
  8183. }
  8184. else
  8185. {
  8186. // Nemesis or Survivor glow / remove glow
  8187. if (g_nemesis[id] && get_pcvar_num(cvar_nemglow))
  8188. fm_set_rendering(id, kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 25)
  8189. else if (g_survivor[id] && get_pcvar_num(cvar_survglow))
  8190. fm_set_rendering(id, kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 25)
  8191. else
  8192. fm_set_rendering(id)
  8193. }
  8194.  
  8195. // Gradually remove screen's blue tint
  8196. message_begin(MSG_ONE, g_msgScreenFade, _, id)
  8197. write_short(UNIT_SECOND) // duration
  8198. write_short(0) // hold time
  8199. write_short(FFADE_IN) // fade type
  8200. write_byte(0) // red
  8201. write_byte(50) // green
  8202. write_byte(200) // blue
  8203. write_byte(100) // alpha
  8204. message_end()
  8205.  
  8206. // Broken glass sound
  8207. static sound[64]
  8208. ArrayGetString(grenade_frost_break, random_num(0, ArraySize(grenade_frost_break) - 1), sound, charsmax(sound))
  8209. emit_sound(id, CHAN_BODY, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  8210.  
  8211. // Get player's origin
  8212. static origin2[3]
  8213. get_user_origin(id, origin2)
  8214.  
  8215. // Glass shatter
  8216. message_begin(MSG_PVS, SVC_TEMPENTITY, origin2)
  8217. write_byte(TE_BREAKMODEL) // TE id
  8218. write_coord(origin2[0]) // x
  8219. write_coord(origin2[1]) // y
  8220. write_coord(origin2[2]+24) // z
  8221. write_coord(16) // size x
  8222. write_coord(16) // size y
  8223. write_coord(16) // size z
  8224. write_coord(random_num(-50, 50)) // velocity x
  8225. write_coord(random_num(-50, 50)) // velocity y
  8226. write_coord(25) // velocity z
  8227. write_byte(10) // random velocity
  8228. write_short(g_glassSpr) // model
  8229. write_byte(10) // count
  8230. write_byte(25) // life
  8231. write_byte(BREAK_GLASS) // flags
  8232. message_end()
  8233.  
  8234. ExecuteForward(g_fwUserUnfrozen, g_fwDummyResult, id);
  8235. }
  8236.  
  8237. // Remove Stuff Task
  8238. public remove_stuff()
  8239. {
  8240. static ent
  8241.  
  8242. // Remove rotating doors
  8243. if (get_pcvar_num(cvar_removedoors) > 0)
  8244. {
  8245. ent = -1;
  8246. while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "func_door_rotating")) != 0)
  8247. engfunc(EngFunc_SetOrigin, ent, Float:{8192.0 ,8192.0 ,8192.0})
  8248. }
  8249.  
  8250. // Remove all doors
  8251. if (get_pcvar_num(cvar_removedoors) > 1)
  8252. {
  8253. ent = -1;
  8254. while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "func_door")) != 0)
  8255. engfunc(EngFunc_SetOrigin, ent, Float:{8192.0 ,8192.0 ,8192.0})
  8256. }
  8257.  
  8258. // Triggered lights
  8259. if (!get_pcvar_num(cvar_triggered))
  8260. {
  8261. ent = -1
  8262. while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "light")) != 0)
  8263. {
  8264. dllfunc(DLLFunc_Use, ent, 0); // turn off the light
  8265. set_pev(ent, pev_targetname, 0) // prevent it from being triggered
  8266. }
  8267. }
  8268. }
  8269.  
  8270. // Set Custom Weapon Models
  8271. replace_weapon_models(id, weaponid)
  8272. {
  8273. switch (weaponid)
  8274. {
  8275. case CSW_KNIFE: // Custom knife models
  8276. {
  8277. if (g_zombie[id])
  8278. {
  8279. if (g_nemesis[id]) // Nemesis
  8280. {
  8281. set_pev(id, pev_viewmodel2, model_vknife_nemesis)
  8282. set_pev(id, pev_weaponmodel2, "")
  8283. }
  8284. else // Zombies
  8285. {
  8286. // Admin knife models?
  8287. if (get_pcvar_num(cvar_adminknifemodelszombie) && get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS])
  8288. {
  8289. set_pev(id, pev_viewmodel2, model_vknife_admin_zombie)
  8290. set_pev(id, pev_weaponmodel2, "")
  8291. }
  8292. else
  8293. {
  8294. static clawmodel[100]
  8295. ArrayGetString(g_zclass_clawmodel, g_zombieclass[id], clawmodel, charsmax(clawmodel))
  8296. format(clawmodel, charsmax(clawmodel), "models/zombie_plague/%s", clawmodel)
  8297. set_pev(id, pev_viewmodel2, clawmodel)
  8298. set_pev(id, pev_weaponmodel2, "")
  8299. }
  8300. }
  8301. }
  8302. else // Humans
  8303. {
  8304. // Admin knife models?
  8305. if (get_pcvar_num(cvar_adminknifemodelshuman) && get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS])
  8306. {
  8307. set_pev(id, pev_viewmodel2, model_vknife_admin_human)
  8308. set_pev(id, pev_weaponmodel2, "")
  8309. }
  8310. else
  8311. {
  8312. set_pev(id, pev_viewmodel2, model_vknife_human)
  8313. set_pev(id, pev_weaponmodel2, "models/p_knife.mdl")
  8314. }
  8315. }
  8316. }
  8317. case CSW_M249: // Survivor's M249
  8318. {
  8319. if (g_survivor[id])
  8320. set_pev(id, pev_viewmodel2, model_vm249_survivor)
  8321. }
  8322. case CSW_HEGRENADE: // Infection bomb or fire grenade
  8323. {
  8324. if (g_zombie[id])
  8325. set_pev(id, pev_viewmodel2, model_grenade_infect)
  8326. else
  8327. set_pev(id, pev_viewmodel2, model_grenade_fire)
  8328. }
  8329. case CSW_FLASHBANG: // Frost grenade
  8330. {
  8331. set_pev(id, pev_viewmodel2, model_grenade_frost)
  8332. }
  8333. case CSW_SMOKEGRENADE: // Flare grenade
  8334. {
  8335. set_pev(id, pev_viewmodel2, model_grenade_flare)
  8336. }
  8337. }
  8338.  
  8339. // Update model on weaponmodel ent
  8340. if (g_handle_models_on_separate_ent) fm_set_weaponmodel_ent(id)
  8341. }
  8342.  
  8343. // Reset Player Vars
  8344. reset_vars(id, resetall)
  8345. {
  8346. g_zombie[id] = false
  8347. g_nemesis[id] = false
  8348. g_survivor[id] = false
  8349. g_firstzombie[id] = false
  8350. g_lastzombie[id] = false
  8351. g_lasthuman[id] = false
  8352. g_frozen[id] = false
  8353. g_nodamage[id] = false
  8354. g_respawn_as_zombie[id] = false
  8355. g_nvision[id] = false
  8356. g_nvisionenabled[id] = false
  8357. g_flashlight[id] = false
  8358. g_flashbattery[id] = 100
  8359. g_canbuy[id] = true
  8360. g_burning_duration[id] = 0
  8361.  
  8362. if (resetall)
  8363. {
  8364. g_ammopacks[id] = get_pcvar_num(cvar_startammopacks)
  8365. g_zombieclass[id] = ZCLASS_NONE
  8366. g_zombieclassnext[id] = ZCLASS_NONE
  8367. g_damagedealt[id] = 0
  8368. WPN_AUTO_ON = 0
  8369. }
  8370. }
  8371.  
  8372. // Set spectators nightvision
  8373. public spec_nvision(id)
  8374. {
  8375. // Not connected, alive, or bot
  8376. if (!g_isconnected[id] || g_isalive[id] || g_isbot[id])
  8377. return;
  8378.  
  8379. // Give Night Vision?
  8380. if (get_pcvar_num(cvar_nvggive))
  8381. {
  8382. g_nvision[id] = true
  8383.  
  8384. // Turn on Night Vision automatically?
  8385. if (get_pcvar_num(cvar_nvggive) == 1)
  8386. {
  8387. g_nvisionenabled[id] = true
  8388.  
  8389. // Custom nvg?
  8390. if (get_pcvar_num(cvar_customnvg))
  8391. {
  8392. remove_task(id+TASK_NVISION)
  8393. set_task(0.1, "set_user_nvision", id+TASK_NVISION, _, _, "b")
  8394. }
  8395. else
  8396. set_user_gnvision(id, 1)
  8397. }
  8398. }
  8399. }
  8400.  
  8401. // Show HUD Task
  8402. public ShowHUD(taskid)
  8403. {
  8404. static id
  8405. id = ID_SHOWHUD;
  8406.  
  8407. // Player died?
  8408. if (!g_isalive[id])
  8409. {
  8410. // Get spectating target
  8411. id = pev(id, PEV_SPEC_TARGET)
  8412.  
  8413. // Target not alive
  8414. if (!g_isalive[id]) return;
  8415. }
  8416.  
  8417. // Format classname
  8418. static class[32], red, green, blue
  8419.  
  8420. if (g_zombie[id]) // zombies
  8421. {
  8422. red = 200
  8423. green = 250
  8424. blue = 0
  8425.  
  8426. if (g_nemesis[id])
  8427. formatex(class, charsmax(class), "%L", ID_SHOWHUD, "CLASS_NEMESIS")
  8428. else
  8429. copy(class, charsmax(class), g_zombie_classname[id])
  8430. }
  8431. else // humans
  8432. {
  8433. red = 0
  8434. green = 0
  8435. blue = 255
  8436.  
  8437. if (g_survivor[id])
  8438. formatex(class, charsmax(class), "%L", ID_SHOWHUD, "CLASS_SURVIVOR")
  8439. else
  8440. formatex(class, charsmax(class), "%L", ID_SHOWHUD, "CLASS_HUMAN")
  8441. }
  8442.  
  8443. // Spectating someone else?
  8444. if (id != ID_SHOWHUD)
  8445. {
  8446. // Show name, health, class, and ammo packs
  8447. set_hudmessage(255, 255, 255, HUD_SPECT_X, HUD_SPECT_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
  8448. ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync2, "%L %s^nHP: %d - %L %s - %L %d", ID_SHOWHUD, "SPECTATING", g_playername[id], pev(id, pev_health), ID_SHOWHUD, "CLASS_CLASS", class, ID_SHOWHUD, "AMMO_PACKS1", g_ammopacks[id])
  8449. }
  8450. else
  8451. {
  8452. // Show health, class and ammo packs
  8453. set_hudmessage(red, green, blue, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
  8454. ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync, "HP: %d^n %L %s^n %L %d^n Armor: %d", get_user_health(ID_SHOWHUD), ID_SHOWHUD, "CLASS_CLASS", class, ID_SHOWHUD, "AMMO_PACKS1", g_ammopacks[id], ID_SHOWHUD, get_user_armor(ID_SHOWHUD))
  8455. }
  8456. }
  8457.  
  8458. // Play idle zombie sounds
  8459. public zombie_play_idle(taskid)
  8460. {
  8461. // Round ended/new one starting
  8462. if (g_endround || g_newround)
  8463. return;
  8464.  
  8465. static sound[64]
  8466.  
  8467. // Last zombie?
  8468. if (g_lastzombie[ID_BLOOD])
  8469. {
  8470. ArrayGetString(zombie_idle_last, random_num(0, ArraySize(zombie_idle_last) - 1), sound, charsmax(sound))
  8471. emit_sound(ID_BLOOD, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  8472. }
  8473. else
  8474. {
  8475. ArrayGetString(zombie_idle, random_num(0, ArraySize(zombie_idle) - 1), sound, charsmax(sound))
  8476. emit_sound(ID_BLOOD, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  8477. }
  8478. }
  8479.  
  8480. // Madness Over Task
  8481. public madness_over(taskid)
  8482. {
  8483. g_nodamage[ID_BLOOD] = false
  8484. }
  8485.  
  8486. // Place user at a random spawn
  8487. do_random_spawn(id, regularspawns = 0)
  8488. {
  8489. static hull, sp_index, i
  8490.  
  8491. // Get whether the player is crouching
  8492. hull = (pev(id, pev_flags) & FL_DUCKING) ? HULL_HEAD : HULL_HUMAN
  8493.  
  8494. // Use regular spawns?
  8495. if (!regularspawns)
  8496. {
  8497. // No spawns?
  8498. if (!g_spawnCount)
  8499. return;
  8500.  
  8501. // Choose random spawn to start looping at
  8502. sp_index = random_num(0, g_spawnCount - 1)
  8503.  
  8504. // Try to find a clear spawn
  8505. for (i = sp_index + 1; /*no condition*/; i++)
  8506. {
  8507. // Start over when we reach the end
  8508. if (i >= g_spawnCount) i = 0
  8509.  
  8510. // Free spawn space?
  8511. if (is_hull_vacant(g_spawns[i], hull))
  8512. {
  8513. // Engfunc_SetOrigin is used so ent's mins and maxs get updated instantly
  8514. engfunc(EngFunc_SetOrigin, id, g_spawns[i])
  8515. break;
  8516. }
  8517.  
  8518. // Loop completed, no free space found
  8519. if (i == sp_index) break;
  8520. }
  8521. }
  8522. else
  8523. {
  8524. // No spawns?
  8525. if (!g_spawnCount2)
  8526. return;
  8527.  
  8528. // Choose random spawn to start looping at
  8529. sp_index = random_num(0, g_spawnCount2 - 1)
  8530.  
  8531. // Try to find a clear spawn
  8532. for (i = sp_index + 1; /*no condition*/; i++)
  8533. {
  8534. // Start over when we reach the end
  8535. if (i >= g_spawnCount2) i = 0
  8536.  
  8537. // Free spawn space?
  8538. if (is_hull_vacant(g_spawns2[i], hull))
  8539. {
  8540. // Engfunc_SetOrigin is used so ent's mins and maxs get updated instantly
  8541. engfunc(EngFunc_SetOrigin, id, g_spawns2[i])
  8542. break;
  8543. }
  8544.  
  8545. // Loop completed, no free space found
  8546. if (i == sp_index) break;
  8547. }
  8548. }
  8549. }
  8550.  
  8551. // Get Zombies -returns alive zombies number-
  8552. fnGetZombies()
  8553. {
  8554. static iZombies, id
  8555. iZombies = 0
  8556.  
  8557. for (id = 1; id <= g_maxplayers; id++)
  8558. {
  8559. if (g_isalive[id] && g_zombie[id])
  8560. iZombies++
  8561. }
  8562.  
  8563. return iZombies;
  8564. }
  8565.  
  8566. // Get Humans -returns alive humans number-
  8567. fnGetHumans()
  8568. {
  8569. static iHumans, id
  8570. iHumans = 0
  8571.  
  8572. for (id = 1; id <= g_maxplayers; id++)
  8573. {
  8574. if (g_isalive[id] && !g_zombie[id])
  8575. iHumans++
  8576. }
  8577.  
  8578. return iHumans;
  8579. }
  8580.  
  8581. // Get Nemesis -returns alive nemesis number-
  8582. fnGetNemesis()
  8583. {
  8584. static iNemesis, id
  8585. iNemesis = 0
  8586.  
  8587. for (id = 1; id <= g_maxplayers; id++)
  8588. {
  8589. if (g_isalive[id] && g_nemesis[id])
  8590. iNemesis++
  8591. }
  8592.  
  8593. return iNemesis;
  8594. }
  8595.  
  8596. // Get Survivors -returns alive survivors number-
  8597. fnGetSurvivors()
  8598. {
  8599. static iSurvivors, id
  8600. iSurvivors = 0
  8601.  
  8602. for (id = 1; id <= g_maxplayers; id++)
  8603. {
  8604. if (g_isalive[id] && g_survivor[id])
  8605. iSurvivors++
  8606. }
  8607.  
  8608. return iSurvivors;
  8609. }
  8610.  
  8611. // Get Alive -returns alive players number-
  8612. fnGetAlive()
  8613. {
  8614. static iAlive, id
  8615. iAlive = 0
  8616.  
  8617. for (id = 1; id <= g_maxplayers; id++)
  8618. {
  8619. if (g_isalive[id])
  8620. iAlive++
  8621. }
  8622.  
  8623. return iAlive;
  8624. }
  8625.  
  8626. // Get Random Alive -returns index of alive player number n -
  8627. fnGetRandomAlive(n)
  8628. {
  8629. static iAlive, id
  8630. iAlive = 0
  8631.  
  8632. for (id = 1; id <= g_maxplayers; id++)
  8633. {
  8634. if (g_isalive[id])
  8635. iAlive++
  8636.  
  8637. if (iAlive == n)
  8638. return id;
  8639. }
  8640.  
  8641. return -1;
  8642. }
  8643.  
  8644. // Get Playing -returns number of users playing-
  8645. fnGetPlaying()
  8646. {
  8647. static iPlaying, id, team
  8648. iPlaying = 0
  8649.  
  8650. for (id = 1; id <= g_maxplayers; id++)
  8651. {
  8652. if (g_isconnected[id])
  8653. {
  8654. team = fm_cs_get_user_team(id)
  8655.  
  8656. if (team != FM_CS_TEAM_SPECTATOR && team != FM_CS_TEAM_UNASSIGNED)
  8657. iPlaying++
  8658. }
  8659. }
  8660.  
  8661. return iPlaying;
  8662. }
  8663.  
  8664. // Get CTs -returns number of CTs connected-
  8665. fnGetCTs()
  8666. {
  8667. static iCTs, id
  8668. iCTs = 0
  8669.  
  8670. for (id = 1; id <= g_maxplayers; id++)
  8671. {
  8672. if (g_isconnected[id])
  8673. {
  8674. if (fm_cs_get_user_team(id) == FM_CS_TEAM_CT)
  8675. iCTs++
  8676. }
  8677. }
  8678.  
  8679. return iCTs;
  8680. }
  8681.  
  8682. // Get Ts -returns number of Ts connected-
  8683. fnGetTs()
  8684. {
  8685. static iTs, id
  8686. iTs = 0
  8687.  
  8688. for (id = 1; id <= g_maxplayers; id++)
  8689. {
  8690. if (g_isconnected[id])
  8691. {
  8692. if (fm_cs_get_user_team(id) == FM_CS_TEAM_T)
  8693. iTs++
  8694. }
  8695. }
  8696.  
  8697. return iTs;
  8698. }
  8699.  
  8700. // Get Alive CTs -returns number of CTs alive-
  8701. fnGetAliveCTs()
  8702. {
  8703. static iCTs, id
  8704. iCTs = 0
  8705.  
  8706. for (id = 1; id <= g_maxplayers; id++)
  8707. {
  8708. if (g_isalive[id])
  8709. {
  8710. if (fm_cs_get_user_team(id) == FM_CS_TEAM_CT)
  8711. iCTs++
  8712. }
  8713. }
  8714.  
  8715. return iCTs;
  8716. }
  8717.  
  8718. // Get Alive Ts -returns number of Ts alive-
  8719. fnGetAliveTs()
  8720. {
  8721. static iTs, id
  8722. iTs = 0
  8723.  
  8724. for (id = 1; id <= g_maxplayers; id++)
  8725. {
  8726. if (g_isalive[id])
  8727. {
  8728. if (fm_cs_get_user_team(id) == FM_CS_TEAM_T)
  8729. iTs++
  8730. }
  8731. }
  8732.  
  8733. return iTs;
  8734. }
  8735.  
  8736. // Last Zombie Check -check for last zombie and set its flag-
  8737. fnCheckLastZombie()
  8738. {
  8739. static id
  8740. for (id = 1; id <= g_maxplayers; id++)
  8741. {
  8742. // Last zombie
  8743. if (g_isalive[id] && g_zombie[id] && !g_nemesis[id] && fnGetZombies() == 1)
  8744. {
  8745. if (!g_lastzombie[id])
  8746. {
  8747. // Last zombie forward
  8748. ExecuteForward(g_fwUserLastZombie, g_fwDummyResult, id);
  8749. }
  8750. g_lastzombie[id] = true
  8751. }
  8752. else
  8753. g_lastzombie[id] = false
  8754.  
  8755. // Last human
  8756. if (g_isalive[id] && !g_zombie[id] && !g_survivor[id] && fnGetHumans() == 1)
  8757. {
  8758. if (!g_lasthuman[id])
  8759. {
  8760. // Last human forward
  8761. ExecuteForward(g_fwUserLastHuman, g_fwDummyResult, id);
  8762.  
  8763. // Reward extra hp
  8764. fm_set_user_health(id, pev(id, pev_health) + get_pcvar_num(cvar_humanlasthp))
  8765. }
  8766. g_lasthuman[id] = true
  8767. }
  8768. else
  8769. g_lasthuman[id] = false
  8770. }
  8771. }
  8772.  
  8773. // Save player's stats to database
  8774. save_stats(id)
  8775. {
  8776. // Check whether there is another record already in that slot
  8777. if (db_name[id][0] && !equal(g_playername[id], db_name[id]))
  8778. {
  8779. // If DB size is exceeded, write over old records
  8780. if (db_slot_i >= sizeof db_name)
  8781. db_slot_i = g_maxplayers+1
  8782.  
  8783. // Move previous record onto an additional save slot
  8784. copy(db_name[db_slot_i], charsmax(db_name[]), db_name[id])
  8785. db_ammopacks[db_slot_i] = db_ammopacks[id]
  8786. db_zombieclass[db_slot_i] = db_zombieclass[id]
  8787. db_slot_i++
  8788. }
  8789.  
  8790. // Now save the current player stats
  8791. copy(db_name[id], charsmax(db_name[]), g_playername[id]) // name
  8792. db_ammopacks[id] = g_ammopacks[id] // ammo packs
  8793. db_zombieclass[id] = g_zombieclassnext[id] // zombie class
  8794. }
  8795.  
  8796. // Load player's stats from database (if a record is found)
  8797. load_stats(id)
  8798. {
  8799. // Look for a matching record
  8800. static i
  8801. for (i = 0; i < sizeof db_name; i++)
  8802. {
  8803. if (equal(g_playername[id], db_name[i]))
  8804. {
  8805. // Bingo!
  8806. g_ammopacks[id] = db_ammopacks[i]
  8807. g_zombieclass[id] = db_zombieclass[i]
  8808. g_zombieclassnext[id] = db_zombieclass[i]
  8809. return;
  8810. }
  8811. }
  8812. }
  8813.  
  8814. // Checks if a player is allowed to be zombie
  8815. allowed_zombie(id)
  8816. {
  8817. if ((g_zombie[id] && !g_nemesis[id]) || g_endround || !g_isalive[id] || task_exists(TASK_WELCOMEMSG) || (!g_newround && !g_zombie[id] && fnGetHumans() == 1))
  8818. return false;
  8819.  
  8820. return true;
  8821. }
  8822.  
  8823. // Checks if a player is allowed to be human
  8824. allowed_human(id)
  8825. {
  8826. if ((!g_zombie[id] && !g_survivor[id]) || g_endround || !g_isalive[id] || task_exists(TASK_WELCOMEMSG) || (!g_newround && g_zombie[id] && fnGetZombies() == 1))
  8827. return false;
  8828.  
  8829. return true;
  8830. }
  8831.  
  8832. // Checks if a player is allowed to be survivor
  8833. allowed_survivor(id)
  8834. {
  8835. if (g_endround || g_survivor[id] || !g_isalive[id] || task_exists(TASK_WELCOMEMSG) || (!g_newround && g_zombie[id] && fnGetZombies() == 1))
  8836. return false;
  8837.  
  8838. return true;
  8839. }
  8840.  
  8841. // Checks if a player is allowed to be nemesis
  8842. allowed_nemesis(id)
  8843. {
  8844. if (g_endround || g_nemesis[id] || !g_isalive[id] || task_exists(TASK_WELCOMEMSG) || (!g_newround && !g_zombie[id] && fnGetHumans() == 1))
  8845. return false;
  8846.  
  8847. return true;
  8848. }
  8849.  
  8850. // Checks if a player is allowed to respawn
  8851. allowed_respawn(id)
  8852. {
  8853. static team
  8854. team = fm_cs_get_user_team(id)
  8855.  
  8856. if (g_endround || team == FM_CS_TEAM_SPECTATOR || team == FM_CS_TEAM_UNASSIGNED || g_isalive[id])
  8857. return false;
  8858.  
  8859. return true;
  8860. }
  8861.  
  8862. // Checks if swarm mode is allowed
  8863. allowed_swarm()
  8864. {
  8865. if (g_endround || !g_newround || task_exists(TASK_WELCOMEMSG))
  8866. return false;
  8867.  
  8868. return true;
  8869. }
  8870.  
  8871. // Checks if multi infection mode is allowed
  8872. allowed_multi()
  8873. {
  8874. if (g_endround || !g_newround || task_exists(TASK_WELCOMEMSG) || floatround(fnGetAlive()*get_pcvar_float(cvar_multiratio), floatround_ceil) < 2 || floatround(fnGetAlive()*get_pcvar_float(cvar_multiratio), floatround_ceil) >= fnGetAlive())
  8875. return false;
  8876.  
  8877. return true;
  8878. }
  8879.  
  8880. // Checks if plague mode is allowed
  8881. allowed_plague()
  8882. {
  8883. if (g_endround || !g_newround || task_exists(TASK_WELCOMEMSG) || floatround((fnGetAlive()-(get_pcvar_num(cvar_plaguenemnum)+get_pcvar_num(cvar_plaguesurvnum)))*get_pcvar_float(cvar_plagueratio), floatround_ceil) < 1
  8884. || fnGetAlive()-(get_pcvar_num(cvar_plaguesurvnum)+get_pcvar_num(cvar_plaguenemnum)+floatround((fnGetAlive()-(get_pcvar_num(cvar_plaguenemnum)+get_pcvar_num(cvar_plaguesurvnum)))*get_pcvar_float(cvar_plagueratio), floatround_ceil)) < 1)
  8885. return false;
  8886.  
  8887. return true;
  8888. }
  8889.  
  8890. // Admin Command. zp_zombie
  8891. command_zombie(id, player)
  8892. {
  8893. // Show activity?
  8894. switch (get_pcvar_num(cvar_showactivity))
  8895. {
  8896. case 1: client_print(0, print_chat, "ADMIN - %s %L", g_playername[player], LANG_PLAYER, "CMD_INFECT")
  8897. case 2: client_print(0, print_chat, "ADMIN %s - %s %L", g_playername[id], g_playername[player], LANG_PLAYER, "CMD_INFECT")
  8898. }
  8899.  
  8900. // Log to Zombie Plague log file?
  8901. if (get_pcvar_num(cvar_logcommands))
  8902. {
  8903. static logdata[100], authid[32], ip[16]
  8904. get_user_authid(id, authid, charsmax(authid))
  8905. get_user_ip(id, ip, charsmax(ip), 1)
  8906. formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %s %L (Players: %d/%d)", g_playername[id], authid, ip, g_playername[player], LANG_SERVER, "CMD_INFECT", fnGetPlaying(), g_maxplayers)
  8907. log_to_file("zombieplague.log", logdata)
  8908. }
  8909.  
  8910. // New round?
  8911. if (g_newround)
  8912. {
  8913. // Set as first zombie
  8914. remove_task(TASK_MAKEZOMBIE)
  8915. make_a_zombie(MODE_INFECTION, player)
  8916. }
  8917. else
  8918. {
  8919. // Just infect
  8920. zombieme(player, 0, 0, 0, 0)
  8921. }
  8922. }
  8923.  
  8924. // Admin Command. zp_human
  8925. command_human(id, player)
  8926. {
  8927. // Show activity?
  8928. switch (get_pcvar_num(cvar_showactivity))
  8929. {
  8930. case 1: client_print(0, print_chat, "ADMIN - %s %L", g_playername[player], LANG_PLAYER, "CMD_DISINFECT")
  8931. case 2: client_print(0, print_chat, "ADMIN %s - %s %L", g_playername[id], g_playername[player], LANG_PLAYER, "CMD_DISINFECT")
  8932. }
  8933.  
  8934. // Log to Zombie Plague log file?
  8935. if (get_pcvar_num(cvar_logcommands))
  8936. {
  8937. static logdata[100], authid[32], ip[16]
  8938. get_user_authid(id, authid, charsmax(authid))
  8939. get_user_ip(id, ip, charsmax(ip), 1)
  8940. formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %s %L (Players: %d/%d)", g_playername[id], authid, ip, g_playername[player], LANG_SERVER,"CMD_DISINFECT", fnGetPlaying(), g_maxplayers)
  8941. log_to_file("zombieplague.log", logdata)
  8942. }
  8943.  
  8944. // Turn to human
  8945. humanme(player, 0, 0)
  8946. }
  8947.  
  8948. // Admin Command. zp_survivor
  8949. command_survivor(id, player)
  8950. {
  8951. // Show activity?
  8952. switch (get_pcvar_num(cvar_showactivity))
  8953. {
  8954. case 1: client_print(0, print_chat, "ADMIN - %s %L", g_playername[player], LANG_PLAYER, "CMD_SURVIVAL")
  8955. case 2: client_print(0, print_chat, "ADMIN %s - %s %L", g_playername[id], g_playername[player], LANG_PLAYER, "CMD_SURVIVAL")
  8956. }
  8957.  
  8958. // Log to Zombie Plague log file?
  8959. if (get_pcvar_num(cvar_logcommands))
  8960. {
  8961. static logdata[100], authid[32], ip[16]
  8962. get_user_authid(id, authid, charsmax(authid))
  8963. get_user_ip(id, ip, charsmax(ip), 1)
  8964. formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %s %L (Players: %d/%d)", g_playername[id], authid, ip, g_playername[player], LANG_SERVER,"CMD_SURVIVAL", fnGetPlaying(), g_maxplayers)
  8965. log_to_file("zombieplague.log", logdata)
  8966. }
  8967.  
  8968. // New round?
  8969. if (g_newround)
  8970. {
  8971. // Set as first survivor
  8972. remove_task(TASK_MAKEZOMBIE)
  8973. make_a_zombie(MODE_SURVIVOR, player)
  8974. }
  8975. else
  8976. {
  8977. // Turn player into a Survivor
  8978. humanme(player, 1, 0)
  8979. }
  8980. }
  8981.  
  8982. // Admin Command. zp_nemesis
  8983. command_nemesis(id, player)
  8984. {
  8985. // Show activity?
  8986. switch (get_pcvar_num(cvar_showactivity))
  8987. {
  8988. case 1: client_print(0, print_chat, "ADMIN - %s %L", g_playername[player], LANG_PLAYER, "CMD_NEMESIS")
  8989. case 2: client_print(0, print_chat, "ADMIN %s - %s %L", g_playername[id], g_playername[player], LANG_PLAYER, "CMD_NEMESIS")
  8990. }
  8991.  
  8992. // Log to Zombie Plague log file?
  8993. if (get_pcvar_num(cvar_logcommands))
  8994. {
  8995. static logdata[100], authid[32], ip[16]
  8996. get_user_authid(id, authid, charsmax(authid))
  8997. get_user_ip(id, ip, charsmax(ip), 1)
  8998. formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %s %L (Players: %d/%d)", g_playername[id], authid, ip, g_playername[player], LANG_SERVER,"CMD_NEMESIS", fnGetPlaying(), g_maxplayers)
  8999. log_to_file("zombieplague.log", logdata)
  9000. }
  9001.  
  9002. // New round?
  9003. if (g_newround)
  9004. {
  9005. // Set as first nemesis
  9006. remove_task(TASK_MAKEZOMBIE)
  9007. make_a_zombie(MODE_NEMESIS, player)
  9008. }
  9009. else
  9010. {
  9011. // Turn player into a Nemesis
  9012. zombieme(player, 0, 1, 0, 0)
  9013. }
  9014. }
  9015.  
  9016. // Admin Command. zp_respawn
  9017. command_respawn(id, player)
  9018. {
  9019. // Show activity?
  9020. switch (get_pcvar_num(cvar_showactivity))
  9021. {
  9022. case 1: client_print(0, print_chat, "ADMIN - %s %L", g_playername[player], LANG_PLAYER, "CMD_RESPAWN")
  9023. case 2: client_print(0, print_chat, "ADMIN %s - %s %L", g_playername[id], g_playername[player], LANG_PLAYER, "CMD_RESPAWN")
  9024. }
  9025.  
  9026. // Log to Zombie Plague log file?
  9027. if (get_pcvar_num(cvar_logcommands))
  9028. {
  9029. static logdata[100], authid[32], ip[16]
  9030. get_user_authid(id, authid, charsmax(authid))
  9031. get_user_ip(id, ip, charsmax(ip), 1)
  9032. formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %s %L (Players: %d/%d)", g_playername[id], authid, ip, g_playername[player], LANG_SERVER, "CMD_RESPAWN", fnGetPlaying(), g_maxplayers)
  9033. log_to_file("zombieplague.log", logdata)
  9034. }
  9035.  
  9036. // Respawn as zombie?
  9037. if (get_pcvar_num(cvar_deathmatch) == 2 || (get_pcvar_num(cvar_deathmatch) == 3 && random_num(0, 1)) || (get_pcvar_num(cvar_deathmatch) == 4 && fnGetZombies() < fnGetAlive()/2))
  9038. g_respawn_as_zombie[player] = true
  9039.  
  9040. // Override respawn as zombie setting on nemesis and survivor rounds
  9041. if (g_survround) g_respawn_as_zombie[player] = true
  9042. else if (g_nemround) g_respawn_as_zombie[player] = false
  9043.  
  9044. respawn_player_manually(player);
  9045. }
  9046.  
  9047. // Admin Command. zp_swarm
  9048. command_swarm(id)
  9049. {
  9050. // Show activity?
  9051. switch (get_pcvar_num(cvar_showactivity))
  9052. {
  9053. case 1: client_print(0, print_chat, "ADMIN - %L", LANG_PLAYER, "CMD_SWARM")
  9054. case 2: client_print(0, print_chat, "ADMIN %s - %L", g_playername[id], LANG_PLAYER, "CMD_SWARM")
  9055. }
  9056.  
  9057. // Log to Zombie Plague log file?
  9058. if (get_pcvar_num(cvar_logcommands))
  9059. {
  9060. static logdata[100], authid[32], ip[16]
  9061. get_user_authid(id, authid, charsmax(authid))
  9062. get_user_ip(id, ip, charsmax(ip), 1)
  9063. formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %L (Players: %d/%d)", g_playername[id], authid, ip, LANG_SERVER, "CMD_SWARM", fnGetPlaying(), g_maxplayers)
  9064. log_to_file("zombieplague.log", logdata)
  9065. }
  9066.  
  9067. // Call Swarm Mode
  9068. remove_task(TASK_MAKEZOMBIE)
  9069. make_a_zombie(MODE_SWARM, 0)
  9070. }
  9071.  
  9072. // Admin Command. zp_multi
  9073. command_multi(id)
  9074. {
  9075. // Show activity?
  9076. switch (get_pcvar_num(cvar_showactivity))
  9077. {
  9078. case 1: client_print(0, print_chat, "ADMIN - %L", LANG_PLAYER, "CMD_MULTI")
  9079. case 2: client_print(0, print_chat, "ADMIN %s - %L", g_playername[id], LANG_PLAYER, "CMD_MULTI")
  9080. }
  9081.  
  9082. // Log to Zombie Plague log file?
  9083. if (get_pcvar_num(cvar_logcommands))
  9084. {
  9085. static logdata[100], authid[32], ip[16]
  9086. get_user_authid(id, authid, charsmax(authid))
  9087. get_user_ip(id, ip, charsmax(ip), 1)
  9088. formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %L (Players: %d/%d)", g_playername[id], authid, ip, LANG_SERVER,"CMD_MULTI", fnGetPlaying(), g_maxplayers)
  9089. log_to_file("zombieplague.log", logdata)
  9090. }
  9091.  
  9092. // Call Multi Infection
  9093. remove_task(TASK_MAKEZOMBIE)
  9094. make_a_zombie(MODE_MULTI, 0)
  9095. }
  9096.  
  9097. // Admin Command. zp_plague
  9098. command_plague(id)
  9099. {
  9100. // Show activity?
  9101. switch (get_pcvar_num(cvar_showactivity))
  9102. {
  9103. case 1: client_print(0, print_chat, "ADMIN - %L", LANG_PLAYER, "CMD_PLAGUE")
  9104. case 2: client_print(0, print_chat, "ADMIN %s - %L", g_playername[id], LANG_PLAYER, "CMD_PLAGUE")
  9105. }
  9106.  
  9107. // Log to Zombie Plague log file?
  9108. if (get_pcvar_num(cvar_logcommands))
  9109. {
  9110. static logdata[100], authid[32], ip[16]
  9111. get_user_authid(id, authid, charsmax(authid))
  9112. get_user_ip(id, ip, charsmax(ip), 1)
  9113. formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %L (Players: %d/%d)", g_playername[id], authid, ip, LANG_SERVER,"CMD_PLAGUE", fnGetPlaying(), g_maxplayers)
  9114. log_to_file("zombieplague.log", logdata)
  9115. }
  9116.  
  9117. // Call Plague Mode
  9118. remove_task(TASK_MAKEZOMBIE)
  9119. make_a_zombie(MODE_PLAGUE, 0)
  9120. }
  9121.  
  9122. /*================================================================================
  9123. [Custom Natives]
  9124. =================================================================================*/
  9125.  
  9126. // Native: zp_get_user_zombie
  9127. public native_get_user_zombie(id)
  9128. {
  9129. return g_zombie[id];
  9130. }
  9131.  
  9132. // Native: zp_get_user_nemesis
  9133. public native_get_user_nemesis(id)
  9134. {
  9135. return g_nemesis[id];
  9136. }
  9137.  
  9138. // Native: zp_get_user_survivor
  9139. public native_get_user_survivor(id)
  9140. {
  9141. return g_survivor[id];
  9142. }
  9143.  
  9144. public native_get_user_first_zombie(id)
  9145. {
  9146. return g_firstzombie[id];
  9147. }
  9148.  
  9149. // Native: zp_get_user_last_zombie
  9150. public native_get_user_last_zombie(id)
  9151. {
  9152. return g_lastzombie[id];
  9153. }
  9154.  
  9155. // Native: zp_get_user_last_human
  9156. public native_get_user_last_human(id)
  9157. {
  9158. return g_lasthuman[id];
  9159. }
  9160.  
  9161. // Native: zp_get_user_zombie_class
  9162. public native_get_user_zombie_class(id)
  9163. {
  9164. return g_zombieclass[id];
  9165. }
  9166.  
  9167. // Native: zp_get_user_next_class
  9168. public native_get_user_next_class(id)
  9169. {
  9170. return g_zombieclassnext[id];
  9171. }
  9172.  
  9173. // Native: zp_set_user_zombie_class
  9174. public native_set_user_zombie_class(id, classid)
  9175. {
  9176. if (classid < 0 || classid >= g_zclass_i)
  9177. return 0;
  9178.  
  9179. g_zombieclassnext[id] = classid
  9180. return 1;
  9181. }
  9182.  
  9183. // Native: zp_get_user_ammo_packs
  9184. public native_get_user_ammo_packs(id)
  9185. {
  9186. return g_ammopacks[id];
  9187. }
  9188.  
  9189. // Native: zp_set_user_ammo_packs
  9190. public native_set_user_ammo_packs(id, amount)
  9191. {
  9192. g_ammopacks[id] = amount;
  9193. }
  9194.  
  9195. // Native: zp_get_zombie_maxhealth
  9196. public native_get_zombie_maxhealth(id)
  9197. {
  9198. // ZP disabled
  9199. if (!g_pluginenabled)
  9200. return -1;
  9201.  
  9202. if (g_zombie[id] && !g_nemesis[id])
  9203. {
  9204. if (g_firstzombie[id])
  9205. return floatround(float(ArrayGetCell(g_zclass_hp, g_zombieclass[id])) * get_pcvar_float(cvar_zombiefirsthp));
  9206. else
  9207. return ArrayGetCell(g_zclass_hp, g_zombieclass[id]);
  9208. }
  9209. return -1;
  9210. }
  9211.  
  9212. // Native: zp_get_user_batteries
  9213. public native_get_user_batteries(id)
  9214. {
  9215. return g_flashbattery[id];
  9216. }
  9217.  
  9218. // Native: zp_set_user_batteries
  9219. public native_set_user_batteries(id, value)
  9220. {
  9221. // ZP disabled
  9222. if (!g_pluginenabled)
  9223. return;
  9224.  
  9225. g_flashbattery[id] = clamp(value, 0, 100);
  9226.  
  9227. if (g_cached_customflash)
  9228. {
  9229. // Set the flashlight charge task to update battery status
  9230. remove_task(id+TASK_CHARGE)
  9231. set_task(1.0, "flashlight_charge", id+TASK_CHARGE, _, _, "b")
  9232. }
  9233. }
  9234.  
  9235. // Native: zp_get_user_nightvision
  9236. public native_get_user_nightvision(id)
  9237. {
  9238. return g_nvision[id];
  9239. }
  9240.  
  9241. // Native: zp_set_user_nightvision
  9242. public native_set_user_nightvision(id, set)
  9243. {
  9244. // ZP disabled
  9245. if (!g_pluginenabled)
  9246. return;
  9247.  
  9248. if (set)
  9249. {
  9250. g_nvision[id] = true
  9251.  
  9252. if (!g_isbot[id])
  9253. {
  9254. g_nvisionenabled[id] = true
  9255.  
  9256. // Custom nvg?
  9257. if (get_pcvar_num(cvar_customnvg))
  9258. {
  9259. remove_task(id+TASK_NVISION)
  9260. set_task(0.1, "set_user_nvision", id+TASK_NVISION, _, _, "b")
  9261. }
  9262. else
  9263. set_user_gnvision(id, 1)
  9264. }
  9265. else
  9266. cs_set_user_nvg(id, 1)
  9267. }
  9268. else
  9269. {
  9270. // Turn off NVG for bots
  9271. if (g_isbot[id]) cs_set_user_nvg(id, 0);
  9272. if (get_pcvar_num(cvar_customnvg)) remove_task(id+TASK_NVISION)
  9273. else if (g_nvisionenabled[id]) set_user_gnvision(id, 0)
  9274. g_nvision[id] = false
  9275. g_nvisionenabled[id] = false
  9276. }
  9277. }
  9278.  
  9279. // Native: zp_infect_user
  9280. public native_infect_user(id, infector, silent, rewards)
  9281. {
  9282. // ZP disabled
  9283. if (!g_pluginenabled)
  9284. return -1;
  9285.  
  9286. // Not allowed to be zombie
  9287. if (!allowed_zombie(id))
  9288. return 0;
  9289.  
  9290. // New round?
  9291. if (g_newround)
  9292. {
  9293. // Set as first zombie
  9294. remove_task(TASK_MAKEZOMBIE)
  9295. make_a_zombie(MODE_INFECTION, id)
  9296. }
  9297. else
  9298. {
  9299. // Just infect (plus some checks)
  9300. zombieme(id, is_user_valid_alive(infector) ? infector : 0, 0, (silent == 1) ? 1 : 0, (rewards == 1) ? 1 : 0)
  9301. }
  9302.  
  9303. return 1;
  9304. }
  9305.  
  9306. // Native: zp_disinfect_user
  9307. public native_disinfect_user(id, silent)
  9308. {
  9309. // ZP disabled
  9310. if (!g_pluginenabled)
  9311. return -1;
  9312.  
  9313. // Not allowed to be human
  9314. if (!allowed_human(id))
  9315. return 0;
  9316.  
  9317. // Turn to human
  9318. humanme(id, 0, (silent == 1) ? 1 : 0)
  9319. return 1;
  9320. }
  9321.  
  9322. // Native: zp_make_user_nemesis
  9323. public native_make_user_nemesis(id)
  9324. {
  9325. // ZP disabled
  9326. if (!g_pluginenabled)
  9327. return -1;
  9328.  
  9329. // Not allowed to be nemesis
  9330. if (!allowed_nemesis(id))
  9331. return 0;
  9332.  
  9333. // New round?
  9334. if (g_newround)
  9335. {
  9336. // Set as first nemesis
  9337. remove_task(TASK_MAKEZOMBIE)
  9338. make_a_zombie(MODE_NEMESIS, id)
  9339. }
  9340. else
  9341. {
  9342. // Turn player into a Nemesis
  9343. zombieme(id, 0, 1, 0, 0)
  9344. }
  9345.  
  9346. return 1;
  9347. }
  9348.  
  9349. // Native: zp_make_user_survivor
  9350. public native_make_user_survivor(id)
  9351. {
  9352. // ZP disabled
  9353. if (!g_pluginenabled)
  9354. return -1;
  9355.  
  9356. // Not allowed to be survivor
  9357. if (!allowed_survivor(id))
  9358. return 0;
  9359.  
  9360. // New round?
  9361. if (g_newround)
  9362. {
  9363. // Set as first survivor
  9364. remove_task(TASK_MAKEZOMBIE)
  9365. make_a_zombie(MODE_SURVIVOR, id)
  9366. }
  9367. else
  9368. {
  9369. // Turn player into a Survivor
  9370. humanme(id, 1, 0)
  9371. }
  9372.  
  9373. return 1;
  9374. }
  9375.  
  9376. // Native: zp_respawn_user
  9377. public native_respawn_user(id, team)
  9378. {
  9379. // ZP disabled
  9380. if (!g_pluginenabled)
  9381. return -1;
  9382.  
  9383. // Invalid player
  9384. if (!is_user_valid_connected(id))
  9385. return 0;
  9386.  
  9387. // Respawn not allowed
  9388. if (!allowed_respawn(id))
  9389. return 0;
  9390.  
  9391. // Respawn as zombie?
  9392. g_respawn_as_zombie[id] = (team == ZP_TEAM_ZOMBIE) ? true : false
  9393.  
  9394. // Respawnish!
  9395. respawn_player_manually(id)
  9396. return 1;
  9397. }
  9398.  
  9399. // Native: zp_force_buy_extra_item
  9400. public native_force_buy_extra_item(id, itemid, ignorecost)
  9401. {
  9402. // ZP disabled
  9403. if (!g_pluginenabled)
  9404. return -1;
  9405.  
  9406. if (itemid < 0 || itemid >= g_extraitem_i)
  9407. return 0;
  9408.  
  9409. buy_extra_item(id, itemid, ignorecost)
  9410. return 1;
  9411. }
  9412.  
  9413. // Native: zp_has_round_started
  9414. public native_has_round_started()
  9415. {
  9416. if (g_newround) return 0; // not started
  9417. if (g_modestarted) return 1; // started
  9418. return 2; // starting
  9419. }
  9420.  
  9421. // Native: zp_is_nemesis_round
  9422. public native_is_nemesis_round()
  9423. {
  9424. return g_nemround;
  9425. }
  9426.  
  9427. // Native: zp_is_survivor_round
  9428. public native_is_survivor_round()
  9429. {
  9430. return g_survround;
  9431. }
  9432.  
  9433. // Native: zp_is_swarm_round
  9434. public native_is_swarm_round()
  9435. {
  9436. return g_swarmround;
  9437. }
  9438.  
  9439. // Native: zp_is_plague_round
  9440. public native_is_plague_round()
  9441. {
  9442. return g_plagueround;
  9443. }
  9444.  
  9445. // Native: zp_get_zombie_count
  9446. public native_get_zombie_count()
  9447. {
  9448. return fnGetZombies();
  9449. }
  9450.  
  9451. // Native: zp_get_human_count
  9452. public native_get_human_count()
  9453. {
  9454. return fnGetHumans();
  9455. }
  9456.  
  9457. // Native: zp_get_nemesis_count
  9458. public native_get_nemesis_count()
  9459. {
  9460. return fnGetNemesis();
  9461. }
  9462.  
  9463. // Native: zp_get_survivor_count
  9464. public native_get_survivor_count()
  9465. {
  9466. return fnGetSurvivors();
  9467. }
  9468.  
  9469. // Native: zp_register_extra_item
  9470. public native_register_extra_item(const name[], cost, team)
  9471. {
  9472. // ZP disabled
  9473. if (!g_pluginenabled)
  9474. return -1;
  9475.  
  9476. // Arrays not yet initialized
  9477. if (!g_arrays_created)
  9478. return -1;
  9479.  
  9480. // For backwards compatibility
  9481. if (team == ZP_TEAM_ANY)
  9482. team = ZP_TEAM_ZOMBIE|ZP_TEAM_HUMAN
  9483.  
  9484. // Strings passed byref
  9485. param_convert(1)
  9486.  
  9487. // Add the item
  9488. ArrayPushString(g_extraitem_name, name)
  9489. ArrayPushCell(g_extraitem_cost, cost)
  9490. ArrayPushCell(g_extraitem_team, team)
  9491.  
  9492. // Set temporary new item flag
  9493. ArrayPushCell(g_extraitem_new, 1)
  9494.  
  9495. // Override extra items data with our customizations
  9496. new i, buffer[32], size = ArraySize(g_extraitem2_realname)
  9497. for (i = 0; i < size; i++)
  9498. {
  9499. ArrayGetString(g_extraitem2_realname, i, buffer, charsmax(buffer))
  9500.  
  9501. // Check if this is the intended item to override
  9502. if (!equal(name, buffer))
  9503. continue;
  9504.  
  9505. // Remove new item flag
  9506. ArraySetCell(g_extraitem_new, g_extraitem_i, 0)
  9507.  
  9508. // Replace caption
  9509. ArrayGetString(g_extraitem2_name, i, buffer, charsmax(buffer))
  9510. ArraySetString(g_extraitem_name, g_extraitem_i, buffer)
  9511.  
  9512. // Replace cost
  9513. buffer[0] = ArrayGetCell(g_extraitem2_cost, i)
  9514. ArraySetCell(g_extraitem_cost, g_extraitem_i, buffer[0])
  9515.  
  9516. // Replace team
  9517. buffer[0] = ArrayGetCell(g_extraitem2_team, i)
  9518. ArraySetCell(g_extraitem_team, g_extraitem_i, buffer[0])
  9519. }
  9520.  
  9521. // Increase registered items counter
  9522. g_extraitem_i++
  9523.  
  9524. // Return id under which we registered the item
  9525. return g_extraitem_i-1;
  9526. }
  9527.  
  9528. // Function: zp_register_extra_item (to be used within this plugin only)
  9529. native_register_extra_item2(const name[], cost, team)
  9530. {
  9531. // Add the item
  9532. ArrayPushString(g_extraitem_name, name)
  9533. ArrayPushCell(g_extraitem_cost, cost)
  9534. ArrayPushCell(g_extraitem_team, team)
  9535.  
  9536. // Set temporary new item flag
  9537. ArrayPushCell(g_extraitem_new, 1)
  9538.  
  9539. // Increase registered items counter
  9540. g_extraitem_i++
  9541. }
  9542.  
  9543. // Native: zp_register_zombie_class
  9544. public native_register_zombie_class(const name[], const info[], const model[], const clawmodel[], hp, speed, Float:gravity, Float:knockback)
  9545. {
  9546. // ZP disabled
  9547. if (!g_pluginenabled)
  9548. return -1;
  9549.  
  9550. // Arrays not yet initialized
  9551. if (!g_arrays_created)
  9552. return -1;
  9553.  
  9554. // Strings passed byref
  9555. param_convert(1)
  9556. param_convert(2)
  9557. param_convert(3)
  9558. param_convert(4)
  9559.  
  9560. // Add the class
  9561. ArrayPushString(g_zclass_name, name)
  9562. ArrayPushString(g_zclass_info, info)
  9563.  
  9564. // Using same zombie models for all classes?
  9565. if (g_same_models_for_all)
  9566. {
  9567. ArrayPushCell(g_zclass_modelsstart, 0)
  9568. ArrayPushCell(g_zclass_modelsend, ArraySize(g_zclass_playermodel))
  9569. }
  9570. else
  9571. {
  9572. ArrayPushCell(g_zclass_modelsstart, ArraySize(g_zclass_playermodel))
  9573. ArrayPushString(g_zclass_playermodel, model)
  9574. ArrayPushCell(g_zclass_modelsend, ArraySize(g_zclass_playermodel))
  9575. ArrayPushCell(g_zclass_modelindex, -1)
  9576. }
  9577.  
  9578. ArrayPushString(g_zclass_clawmodel, clawmodel)
  9579. ArrayPushCell(g_zclass_hp, hp)
  9580. ArrayPushCell(g_zclass_spd, speed)
  9581. ArrayPushCell(g_zclass_grav, gravity)
  9582. ArrayPushCell(g_zclass_kb, knockback)
  9583.  
  9584. // Set temporary new class flag
  9585. ArrayPushCell(g_zclass_new, 1)
  9586.  
  9587. // Override zombie classes data with our customizations
  9588. new i, k, buffer[32], Float:buffer2, nummodels_custom, nummodels_default, prec_mdl[100], size = ArraySize(g_zclass2_realname)
  9589. for (i = 0; i < size; i++)
  9590. {
  9591. ArrayGetString(g_zclass2_realname, i, buffer, charsmax(buffer))
  9592.  
  9593. // Check if this is the intended class to override
  9594. if (!equal(name, buffer))
  9595. continue;
  9596.  
  9597. // Remove new class flag
  9598. ArraySetCell(g_zclass_new, g_zclass_i, 0)
  9599.  
  9600. // Replace caption
  9601. ArrayGetString(g_zclass2_name, i, buffer, charsmax(buffer))
  9602. ArraySetString(g_zclass_name, g_zclass_i, buffer)
  9603.  
  9604. // Replace info
  9605. ArrayGetString(g_zclass2_info, i, buffer, charsmax(buffer))
  9606. ArraySetString(g_zclass_info, g_zclass_i, buffer)
  9607.  
  9608. // Replace models, unless using same models for all classes
  9609. if (!g_same_models_for_all)
  9610. {
  9611. nummodels_custom = ArrayGetCell(g_zclass2_modelsend, i) - ArrayGetCell(g_zclass2_modelsstart, i)
  9612. nummodels_default = ArrayGetCell(g_zclass_modelsend, g_zclass_i) - ArrayGetCell(g_zclass_modelsstart, g_zclass_i)
  9613.  
  9614. // Replace each player model and model index
  9615. for (k = 0; k < min(nummodels_custom, nummodels_default); k++)
  9616. {
  9617. ArrayGetString(g_zclass2_playermodel, ArrayGetCell(g_zclass2_modelsstart, i) + k, buffer, charsmax(buffer))
  9618. ArraySetString(g_zclass_playermodel, ArrayGetCell(g_zclass_modelsstart, g_zclass_i) + k, buffer)
  9619.  
  9620. // Precache player model and replace its modelindex with the real one
  9621. formatex(prec_mdl, charsmax(prec_mdl), "models/player/%s/%s.mdl", buffer, buffer)
  9622. ArraySetCell(g_zclass_modelindex, ArrayGetCell(g_zclass_modelsstart, g_zclass_i) + k, engfunc(EngFunc_PrecacheModel, prec_mdl))
  9623. if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, prec_mdl)
  9624. if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, prec_mdl)
  9625. }
  9626.  
  9627. // We have more custom models than what we can accommodate,
  9628. // Let's make some space...
  9629. if (nummodels_custom > nummodels_default)
  9630. {
  9631. for (k = nummodels_default; k < nummodels_custom; k++)
  9632. {
  9633. ArrayGetString(g_zclass2_playermodel, ArrayGetCell(g_zclass2_modelsstart, i) + k, buffer, charsmax(buffer))
  9634. ArrayInsertStringAfter(g_zclass_playermodel, ArrayGetCell(g_zclass_modelsstart, g_zclass_i) + k - 1, buffer)
  9635.  
  9636. // Precache player model and retrieve its modelindex
  9637. formatex(prec_mdl, charsmax(prec_mdl), "models/player/%s/%s.mdl", buffer, buffer)
  9638. ArrayInsertCellAfter(g_zclass_modelindex, ArrayGetCell(g_zclass_modelsstart, g_zclass_i) + k - 1, engfunc(EngFunc_PrecacheModel, prec_mdl))
  9639. if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, prec_mdl)
  9640. if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, prec_mdl)
  9641. }
  9642.  
  9643. // Fix models end index for this class
  9644. ArraySetCell(g_zclass_modelsend, g_zclass_i, ArrayGetCell(g_zclass_modelsend, g_zclass_i) + (nummodels_custom - nummodels_default))
  9645. }
  9646.  
  9647. /* --- Not needed since classes can't have more than 1 default model for now ---
  9648. // We have less custom models than what this class has by default,
  9649. // Get rid of those extra entries...
  9650. if (nummodels_custom < nummodels_default)
  9651. {
  9652. for (k = nummodels_custom; k < nummodels_default; k++)
  9653. {
  9654. ArrayDeleteItem(g_zclass_playermodel, ArrayGetCell(g_zclass_modelsstart, g_zclass_i) + nummodels_custom)
  9655. }
  9656.  
  9657. // Fix models end index for this class
  9658. ArraySetCell(g_zclass_modelsend, g_zclass_i, ArrayGetCell(g_zclass_modelsend, g_zclass_i) - (nummodels_default - nummodels_custom))
  9659. }
  9660. */
  9661. }
  9662.  
  9663. // Replace clawmodel
  9664. ArrayGetString(g_zclass2_clawmodel, i, buffer, charsmax(buffer))
  9665. ArraySetString(g_zclass_clawmodel, g_zclass_i, buffer)
  9666.  
  9667. // Precache clawmodel
  9668. formatex(prec_mdl, charsmax(prec_mdl), "models/zombie_plague/%s", buffer)
  9669. engfunc(EngFunc_PrecacheModel, prec_mdl)
  9670.  
  9671. // Replace health
  9672. buffer[0] = ArrayGetCell(g_zclass2_hp, i)
  9673. ArraySetCell(g_zclass_hp, g_zclass_i, buffer[0])
  9674.  
  9675. // Replace speed
  9676. buffer[0] = ArrayGetCell(g_zclass2_spd, i)
  9677. ArraySetCell(g_zclass_spd, g_zclass_i, buffer[0])
  9678.  
  9679. // Replace gravity
  9680. buffer2 = Float:ArrayGetCell(g_zclass2_grav, i)
  9681. ArraySetCell(g_zclass_grav, g_zclass_i, buffer2)
  9682.  
  9683. // Replace knockback
  9684. buffer2 = Float:ArrayGetCell(g_zclass2_kb, i)
  9685. ArraySetCell(g_zclass_kb, g_zclass_i, buffer2)
  9686. }
  9687.  
  9688. // If class was not overriden with customization data
  9689. if (ArrayGetCell(g_zclass_new, g_zclass_i))
  9690. {
  9691. // If not using same models for all classes
  9692. if (!g_same_models_for_all)
  9693. {
  9694. // Precache default class model and replace modelindex with the real one
  9695. formatex(prec_mdl, charsmax(prec_mdl), "models/player/%s/%s.mdl", model, model)
  9696. ArraySetCell(g_zclass_modelindex, ArrayGetCell(g_zclass_modelsstart, g_zclass_i), engfunc(EngFunc_PrecacheModel, prec_mdl))
  9697. if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, prec_mdl)
  9698. if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, prec_mdl)
  9699. }
  9700.  
  9701. // Precache default clawmodel
  9702. formatex(prec_mdl, charsmax(prec_mdl), "models/zombie_plague/%s", clawmodel)
  9703. engfunc(EngFunc_PrecacheModel, prec_mdl)
  9704. }
  9705.  
  9706. // Increase registered classes counter
  9707. g_zclass_i++
  9708.  
  9709. // Return id under which we registered the class
  9710. return g_zclass_i-1;
  9711. }
  9712.  
  9713. // Native: zp_get_extra_item_id
  9714. public native_get_extra_item_id(const name[])
  9715. {
  9716. // ZP disabled
  9717. if (!g_pluginenabled)
  9718. return -1;
  9719.  
  9720. // Strings passed byref
  9721. param_convert(1)
  9722.  
  9723. // Loop through every item
  9724. static i, item_name[32]
  9725. for (i = 0; i < g_extraitem_i; i++)
  9726. {
  9727. ArrayGetString(g_extraitem_name, i, item_name, charsmax(item_name))
  9728.  
  9729. // Check if this is the item to retrieve
  9730. if (equali(name, item_name))
  9731. return i;
  9732. }
  9733.  
  9734. return -1;
  9735. }
  9736.  
  9737. // Native: zp_get_zombie_class_id
  9738. public native_get_zombie_class_id(const name[])
  9739. {
  9740. // ZP disabled
  9741. if (!g_pluginenabled)
  9742. return -1;
  9743.  
  9744. // Strings passed byref
  9745. param_convert(1)
  9746.  
  9747. // Loop through every class
  9748. static i, class_name[32]
  9749. for (i = 0; i < g_zclass_i; i++)
  9750. {
  9751. ArrayGetString(g_zclass_name, i, class_name, charsmax(class_name))
  9752.  
  9753. // Check if this is the class to retrieve
  9754. if (equali(name, class_name))
  9755. return i;
  9756. }
  9757.  
  9758. return -1;
  9759. }
  9760.  
  9761. /*================================================================================
  9762. [Custom Messages]
  9763. =================================================================================*/
  9764.  
  9765. // Custom Night Vision
  9766. public set_user_nvision(taskid)
  9767. {
  9768. // Get player's origin
  9769. static origin[3]
  9770. get_user_origin(ID_NVISION, origin)
  9771.  
  9772. // Nightvision message
  9773. message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, _, ID_NVISION)
  9774. write_byte(TE_DLIGHT) // TE id
  9775. write_coord(origin[0]) // x
  9776. write_coord(origin[1]) // y
  9777. write_coord(origin[2]) // z
  9778. write_byte(get_pcvar_num(cvar_nvgsize)) // radius
  9779.  
  9780. // Nemesis / Madness / Spectator in nemesis round
  9781. if (g_nemesis[ID_NVISION] || (g_zombie[ID_NVISION] && g_nodamage[ID_NVISION]) || (!g_isalive[ID_NVISION] && g_nemround))
  9782. {
  9783. write_byte(get_pcvar_num(cvar_nemnvgcolor[0])) // r
  9784. write_byte(get_pcvar_num(cvar_nemnvgcolor[1])) // g
  9785. write_byte(get_pcvar_num(cvar_nemnvgcolor[2])) // b
  9786. }
  9787. // Human / Spectator in normal round
  9788. else if (!g_zombie[ID_NVISION] || !g_isalive[ID_NVISION])
  9789. {
  9790. write_byte(get_pcvar_num(cvar_humnvgcolor[0])) // r
  9791. write_byte(get_pcvar_num(cvar_humnvgcolor[1])) // g
  9792. write_byte(get_pcvar_num(cvar_humnvgcolor[2])) // b
  9793. }
  9794. // Zombie
  9795. else
  9796. {
  9797. write_byte(get_pcvar_num(cvar_nvgcolor[0])) // r
  9798. write_byte(get_pcvar_num(cvar_nvgcolor[1])) // g
  9799. write_byte(get_pcvar_num(cvar_nvgcolor[2])) // b
  9800. }
  9801.  
  9802. write_byte(2) // life
  9803. write_byte(0) // decay rate
  9804. message_end()
  9805. }
  9806.  
  9807. // Game Nightvision
  9808. set_user_gnvision(id, toggle)
  9809. {
  9810. // Toggle NVG message
  9811. message_begin(MSG_ONE, g_msgNVGToggle, _, id)
  9812. write_byte(toggle) // toggle
  9813. message_end()
  9814. }
  9815.  
  9816. // Custom Flashlight
  9817. public set_user_flashlight(taskid)
  9818. {
  9819. // Get player and aiming origins
  9820. static Float:originF[3], Float:destoriginF[3]
  9821. pev(ID_FLASH, pev_origin, originF)
  9822. fm_get_aim_origin(ID_FLASH, destoriginF)
  9823.  
  9824. // Max distance check
  9825. if (get_distance_f(originF, destoriginF) > get_pcvar_float(cvar_flashdist))
  9826. return;
  9827.  
  9828. // Send to all players?
  9829. if (get_pcvar_num(cvar_flashshowall))
  9830. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, destoriginF, 0)
  9831. else
  9832. message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, _, ID_FLASH)
  9833.  
  9834. // Flashlight
  9835. write_byte(TE_DLIGHT) // TE id
  9836. engfunc(EngFunc_WriteCoord, destoriginF[0]) // x
  9837. engfunc(EngFunc_WriteCoord, destoriginF[1]) // y
  9838. engfunc(EngFunc_WriteCoord, destoriginF[2]) // z
  9839. write_byte(get_pcvar_num(cvar_flashsize)) // radius
  9840. write_byte(get_pcvar_num(cvar_flashcolor[0])) // r
  9841. write_byte(get_pcvar_num(cvar_flashcolor[1])) // g
  9842. write_byte(get_pcvar_num(cvar_flashcolor[2])) // b
  9843. write_byte(3) // life
  9844. write_byte(0) // decay rate
  9845. message_end()
  9846. }
  9847.  
  9848. // Infection special effects
  9849. infection_effects(id)
  9850. {
  9851. // Screen fade? (unless frozen)
  9852. if (!g_frozen[id] && get_pcvar_num(cvar_infectionscreenfade))
  9853. {
  9854. message_begin(MSG_ONE_UNRELIABLE, g_msgScreenFade, _, id)
  9855. write_short(UNIT_SECOND) // duration
  9856. write_short(0) // hold time
  9857. write_short(FFADE_IN) // fade type
  9858. if (g_nemesis[id])
  9859. {
  9860. write_byte(get_pcvar_num(cvar_nemnvgcolor[0])) // r
  9861. write_byte(get_pcvar_num(cvar_nemnvgcolor[1])) // g
  9862. write_byte(get_pcvar_num(cvar_nemnvgcolor[2])) // b
  9863. }
  9864. else
  9865. {
  9866. write_byte(get_pcvar_num(cvar_nvgcolor[0])) // r
  9867. write_byte(get_pcvar_num(cvar_nvgcolor[1])) // g
  9868. write_byte(get_pcvar_num(cvar_nvgcolor[2])) // b
  9869. }
  9870. write_byte (255) // alpha
  9871. message_end()
  9872. }
  9873.  
  9874. // Screen shake?
  9875. if (get_pcvar_num(cvar_infectionscreenshake))
  9876. {
  9877. message_begin(MSG_ONE_UNRELIABLE, g_msgScreenShake, _, id)
  9878. write_short(UNIT_SECOND*4) // amplitude
  9879. write_short(UNIT_SECOND*2) // duration
  9880. write_short(UNIT_SECOND*10) // frequency
  9881. message_end()
  9882. }
  9883.  
  9884. // Infection icon?
  9885. if (get_pcvar_num(cvar_hudicons))
  9886. {
  9887. message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, _, id)
  9888. write_byte(0) // damage save
  9889. write_byte(0) // damage take
  9890. write_long(DMG_NERVEGAS) // damage type - DMG_RADIATION
  9891. write_coord(0) // x
  9892. write_coord(0) // y
  9893. write_coord(0) // z
  9894. message_end()
  9895. }
  9896.  
  9897. // Get player's origin
  9898. static origin[3]
  9899. get_user_origin(id, origin)
  9900.  
  9901. // Tracers?
  9902. if (get_pcvar_num(cvar_infectiontracers))
  9903. {
  9904. message_begin(MSG_PVS, SVC_TEMPENTITY, origin)
  9905. write_byte(TE_IMPLOSION) // TE id
  9906. write_coord(origin[0]) // x
  9907. write_coord(origin[1]) // y
  9908. write_coord(origin[2]) // z
  9909. write_byte(128) // radius
  9910. write_byte(20) // count
  9911. write_byte(3) // duration
  9912. message_end()
  9913. }
  9914.  
  9915. // Particle burst?
  9916. if (get_pcvar_num(cvar_infectionparticles))
  9917. {
  9918. message_begin(MSG_PVS, SVC_TEMPENTITY, origin)
  9919. write_byte(TE_PARTICLEBURST) // TE id
  9920. write_coord(origin[0]) // x
  9921. write_coord(origin[1]) // y
  9922. write_coord(origin[2]) // z
  9923. write_short(50) // radius
  9924. write_byte(70) // color
  9925. write_byte(3) // duration (will be randomized a bit)
  9926. message_end()
  9927. }
  9928.  
  9929. // Light sparkle?
  9930. if (get_pcvar_num(cvar_infectionsparkle))
  9931. {
  9932. message_begin(MSG_PVS, SVC_TEMPENTITY, origin)
  9933. write_byte(TE_DLIGHT) // TE id
  9934. write_coord(origin[0]) // x
  9935. write_coord(origin[1]) // y
  9936. write_coord(origin[2]) // z
  9937. write_byte(20) // radius
  9938. write_byte(get_pcvar_num(cvar_nvgcolor[0])) // r
  9939. write_byte(get_pcvar_num(cvar_nvgcolor[1])) // g
  9940. write_byte(get_pcvar_num(cvar_nvgcolor[2])) // b
  9941. write_byte(2) // life
  9942. write_byte(0) // decay rate
  9943. message_end()
  9944. }
  9945. }
  9946.  
  9947. // Nemesis/madness aura task
  9948. public zombie_aura(taskid)
  9949. {
  9950. // Not nemesis, not in zombie madness
  9951. if (!g_nemesis[ID_AURA] && !g_nodamage[ID_AURA])
  9952. {
  9953. // Task not needed anymore
  9954. remove_task(taskid);
  9955. return;
  9956. }
  9957.  
  9958. // Get player's origin
  9959. static origin[3]
  9960. get_user_origin(ID_AURA, origin)
  9961.  
  9962. // Colored Aura
  9963. message_begin(MSG_PVS, SVC_TEMPENTITY, origin)
  9964. write_byte(TE_DLIGHT) // TE id
  9965. write_coord(origin[0]) // x
  9966. write_coord(origin[1]) // y
  9967. write_coord(origin[2]) // z
  9968. write_byte(20) // radius
  9969. write_byte(get_pcvar_num(cvar_nemnvgcolor[0])) // r
  9970. write_byte(get_pcvar_num(cvar_nemnvgcolor[1])) // g
  9971. write_byte(get_pcvar_num(cvar_nemnvgcolor[2])) // b
  9972. write_byte(2) // life
  9973. write_byte(0) // decay rate
  9974. message_end()
  9975. }
  9976.  
  9977. // Make zombies leave footsteps and bloodstains on the floor
  9978. public make_blood(taskid)
  9979. {
  9980. // Only bleed when moving on ground
  9981. if (!(pev(ID_BLOOD, pev_flags) & FL_ONGROUND) || fm_get_speed(ID_BLOOD) < 80)
  9982. return;
  9983.  
  9984. // Get user origin
  9985. static Float:originF[3]
  9986. pev(ID_BLOOD, pev_origin, originF)
  9987.  
  9988. // If ducking set a little lower
  9989. if (pev(ID_BLOOD, pev_bInDuck))
  9990. originF[2] -= 18.0
  9991. else
  9992. originF[2] -= 36.0
  9993.  
  9994. // Send the decal message
  9995. engfunc(EngFunc_MessageBegin, MSG_PAS, SVC_TEMPENTITY, originF, 0)
  9996. write_byte(TE_WORLDDECAL) // TE id
  9997. engfunc(EngFunc_WriteCoord, originF[0]) // x
  9998. engfunc(EngFunc_WriteCoord, originF[1]) // y
  9999. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10000. write_byte(ArrayGetCell(zombie_decals, random_num(0, ArraySize(zombie_decals) - 1)) + (g_czero * 12)) // random decal number (offsets +12 for CZ)
  10001. message_end()
  10002. }
  10003.  
  10004. // Flare Lighting Effects
  10005. flare_lighting(entity, duration)
  10006. {
  10007. // Get origin and color
  10008. static Float:originF[3], color[3]
  10009. pev(entity, pev_origin, originF)
  10010. pev(entity, PEV_FLARE_COLOR, color)
  10011.  
  10012. // Lighting
  10013. engfunc(EngFunc_MessageBegin, MSG_PAS, SVC_TEMPENTITY, originF, 0)
  10014. write_byte(TE_DLIGHT) // TE id
  10015. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10016. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10017. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10018. write_byte(get_pcvar_num(cvar_flaresize)) // radius
  10019. write_byte(color[0]) // r
  10020. write_byte(color[1]) // g
  10021. write_byte(color[2]) // b
  10022. write_byte(51) //life
  10023. write_byte((duration < 2) ? 3 : 0) //decay rate
  10024. message_end()
  10025.  
  10026. // Sparks
  10027. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10028. write_byte(TE_SPARKS) // TE id
  10029. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10030. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10031. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10032. message_end()
  10033. }
  10034.  
  10035. // Burning Flames
  10036. public burning_flame(taskid)
  10037. {
  10038. // Get player origin and flags
  10039. static origin[3], flags
  10040. get_user_origin(ID_BURN, origin)
  10041. flags = pev(ID_BURN, pev_flags)
  10042.  
  10043. // Madness mode - in water - burning stopped
  10044. if (g_nodamage[ID_BURN] || (flags & FL_INWATER) || g_burning_duration[ID_BURN] < 1)
  10045. {
  10046. // Smoke sprite
  10047. message_begin(MSG_PVS, SVC_TEMPENTITY, origin)
  10048. write_byte(TE_SMOKE) // TE id
  10049. write_coord(origin[0]) // x
  10050. write_coord(origin[1]) // y
  10051. write_coord(origin[2]-50) // z
  10052. write_short(g_smokeSpr) // sprite
  10053. write_byte(random_num(15, 20)) // scale
  10054. write_byte(random_num(10, 20)) // framerate
  10055. message_end()
  10056.  
  10057. // Task not needed anymore
  10058. remove_task(taskid);
  10059. return;
  10060. }
  10061.  
  10062. // Randomly play burning zombie scream sounds (not for nemesis)
  10063. if (!g_nemesis[ID_BURN] && !random_num(0, 20))
  10064. {
  10065. static sound[64]
  10066. ArrayGetString(grenade_fire_player, random_num(0, ArraySize(grenade_fire_player) - 1), sound, charsmax(sound))
  10067. emit_sound(ID_BURN, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  10068. }
  10069.  
  10070. // Fire slow down, unless nemesis
  10071. if (!g_nemesis[ID_BURN] && (flags & FL_ONGROUND) && get_pcvar_float(cvar_fireslowdown) > 0.0)
  10072. {
  10073. static Float:velocity[3]
  10074. pev(ID_BURN, pev_velocity, velocity)
  10075. xs_vec_mul_scalar(velocity, get_pcvar_float(cvar_fireslowdown), velocity)
  10076. set_pev(ID_BURN, pev_velocity, velocity)
  10077. }
  10078.  
  10079. // Get player's health
  10080. static health
  10081. health = pev(ID_BURN, pev_health)
  10082.  
  10083. // Take damage from the fire
  10084. if (health - floatround(get_pcvar_float(cvar_firedamage), floatround_ceil) > 0)
  10085. fm_set_user_health(ID_BURN, health - floatround(get_pcvar_float(cvar_firedamage), floatround_ceil))
  10086.  
  10087. // Flame sprite
  10088. message_begin(MSG_PVS, SVC_TEMPENTITY, origin)
  10089. write_byte(TE_SPRITE) // TE id
  10090. write_coord(origin[0]+random_num(-5, 5)) // x
  10091. write_coord(origin[1]+random_num(-5, 5)) // y
  10092. write_coord(origin[2]+random_num(-10, 10)) // z
  10093. write_short(g_flameSpr) // sprite
  10094. write_byte(random_num(5, 10)) // scale
  10095. write_byte(200) // brightness
  10096. message_end()
  10097.  
  10098. // Decrease burning duration counter
  10099. g_burning_duration[ID_BURN]--
  10100. }
  10101.  
  10102. // Infection Bomb: Green Blast
  10103. create_blast(const Float:originF[3])
  10104. {
  10105. // Smallest ring
  10106. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10107. write_byte(TE_BEAMCYLINDER) // TE id
  10108. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10109. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10110. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10111. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10112. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10113. engfunc(EngFunc_WriteCoord, originF[2]+385.0) // z axis
  10114. write_short(g_exploSpr) // sprite
  10115. write_byte(0) // startframe
  10116. write_byte(0) // framerate
  10117. write_byte(4) // life
  10118. write_byte(60) // width
  10119. write_byte(0) // noise
  10120. write_byte(0) // red
  10121. write_byte(200) // green
  10122. write_byte(0) // blue
  10123. write_byte(200) // brightness
  10124. write_byte(0) // speed
  10125. message_end()
  10126.  
  10127. // Medium ring
  10128. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10129. write_byte(TE_BEAMCYLINDER) // TE id
  10130. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10131. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10132. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10133. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10134. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10135. engfunc(EngFunc_WriteCoord, originF[2]+470.0) // z axis
  10136. write_short(g_exploSpr) // sprite
  10137. write_byte(0) // startframe
  10138. write_byte(0) // framerate
  10139. write_byte(4) // life
  10140. write_byte(60) // width
  10141. write_byte(0) // noise
  10142. write_byte(0) // red
  10143. write_byte(200) // green
  10144. write_byte(0) // blue
  10145. write_byte(200) // brightness
  10146. write_byte(0) // speed
  10147. message_end()
  10148.  
  10149. // Largest ring
  10150. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10151. write_byte(TE_BEAMCYLINDER) // TE id
  10152. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10153. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10154. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10155. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10156. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10157. engfunc(EngFunc_WriteCoord, originF[2]+555.0) // z axis
  10158. write_short(g_exploSpr) // sprite
  10159. write_byte(0) // startframe
  10160. write_byte(0) // framerate
  10161. write_byte(4) // life
  10162. write_byte(60) // width
  10163. write_byte(0) // noise
  10164. write_byte(0) // red
  10165. write_byte(200) // green
  10166. write_byte(0) // blue
  10167. write_byte(200) // brightness
  10168. write_byte(0) // speed
  10169. message_end()
  10170. }
  10171.  
  10172. // Fire Grenade: Fire Blast
  10173. create_blast2(const Float:originF[3])
  10174. {
  10175. // Smallest ring
  10176. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10177. write_byte(TE_BEAMCYLINDER) // TE id
  10178. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10179. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10180. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10181. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10182. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10183. engfunc(EngFunc_WriteCoord, originF[2]+385.0) // z axis
  10184. write_short(g_exploSpr) // sprite
  10185. write_byte(0) // startframe
  10186. write_byte(0) // framerate
  10187. write_byte(4) // life
  10188. write_byte(60) // width
  10189. write_byte(0) // noise
  10190. write_byte(200) // red
  10191. write_byte(100) // green
  10192. write_byte(0) // blue
  10193. write_byte(200) // brightness
  10194. write_byte(0) // speed
  10195. message_end()
  10196.  
  10197. // Medium ring
  10198. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10199. write_byte(TE_BEAMCYLINDER) // TE id
  10200. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10201. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10202. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10203. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10204. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10205. engfunc(EngFunc_WriteCoord, originF[2]+470.0) // z axis
  10206. write_short(g_exploSpr) // sprite
  10207. write_byte(0) // startframe
  10208. write_byte(0) // framerate
  10209. write_byte(4) // life
  10210. write_byte(60) // width
  10211. write_byte(0) // noise
  10212. write_byte(200) // red
  10213. write_byte(50) // green
  10214. write_byte(0) // blue
  10215. write_byte(200) // brightness
  10216. write_byte(0) // speed
  10217. message_end()
  10218.  
  10219. // Largest ring
  10220. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10221. write_byte(TE_BEAMCYLINDER) // TE id
  10222. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10223. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10224. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10225. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10226. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10227. engfunc(EngFunc_WriteCoord, originF[2]+555.0) // z axis
  10228. write_short(g_exploSpr) // sprite
  10229. write_byte(0) // startframe
  10230. write_byte(0) // framerate
  10231. write_byte(4) // life
  10232. write_byte(60) // width
  10233. write_byte(0) // noise
  10234. write_byte(200) // red
  10235. write_byte(0) // green
  10236. write_byte(0) // blue
  10237. write_byte(200) // brightness
  10238. write_byte(0) // speed
  10239. message_end()
  10240. }
  10241.  
  10242. // Frost Grenade: Freeze Blast
  10243. create_blast3(const Float:originF[3])
  10244. {
  10245. // Smallest ring
  10246. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10247. write_byte(TE_BEAMCYLINDER) // TE id
  10248. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10249. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10250. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10251. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10252. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10253. engfunc(EngFunc_WriteCoord, originF[2]+385.0) // z axis
  10254. write_short(g_exploSpr) // sprite
  10255. write_byte(0) // startframe
  10256. write_byte(0) // framerate
  10257. write_byte(4) // life
  10258. write_byte(60) // width
  10259. write_byte(0) // noise
  10260. write_byte(0) // red
  10261. write_byte(100) // green
  10262. write_byte(200) // blue
  10263. write_byte(200) // brightness
  10264. write_byte(0) // speed
  10265. message_end()
  10266.  
  10267. // Medium ring
  10268. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10269. write_byte(TE_BEAMCYLINDER) // TE id
  10270. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10271. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10272. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10273. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10274. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10275. engfunc(EngFunc_WriteCoord, originF[2]+470.0) // z axis
  10276. write_short(g_exploSpr) // sprite
  10277. write_byte(0) // startframe
  10278. write_byte(0) // framerate
  10279. write_byte(4) // life
  10280. write_byte(60) // width
  10281. write_byte(0) // noise
  10282. write_byte(0) // red
  10283. write_byte(100) // green
  10284. write_byte(200) // blue
  10285. write_byte(200) // brightness
  10286. write_byte(0) // speed
  10287. message_end()
  10288.  
  10289. // Largest ring
  10290. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10291. write_byte(TE_BEAMCYLINDER) // TE id
  10292. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10293. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10294. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10295. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10296. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10297. engfunc(EngFunc_WriteCoord, originF[2]+555.0) // z axis
  10298. write_short(g_exploSpr) // sprite
  10299. write_byte(0) // startframe
  10300. write_byte(0) // framerate
  10301. write_byte(4) // life
  10302. write_byte(60) // width
  10303. write_byte(0) // noise
  10304. write_byte(0) // red
  10305. write_byte(100) // green
  10306. write_byte(200) // blue
  10307. write_byte(200) // brightness
  10308. write_byte(0) // speed
  10309. message_end()
  10310. }
  10311.  
  10312. // Fix Dead Attrib on scoreboard
  10313. FixDeadAttrib(id)
  10314. {
  10315. message_begin(MSG_BROADCAST, g_msgScoreAttrib)
  10316. write_byte(id) // id
  10317. write_byte(0) // attrib
  10318. message_end()
  10319. }
  10320.  
  10321. // Send Death Message for infections
  10322. SendDeathMsg(attacker, victim)
  10323. {
  10324. message_begin(MSG_BROADCAST, g_msgDeathMsg)
  10325. write_byte(attacker) // killer
  10326. write_byte(victim) // victim
  10327. write_byte(1) // headshot flag
  10328. write_string("infection") // killer's weapon
  10329. message_end()
  10330. }
  10331.  
  10332. // Update Player Frags and Deaths
  10333. UpdateFrags(attacker, victim, frags, deaths, scoreboard)
  10334. {
  10335. // Set attacker frags
  10336. set_pev(attacker, pev_frags, float(pev(attacker, pev_frags) + frags))
  10337.  
  10338. // Set victim deaths
  10339. fm_cs_set_user_deaths(victim, cs_get_user_deaths(victim) + deaths)
  10340.  
  10341. // Update scoreboard with attacker and victim info
  10342. if (scoreboard)
  10343. {
  10344. message_begin(MSG_BROADCAST, g_msgScoreInfo)
  10345. write_byte(attacker) // id
  10346. write_short(pev(attacker, pev_frags)) // frags
  10347. write_short(cs_get_user_deaths(attacker)) // deaths
  10348. write_short(0) // class?
  10349. write_short(fm_cs_get_user_team(attacker)) // team
  10350. message_end()
  10351.  
  10352. message_begin(MSG_BROADCAST, g_msgScoreInfo)
  10353. write_byte(victim) // id
  10354. write_short(pev(victim, pev_frags)) // frags
  10355. write_short(cs_get_user_deaths(victim)) // deaths
  10356. write_short(0) // class?
  10357. write_short(fm_cs_get_user_team(victim)) // team
  10358. message_end()
  10359. }
  10360. }
  10361.  
  10362. // Remove Player Frags (when Nemesis/Survivor ignore_frags cvar is enabled)
  10363. RemoveFrags(attacker, victim)
  10364. {
  10365. // Remove attacker frags
  10366. set_pev(attacker, pev_frags, float(pev(attacker, pev_frags) - 1))
  10367.  
  10368. // Remove victim deaths
  10369. fm_cs_set_user_deaths(victim, cs_get_user_deaths(victim) - 1)
  10370. }
  10371.  
  10372. // Plays a sound on clients
  10373. PlaySound(const sound[])
  10374. {
  10375. client_cmd(0, "spk ^"%s^"", sound)
  10376. }
  10377.  
  10378. // Prints a colored message to target (use 0 for everyone), supports ML formatting.
  10379. // Note: I still need to make something like gungame's LANG_PLAYER_C to avoid unintended
  10380. // argument replacement when a function passes -1 (it will be considered a LANG_PLAYER)
  10381. zp_colored_print(target, const message[], any:...)
  10382. {
  10383. static buffer[512], i, argscount
  10384. argscount = numargs()
  10385.  
  10386. // Send to everyone
  10387. if (!target)
  10388. {
  10389. static player
  10390. for (player = 1; player <= g_maxplayers; player++)
  10391. {
  10392. // Not connected
  10393. if (!g_isconnected[player])
  10394. continue;
  10395.  
  10396. // Remember changed arguments
  10397. static changed[5], changedcount // [5] = max LANG_PLAYER occurencies
  10398. changedcount = 0
  10399.  
  10400. // Replace LANG_PLAYER with player id
  10401. for (i = 2; i < argscount; i++)
  10402. {
  10403. if (getarg(i) == LANG_PLAYER)
  10404. {
  10405. setarg(i, 0, player)
  10406. changed[changedcount] = i
  10407. changedcount++
  10408. }
  10409. }
  10410.  
  10411. // Format message for player
  10412. vformat(buffer, charsmax(buffer), message, 3)
  10413.  
  10414. // Send it
  10415. message_begin(MSG_ONE_UNRELIABLE, g_msgSayText, _, player)
  10416. write_byte(player)
  10417. write_string(buffer)
  10418. message_end()
  10419.  
  10420. // Replace back player id's with LANG_PLAYER
  10421. for (i = 0; i < changedcount; i++)
  10422. setarg(changed[i], 0, LANG_PLAYER)
  10423. }
  10424. }
  10425. // Send to specific target
  10426. else
  10427. {
  10428. /*
  10429. // Not needed since you should set the ML argument
  10430. // to the player's id for a targeted print message
  10431.  
  10432. // Replace LANG_PLAYER with player id
  10433. for (i = 2; i < argscount; i++)
  10434. {
  10435. if (getarg(i) == LANG_PLAYER)
  10436. setarg(i, 0, target)
  10437. }
  10438. */
  10439.  
  10440. // Format message for player
  10441. vformat(buffer, charsmax(buffer), message, 3)
  10442.  
  10443. // Send it
  10444. message_begin(MSG_ONE, g_msgSayText, _, target)
  10445. write_byte(target)
  10446. write_string(buffer)
  10447. message_end()
  10448. }
  10449. }
  10450.  
  10451. /*================================================================================
  10452. [Stocks]
  10453. =================================================================================*/
  10454.  
  10455. // Set an entity's key value (from fakemeta_util)
  10456. stock fm_set_kvd(entity, const key[], const value[], const classname[])
  10457. {
  10458. set_kvd(0, KV_ClassName, classname)
  10459. set_kvd(0, KV_KeyName, key)
  10460. set_kvd(0, KV_Value, value)
  10461. set_kvd(0, KV_fHandled, 0)
  10462.  
  10463. dllfunc(DLLFunc_KeyValue, entity, 0)
  10464. }
  10465.  
  10466. // Set entity's rendering type (from fakemeta_util)
  10467. stock fm_set_rendering(entity, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16)
  10468. {
  10469. static Float:color[3]
  10470. color[0] = float(r)
  10471. color[1] = float(g)
  10472. color[2] = float(b)
  10473.  
  10474. set_pev(entity, pev_renderfx, fx)
  10475. set_pev(entity, pev_rendercolor, color)
  10476. set_pev(entity, pev_rendermode, render)
  10477. set_pev(entity, pev_renderamt, float(amount))
  10478. }
  10479.  
  10480. // Get entity's speed (from fakemeta_util)
  10481. stock fm_get_speed(entity)
  10482. {
  10483. static Float:velocity[3]
  10484. pev(entity, pev_velocity, velocity)
  10485.  
  10486. return floatround(vector_length(velocity));
  10487. }
  10488.  
  10489. // Get entity's aim origins (from fakemeta_util)
  10490. stock fm_get_aim_origin(id, Float:origin[3])
  10491. {
  10492. static Float:origin1F[3], Float:origin2F[3]
  10493. pev(id, pev_origin, origin1F)
  10494. pev(id, pev_view_ofs, origin2F)
  10495. xs_vec_add(origin1F, origin2F, origin1F)
  10496.  
  10497. pev(id, pev_v_angle, origin2F);
  10498. engfunc(EngFunc_MakeVectors, origin2F)
  10499. global_get(glb_v_forward, origin2F)
  10500. xs_vec_mul_scalar(origin2F, 9999.0, origin2F)
  10501. xs_vec_add(origin1F, origin2F, origin2F)
  10502.  
  10503. engfunc(EngFunc_TraceLine, origin1F, origin2F, 0, id, 0)
  10504. get_tr2(0, TR_vecEndPos, origin)
  10505. }
  10506.  
  10507. // Find entity by its owner (from fakemeta_util)
  10508. stock fm_find_ent_by_owner(entity, const classname[], owner)
  10509. {
  10510. while ((entity = engfunc(EngFunc_FindEntityByString, entity, "classname", classname)) && pev(entity, pev_owner) != owner) { /* keep looping */ }
  10511. return entity;
  10512. }
  10513.  
  10514. // Set player's health (from fakemeta_util)
  10515. stock fm_set_user_health(id, health)
  10516. {
  10517. (health > 0) ? set_pev(id, pev_health, float(health)) : dllfunc(DLLFunc_ClientKill, id);
  10518. }
  10519.  
  10520. // Give an item to a player (from fakemeta_util)
  10521. stock fm_give_item(id, const item[])
  10522. {
  10523. static ent
  10524. ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, item))
  10525. if (!pev_valid(ent)) return;
  10526.  
  10527. static Float:originF[3]
  10528. pev(id, pev_origin, originF)
  10529. set_pev(ent, pev_origin, originF)
  10530. set_pev(ent, pev_spawnflags, pev(ent, pev_spawnflags) | SF_NORESPAWN)
  10531. dllfunc(DLLFunc_Spawn, ent)
  10532.  
  10533. static save
  10534. save = pev(ent, pev_solid)
  10535. dllfunc(DLLFunc_Touch, ent, id)
  10536. if (pev(ent, pev_solid) != save)
  10537. return;
  10538.  
  10539. engfunc(EngFunc_RemoveEntity, ent)
  10540. }
  10541.  
  10542. // Strip user weapons (from fakemeta_util)
  10543. stock fm_strip_user_weapons(id)
  10544. {
  10545. static ent
  10546. ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "player_weaponstrip"))
  10547. if (!pev_valid(ent)) return;
  10548.  
  10549. dllfunc(DLLFunc_Spawn, ent)
  10550. dllfunc(DLLFunc_Use, ent, id)
  10551. engfunc(EngFunc_RemoveEntity, ent)
  10552. }
  10553.  
  10554. // Collect random spawn points
  10555. stock load_spawns()
  10556. {
  10557. // Check for CSDM spawns of the current map
  10558. new cfgdir[32], mapname[32], filepath[100], linedata[64]
  10559. get_configsdir(cfgdir, charsmax(cfgdir))
  10560. get_mapname(mapname, charsmax(mapname))
  10561. formatex(filepath, charsmax(filepath), "%s/csdm/%s.spawns.cfg", cfgdir, mapname)
  10562.  
  10563. // Load CSDM spawns if present
  10564. if (file_exists(filepath))
  10565. {
  10566. new csdmdata[10][6], file = fopen(filepath,"rt")
  10567.  
  10568. while (file && !feof(file))
  10569. {
  10570. fgets(file, linedata, charsmax(linedata))
  10571.  
  10572. // invalid spawn
  10573. if(!linedata[0] || str_count(linedata,' ') < 2) continue;
  10574.  
  10575. // get spawn point data
  10576. 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)
  10577.  
  10578. // origin
  10579. g_spawns[g_spawnCount][0] = floatstr(csdmdata[0])
  10580. g_spawns[g_spawnCount][1] = floatstr(csdmdata[1])
  10581. g_spawns[g_spawnCount][2] = floatstr(csdmdata[2])
  10582.  
  10583. // increase spawn count
  10584. g_spawnCount++
  10585. if (g_spawnCount >= sizeof g_spawns) break;
  10586. }
  10587. if (file) fclose(file)
  10588. }
  10589. else
  10590. {
  10591. // Collect regular spawns
  10592. collect_spawns_ent("info_player_start")
  10593. collect_spawns_ent("info_player_deathmatch")
  10594. }
  10595.  
  10596. // Collect regular spawns for non-random spawning unstuck
  10597. collect_spawns_ent2("info_player_start")
  10598. collect_spawns_ent2("info_player_deathmatch")
  10599. }
  10600.  
  10601. // Collect spawn points from entity origins
  10602. stock collect_spawns_ent(const classname[])
  10603. {
  10604. new ent = -1
  10605. while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", classname)) != 0)
  10606. {
  10607. // get origin
  10608. new Float:originF[3]
  10609. pev(ent, pev_origin, originF)
  10610. g_spawns[g_spawnCount][0] = originF[0]
  10611. g_spawns[g_spawnCount][1] = originF[1]
  10612. g_spawns[g_spawnCount][2] = originF[2]
  10613.  
  10614. // increase spawn count
  10615. g_spawnCount++
  10616. if (g_spawnCount >= sizeof g_spawns) break;
  10617. }
  10618. }
  10619.  
  10620. // Collect spawn points from entity origins
  10621. stock collect_spawns_ent2(const classname[])
  10622. {
  10623. new ent = -1
  10624. while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", classname)) != 0)
  10625. {
  10626. // get origin
  10627. new Float:originF[3]
  10628. pev(ent, pev_origin, originF)
  10629. g_spawns2[g_spawnCount2][0] = originF[0]
  10630. g_spawns2[g_spawnCount2][1] = originF[1]
  10631. g_spawns2[g_spawnCount2][2] = originF[2]
  10632.  
  10633. // increase spawn count
  10634. g_spawnCount2++
  10635. if (g_spawnCount2 >= sizeof g_spawns2) break;
  10636. }
  10637. }
  10638.  
  10639. // Drop primary/secondary weapons
  10640. stock drop_weapons(id, dropwhat)
  10641. {
  10642. // Get user weapons
  10643. static weapons[32], num, i, weaponid
  10644. num = 0 // reset passed weapons count (bugfix)
  10645. get_user_weapons(id, weapons, num)
  10646.  
  10647. // Loop through them and drop primaries or secondaries
  10648. for (i = 0; i < num; i++)
  10649. {
  10650. // Prevent re-indexing the array
  10651. weaponid = weapons[i]
  10652.  
  10653. if ((dropwhat == 1 && ((1<<weaponid) & PRIMARY_WEAPONS_BIT_SUM)) || (dropwhat == 2 && ((1<<weaponid) & SECONDARY_WEAPONS_BIT_SUM)))
  10654. {
  10655. // Get weapon entity
  10656. static wname[32], weapon_ent
  10657. get_weaponname(weaponid, wname, charsmax(wname))
  10658. weapon_ent = fm_find_ent_by_owner(-1, wname, id)
  10659.  
  10660. // Hack: store weapon bpammo on PEV_ADDITIONAL_AMMO
  10661. set_pev(weapon_ent, PEV_ADDITIONAL_AMMO, cs_get_user_bpammo(id, weaponid))
  10662.  
  10663. // Player drops the weapon and looses his bpammo
  10664. engclient_cmd(id, "drop", wname)
  10665. cs_set_user_bpammo(id, weaponid, 0)
  10666. }
  10667. }
  10668. }
  10669.  
  10670. // Stock by (probably) Twilight Suzuka -counts number of chars in a string
  10671. stock str_count(const str[], searchchar)
  10672. {
  10673. new count, i, len = strlen(str)
  10674.  
  10675. for (i = 0; i <= len; i++)
  10676. {
  10677. if(str[i] == searchchar)
  10678. count++
  10679. }
  10680.  
  10681. return count;
  10682. }
  10683.  
  10684. // Checks if a space is vacant (credits to VEN)
  10685. stock is_hull_vacant(Float:origin[3], hull)
  10686. {
  10687. engfunc(EngFunc_TraceHull, origin, origin, 0, hull, 0, 0)
  10688.  
  10689. if (!get_tr2(0, TR_StartSolid) && !get_tr2(0, TR_AllSolid) && get_tr2(0, TR_InOpen))
  10690. return true;
  10691.  
  10692. return false;
  10693. }
  10694.  
  10695. // Check if a player is stuck (credits to VEN)
  10696. stock is_player_stuck(id)
  10697. {
  10698. static Float:originF[3]
  10699. pev(id, pev_origin, originF)
  10700.  
  10701. engfunc(EngFunc_TraceHull, originF, originF, 0, (pev(id, pev_flags) & FL_DUCKING) ? HULL_HEAD : HULL_HUMAN, id, 0)
  10702.  
  10703. if (get_tr2(0, TR_StartSolid) || get_tr2(0, TR_AllSolid) || !get_tr2(0, TR_InOpen))
  10704. return true;
  10705.  
  10706. return false;
  10707. }
  10708.  
  10709. // Simplified get_weaponid (CS only)
  10710. stock cs_weapon_name_to_id(const weapon[])
  10711. {
  10712. static i
  10713. for (i = 0; i < sizeof WEAPONENTNAMES; i++)
  10714. {
  10715. if (equal(weapon, WEAPONENTNAMES[i]))
  10716. return i;
  10717. }
  10718.  
  10719. return 0;
  10720. }
  10721.  
  10722. // Get User Current Weapon Entity
  10723. stock fm_cs_get_current_weapon_ent(id)
  10724. {
  10725. return get_pdata_cbase(id, OFFSET_ACTIVE_ITEM, OFFSET_LINUX);
  10726. }
  10727.  
  10728. // Get Weapon Entity's Owner
  10729. stock fm_cs_get_weapon_ent_owner(ent)
  10730. {
  10731. return get_pdata_cbase(ent, OFFSET_WEAPONOWNER, OFFSET_LINUX_WEAPONS);
  10732. }
  10733.  
  10734. // Set User Deaths
  10735. stock fm_cs_set_user_deaths(id, value)
  10736. {
  10737. set_pdata_int(id, OFFSET_CSDEATHS, value, OFFSET_LINUX)
  10738. }
  10739.  
  10740. // Get User Team
  10741. stock fm_cs_get_user_team(id)
  10742. {
  10743. return get_pdata_int(id, OFFSET_CSTEAMS, OFFSET_LINUX);
  10744. }
  10745.  
  10746. // Set a Player's Team
  10747. stock fm_cs_set_user_team(id, team)
  10748. {
  10749. set_pdata_int(id, OFFSET_CSTEAMS, team, OFFSET_LINUX)
  10750. }
  10751.  
  10752. // Set User Money
  10753. stock fm_cs_set_user_money(id, value)
  10754. {
  10755. set_pdata_int(id, OFFSET_CSMONEY, value, OFFSET_LINUX)
  10756. }
  10757.  
  10758. // Set User Flashlight Batteries
  10759. stock fm_cs_set_user_batteries(id, value)
  10760. {
  10761. set_pdata_int(id, OFFSET_FLASHLIGHT_BATTERY, value, OFFSET_LINUX)
  10762. }
  10763.  
  10764. // Update Player's Team on all clients (adding needed delays)
  10765. stock fm_user_team_update(id)
  10766. {
  10767. static Float:current_time
  10768. current_time = get_gametime()
  10769.  
  10770. if (current_time - g_teams_targettime >= 0.1)
  10771. {
  10772. set_task(0.1, "fm_cs_set_user_team_msg", id+TASK_TEAM)
  10773. g_teams_targettime = current_time + 0.1
  10774. }
  10775. else
  10776. {
  10777. set_task((g_teams_targettime + 0.1) - current_time, "fm_cs_set_user_team_msg", id+TASK_TEAM)
  10778. g_teams_targettime = g_teams_targettime + 0.1
  10779. }
  10780. }
  10781.  
  10782. // Send User Team Message
  10783. public fm_cs_set_user_team_msg(taskid)
  10784. {
  10785. // Note to self: this next message can now be received by other plugins
  10786.  
  10787. // Set the switching team flag
  10788. g_switchingteam = true
  10789.  
  10790. // Tell everyone my new team
  10791. emessage_begin(MSG_ALL, g_msgTeamInfo)
  10792. ewrite_byte(ID_TEAM) // player
  10793. ewrite_string(CS_TEAM_NAMES[fm_cs_get_user_team(ID_TEAM)]) // team
  10794. emessage_end()
  10795.  
  10796. // Done switching team
  10797. g_switchingteam = false
  10798. }
  10799.  
  10800. // Set the precached model index (updates hitboxes server side)
  10801. stock fm_cs_set_user_model_index(id, value)
  10802. {
  10803. set_pdata_int(id, OFFSET_MODELINDEX, value, OFFSET_LINUX)
  10804. }
  10805.  
  10806. // Set Player Model on Entity
  10807. stock fm_set_playermodel_ent(id)
  10808. {
  10809. // Make original player entity invisible without hiding shadows or firing effects
  10810. fm_set_rendering(id, kRenderFxNone, 255, 255, 255, kRenderTransTexture, 1)
  10811.  
  10812. // Format model string
  10813. static model[100]
  10814. formatex(model, charsmax(model), "models/player/%s/%s.mdl", g_playermodel[id], g_playermodel[id])
  10815.  
  10816. // Set model on entity or make a new one if unexistant
  10817. if (!pev_valid(g_ent_playermodel[id]))
  10818. {
  10819. g_ent_playermodel[id] = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
  10820. if (!pev_valid(g_ent_playermodel[id])) return;
  10821.  
  10822. set_pev(g_ent_playermodel[id], pev_classname, MODEL_ENT_CLASSNAME)
  10823. set_pev(g_ent_playermodel[id], pev_movetype, MOVETYPE_FOLLOW)
  10824. set_pev(g_ent_playermodel[id], pev_aiment, id)
  10825. set_pev(g_ent_playermodel[id], pev_owner, id)
  10826. }
  10827.  
  10828. engfunc(EngFunc_SetModel, g_ent_playermodel[id], model)
  10829. }
  10830.  
  10831. // Set Weapon Model on Entity
  10832. stock fm_set_weaponmodel_ent(id)
  10833. {
  10834. // Get player's p_ weapon model
  10835. static model[100]
  10836. pev(id, pev_weaponmodel2, model, charsmax(model))
  10837.  
  10838. // Set model on entity or make a new one if unexistant
  10839. if (!pev_valid(g_ent_weaponmodel[id]))
  10840. {
  10841. g_ent_weaponmodel[id] = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
  10842. if (!pev_valid(g_ent_weaponmodel[id])) return;
  10843.  
  10844. set_pev(g_ent_weaponmodel[id], pev_classname, WEAPON_ENT_CLASSNAME)
  10845. set_pev(g_ent_weaponmodel[id], pev_movetype, MOVETYPE_FOLLOW)
  10846. set_pev(g_ent_weaponmodel[id], pev_aiment, id)
  10847. set_pev(g_ent_weaponmodel[id], pev_owner, id)
  10848. }
  10849.  
  10850. engfunc(EngFunc_SetModel, g_ent_weaponmodel[id], model)
  10851. }
  10852.  
  10853. // Remove Custom Model Entities
  10854. stock fm_remove_model_ents(id)
  10855. {
  10856. // Remove "playermodel" ent if present
  10857. if (pev_valid(g_ent_playermodel[id]))
  10858. {
  10859. engfunc(EngFunc_RemoveEntity, g_ent_playermodel[id])
  10860. g_ent_playermodel[id] = 0
  10861. }
  10862. // Remove "weaponmodel" ent if present
  10863. if (pev_valid(g_ent_weaponmodel[id]))
  10864. {
  10865. engfunc(EngFunc_RemoveEntity, g_ent_weaponmodel[id])
  10866. g_ent_weaponmodel[id] = 0
  10867. }
  10868. }
  10869.  
  10870. // Set User Model
  10871. public fm_cs_set_user_model(taskid)
  10872. {
  10873. set_user_info(ID_MODEL, "model", g_playermodel[ID_MODEL])
  10874. }
  10875.  
  10876. // Get User Model -model passed byref-
  10877. stock fm_cs_get_user_model(player, model[], len)
  10878. {
  10879. get_user_info(player, "model", model, len)
  10880. }
  10881.  
  10882. // Update Player's Model on all clients (adding needed delays)
  10883. public fm_user_model_update(taskid)
  10884. {
  10885. static Float:current_time
  10886. current_time = get_gametime()
  10887.  
  10888. if (current_time - g_models_targettime >= g_modelchange_delay)
  10889. {
  10890. fm_cs_set_user_model(taskid)
  10891. g_models_targettime = current_time
  10892. }
  10893. else
  10894. {
  10895. set_task((g_models_targettime + g_modelchange_delay) - current_time, "fm_cs_set_user_model", taskid)
  10896. g_models_targettime = g_models_targettime + g_modelchange_delay
  10897. }
  10898. }
Add Comment
Please, Sign In to add comment