陳維亨
                        
                      
                    
                            
                      
                     
                    
                      
                    
                   | 
                  
                    
                    分享: 
                     
					 
						  
					 
					 
						  
					 
					 
						  
					 
                    
                    
                    	
                    
                      ▲
                    
                      ▼
                    
                    
                    
                      
                     
                     
                     
                     
                    
                    
                    
                      
                          給你看吧!  a7811311622大大
                          
                      
                       
                      
                      
                      
        
                          /*================================================================================                      *****************************************************               ************** [Zombie Plague Mod 4.3] **************               *****************************************************               ----------------------        -*- Licensing Info -*-        ----------------------               Zombie Plague Mod        Copyright (C) 2008-2009 by MeRcyLeZZ               This program is free software: you can redistribute it and/or modify        it under the terms of the GNU General Public License as published by        the Free Software Foundation, either version 3 of the License, or        (at your option) any later version.               This program is distributed in the hope that it will be useful,        but WITHOUT ANY WARRANTY; without even the implied warranty of        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        GNU General Public License for more details.               You should have received a copy of the GNU General Public License        along with this program.  If not, see < http://www.gnu.org/...s/>.              In addition, as a special exception, the author gives permission to        link the code of this program with the Half-Life Game Engine ("HL        Engine") and Modified Game Libraries ("MODs") developed by Valve,        L.L.C ("Valve"). You must obey the GNU General Public License in all        respects for all of the code used other than the HL Engine and MODs        from Valve. If you modify this file, you may extend this exception        to your version of the file, but you are not obligated to do so. If        you do not wish to do so, delete this exception statement from your        version.               -------------------        -*- Description -*-        -------------------               Zombie Plague is a Counter-Strike server side modification, developed as        an AMX Mod X plugin, which completely revamps the gameplay, turning the        game into an intense "Humans vs Zombies" survival experience.               Even though it's strongly based on the classic zombie infection mods, it        takes the concept to a new level by introducing:               * New Gameplay Modes: Nemesis, Survivor, Multi Infection, Swarm, Plague        * Zombie Classes System: allows addding unlimited custom zombie classes        * Ammo Packs: awarded to skilled players, can be exchanged for goods        * Extra Items System: allows adding unlimited custom items to buy        * Custom Grenades: Napalms, Frost Nades, Flares, and Infection Bombs        * Deathmatch Mode: where zombies or humans can continually respawn        * Admin Menus: to easily perform the included console commands        * Special Effects: from the HL Engine, such as dynamic lighting and fog               There is plenty of customization as well, which enables you to create        several different styles of gameplay. You can:               * Set zombies and humans' health, speed, models, rewards, and more        * Toggle unlimited ammo and adjustable knockback for weapons        * Separately enable and customize the new gameplay modes to your liking        * Change overall map lighting (lightnings available for the dark settings)        * Set different colors and sizes for flashlight and nightvision        * Toggle leap (long jumping) and pain shock free (no damage slowdowns)        * Toggle various infection effects, such as sparks and screen shakes        * Enable random spawning (CSDM-spawn friendly)        * Replace sounds or add some background themes        * And many more...               -------------        -*- Media -*-        -------------               * Gameplay Video 1:    按這裡檢視影片,登入論壇可以直接觀看       * Gameplay Video 2:    按這裡檢視影片,登入論壇可以直接觀看              --------------------        -*- Requirements -*-        --------------------               * Mods: Counter-Strike 1.6 or Condition-Zero        * AMXX: Version 1.8.0 or later               --------------------        -*- Installation -*-        --------------------               Extract the contents from the .zip file to your server's mod directory        ("cstrike" or "czero"). Make sure to keep folder structure.               -----------------------        -*- Official Forums -*-        -----------------------               For the official Zombie Plague forums visit:        http://forums.alliedmods.net...y.php?f=126              There you can:               * Get the latest releases and early betas        * Discuss new features and suggestions        * Share sub-plugins (expansions) for the mod        * Find the support and help you need        * Report any bugs you might find        * And all that sort of stuff...               -------------------------------        -*- CVARS and Customization -*-        -------------------------------               For a complete and in-depth cvar list, look at the zombieplague.cfg file        located in the amxmodx\configs directory.               Additionally, you can change player models, sounds, weather effects,        and some other stuff from the configuration file zombieplague.ini.               As for editing attributes of zombie classes or custom extra items, you'll        find a zp_zombieclasses.ini and zp_extraitems.ini. These files will be        automatically updated as you install new custom classes or items with        new entries for you to edit conveniently.               ---------------        -*- History -*-        ---------------               This project started back on late 2007, when the free infection mods        around were quite buggy and I wanted to make one on my own. With little        to no experience at AMXX scripting, I had to start from the very scratch.               Not after spending over a week looking at many plugins (mainly Zombie        Swarm) and scarce tutorials, I somehow managed to have all the basic        stuff working quite well (even though the code was a real mess). The        following months were spent polishing things up and trying to fulfill        new original ideas, most of them quite worth the hard work.               In the meantime, I got the chance to try the plugin out on a 32 man        server. This meant a huge progress on development, and after lots of        testing and bug fixing, the mod turned out to be more than the simple        infection plugin I had originally planned it to be.               The project has come a long way since, and I'm glad to say I'm finally        making it freely available. All I'm asking in return is to keep my        name in the plugin.               -Enjoy!               ----------------------        -*- Infection Mode -*-        ----------------------               On every round players start out as humans, equip themselves with a few        weapons and grenades, and head to the closest cover they find, knowing        that one of them is infected with the T-Virus, and will suddenly turn        into a vicious brain eating creature.               Only little time after, the battle for survival begins. The first zombie        has to infect as many humans as possible to cluster a numerous zombie        horde and take over the world.               Maps are set in the dark by default. Humans must use flashlights to light        their way and spot any enemies. Zombies, on the other hand, have night        vision but can only attack melee.               --------------------------        -*- New Gameplay Modes -*-        --------------------------               * Nemesis:           The first zombie may turn into a Nemesis, a powerful fast-moving           beast. His goal is to kill every human while sustaining the gunfire.               * Survivor:           Everyone became a zombie except him. The survivor gets a machinegun           with unlimited ammo and has to stop the never-ending army of undead.               * Multiple Infection:           The round starts with many humans infected, so the remaining players           will have to act quickly in order to control the situation.               * Swarm Mode:           Half of the players turn into zombies, the rest become immune and           cannot be infected. It's a battle to death.               * Plague Mode: [bonus]           A full armed Survivor and his soldiers are to face Nemesis and           his zombie minions. The future of the world is in their hands.               --------------------        -*- In-Game Menu -*-        --------------------               Players can access the mod menu by typing "zpmenu" on chat, or by        pressing the M ("chooseteam") key. The menu allows players to choose        their zombie class, buy extra items, get unstuck, or see the ingame        help. Admins will find an additional option to easily perform all        console commands.               ----------------------        -*- Admin Commands -*-        ----------------------               The following console commands are available:               * zp_zombie <target> - Turn someone into a Zombie        * zp_human <target> - Turn someone back to Human        * zp_nemesis <target> - Turn someone into a Nemesis        * zp_survivor <target> - Turn someone into a Survivor        * zp_respawn <target> - Respawn someone        * zp_swarm - Start Swarm Mode (*)        * zp_multi - Start Multi Infection (*)        * zp_plague - Start Plague Mode (*)               (*) - These commands can only be used at round start, that is, when the        T-Virus notice is shown on screen.                ------------------        -*- Plugin API -*-        ------------------               From version 3.6, some natives and forwards have been added to ease the        development of sub-plugins, though you may also find them useful to work        out compatibility issues with existing plugins.               Look for the zombieplague.inc file in your amxmodx\scripting\include        folder for the full documented list.               ----------------------        -*- Zombie Classes -*-        ----------------------               From version 4.0 it is possible to create and add an unlimited number of        zombie classes to the main mod. They can be made as separate plugins,        by using the provided zombie class API, and easily distributed.               By default, five zombie classes are included:               * Classic Zombie: well balanced zombie for beginners.        * Raptor Zombie: fast moving zombie, but also the weakest.        * Poison Zombie: light weighed zombie, jumps higher.        * Big Zombie: slow but strong zombie, with lots of hit points.        * Leech Zombie: regains additional health when infecting.               -------------------        -*- Extra Items -*-        -------------------               From version 4.0 it is possible to add an unlimited number of items        which can be purchased through the Extra Items menu. All you need        to do is use the provided item registration natives on your custom        plugins. You can set the name, the cost in ammo packs, and the team        the extra item should be available for.               By default there is a number of items already included, listed here:               * Night Vision: makes you able to see in the dark for a single round [Human]        * T-Virus Antidote: makes you turn back to your human form [Zombie]        * Zombie Madness: you develop a powerful shield for a short time [Zombie]        * Infection Bomb: infects anyone within its explosion radius [Zombie]               You are also able to choose some weapons to act as extra items, and change        ammo packs costs in the customization file (zombieplague.ini).               ---------------        -*- Credits -*-        ---------------               * AMXX Dev Team: for all the hard work which made this possible        * Imperio LNJ Community: for providing the first server where I           could really test the plugin and for everyone's support        * Mini_Midget: for his Zombie Swarm plugin which I used for reference           on earliest stages of development        * Avalanche: for the random spawning code I got from GunGame and the           original Frostnades concept that I ported in here        * cheap_suit: for some modelchange and knockback codes that I got from           Biohazard        * Simon Logic/ConnorMcLeod: for the Pain Shock Free feature        * KRoT@L: for some code from Follow the Wounded, used to make the zombie           bleeding feature        * VEN: for Fakemeta Utilities and some useful stocks        * RaaPuar and Goltark: for the custom grenade models        * Orangutanz: for finding the precached modelindex offset        * ML Translations: DKs/nunoabc/DarkMarcos (bp), JahMan/KWo (pl), DA (de),           Zombie Lurker (ls), DoPe^ (da), k1nny (fr), NeWbiE' (cz), skymoon (tc),           SUPER MATRIX/Shidla/zDemon/4eRT (ru), zsy314 (cn), lOlIl/Seehank (sk),           Bridgestone (sv), crazyeffect.net/Mave/Wesley (nl), hleV/aaarnas (lt),           darkbad945 (bg), decongamco (vn), beckham9224 (mn), TehGeorge (gr),           shadoww_ro/tuty/georgik57/EastSider (ro)        * Beta testers: for all the feedback, bug reports, and suggestions which           constantly help improve this mod further        * And to all zombie-mod supporters out there!               -----------------        -*- Changelog -*-        -----------------               * v1.0: (Dec 2007)           - First Release: most of the basic stuff done.           - Added: random spawning, HP display on hud, lighting setting,              simple buy menu, custom nightvision, admin commands, Nemesis              and Survivor modes, glow and leap settings for them.               * v2.2: (Jan 2008)           - Added: zombie classes, ammo packs system, buying ammo for weapons,              custom flashlight, admin skins setting, zombieplague.cfg file           - Upgraded: weapons menu improved, flashlight and nightvision colors              now customizable, HamSandwich module used to handle damage.           - Fixed various bugs.               * v3.0: (Mar 2008)           - Added: door removal setting, unstuck feature, human cvars, armor              cvar for zombies, weapon knockback, zombie bleeding, flares,              extra items (weapons, antidote, infection bomb), pain shock              free setting, Multiple Infection and Swarm modes.           - Upgraded: dumped Engine, Fun and Cstrike modules, code optimized,              new model change method, new gfx effects for zombie infections.           - Fixed a bunch of gameplay bugs.               * v3.5: (May 2008)           - Added: deathmatch setting with spawn protection, unlimited ammo              setting, fire and frost grenades, additional customization cvars,              new extra items, help menu.           - Upgraded: better objectives removal method, dropped weapons now              keep their bpammo, code optimized a lot.           - Fixed: no more game commencing bug when last zombie/human leaves,              no more hegrenade infection bug, reduced svc_bad errors, and              many more.               * v3.6: (Jun 2008)           - Added: a few natives and forwards for sub-plugins support,              zombie classes can now have their own models, additional              knockback customization, bot support, various CVARs.           - Upgraded: extra items now supporting grenades and pistols, changed              bomb removal method, players can join on survivor/swarm rounds,              extended lightnings support to other dark settings.           - Fixed: a bunch of minor bugs, and a server crash with CZ bots.               * v4.0: (Aug 2008)           - Added: new gameplay mode (Plague Mode), option to remember weapon              selection, command to enable/disable the plugin, more CVARs.           - Upgraded: redid all the menus, extra items and zombie classes now              support external additions, survivor can now have its own model,              upgraded model changing method.           - Fixed: some bugs with bots, win sounds not being precached.               * v4.1: (Oct 2008)           - Added: more CVARs, more customization, more natives, custom              leap system, admin zombie models support, and more.           - Upgraded: custom grenades compatible with Nade Modes, ambience              sounds specific game mode support, optimized bandwidth usage              for temp ents, admin commands logged with IP and SteamID.           - Fixed: lots of bugs (some minor, some not)               * v4.2: (Feb 2009)           - Added various CVARs for customization, improved prevention of              svc_bad in some cases, optimized ammo handling code.           - Fixed server crash with 'msg 35 has not been sent yet' error,              fixed client overflow issues with ambience sounds, resolved              many gameplay bugs.               * v4.3: (Apr 2009)           - Customization settings can now be edited through external files,              added support for global and multiple random zombie models,              added even more CVARs for tweaking stuff, extended admin commands'              functionality, greatly extended API capabilities, implemented a              more efficient Pain Shock Free code, reworked some menus.           - Fixed pretty much all reported bugs to the date.        =================================================================================*/ /*================================================================================  [Plugin Customization] =================================================================================*/ // All customization settings have been moved // to external files to allow easier editing new const ZP_CUSTOMIZATION_FILE[] = "zombieplague.ini" new const ZP_EXTRAITEMS_FILE[] = "zp_extraitems.ini" new const ZP_ZOMBIECLASSES_FILE[] = "zp_zombieclasses.ini" // Limiters for stuff not worth making dynamic arrays out of (increase if needed) const MAX_CSDM_SPAWNS = 128 const MAX_STATS_SAVED = 64 /*================================================================================  Customization ends here! Yes, that's it. Editing anything beyond  here is not officially supported. Proceed at your own risk... =================================================================================*/ #include <amxmodx> #include <amxmisc> #include <cstrike> #include <fakemeta> #include <hamsandwich> #include <xs> /*================================================================================  [Constants, Offsets, Macros] =================================================================================*/ new const sound_first_zombie[][] = { "zombie_plague/zombie_coming1.wav", "zombie_plague/zombie_coming2.wav" } //第一隻喪屍出現時的聲音 //回合開始倒數計時的聲音(英文數字1~10)  //可以自行設定要使用男聲還是女聲,看要使用那一種聲音只要去掉該項 new const sound_countdown 前面的 // 字符,並在另一項前面加上 // 字符即可. //男聲 new const sound_countdown[10][] = { "zombie_plague/one.wav", "zombie_plague/two.wav", "zombie_plague/three.wav", "zombie_plague/four.wav", "zombie_plague/five.wav", "zombie_plague/six.wav", "zombie_plague/seven.wav", "zombie_plague/eight.wav", "zombie_plague/nine.wav", "zombie_plague/ten.wav" } //女聲 //new const sound_countdown[10][] = { "fvox/one.wav", "fvox/two.wav", "fvox/three.wav", "fvox/four.wav", "fvox/five.wav", "fvox/six.wav", "fvox/seven.wav", "fvox/eight.wav", "fvox/nine.wav", "fvox/ten.wav" } // Plugin Version new const PLUGIN_VERSION[] = "4.3" // Customization file sections enum {        SECTION_NONE = 0,        SECTION_ACCESS_FLAGS,        SECTION_PLAYER_MODELS,        SECTION_WEAPON_MODELS,        SECTION_GRENADE_SPRITES,        SECTION_SOUNDS,        SECTION_AMBIENCE_SOUNDS,        SECTION_BUY_MENU_WEAPONS,        SECTION_EXTRA_ITEMS_WEAPONS,        SECTION_HARD_CODED_ITEMS_COSTS,        SECTION_WEATHER_EFFECTS,        SECTION_SKY,        SECTION_LIGHTNING,        SECTION_ZOMBIE_DECALS,        SECTION_KNOCKBACK,        SECTION_OBJECTIVE_ENTS,        SECTION_SVC_BAD } // Access flags enum {        ACCESS_ENABLE_MOD = 0,        ACCESS_ADMIN_MENU,        ACCESS_MODE_INFECTION,        ACCESS_MODE_NEMESIS,        ACCESS_MODE_SURVIVOR,        ACCESS_MODE_SWARM,        ACCESS_MODE_MULTI,        ACCESS_MODE_PLAGUE,        ACCESS_MAKE_ZOMBIE,        ACCESS_MAKE_HUMAN,        ACCESS_MAKE_NEMESIS,        ACCESS_MAKE_SURVIVOR,        ACCESS_RESPAWN_PLAYERS,        ACCESS_ADMIN_MODELS,        MAX_ACCESS_FLAGS } // Task offsets enum (+= 100) {        TASK_MODEL = 2000,        TASK_TEAM,        TASK_SPAWN,        TASK_BLOOD,        TASK_AURA,        TASK_BURN,        TASK_NVISION,        TASK_FLASH,        TASK_CHARGE,        TASK_SHOWHUD,        TASK_MAKEZOMBIE,        TASK_WELCOMEMSG,        TASK_THUNDER_PRE,        TASK_THUNDER,        TASK_AMBIENCESOUNDS } // IDs inside tasks #define ID_MODEL (taskid - TASK_MODEL) #define ID_TEAM (taskid - TASK_TEAM) #define ID_SPAWN (taskid - TASK_SPAWN) #define ID_BLOOD (taskid - TASK_BLOOD) #define ID_AURA (taskid - TASK_AURA) #define ID_BURN (taskid - TASK_BURN) #define ID_NVISION (taskid - TASK_NVISION) #define ID_FLASH (taskid - TASK_FLASH) #define ID_CHARGE (taskid - TASK_CHARGE) #define ID_SHOWHUD (taskid - TASK_SHOWHUD) // BP Ammo Refill task #define REFILL_WEAPONID args[0] // For weapon buy menu handlers #define WPN_STARTID g_menu_data[id][1] #define WPN_MAXIDS ArraySize(g_primary_items) #define WPN_SELECTION (g_menu_data[id][1]+key) #define WPN_AUTO_ON g_menu_data[id][2] #define WPN_AUTO_PRI g_menu_data[id][3] #define WPN_AUTO_SEC g_menu_data[id][4] // For player list menu handlers #define PL_ACTION g_menu_data[id][0] // For extra items menu handlers #define EXTRAS_CUSTOM_STARTID (EXTRA_WEAPONS_STARTID + ArraySize(g_extraweapon_names)) // Menu selections const MENU_KEY_AUTOSELECT = 7 const MENU_KEY_BACK = 7 const MENU_KEY_NEXT = 8 const MENU_KEY_EXIT = 9 // Hard coded extra items enum {        EXTRA_NVISION = 0,        EXTRA_ANTIDOTE,        EXTRA_MADNESS,        EXTRA_INFBOMB,        EXTRA_WEAPONS_STARTID } // Game modes enum {        MODE_NONE = 0,        MODE_INFECTION,        MODE_NEMESIS,        MODE_SURVIVOR,        MODE_SWARM,        MODE_MULTI,        MODE_PLAGUE } // ZP Teams const ZP_TEAM_NO_ONE = 0 const ZP_TEAM_ANY = 0 const ZP_TEAM_ZOMBIE = (1<<0) const ZP_TEAM_HUMAN = (1<<1) const ZP_TEAM_NEMESIS = (1<<2) const ZP_TEAM_SURVIVOR = (1<<3) new const ZP_TEAM_NAMES[][] = { "ZOMBIE , HUMAN", "ZOMBIE", "HUMAN", "ZOMBIE , HUMAN", "NEMESIS",                      "ZOMBIE , NEMESIS", "HUMAN , NEMESIS", "ZOMBIE , HUMAN , NEMESIS",                      "SURVIVOR", "ZOMBIE , SURVIVOR", "HUMAN , SURVIVOR", "ZOMBIE , HUMAN , SURVIVOR",                      "NEMESIS , SURVIVOR", "ZOMBIE , NEMESIS , SURVIVOR", "HUMAN, NEMESIS, SURVIVOR",                      "ZOMBIE , HUMAN , NEMESIS , SURVIVOR" } // Zombie classes const ZCLASS_NONE = -1 // HUD messages const Float:HUD_EVENT_X = -1.0 const Float:HUD_EVENT_Y = 0.17 const Float:HUD_INFECT_X = 0.05 const Float:HUD_INFECT_Y = 0.45 const Float:HUD_SPECT_X = 0.6 const Float:HUD_SPECT_Y = 0.8 const Float:HUD_STATS_X = 0.02 const Float:HUD_STATS_Y = 0.9 // CS Player PData Offsets (win32) const OFFSET_PAINSHOCK = 108 // ConnorMcLeod const OFFSET_CSTEAMS = 114 const OFFSET_CSMONEY = 115 const OFFSET_FLASHLIGHT_BATTERY = 244 const OFFSET_CSDEATHS = 444 const OFFSET_MODELINDEX = 491 // Orangutanz // CS Player CBase Offsets (win32) const OFFSET_ACTIVE_ITEM = 373 // CS Weapon CBase Offsets (win32) const OFFSET_WEAPONOWNER = 41 // Linux diff's const OFFSET_LINUX = 5 // offsets 5 higher in Linux builds const OFFSET_LINUX_WEAPONS = 4 // weapon offsets are only 4 steps higher on Linux // CS Teams enum {        FM_CS_TEAM_UNASSIGNED = 0,        FM_CS_TEAM_T,        FM_CS_TEAM_CT,        FM_CS_TEAM_SPECTATOR } new const CS_TEAM_NAMES[][] = { "UNASSIGNED", "TERRORIST", "CT", "SPECTATOR" } // Some constants const HIDE_MONEY = (1<<5) const UNIT_SECOND = (1<<12) const DMG_HEGRENADE = (1<<24) const IMPULSE_FLASHLIGHT = 100 const USE_USING = 2 const USE_STOPPED = 0 const STEPTIME_SILENT = 999 const BREAK_GLASS = 0x01 const FFADE_IN = 0x0000 const FFADE_STAYOUT = 0x0004 const PEV_SPEC_TARGET = pev_iuser2 // Max BP ammo for weapons new const MAXBPAMMO[] = { -1, 200, -1, 200, 1, 96, 1, 200, 200, 1, 200, 200, 200, 200, 200, 200, 200, 200,                      200, 200, 200, 96, 200, 200, 200, 2, 200, 200, 200, -1, 200 } // Max Clip for weapons new const MAXCLIP[] = { -1, 13, -1, 10, -1, 7, -1, 30, 30, -1, 30, 20, 25, 30, 35, 25, 12, 20,                      10, 30, 100, 8, 30, 30, 20, -1, 7, 30, 30, -1, 50 } // Amount of ammo to give when buying additional clips for weapons new const BUYAMMO[] = { -1, 13, -1, 30, -1, 8, -1, 12, 30, -1, 30, 50, 12, 30, 30, 30, 12, 30,                      10, 30, 30, 8, 30, 30, 30, -1, 7, 30, 30, -1, 50 } // Ammo IDs for weapons new const AMMOID[] = { -1, 9, -1, 2, 12, 5, 14, 6, 4, 13, 10, 7, 6, 4, 4, 4, 6, 10,                      1, 10, 3, 5, 4, 10, 2, 11, 8, 4, 2, -1, 7 } // Ammo Type Names for weapons new const AMMOTYPE[][] = { "", "357sig", "", "762nato", "", "buckshot", "", "45acp", "556nato", "", "9mm", "57mm", "45acp",                      "556nato", "556nato", "556nato", "45acp", "9mm", "338magnum", "9mm", "556natobox", "buckshot",                      "556nato", "9mm", "762nato", "", "50ae", "556nato", "762nato", "", "57mm" } // Weapon IDs for ammo types new const AMMOWEAPON[] = { 0, CSW_AWP, CSW_SCOUT, CSW_M249, CSW_AUG, CSW_XM1014, CSW_MAC10, CSW_FIVESEVEN, CSW_DEAGLE,                      CSW_P228, CSW_ELITE, CSW_FLASHBANG, CSW_HEGRENADE, CSW_SMOKEGRENADE, CSW_C4 } // Primary and Secondary Weapon Names new const WEAPONNAMES[][] = { "", "P227nk", "", "M24-S", "", "XM1017", "", "MAC15", "SKULL-4",                      "", "DualDeagle", "Fivetexen", "Krisst", "AS50-S", "Gauill-ex", "G11-nutre",                      "USPEX", "GlockEX", "RXT-700", "KALGREEN", "Powersaw",                      "M1887-KN", "SFGUN", "TMPVK", "SVDEX", "", "Deagle-II",                      "MK2-UR1", "CV47-60R", "", "Daul Mp7a1" } // Weapon entity names new const WEAPONENTNAMES[][] = { "", "weapon_p228", "", "weapon_scout", "weapon_hegrenade", "weapon_xm1014", "weapon_c4", "weapon_mac10",                      "weapon_aug", "weapon_smokegrenade", "weapon_elite", "weapon_fiveseven", "weapon_ump45", "weapon_sg550",                      "weapon_galil", "weapon_famas", "weapon_usp", "weapon_glock18", "weapon_awp", "weapon_mp5navy", "weapon_m249",                      "weapon_m3", "weapon_m4a1", "weapon_tmp", "weapon_g3sg1", "weapon_flashbang", "weapon_deagle", "weapon_sg552",                      "weapon_ak47", "weapon_knife", "weapon_p90" } // CS sounds new const sound_flashlight[] = "items/flashlight1.wav" new const sound_buyammo[] = "items/9mmclip1.wav" new const sound_armorhit[] = "player/bhit_helmet-1.wav" // Explosion radius for custom grenades const Float:NADE_EXPLOSION_RADIUS = 240.0 // HACK: pev_ field used to store additional ammo on weapons const PEV_ADDITIONAL_AMMO = pev_iuser1 // HACK: pev_ field used to store custom nade types and their values const PEV_NADE_TYPE = pev_flTimeStepSound const NADE_TYPE_INFECTION = 1111 const NADE_TYPE_NAPALM = 2222 const NADE_TYPE_FROST = 3333 const NADE_TYPE_FLARE = 4444 const PEV_FLARE_COLOR = pev_punchangle const PEV_FLARE_DURATION = pev_flSwimTime // Weapon bitsums 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) const SECONDARY_WEAPONS_BIT_SUM = (1<<CSW_P228)|(1<<CSW_ELITE)|(1<<CSW_FIVESEVEN)|(1<<CSW_USP)|(1<<CSW_GLOCK18)|(1<<CSW_DEAGLE) // Allowed weapons for zombies (added grenades/bomb for sub-plugin support, since they shouldn't be getting them anyway) const ZOMBIE_ALLOWED_WEAPONS_BITSUM = (1<<CSW_KNIFE)|(1<<CSW_HEGRENADE)|(1<<CSW_FLASHBANG)|(1<<CSW_SMOKEGRENADE)|(1<<CSW_C4) // Classnames for separate model entities new const MODEL_ENT_CLASSNAME[] = "player_model" new const WEAPON_ENT_CLASSNAME[] = "weapon_model" // Menu keys 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 // Ambience Sounds enum {        AMBIENCE_SOUNDS_INFECTION = 0,        AMBIENCE_SOUNDS_NEMESIS,        AMBIENCE_SOUNDS_SURVIVOR,        AMBIENCE_SOUNDS_SWARM,        AMBIENCE_SOUNDS_PLAGUE,        MAX_AMBIENCE_SOUNDS } // Admin menu actions enum {        ACTION_ZOMBIEFY_HUMANIZE = 0,        ACTION_MAKE_NEMESIS,        ACTION_MAKE_SURVIVOR,        ACTION_RESPAWN_PLAYER,        ACTION_MODE_SWARM,        ACTION_MODE_MULTI,        ACTION_MODE_PLAGUE } // Custom forward return values const ZP_PLUGIN_HANDLED = 97 /*================================================================================  [Global Variables] =================================================================================*/ // Player vars new g_zombie[33] // is zombie new g_nemesis[33] // is nemesis new g_survivor[33] // is survivor new g_firstzombie[33] // is first zombie new g_lastzombie[33] // is last zombie new g_lasthuman[33] // is last human new g_frozen[33] // is frozen (can't move) new g_nodamage[33] // has spawn protection/zombie madness new g_respawn_as_zombie[33] // should respawn as zombie new g_nvision[33] // has night vision new g_nvisionenabled[33] // has night vision turned on new g_zombieclass[33] // zombie class new g_zombieclassnext[33] // zombie class for next infection new g_flashlight[33] // has custom flashlight turned on new g_flashbattery[33] = { 100, ... } // custom flashlight battery new g_canbuy[33] // is allowed to buy a new weapon through the menu new g_ammopacks[33] // ammo pack count new g_damagedealt[33] // damage dealt to zombies (used to calculate ammo packs reward) new Float:g_lastleaptime[33] // time leap was last used new Float:g_lastflashtime[33] // time flashlight was last toggled new g_playermodel[33][32] // current model's short name [player][model] new g_menu_data[33][5] // data for some menu handlers new g_ent_playermodel[33] // player model entity new g_ent_weaponmodel[33] // weapon model entity new g_burning_duration[33] // burning task duration new g_menu_last_data[33][2] // store the player last view menu data // Game vars new g_pluginenabled // ZP enabled new g_newround // new round starting new g_endround // round ended new g_nemround // nemesis round new g_survround // survivor round new g_swarmround // swarm round new g_plagueround // plague round new g_modestarted // mode fully started new g_lastmode // last played mode new g_scorezombies, g_scorehumans // team scores new g_spawnCount, g_spawnCount2 // available spawn points counter new Float:g_spawns[MAX_CSDM_SPAWNS][3], Float:g_spawns2[MAX_CSDM_SPAWNS][3] // spawn points data new g_lights_i // lightning current lights counter new g_lights_cycle[32] // current lightning cycle new g_lights_cycle_len // lightning cycle length new Float:g_models_targettime // for adding delays between Model Change messages new Float:g_teams_targettime // for adding delays between Team Change messages new g_MsgSync, g_MsgSync2 // message sync objects new g_trailSpr, g_exploSpr, g_flameSpr, g_smokeSpr, g_glassSpr // grenade sprites new g_modname[32] // for formatting the mod name new g_freezetime // whether CS's freeze time is on new g_maxplayers // max players counter new g_czero // whether we are running on a CZ server new g_hamczbots // whether ham forwards are registered for CZ bots new g_fwSpawn, g_fwPrecacheSound // spawn and precache sound forward handles new g_infbombcounter, g_antidotecounter, g_madnesscounter // to limit buying some items new g_arrays_created // to prevent stuff from being registered before initializing arrays new g_lastplayerleaving // flag for whenever a player leaves and another takes his place new g_switchingteam // flag for whenever a player's team change emessage is sent new g_time_countdown // 回合開始倒數計時用的變數 // Message IDs vars new g_msgScoreInfo, g_msgNVGToggle, g_msgScoreAttrib, g_msgAmmoPickup, g_msgScreenFade, g_msgDeathMsg, g_msgSetFOV, g_msgFlashlight, g_msgFlashBat, g_msgTeamInfo, g_msgDamage, g_msgHideWeapon, g_msgCrosshair, g_msgSayText, g_msgScreenShake, g_msgCurWeapon // Some forward handlers new g_fwRoundStart, g_fwRoundEnd, g_fwUserInfected_pre, g_fwUserInfected_post, g_fwUserHumanized_pre, g_fwUserHumanized_post, g_fwUserInfect_attempt, g_fwUserHumanize_attempt, g_fwExtraItemSelected, g_fwUserUnfrozen, g_fwUserLastZombie, g_fwUserLastHuman, g_fwDummyResult // Temporary Database vars (used to restore players stats in case they get disconnected) new db_name[MAX_STATS_SAVED][32] // player name new db_ammopacks[MAX_STATS_SAVED] // ammo pack count new db_zombieclass[MAX_STATS_SAVED] // zombie class new db_slot_i // additional saved slots counter (should start on maxplayers+1) // Extra Items vars new Array:g_extraitem_name // caption new Array:g_extraitem_cost // cost new Array:g_extraitem_team // team new g_extraitem_i // loaded extra items counter // For extra items file parsing new Array:g_extraitem2_realname, Array:g_extraitem2_name, Array:g_extraitem2_cost, Array:g_extraitem2_team, Array:g_extraitem_new // Zombie Classes vars new Array:g_zclass_name // caption new Array:g_zclass_info // description new Array:g_zclass_modelsstart // start position in models array new Array:g_zclass_modelsend // end position in models array new Array:g_zclass_playermodel // player models array new Array:g_zclass_modelindex // model indices array new Array:g_zclass_clawmodel // claw model new Array:g_zclass_hp // health new Array:g_zclass_spd // speed new Array:g_zclass_grav // gravity new Array:g_zclass_kb // knockback new g_zclass_i // loaded zombie classes counter // For zombie classes file parsing new Array:g_zclass2_realname, Array:g_zclass2_name, Array:g_zclass2_info, Array:g_zclass2_modelsstart, Array:g_zclass2_modelsend, Array:g_zclass2_playermodel, Array:g_zclass2_modelindex, Array:g_zclass2_clawmodel, Array:g_zclass2_hp, Array:g_zclass2_spd, Array:g_zclass2_grav, Array:g_zclass2_kb, Array:g_zclass_new // Customization vars new g_access_flag[MAX_ACCESS_FLAGS], Array:model_nemesis, Array:model_survivor, Array:model_human, Array:model_admin_zombie, Array:model_admin_human, Array:g_modelindex_human, Array:g_modelindex_nemesis, Array:g_modelindex_survivor, g_same_models_for_all, Array:g_modelindex_admin_zombie, Array:g_modelindex_admin_human, model_vknife_human[64], model_vknife_nemesis[64], model_vm249_survivor[64], model_grenade_infect[64], model_grenade_fire[64], model_grenade_frost[64], model_grenade_flare[64], model_vknife_admin_human[64], model_vknife_admin_zombie[64], sprite_grenade_trail[64], sprite_grenade_ring[64], sprite_grenade_fire[64], sprite_grenade_smoke[64], sprite_grenade_glass[64], Array:sound_win_zombies, Array:sound_win_humans, Array:sound_win_no_one, Array:zombie_infect, Array:zombie_idle, Array:zombie_pain, Array:nemesis_pain, Array:zombie_die, Array:zombie_fall, Array:zombie_miss_wall, Array:zombie_hit_normal, Array:zombie_hit_stab, g_ambience_rain, Array:zombie_idle_last, Array:zombie_madness, Array:sound_nemesis, Array:sound_survivor, Array:sound_swarm, Array:sound_multi, Array:sound_plague, Array:grenade_infect, Array:grenade_infect_player, Array:grenade_fire, Array:grenade_fire_player, Array:grenade_frost, Array:grenade_frost_player, Array:grenade_frost_break, Array:grenade_flare, Array:sound_antidote, Array:sound_thunder, g_ambience_sounds[MAX_AMBIENCE_SOUNDS], Array:sound_ambience1, Array:sound_ambience2, Array:sound_ambience3, Array:sound_ambience4, Array:sound_ambience5, Array:sound_ambience1_duration, Array:sound_ambience2_duration, Array:sound_ambience3_duration, Array:sound_ambience4_duration, Array:sound_ambience5_duration, Array:sound_ambience1_ismp3, Array:sound_ambience2_ismp3, Array:sound_ambience3_ismp3, Array:sound_ambience4_ismp3, Array:sound_ambience5_ismp3, Array:g_primary_items, Array:g_secondary_items, Array:g_additional_items, Array:g_primary_weaponids, Array:g_secondary_weaponids, Array:g_extraweapon_names, Array:g_extraweapon_items, Array:g_extraweapon_costs, g_extra_costs2[EXTRA_WEAPONS_STARTID], g_ambience_snow, g_ambience_fog, g_fog_density[10], g_fog_color[12], g_sky_enable, Array:g_sky_names, Array:lights_thunder, Array:zombie_decals, Array:g_objective_ents, Float:g_modelchange_delay, g_set_modelindex_offset, g_handle_models_on_separate_ent, Float:kb_weapon_power[31] = { -1.0, ... }, Array:zombie_miss_slash, g_force_consistency // CVAR pointers new cvar_lighting, cvar_zombiefov, cvar_plague, cvar_plaguechance, cvar_zombiefirsthp, cvar_removemoney, cvar_thunder, cvar_zombiebonushp, cvar_nemhp, cvar_nem, cvar_surv, cvar_nemchance, cvar_deathmatch, cvar_nemglow, cvar_customnvg, cvar_hitzones, cvar_humanhp, cvar_nemgravity, cvar_flashsize, cvar_ammodamage, cvar_zombiearmor, cvar_survpainfree, cvar_nempainfree, cvar_nemspd, cvar_survchance, cvar_survhp, cvar_survspd, cvar_humanspd, cvar_swarmchance, cvar_flashdrain, cvar_zombiebleeding, cvar_removedoors, cvar_customflash, cvar_randspawn, cvar_multi, cvar_multichance, cvar_infammo, cvar_swarm, cvar_ammoinfect, cvar_toggle, cvar_knockbackpower, cvar_freezeduration, cvar_triggered, cvar_flashcharge, cvar_firegrenades, cvar_frostgrenades, cvar_survgravity, cvar_logcommands, cvar_survglow, cvar_humangravity, cvar_spawnprotection, cvar_nvgsize, cvar_flareduration, cvar_zclasses, cvar_extraitems, cvar_showactivity, cvar_humanlasthp, cvar_nemignorefrags, cvar_warmup, cvar_flashdist, cvar_flarecolor, cvar_survignorefrags, cvar_fireduration, cvar_firedamage, cvar_flaregrenades, cvar_knockbackducking, cvar_knockbackdamage, cvar_knockbackzvel, cvar_multiratio, cvar_flaresize, cvar_spawndelay, cvar_extraantidote, cvar_extramadness, cvar_extraweapons, cvar_extranvision, cvar_nvggive, cvar_preventconsecutive, cvar_botquota, cvar_buycustom, cvar_zombiepainfree, cvar_fireslowdown, cvar_survbasehp, cvar_survaura, cvar_nemignoreammo, cvar_survignoreammo, cvar_nemaura, cvar_extrainfbomb, cvar_knockback, cvar_fragsinfect, cvar_fragskill, cvar_humanarmor, cvar_zombiesilent, cvar_removedropped, cvar_plagueratio, cvar_blocksuicide, cvar_knockbackdist, cvar_nemdamage, cvar_leapzombies, cvar_leapzombiesforce, cvar_leapzombiesheight, cvar_leapzombiescooldown, cvar_leapnemesis, cvar_leapnemesisforce, cvar_leapnemesisheight, cvar_leapnemesiscooldown, cvar_leapsurvivor, cvar_leapsurvivorforce, cvar_leapsurvivorheight, cvar_nemminplayers, cvar_survminplayers, cvar_respawnonsuicide, cvar_respawnafterlast, cvar_leapsurvivorcooldown, cvar_statssave, cvar_swarmminplayers, cvar_multiminplayers, cvar_plagueminplayers, cvar_adminmodelshuman, cvar_adminmodelszombie, cvar_nembasehp, cvar_blockpushables, cvar_respawnworldspawnkill, cvar_madnessduration, cvar_plaguenemnum, cvar_plaguenemhpmulti, cvar_plaguesurvhpmulti, cvar_survweapon, cvar_plaguesurvnum, cvar_infectionscreenfade, cvar_infectionscreenshake, cvar_infectionsparkle, cvar_infectiontracers, cvar_infectionparticles, cvar_infbomblimit, cvar_allowrespawnsurv, cvar_flashshowall, cvar_allowrespawninfection, cvar_allowrespawnnem, cvar_allowrespawnswarm, cvar_allowrespawnplague, cvar_survinfammo, cvar_nemknockback, cvar_nvgcolor[3], cvar_nemnvgcolor[3], cvar_humnvgcolor[3], cvar_flashcolor[3], cvar_hudicons, cvar_respawnzomb, cvar_respawnhum, cvar_respawnnem, cvar_respawnsurv, cvar_startammopacks, cvar_randweapons, cvar_antidotelimit, cvar_madnesslimit, cvar_adminknifemodelshuman, cvar_adminknifemodelszombie, cvar_keephealthondisconnect // Cached stuff for players new g_isconnected[33] // whether player is connected new g_isalive[33] // whether player is alive new g_isbot[33] // whether player is a bot new g_currentweapon[33] // player's current weapon id new g_playername[33][32] // player's name new Float:g_zombie_spd[33] // zombie class speed new Float:g_zombie_knockback[33] // zombie class knockback new g_zombie_classname[33][32] // zombie class name #define is_user_valid_connected(%1) (1 <= %1 <= g_maxplayers && g_isconnected[%1]) #define is_user_valid_alive(%1) (1 <= %1 <= g_maxplayers && g_isalive[%1]) // Cached CVARs new g_cached_customflash, g_cached_zombiesilent, Float:g_cached_humanspd, Float:g_cached_nemspd, Float:g_cached_survspd, g_cached_leapzombies, Float:g_cached_leapzombiescooldown, g_cached_leapnemesis, Float:g_cached_leapnemesiscooldown, g_cached_leapsurvivor, Float:g_cached_leapsurvivorcooldown /*================================================================================  [Natives, Precache and Init] =================================================================================*/ public plugin_natives() {        // Player specific natives        register_native("zp_get_user_zombie", "native_get_user_zombie", 1)        register_native("zp_get_user_nemesis", "native_get_user_nemesis", 1)        register_native("zp_get_user_survivor", "native_get_user_survivor", 1)        register_native("zp_get_user_first_zombie", "native_get_user_first_zombie", 1)        register_native("zp_get_user_last_zombie", "native_get_user_last_zombie", 1)        register_native("zp_get_user_last_human", "native_get_user_last_human", 1)        register_native("zp_get_user_zombie_class", "native_get_user_zombie_class", 1)        register_native("zp_get_user_next_class", "native_get_user_next_class", 1)        register_native("zp_set_user_zombie_class", "native_set_user_zombie_class", 1)        register_native("zp_get_user_ammo_packs", "native_get_user_ammo_packs", 1)        register_native("zp_set_user_ammo_packs", "native_set_user_ammo_packs", 1)        register_native("zp_get_zombie_maxhealth", "native_get_zombie_maxhealth", 1)        register_native("zp_get_user_batteries", "native_get_user_batteries", 1)        register_native("zp_set_user_batteries", "native_set_user_batteries", 1)        register_native("zp_get_user_nightvision", "native_get_user_nightvision", 1)        register_native("zp_set_user_nightvision", "native_set_user_nightvision", 1)        register_native("zp_infect_user", "native_infect_user", 1)        register_native("zp_disinfect_user", "native_disinfect_user", 1)        register_native("zp_make_user_nemesis", "native_make_user_nemesis", 1)        register_native("zp_make_user_survivor", "native_make_user_survivor", 1)        register_native("zp_respawn_user", "native_respawn_user", 1)        register_native("zp_force_buy_extra_item", "native_force_buy_extra_item", 1)               // Round natives        register_native("zp_has_round_started", "native_has_round_started", 1)        register_native("zp_is_nemesis_round", "native_is_nemesis_round", 1)        register_native("zp_is_survivor_round", "native_is_survivor_round", 1)        register_native("zp_is_swarm_round", "native_is_swarm_round", 1)        register_native("zp_is_plague_round", "native_is_plague_round", 1)        register_native("zp_get_zombie_count", "native_get_zombie_count", 1)        register_native("zp_get_human_count", "native_get_human_count", 1)        register_native("zp_get_nemesis_count", "native_get_nemesis_count", 1)        register_native("zp_get_survivor_count", "native_get_survivor_count", 1)               // External additions natives        register_native("zp_register_extra_item", "native_register_extra_item", 1)        register_native("zp_register_zombie_class", "native_register_zombie_class", 1)        register_native("zp_get_extra_item_id", "native_get_extra_item_id", 1)        register_native("zp_get_zombie_class_id", "native_get_zombie_class_id", 1) } public plugin_precache() {        // Register earlier to show up in plugins list properly after plugin disable/error at loading        register_plugin("Zombie Plague", PLUGIN_VERSION, "MeRcyLeZZ")               // To switch plugin on/off        register_concmd("zp_toggle", "cmd_toggle", _, "<1/0> - Enable/Disable Zombie Plague (will restart the current map)", 0)        cvar_toggle = register_cvar("zp_on", "1")               // Plugin disabled?        if (!get_pcvar_num(cvar_toggle)) return;        g_pluginenabled = true               // Initialize a few dynamically sized arrays (alright, maybe more than just a few...)        model_human = ArrayCreate(32, 1)        model_nemesis = ArrayCreate(32, 1)        model_survivor = ArrayCreate(32, 1)        model_admin_human = ArrayCreate(32, 1)        model_admin_zombie = ArrayCreate(32, 1)        g_modelindex_human = ArrayCreate(1, 1)        g_modelindex_nemesis = ArrayCreate(1, 1)        g_modelindex_survivor = ArrayCreate(1, 1)        g_modelindex_admin_human = ArrayCreate(1, 1)        g_modelindex_admin_zombie = ArrayCreate(1, 1)        sound_win_zombies = ArrayCreate(64, 1)        sound_win_humans = ArrayCreate(64, 1)        sound_win_no_one = ArrayCreate(64, 1)        zombie_infect = ArrayCreate(64, 1)        zombie_pain = ArrayCreate(64, 1)        nemesis_pain = ArrayCreate(64, 1)        zombie_die = ArrayCreate(64, 1)        zombie_fall = ArrayCreate(64, 1)        zombie_miss_slash = ArrayCreate(64, 1)        zombie_miss_wall = ArrayCreate(64, 1)        zombie_hit_normal = ArrayCreate(64, 1)        zombie_hit_stab = ArrayCreate(64, 1)        zombie_idle = ArrayCreate(64, 1)        zombie_idle_last = ArrayCreate(64, 1)        zombie_madness = ArrayCreate(64, 1)        sound_nemesis = ArrayCreate(64, 1)        sound_survivor = ArrayCreate(64, 1)        sound_swarm = ArrayCreate(64, 1)        sound_multi = ArrayCreate(64, 1)        sound_plague = ArrayCreate(64, 1)        grenade_infect = ArrayCreate(64, 1)        grenade_infect_player = ArrayCreate(64, 1)        grenade_fire = ArrayCreate(64, 1)        grenade_fire_player = ArrayCreate(64, 1)        grenade_frost = ArrayCreate(64, 1)        grenade_frost_player = ArrayCreate(64, 1)        grenade_frost_break = ArrayCreate(64, 1)        grenade_flare = ArrayCreate(64, 1)        sound_antidote = ArrayCreate(64, 1)        sound_thunder = ArrayCreate(64, 1)        sound_ambience1 = ArrayCreate(64, 1)        sound_ambience2 = ArrayCreate(64, 1)        sound_ambience3 = ArrayCreate(64, 1)        sound_ambience4 = ArrayCreate(64, 1)        sound_ambience5 = ArrayCreate(64, 1)        sound_ambience1_duration = ArrayCreate(1, 1)        sound_ambience2_duration = ArrayCreate(1, 1)        sound_ambience3_duration = ArrayCreate(1, 1)        sound_ambience4_duration = ArrayCreate(1, 1)        sound_ambience5_duration = ArrayCreate(1, 1)        sound_ambience1_ismp3 = ArrayCreate(1, 1)        sound_ambience2_ismp3 = ArrayCreate(1, 1)        sound_ambience3_ismp3 = ArrayCreate(1, 1)        sound_ambience4_ismp3 = ArrayCreate(1, 1)        sound_ambience5_ismp3 = ArrayCreate(1, 1)        g_primary_items = ArrayCreate(32, 1)        g_secondary_items = ArrayCreate(32, 1)        g_additional_items = ArrayCreate(32, 1)        g_primary_weaponids = ArrayCreate(1, 1)        g_secondary_weaponids = ArrayCreate(1, 1)        g_extraweapon_names = ArrayCreate(32, 1)        g_extraweapon_items = ArrayCreate(32, 1)        g_extraweapon_costs = ArrayCreate(1, 1)        g_sky_names = ArrayCreate(32, 1)        lights_thunder = ArrayCreate(32, 1)        zombie_decals = ArrayCreate(1, 1)        g_objective_ents = ArrayCreate(32, 1)        g_extraitem_name = ArrayCreate(32, 1)        g_extraitem_cost = ArrayCreate(1, 1)        g_extraitem_team = ArrayCreate(1, 1)        g_extraitem2_realname = ArrayCreate(32, 1)        g_extraitem2_name = ArrayCreate(32, 1)        g_extraitem2_cost = ArrayCreate(1, 1)        g_extraitem2_team = ArrayCreate(1, 1)        g_extraitem_new = ArrayCreate(1, 1)        g_zclass_name = ArrayCreate(32, 1)        g_zclass_info = ArrayCreate(32, 1)        g_zclass_modelsstart = ArrayCreate(1, 1)        g_zclass_modelsend = ArrayCreate(1, 1)        g_zclass_playermodel = ArrayCreate(32, 1)        g_zclass_modelindex = ArrayCreate(1, 1)        g_zclass_clawmodel = ArrayCreate(32, 1)        g_zclass_hp = ArrayCreate(1, 1)        g_zclass_spd = ArrayCreate(1, 1)        g_zclass_grav = ArrayCreate(1, 1)        g_zclass_kb = ArrayCreate(1, 1)        g_zclass2_realname = ArrayCreate(32, 1)        g_zclass2_name = ArrayCreate(32, 1)        g_zclass2_info = ArrayCreate(32, 1)        g_zclass2_modelsstart = ArrayCreate(1, 1)        g_zclass2_modelsend = ArrayCreate(1, 1)        g_zclass2_playermodel = ArrayCreate(32, 1)        g_zclass2_modelindex = ArrayCreate(1, 1)        g_zclass2_clawmodel = ArrayCreate(32, 1)        g_zclass2_hp = ArrayCreate(1, 1)        g_zclass2_spd = ArrayCreate(1, 1)        g_zclass2_grav = ArrayCreate(1, 1)        g_zclass2_kb = ArrayCreate(1, 1)        g_zclass_new = ArrayCreate(1, 1)               // Allow registering stuff now        g_arrays_created = true               // Load customization data        load_customization_from_files()               new i, buffer[100]               // Load up the hard coded extra items        native_register_extra_item2("NightVision", g_extra_costs2[EXTRA_NVISION], ZP_TEAM_HUMAN)        native_register_extra_item2("T-Virus Antidote", g_extra_costs2[EXTRA_ANTIDOTE], ZP_TEAM_ZOMBIE)        native_register_extra_item2("Zombie Madness", g_extra_costs2[EXTRA_MADNESS], ZP_TEAM_ZOMBIE)        native_register_extra_item2("Infection Bomb", g_extra_costs2[EXTRA_INFBOMB], ZP_TEAM_ZOMBIE)               // Extra weapons        for (i = 0; i < ArraySize(g_extraweapon_names); i++)        {               ArrayGetString(g_extraweapon_names, i, buffer, charsmax(buffer))               native_register_extra_item2(buffer, ArrayGetCell(g_extraweapon_costs, i), ZP_TEAM_HUMAN)        }               // Custom player models        for (i = 0; i < ArraySize(model_human); i++)        {               ArrayGetString(model_human, i, buffer, charsmax(buffer))               format(buffer, charsmax(buffer), "models/player/%s/%s.mdl", buffer, buffer)               ArrayPushCell(g_modelindex_human, engfunc(EngFunc_PrecacheModel, buffer))               if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, buffer)               if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, buffer)        }        for (i = 0; i < ArraySize(model_nemesis); i++)        {               ArrayGetString(model_nemesis, i, buffer, charsmax(buffer))               format(buffer, charsmax(buffer), "models/player/%s/%s.mdl", buffer, buffer)               ArrayPushCell(g_modelindex_nemesis, engfunc(EngFunc_PrecacheModel, buffer))               if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, buffer)               if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, buffer)        }        for (i = 0; i < ArraySize(model_survivor); i++)        {               ArrayGetString(model_survivor, i, buffer, charsmax(buffer))               format(buffer, charsmax(buffer), "models/player/%s/%s.mdl", buffer, buffer)               ArrayPushCell(g_modelindex_survivor, engfunc(EngFunc_PrecacheModel, buffer))               if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, buffer)               if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, buffer)        }        for (i = 0; i < ArraySize(model_admin_zombie); i++)        {               ArrayGetString(model_admin_zombie, i, buffer, charsmax(buffer))               format(buffer, charsmax(buffer), "models/player/%s/%s.mdl", buffer, buffer)               ArrayPushCell(g_modelindex_admin_zombie, engfunc(EngFunc_PrecacheModel, buffer))               if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, buffer)               if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, buffer)        }        for (i = 0; i < ArraySize(model_admin_human); i++)        {               ArrayGetString(model_admin_human, i, buffer, charsmax(buffer))               format(buffer, charsmax(buffer), "models/player/%s/%s.mdl", buffer, buffer)               ArrayPushCell(g_modelindex_admin_human, engfunc(EngFunc_PrecacheModel, buffer))               if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, buffer)               if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, buffer)        }               // Custom weapon models        engfunc(EngFunc_PrecacheModel, model_vknife_human)        engfunc(EngFunc_PrecacheModel, model_vknife_nemesis)        engfunc(EngFunc_PrecacheModel, model_vm249_survivor)        engfunc(EngFunc_PrecacheModel, model_grenade_infect)        engfunc(EngFunc_PrecacheModel, model_grenade_fire)        engfunc(EngFunc_PrecacheModel, model_grenade_frost)        engfunc(EngFunc_PrecacheModel, model_grenade_flare)        engfunc(EngFunc_PrecacheModel, model_vknife_admin_human)        engfunc(EngFunc_PrecacheModel, model_vknife_admin_zombie)               // Custom sprites for grenades        g_trailSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_trail)        g_exploSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_ring)        g_flameSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_fire)        g_smokeSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_smoke)        g_glassSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_glass)               // Custom sounds        for (i = 0; i < ArraySize(sound_win_zombies); i++)        {               ArrayGetString(sound_win_zombies, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(sound_win_humans); i++)        {               ArrayGetString(sound_win_humans, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(sound_win_no_one); i++)        {               ArrayGetString(sound_win_no_one, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(zombie_infect); i++)        {               ArrayGetString(zombie_infect, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(zombie_pain); i++)        {               ArrayGetString(zombie_pain, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(nemesis_pain); i++)        {               ArrayGetString(nemesis_pain, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(zombie_die); i++)        {               ArrayGetString(zombie_die, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(zombie_fall); i++)        {               ArrayGetString(zombie_fall, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(zombie_miss_slash); i++)        {               ArrayGetString(zombie_miss_slash, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(zombie_miss_wall); i++)        {               ArrayGetString(zombie_miss_wall, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(zombie_hit_normal); i++)        {               ArrayGetString(zombie_hit_normal, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(zombie_hit_stab); i++)        {               ArrayGetString(zombie_hit_stab, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(zombie_idle); i++)        {               ArrayGetString(zombie_idle, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(zombie_idle_last); i++)        {               ArrayGetString(zombie_idle_last, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(zombie_madness); i++)        {               ArrayGetString(zombie_madness, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(sound_nemesis); i++)        {               ArrayGetString(sound_nemesis, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(sound_survivor); i++)        {               ArrayGetString(sound_survivor, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(sound_swarm); i++)        {               ArrayGetString(sound_swarm, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(sound_multi); i++)        {               ArrayGetString(sound_multi, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(sound_plague); i++)        {               ArrayGetString(sound_plague, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(grenade_infect); i++)        {               ArrayGetString(grenade_infect, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(grenade_infect_player); i++)        {               ArrayGetString(grenade_infect_player, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(grenade_fire); i++)        {               ArrayGetString(grenade_fire, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(grenade_fire_player); i++)        {               ArrayGetString(grenade_fire_player, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(grenade_frost); i++)        {               ArrayGetString(grenade_frost, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(grenade_frost_player); i++)        {               ArrayGetString(grenade_frost_player, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(grenade_frost_break); i++)        {               ArrayGetString(grenade_frost_break, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(grenade_flare); i++)        {               ArrayGetString(grenade_flare, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(sound_antidote); i++)        {               ArrayGetString(sound_antidote, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }        for (i = 0; i < ArraySize(sound_thunder); i++)        {               ArrayGetString(sound_thunder, i, buffer, charsmax(buffer))               engfunc(EngFunc_PrecacheSound, buffer)        }               // Ambience Sounds        if (g_ambience_sounds[AMBIENCE_SOUNDS_INFECTION])        {               for (i = 0; i < ArraySize(sound_ambience1); i++)               {                      ArrayGetString(sound_ambience1, i, buffer, charsmax(buffer))                                           if (ArrayGetCell(sound_ambience1_ismp3, i))                      {                             format(buffer, charsmax(buffer), "sound/%s", buffer)                             engfunc(EngFunc_PrecacheGeneric, buffer)                      }                      else                      {                             engfunc(EngFunc_PrecacheSound, buffer)                      }               }        }        if (g_ambience_sounds[AMBIENCE_SOUNDS_NEMESIS])        {               for (i = 0; i < ArraySize(sound_ambience2); i++)               {                      ArrayGetString(sound_ambience2, i, buffer, charsmax(buffer))                                           if (ArrayGetCell(sound_ambience2_ismp3, i))                      {                             format(buffer, charsmax(buffer), "sound/%s", buffer)                             engfunc(EngFunc_PrecacheGeneric, buffer)                      }                      else                      {                             engfunc(EngFunc_PrecacheSound, buffer)                      }               }        }        if (g_ambience_sounds[AMBIENCE_SOUNDS_SURVIVOR])        {               for (i = 0; i < ArraySize(sound_ambience3); i++)               {                      ArrayGetString(sound_ambience3, i, buffer, charsmax(buffer))                                           if (ArrayGetCell(sound_ambience3_ismp3, i))                      {                             format(buffer, charsmax(buffer), "sound/%s", buffer)                             engfunc(EngFunc_PrecacheGeneric, buffer)                      }                      else                      {                             engfunc(EngFunc_PrecacheSound, buffer)                      }               }        }        if (g_ambience_sounds[AMBIENCE_SOUNDS_SWARM])        {               for (i = 0; i < ArraySize(sound_ambience4); i++)               {                      ArrayGetString(sound_ambience4, i, buffer, charsmax(buffer))                                           if (ArrayGetCell(sound_ambience4_ismp3, i))                      {                             format(buffer, charsmax(buffer), "sound/%s", buffer)                             engfunc(EngFunc_PrecacheGeneric, buffer)                      }                      else                      {                             engfunc(EngFunc_PrecacheSound, buffer)                      }               }        }        if (g_ambience_sounds[AMBIENCE_SOUNDS_PLAGUE])        {               for (i = 0; i < ArraySize(sound_ambience5); i++)               {                      ArrayGetString(sound_ambience5, i, buffer, charsmax(buffer))                                           if (ArrayGetCell(sound_ambience5_ismp3, i))                      {                             format(buffer, charsmax(buffer), "sound/%s", buffer)                             engfunc(EngFunc_PrecacheGeneric, buffer)                      }                      else                      {                             engfunc(EngFunc_PrecacheSound, buffer)                      }               }        }               // CS sounds (just in case)        engfunc(EngFunc_PrecacheSound, sound_flashlight)        engfunc(EngFunc_PrecacheSound, sound_buyammo)        engfunc(EngFunc_PrecacheSound, sound_armorhit)               // 第一隻喪屍出現時的聲音        for (i = 0; i < sizeof sound_first_zombie; i++)               engfunc(EngFunc_PrecacheSound, sound_first_zombie )                // 回合開始倒數計時的聲音 (from Half-Life vox)        for (i = 0; i < sizeof sound_countdown; i++)               engfunc(EngFunc_PrecacheSound, sound_countdown)                new ent                // Fake Hostage (to force round ending)        ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "hostage_entity"))        if (pev_valid(ent))        {               engfunc(EngFunc_SetOrigin, ent, Float:{8192.0,8192.0,8192.0})               dllfunc(DLLFunc_Spawn, ent)        }                // Weather/ambience effects        if (g_ambience_fog)        {               ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "env_fog"))               if (pev_valid(ent))               {                      fm_set_kvd(ent, "density", g_fog_density, "env_fog")                      fm_set_kvd(ent, "rendercolor", g_fog_color, "env_fog")               }        }        if (g_ambience_rain) engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "env_rain"))        if (g_ambience_snow) engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "env_snow"))                // Prevent some entities from spawning        g_fwSpawn = register_forward(FM_Spawn, "fw_Spawn")                // Prevent hostage sounds from being precached        g_fwPrecacheSound = register_forward(FM_PrecacheSound, "fw_PrecacheSound") }
  public plugin_init() {        // Plugin disabled?        if (!g_pluginenabled) return;                // No zombie classes?        if (!g_zclass_i) set_fail_state("No zombie classes loaded!")                // Language files        register_dictionary("zombie_plague.txt")                // Events        register_event("HLTV", "event_round_start", "a", "1=0", "2=0")        register_logevent("logevent_round_start",2, "1=Round_Start")        register_logevent("logevent_round_end", 2, "1=Round_End")        register_event("AmmoX", "event_ammo_x", "be")        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])               register_event("30", "event_intermission", "a")                // HAM Forwards        RegisterHam(Ham_Spawn, "player", "fw_PlayerSpawn_Post", 1)        RegisterHam(Ham_Killed, "player", "fw_PlayerKilled")        RegisterHam(Ham_Killed, "player", "fw_PlayerKilled_Post", 1)        RegisterHam(Ham_TakeDamage, "player", "fw_TakeDamage")        RegisterHam(Ham_TakeDamage, "player", "fw_TakeDamage_Post", 1)        RegisterHam(Ham_TraceAttack, "player", "fw_TraceAttack")        RegisterHam(Ham_Use, "func_tank", "fw_UseStationary")        RegisterHam(Ham_Use, "func_tankmortar", "fw_UseStationary")        RegisterHam(Ham_Use, "func_tankrocket", "fw_UseStationary")        RegisterHam(Ham_Use, "func_tanklaser", "fw_UseStationary")        RegisterHam(Ham_Use, "func_tank", "fw_UseStationary_Post", 1)        RegisterHam(Ham_Use, "func_tankmortar", "fw_UseStationary_Post", 1)        RegisterHam(Ham_Use, "func_tankrocket", "fw_UseStationary_Post", 1)        RegisterHam(Ham_Use, "func_tanklaser", "fw_UseStationary_Post", 1)        RegisterHam(Ham_Use, "func_pushable", "fw_UsePushable")        RegisterHam(Ham_Touch, "weaponbox", "fw_TouchWeapon")        RegisterHam(Ham_Touch, "armoury_entity", "fw_TouchWeapon")        RegisterHam(Ham_Touch, "weapon_shield", "fw_TouchWeapon")        RegisterHam(Ham_AddPlayerItem, "player", "fw_AddPlayerItem")        for (new i = 1; i < sizeof WEAPONENTNAMES; i++)               if (WEAPONENTNAMES[0]) RegisterHam(Ham_Item_Deploy, WEAPONENTNAMES, "fw_Item_Deploy_Post", 1)                // FM Forwards        register_forward(FM_ClientDisconnect, "fw_ClientDisconnect")        register_forward(FM_ClientDisconnect, "fw_ClientDisconnect_Post", 1)        register_forward(FM_ClientKill, "fw_ClientKill")        register_forward(FM_EmitSound, "fw_EmitSound")        if (!g_handle_models_on_separate_ent) register_forward(FM_SetClientKeyValue, "fw_SetClientKeyValue")        register_forward(FM_ClientUserInfoChanged, "fw_ClientUserInfoChanged")        register_forward(FM_GetGameDescription, "fw_GetGameDescription")        register_forward(FM_SetModel, "fw_SetModel")        RegisterHam(Ham_Think, "grenade", "fw_ThinkGrenade")        register_forward(FM_CmdStart, "fw_CmdStart")        register_forward(FM_PlayerPreThink, "fw_PlayerPreThink")        unregister_forward(FM_Spawn, g_fwSpawn)        unregister_forward(FM_PrecacheSound, g_fwPrecacheSound)                // Client commands        register_clcmd("say zpmenu", "clcmd_saymenu")        register_clcmd("say /zpmenu", "clcmd_saymenu")        register_clcmd("say unstuck", "clcmd_sayunstuck")        register_clcmd("say /unstuck", "clcmd_sayunstuck")        register_clcmd("nightvision", "clcmd_nightvision")        register_clcmd("drop", "clcmd_drop")        register_clcmd("buyammo1", "clcmd_buyammo")        register_clcmd("buyammo2", "clcmd_buyammo")        register_clcmd("chooseteam", "clcmd_changeteam")        register_clcmd("jointeam", "clcmd_changeteam")                // Menus        register_menu("Game Menu", KEYSMENU, "menu_game")        register_menu("Buy Menu 1", KEYSMENU, "menu_buy1")        register_menu("Buy Menu 2", KEYSMENU, "menu_buy2")        register_menu("Mod Info", KEYSMENU, "menu_info")        register_menu("Admin Menu", KEYSMENU, "menu_admin")                // Admin commands        register_concmd("zp_zombie", "cmd_zombie", _, "<target> - Turn someone into a Zombie", 0)        register_concmd("zp_human", "cmd_human", _, "<target> - Turn someone back to Human", 0)        register_concmd("zp_nemesis", "cmd_nemesis", _, "<target> - Turn someone into a Nemesis", 0)        register_concmd("zp_survivor", "cmd_survivor", _, "<target> - Turn someone into a Survivor", 0)        register_concmd("zp_respawn", "cmd_respawn", _, "<target> - Respawn someone", 0)        register_concmd("zp_swarm", "cmd_swarm", _, " - Start Swarm Mode", 0)        register_concmd("zp_multi", "cmd_multi", _, " - Start Multi Infection", 0)        register_concmd("zp_plague", "cmd_plague", _, " - Start Plague Mode", 0)                // Message IDs        g_msgScoreInfo = get_user_msgid("ScoreInfo")        g_msgTeamInfo = get_user_msgid("TeamInfo")        g_msgDeathMsg = get_user_msgid("DeathMsg")        g_msgScoreAttrib = get_user_msgid("ScoreAttrib")        g_msgSetFOV = get_user_msgid("SetFOV")        g_msgScreenFade = get_user_msgid("ScreenFade")        g_msgScreenShake = get_user_msgid("ScreenShake")        g_msgNVGToggle = get_user_msgid("NVGToggle")        g_msgFlashlight = get_user_msgid("Flashlight")        g_msgFlashBat = get_user_msgid("FlashBat")        g_msgAmmoPickup = get_user_msgid("AmmoPickup")        g_msgDamage = get_user_msgid("Damage")        g_msgHideWeapon = get_user_msgid("HideWeapon")        g_msgCrosshair = get_user_msgid("Crosshair")        g_msgSayText = get_user_msgid("SayText")        g_msgCurWeapon = get_user_msgid("CurWeapon")                // Message hooks        register_message(g_msgCurWeapon, "message_cur_weapon")        register_message(get_user_msgid("Money"), "message_money")        register_message(get_user_msgid("Health"), "message_health")        register_message(g_msgFlashBat, "message_flashbat")        register_message(g_msgScreenFade, "message_screenfade")        register_message(g_msgNVGToggle, "message_nvgtoggle")        if (g_handle_models_on_separate_ent) register_message(get_user_msgid("ClCorpse"), "message_clcorpse")        register_message(get_user_msgid("WeapPickup"), "message_weappickup")        register_message(g_msgAmmoPickup, "message_ammopickup")        register_message(get_user_msgid("Scenario"), "message_scenario")        register_message(get_user_msgid("HostagePos"), "message_hostagepos")        register_message(get_user_msgid("TextMsg"), "message_textmsg")        register_message(get_user_msgid("SendAudio"), "message_sendaudio")        register_message(get_user_msgid("TeamScore"), "message_teamscore")        register_message(g_msgTeamInfo, "message_teaminfo")                // CVARS - General Purpose        cvar_warmup = register_cvar("zp_delay", "10")        cvar_lighting = register_cvar("zp_lighting", "a")        cvar_thunder = register_cvar("zp_thunderclap", "90")        cvar_triggered = register_cvar("zp_triggered_lights", "1")        cvar_removedoors = register_cvar("zp_remove_doors", "0")        cvar_blockpushables = register_cvar("zp_blockuse_pushables", "1")        cvar_blocksuicide = register_cvar("zp_block_suicide", "1")        cvar_randspawn = register_cvar("zp_random_spawn", "1")        cvar_respawnworldspawnkill = register_cvar("zp_respawn_on_worldspawn_kill", "1")        cvar_removedropped = register_cvar("zp_remove_dropped", "0")        cvar_removemoney = register_cvar("zp_remove_money", "1")        cvar_buycustom = register_cvar("zp_buy_custom", "1")        cvar_randweapons = register_cvar("zp_random_weapons", "0")        cvar_adminmodelshuman = register_cvar("zp_admin_models_human", "1")        cvar_adminknifemodelshuman = register_cvar("zp_admin_knife_models_human", "0")        cvar_adminmodelszombie = register_cvar("zp_admin_models_zombie", "1")        cvar_adminknifemodelszombie = register_cvar("zp_admin_knife_models_zombie", "0")        cvar_zclasses = register_cvar("zp_zombie_classes", "1")        cvar_statssave = register_cvar("zp_stats_save", "1")        cvar_startammopacks = register_cvar("zp_starting_ammo_packs", "5")        cvar_preventconsecutive = register_cvar("zp_prevent_consecutive_modes", "1")        cvar_keephealthondisconnect = register_cvar("zp_keep_health_on_disconnect", "1")                // CVARS - Deathmatch        cvar_deathmatch = register_cvar("zp_deathmatch", "0")        cvar_spawndelay = register_cvar("zp_spawn_delay", "5")        cvar_spawnprotection = register_cvar("zp_spawn_protection", "5")        cvar_respawnonsuicide = register_cvar("zp_respawn_on_suicide", "0")        cvar_respawnafterlast = register_cvar("zp_respawn_after_last_human", "1")        cvar_allowrespawninfection = register_cvar("zp_infection_allow_respawn", "1")        cvar_allowrespawnnem = register_cvar("zp_nem_allow_respawn", "0")        cvar_allowrespawnsurv = register_cvar("zp_surv_allow_respawn", "0")        cvar_allowrespawnswarm = register_cvar("zp_swarm_allow_respawn", "0")        cvar_allowrespawnplague = register_cvar("zp_plague_allow_respawn", "0")        cvar_respawnzomb = register_cvar("zp_respawn_zombies", "1")        cvar_respawnhum = register_cvar("zp_respawn_humans", "1")        cvar_respawnnem = register_cvar("zp_respawn_nemesis", "1")        cvar_respawnsurv = register_cvar("zp_respawn_survivors", "1")                // CVARS - Extra Items        cvar_extraitems = register_cvar("zp_extra_items", "1")        cvar_extraweapons = register_cvar("zp_extra_weapons", "1")        cvar_extranvision = register_cvar("zp_extra_nvision", "1")        cvar_extraantidote = register_cvar("zp_extra_antidote", "1")        cvar_antidotelimit = register_cvar("zp_extra_antidote_limit", "999")        cvar_extramadness = register_cvar("zp_extra_madness", "1")        cvar_madnesslimit = register_cvar("zp_extra_madness_limit", "999")        cvar_madnessduration = register_cvar("zp_extra_madness_duration", "5.0")        cvar_extrainfbomb = register_cvar("zp_extra_infbomb", "1")        cvar_infbomblimit = register_cvar("zp_extra_infbomb_limit", "999")                // CVARS - Flashlight and Nightvision        cvar_nvggive = register_cvar("zp_nvg_give", "1")        cvar_customnvg = register_cvar("zp_nvg_custom", "1")        cvar_nvgsize = register_cvar("zp_nvg_size", "80")        cvar_nvgcolor[0] = register_cvar("zp_nvg_color_R", "0")        cvar_nvgcolor[1] = register_cvar("zp_nvg_color_G", "150")        cvar_nvgcolor[2] = register_cvar("zp_nvg_color_B", "0")        cvar_humnvgcolor[0] = register_cvar("zp_nvg_hum_color_R", "0")        cvar_humnvgcolor[1] = register_cvar("zp_nvg_hum_color_G", "150")        cvar_humnvgcolor[2] = register_cvar("zp_nvg_hum_color_B", "0")        cvar_nemnvgcolor[0] = register_cvar("zp_nvg_nem_color_R", "150")        cvar_nemnvgcolor[1] = register_cvar("zp_nvg_nem_color_G", "0")        cvar_nemnvgcolor[2] = register_cvar("zp_nvg_nem_color_B", "0")        cvar_customflash = register_cvar("zp_flash_custom", "0")        cvar_flashsize = register_cvar("zp_flash_size", "10")        cvar_flashdrain = register_cvar("zp_flash_drain", "1")        cvar_flashcharge = register_cvar("zp_flash_charge", "5")        cvar_flashdist = register_cvar("zp_flash_distance", "1000")        cvar_flashcolor[0] = register_cvar("zp_flash_color_R", "100")        cvar_flashcolor[1] = register_cvar("zp_flash_color_G", "100")        cvar_flashcolor[2] = register_cvar("zp_flash_color_B", "100")        cvar_flashshowall = register_cvar("zp_flash_show_all", "1")                // CVARS - Knockback        cvar_knockback = register_cvar("zp_knockback", "0")        cvar_knockbackdamage = register_cvar("zp_knockback_damage", "1")        cvar_knockbackpower = register_cvar("zp_knockback_power", "1")        cvar_knockbackzvel = register_cvar("zp_knockback_zvel", "0")        cvar_knockbackducking = register_cvar("zp_knockback_ducking", "0.25")        cvar_knockbackdist = register_cvar("zp_knockback_distance", "500")        cvar_nemknockback = register_cvar("zp_knockback_nemesis", "0.25")                // CVARS - Leap        cvar_leapzombies = register_cvar("zp_leap_zombies", "0")        cvar_leapzombiesforce = register_cvar("zp_leap_zombies_force", "500")        cvar_leapzombiesheight = register_cvar("zp_leap_zombies_height", "300")        cvar_leapzombiescooldown = register_cvar("zp_leap_zombies_cooldown", "5.0")        cvar_leapnemesis = register_cvar("zp_leap_nemesis", "1")        cvar_leapnemesisforce = register_cvar("zp_leap_nemesis_force", "500")        cvar_leapnemesisheight = register_cvar("zp_leap_nemesis_height", "300")        cvar_leapnemesiscooldown = register_cvar("zp_leap_nemesis_cooldown", "5.0")        cvar_leapsurvivor = register_cvar("zp_leap_survivor", "0")        cvar_leapsurvivorforce = register_cvar("zp_leap_survivor_force", "500")        cvar_leapsurvivorheight = register_cvar("zp_leap_survivor_height", "300")        cvar_leapsurvivorcooldown = register_cvar("zp_leap_survivor_cooldown", "5.0")                // CVARS - Humans        cvar_humanhp = register_cvar("zp_human_health", "100")        cvar_humanlasthp = register_cvar("zp_human_last_extrahp", "0")        cvar_humanspd = register_cvar("zp_human_speed", "240")        cvar_humangravity = register_cvar("zp_human_gravity", "1.0")        cvar_humanarmor = register_cvar("zp_human_armor_protect", "1")        cvar_infammo = register_cvar("zp_human_unlimited_ammo", "0")        cvar_ammodamage = register_cvar("zp_human_damage_reward", "500")        cvar_fragskill = register_cvar("zp_human_frags_for_kill", "1")                // CVARS - Custom Grenades        cvar_firegrenades = register_cvar("zp_fire_grenades", "1")        cvar_fireduration = register_cvar("zp_fire_duration", "10")        cvar_firedamage = register_cvar("zp_fire_damage", "5")        cvar_fireslowdown = register_cvar("zp_fire_slowdown", "0.5")        cvar_frostgrenades = register_cvar("zp_frost_grenades", "1")        cvar_freezeduration = register_cvar("zp_frost_duration", "3")        cvar_flaregrenades = register_cvar("zp_flare_grenades","1")        cvar_flareduration = register_cvar("zp_flare_duration", "60")        cvar_flaresize = register_cvar("zp_flare_size", "25")        cvar_flarecolor = register_cvar("zp_flare_color", "0")                // CVARS - Zombies        cvar_zombiefirsthp = register_cvar("zp_zombie_first_hp", "2.0")        cvar_zombiearmor = register_cvar("zp_zombie_armor", "0.75")        cvar_hitzones = register_cvar("zp_zombie_hitzones", "0")        cvar_zombiebonushp = register_cvar("zp_zombie_infect_health", "100")        cvar_zombiefov = register_cvar("zp_zombie_fov", "110")        cvar_zombiesilent = register_cvar("zp_zombie_silent", "1")        cvar_zombiepainfree = register_cvar("zp_zombie_painfree", "2")        cvar_zombiebleeding = register_cvar("zp_zombie_bleeding", "1")        cvar_ammoinfect = register_cvar("zp_zombie_infect_reward", "1")        cvar_fragsinfect = register_cvar("zp_zombie_frags_for_infect", "1")                // CVARS - Special Effects        cvar_infectionscreenfade = register_cvar("zp_infection_screenfade", "1")        cvar_infectionscreenshake = register_cvar("zp_infection_screenshake", "1")        cvar_infectionsparkle = register_cvar("zp_infection_sparkle", "1")        cvar_infectiontracers = register_cvar("zp_infection_tracers", "1")        cvar_infectionparticles = register_cvar("zp_infection_particles", "1")        cvar_hudicons = register_cvar("zp_hud_icons", "1")                // CVARS - Nemesis        cvar_nem = register_cvar("zp_nem_enabled", "1")        cvar_nemchance = register_cvar("zp_nem_chance", "20")        cvar_nemminplayers = register_cvar("zp_nem_min_players", "0")        cvar_nemhp = register_cvar("zp_nem_health", "0")        cvar_nembasehp = register_cvar("zp_nem_base_health", "0")        cvar_nemspd = register_cvar("zp_nem_speed", "250")        cvar_nemgravity = register_cvar("zp_nem_gravity", "0.5")        cvar_nemdamage = register_cvar("zp_nem_damage", "250")        cvar_nemglow = register_cvar("zp_nem_glow", "1")        cvar_nemaura = register_cvar("zp_nem_aura", "1")               cvar_nempainfree = register_cvar("zp_nem_painfree", "0")        cvar_nemignorefrags = register_cvar("zp_nem_ignore_frags", "1")        cvar_nemignoreammo = register_cvar("zp_nem_ignore_rewards", "1")                // CVARS - Survivor        cvar_surv = register_cvar("zp_surv_enabled", "1")        cvar_survchance = register_cvar("zp_surv_chance", "20")        cvar_survminplayers = register_cvar("zp_surv_min_players", "0")        cvar_survhp = register_cvar("zp_surv_health", "0")        cvar_survbasehp = register_cvar("zp_surv_base_health", "0")        cvar_survspd = register_cvar("zp_surv_speed", "230")        cvar_survgravity = register_cvar("zp_surv_gravity", "1.25")        cvar_survglow = register_cvar("zp_surv_glow", "1")        cvar_survaura = register_cvar("zp_surv_aura", "1")        cvar_survpainfree = register_cvar("zp_surv_painfree", "1")        cvar_survignorefrags = register_cvar("zp_surv_ignore_frags", "1")        cvar_survignoreammo = register_cvar("zp_surv_ignore_rewards", "1")        cvar_survweapon = register_cvar("zp_surv_weapon", "weapon_m249")        cvar_survinfammo = register_cvar("zp_surv_unlimited_ammo", "2")                // CVARS - Swarm Mode        cvar_swarm = register_cvar("zp_swarm_enabled", "1")        cvar_swarmchance = register_cvar("zp_swarm_chance", "20")        cvar_swarmminplayers = register_cvar("zp_swarm_min_players", "0")                // CVARS - Multi Infection        cvar_multi = register_cvar("zp_multi_enabled", "1")        cvar_multichance = register_cvar("zp_multi_chance", "20")        cvar_multiminplayers = register_cvar("zp_multi_min_players", "0")        cvar_multiratio = register_cvar("zp_multi_ratio", "0.15")                // CVARS - Plague Mode        cvar_plague = register_cvar("zp_plague_enabled", "1")        cvar_plaguechance = register_cvar("zp_plague_chance", "30")        cvar_plagueminplayers = register_cvar("zp_plague_min_players", "0")        cvar_plagueratio = register_cvar("zp_plague_ratio", "0.5")        cvar_plaguenemnum = register_cvar("zp_plague_nem_number", "1")        cvar_plaguenemhpmulti = register_cvar("zp_plague_nem_hp_multi", "0.5")        cvar_plaguesurvnum = register_cvar("zp_plague_surv_number", "1")        cvar_plaguesurvhpmulti = register_cvar("zp_plague_surv_hp_multi", "0.5")                // CVARS - Others        cvar_logcommands = register_cvar("zp_logcommands", "1")        cvar_showactivity = get_cvar_pointer("amx_show_activity")        cvar_botquota = get_cvar_pointer("bot_quota")        register_cvar("zp_version", PLUGIN_VERSION, FCVAR_SERVER|FCVAR_SPONLY)        set_cvar_string("zp_version", PLUGIN_VERSION)                // Custom Forwards        g_fwRoundStart = CreateMultiForward("zp_round_started", ET_IGNORE, FP_CELL, FP_CELL)        g_fwRoundEnd = CreateMultiForward("zp_round_ended", ET_IGNORE, FP_CELL)        g_fwUserInfected_pre = CreateMultiForward("zp_user_infected_pre", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL)        g_fwUserInfected_post = CreateMultiForward("zp_user_infected_post", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL)        g_fwUserHumanized_pre = CreateMultiForward("zp_user_humanized_pre", ET_IGNORE, FP_CELL, FP_CELL)        g_fwUserHumanized_post = CreateMultiForward("zp_user_humanized_post", ET_IGNORE, FP_CELL, FP_CELL)        g_fwUserInfect_attempt = CreateMultiForward("zp_user_infect_attempt", ET_CONTINUE, FP_CELL, FP_CELL, FP_CELL)        g_fwUserHumanize_attempt = CreateMultiForward("zp_user_humanize_attempt", ET_CONTINUE, FP_CELL, FP_CELL)        g_fwExtraItemSelected = CreateMultiForward("zp_extra_item_selected", ET_CONTINUE, FP_CELL, FP_CELL)        g_fwUserUnfrozen = CreateMultiForward("zp_user_unfrozen", ET_IGNORE, FP_CELL)        g_fwUserLastZombie = CreateMultiForward("zp_user_last_zombie", ET_IGNORE, FP_CELL)        g_fwUserLastHuman = CreateMultiForward("zp_user_last_human", ET_IGNORE, FP_CELL)                // Collect random spawn points        load_spawns()                // Set a random skybox?        if (g_sky_enable)        {               new sky[32]               ArrayGetString(g_sky_names, random_num(0, ArraySize(g_sky_names) - 1), sky, charsmax(sky))               set_cvar_string("sv_skyname", sky)        }                // Disable sky lighting so it doesn't mess with our custom lighting        set_cvar_num("sv_skycolor_r", 0)        set_cvar_num("sv_skycolor_g", 0)        set_cvar_num("sv_skycolor_b", 0)                // Create the HUD Sync Objects        g_MsgSync = CreateHudSyncObj()        g_MsgSync2 = CreateHudSyncObj()                // Format mod name        formatex(g_modname, charsmax(g_modname), "Zombie Plague %s", PLUGIN_VERSION)                // Get Max Players        g_maxplayers = get_maxplayers()                // Reserved saving slots starts on maxplayers+1        db_slot_i = g_maxplayers+1                // Check if it's a CZ server        new mymod[6]        get_modname(mymod, charsmax(mymod))        if (equal(mymod, "czero")) g_czero = 1 }
  public plugin_cfg() {        // Plugin disabled?        if (!g_pluginenabled) return;                // Get configs dir        new cfgdir[32]        get_configsdir(cfgdir, charsmax(cfgdir))                // Execute config file (zombieplague.cfg)        server_cmd("exec %s/zombieplague.cfg", cfgdir)                // Prevent any more stuff from registering        g_arrays_created = false                // Save customization data        save_customization()                // Lighting task        set_task(5.0, "lighting_effects", _, _, _, "b")                // Cache CVARs after configs are loaded / call roundstart manually        set_task(0.5, "cache_cvars")        set_task(0.5, "event_round_start")        set_task(0.5, "logevent_round_start") }
  /*================================================================================  [Main Events] =================================================================================*/
  // Event Round Start public event_round_start() {        // Remove doors/lights?        set_task(0.1, "remove_stuff")                // New round starting        g_newround = true        g_endround = false        g_survround = false        g_nemround = false        g_swarmround = false        g_plagueround = false        g_modestarted = false                // Reset bought infection bombs counter        g_infbombcounter = 0        g_antidotecounter = 0        g_madnesscounter = 0                // Freezetime begins        g_freezetime = true                // Show welcome message and T-Virus notice        remove_task(TASK_WELCOMEMSG)        set_task(2.0, "welcome_msg", TASK_WELCOMEMSG)                // Set a new "Make Zombie Task"        g_time_countdown = floatround(get_pcvar_float(cvar_warmup))        remove_task(TASK_MAKEZOMBIE)        set_task(6.0, "make_zombie_task", TASK_MAKEZOMBIE)                for (new i = 1; i <= 32; i++)        {               g_menu_last_data[0] = -1               g_menu_last_data[1] = -1        } }
  // Log Event Round Start public logevent_round_start() {        // Freezetime ends        g_freezetime = false }
  // Log Event Round End public logevent_round_end() {        // Prevent this from getting called twice when restarting (bugfix)        static Float:lastendtime, Float:current_time        current_time = get_gametime()        if (current_time - lastendtime < 0.5) return;        lastendtime = current_time                // Temporarily save player stats?        if (get_pcvar_num(cvar_statssave))        {               static id, team               for (id = 1; id <= g_maxplayers; id++)               {                      // Not connected                      if (!g_isconnected[id])                             continue;                                            team = fm_cs_get_user_team(id)                                            // Not playing                      if (team == FM_CS_TEAM_SPECTATOR || team == FM_CS_TEAM_UNASSIGNED)                             continue;                                            save_stats(id)               }        }                // Round ended        g_endround = true                // Stop old tasks (if any)        remove_task(TASK_WELCOMEMSG)        remove_task(TASK_MAKEZOMBIE)                // Stop ambience sounds        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))        {               remove_task(TASK_AMBIENCESOUNDS)               ambience_sound_stop()        }                // Show HUD notice, play win sound, update team scores...        static sound[64]        if (!fnGetZombies())        {               // Human team wins               set_hudmessage(0, 0, 200, HUD_EVENT_X, HUD_EVENT_Y, 0, 0.0, 3.0, 2.0, 1.0, -1)               client_print(0, print_center, "%L", LANG_PLAYER, "WIN_HUMAN")                              // Play win sound and increase score               ArrayGetString(sound_win_humans, random_num(0, ArraySize(sound_win_humans) - 1), sound, charsmax(sound))               PlaySound(sound)               g_scorehumans++                              // Round end forward               ExecuteForward(g_fwRoundEnd, g_fwDummyResult, ZP_TEAM_HUMAN);        }        else if (!fnGetHumans())        {               // Zombie team wins               set_hudmessage(200, 0, 0, HUD_EVENT_X, HUD_EVENT_Y, 0, 0.0, 3.0, 2.0, 1.0, -1)               client_print(0, print_center, "%L", LANG_PLAYER, "WIN_ZOMBIE")                              // Play win sound and increase score               ArrayGetString(sound_win_zombies, random_num(0, ArraySize(sound_win_zombies) - 1), sound, charsmax(sound))               PlaySound(sound)               g_scorezombies++                              // Round end forward               ExecuteForward(g_fwRoundEnd, g_fwDummyResult, ZP_TEAM_ZOMBIE);        }        else        {               // No one wins               set_hudmessage(0, 200, 0, HUD_EVENT_X, HUD_EVENT_Y, 0, 0.0, 3.0, 2.0, 1.0, -1)               client_print(0, print_center, "%L", LANG_PLAYER, "WIN_NO_ONE")                              // Play win sound               ArrayGetString(sound_win_no_one, random_num(0, ArraySize(sound_win_no_one) - 1), sound, charsmax(sound))               PlaySound(sound)                              // Round end forward               ExecuteForward(g_fwRoundEnd, g_fwDummyResult, ZP_TEAM_NO_ONE);        }                // Balance the teams        balance_teams() }
  // Event Map Ended public event_intermission() {        // Remove ambience sounds task        remove_task(TASK_AMBIENCESOUNDS) }
  // BP Ammo update public event_ammo_x(id) {        // Humans only        if (g_zombie[id])               return;                // Get ammo type        static type        type = read_data(1)                // Unknown ammo type        if (type >= sizeof AMMOWEAPON)               return;                // Get weapon's id        static weapon        weapon = AMMOWEAPON[type]                // Primary and secondary only        if (MAXBPAMMO[weapon] <= 2)               return;                // Get ammo amount        static amount        amount = read_data(2)                // Unlimited BP Ammo?        if (g_survivor[id] ? get_pcvar_num(cvar_survinfammo) : get_pcvar_num(cvar_infammo))        {               if (amount < MAXBPAMMO[weapon])               {                      // The BP Ammo refill code causes the engine to send a message, but we                      // can't have that in this forward or we risk getting some recursion bugs.                      // For more info see: https://bugs.alliedmods.net...gi?id=3664                      static args[1]                      args[0] = weapon                      set_task(0.1, "refill_bpammo", id, args, sizeof args)               }        }        // Bots automatically buy ammo when needed        else if (g_isbot[id] && amount <= BUYAMMO[weapon])        {               // Task needed for the same reason as above               set_task(0.1, "clcmd_buyammo", id)        } }
  /*================================================================================  [Main Forwards] =================================================================================*/
  // Entity Spawn Forward public fw_Spawn(entity) {        // Invalid entity        if (!pev_valid(entity)) return FMRES_IGNORED;                // Get classname        new classname[32], objective[32], size = ArraySize(g_objective_ents)        pev(entity, pev_classname, classname, charsmax(classname))                // Check whether it needs to be removed        for (new i = 0; i < size; i++)        {               ArrayGetString(g_objective_ents, i, objective, charsmax(objective))                              if (equal(classname, objective))               {                      engfunc(EngFunc_RemoveEntity, entity)                      return FMRES_SUPERCEDE;               }        }                return FMRES_IGNORED; }
  // Sound Precache Forward public fw_PrecacheSound(const sound[]) {        // Block all those unneeeded hostage sounds        if (equal(sound, "hostage", 7))               return FMRES_SUPERCEDE;                return FMRES_IGNORED; }
  // Ham Player Spawn Post Forward public fw_PlayerSpawn_Post(id) {        // Not alive or didn't join a team yet        if (!is_user_alive(id) || !fm_cs_get_user_team(id))               return;                // Player spawned        g_isalive[id] = true                // Remove previous tasks        remove_task(id+TASK_SPAWN)        remove_task(id+TASK_MODEL)        remove_task(id+TASK_BLOOD)        remove_task(id+TASK_AURA)        remove_task(id+TASK_BURN)        remove_task(id+TASK_CHARGE)        remove_task(id+TASK_FLASH)        remove_task(id+TASK_NVISION)                // Spawn at a random location?        if (get_pcvar_num(cvar_randspawn)) do_random_spawn(id)                // Hide money?        if (get_pcvar_num(cvar_removemoney))               set_task(0.4, "task_hide_money", id+TASK_SPAWN)                // Respawn player if he dies because of a worldspawn kill?        if (get_pcvar_num(cvar_respawnworldspawnkill))               set_task(2.0, "respawn_player_task", id+TASK_SPAWN)                // Spawn as zombie?        if (g_respawn_as_zombie[id] && !g_newround)        {               reset_vars(id, 0) // reset player vars               zombieme(id, 0, 0, 0, 0) // make him zombie right away               return;        }                // Reset player vars        reset_vars(id, 0)                // Show custom buy menu?        if (get_pcvar_num(cvar_buycustom))               set_task(0.2, "show_menu_buy1", id+TASK_SPAWN)                // Set health and gravity        fm_set_user_health(id, get_pcvar_num(cvar_humanhp))        set_pev(id, pev_gravity, get_pcvar_float(cvar_humangravity))                // Switch to CT if spawning mid-round        if (!g_newround && fm_cs_get_user_team(id) != FM_CS_TEAM_CT) // need to change team?        {               remove_task(id+TASK_TEAM)               fm_cs_set_user_team(id, FM_CS_TEAM_CT)               fm_user_team_update(id)        }                // Custom models stuff        static currentmodel[32], tempmodel[32], already_has_model, i, iRand, size        already_has_model = false                if (g_handle_models_on_separate_ent)        {               // Set the right model               if (get_pcvar_num(cvar_adminmodelshuman) && (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS]))               {                      iRand = random_num(0, ArraySize(model_admin_human) - 1)                      ArrayGetString(model_admin_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))                      if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_admin_human, iRand))               }               else               {                      iRand = random_num(0, ArraySize(model_human) - 1)                      ArrayGetString(model_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))                      if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_human, iRand))               }                              // Set model on player model entity               fm_set_playermodel_ent(id)                              // Remove glow on player model entity               fm_set_rendering(g_ent_playermodel[id])        }        else        {               // Get current model for comparing it with the current one               fm_cs_get_user_model(id, currentmodel, charsmax(currentmodel))                              // Set the right model, after checking that we don't already have it               if (get_pcvar_num(cvar_adminmodelshuman) && (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS]))               {                      size = ArraySize(model_admin_human)                      for (i = 0; i < size; i++)                      {                             ArrayGetString(model_admin_human, i, tempmodel, charsmax(tempmodel))                             if (equal(currentmodel, tempmodel)) already_has_model = true                      }                                            if (!already_has_model)                      {                             iRand = random_num(0, size - 1)                             ArrayGetString(model_admin_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))                             if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_admin_human, iRand))                      }               }               else               {                      size = ArraySize(model_human)                      for (i = 0; i < size; i++)                      {                             ArrayGetString(model_human, i, tempmodel, charsmax(tempmodel))                             if (equal(currentmodel, tempmodel)) already_has_model = true                      }                                            if (!already_has_model)                      {                             iRand = random_num(0, size - 1)                             ArrayGetString(model_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))                             if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_human, iRand))                      }               }                              // Need to change the model?               if (!already_has_model)               {                      // An additional delay is offset at round start                      // since SVC_BAD is more likely to be triggered there                      if (g_newround)                             set_task(5.0 * g_modelchange_delay, "fm_user_model_update", id+TASK_MODEL)                      else                             fm_user_model_update(id+TASK_MODEL)               }                              // Remove glow               fm_set_rendering(id)        }                // Bots stuff        if (g_isbot[id])        {               // Turn off NVG for bots               cs_set_user_nvg(id, 0)                              // Automatically buy extra items/weapons after first zombie is chosen               if (get_pcvar_num(cvar_extraitems))               {                      if (g_newround) set_task(10.0 + get_pcvar_float(cvar_warmup), "bot_buy_extras", id+TASK_SPAWN)                      else set_task(10.0, "bot_buy_extras", id+TASK_SPAWN)               }        }                // Enable spawn protection for humans spawning mid-round        if (!g_newround && get_pcvar_float(cvar_spawnprotection) > 0.0)        {               // Do not take damage               g_nodamage[id] = true                              // Make temporarily invisible               set_pev(id, pev_effects, pev(id, pev_effects) | EF_NODRAW)                              // Set task to remove it               set_task(get_pcvar_float(cvar_spawnprotection), "remove_spawn_protection", id+TASK_SPAWN)        }                // Set the flashlight charge task to update battery status        if (g_cached_customflash)               set_task(1.0, "flashlight_charge", id+TASK_CHARGE, _, _, "b")                // Replace weapon models (bugfix)        static weapon_ent        weapon_ent = fm_cs_get_current_weapon_ent(id)        if (pev_valid(weapon_ent)) replace_weapon_models(id, cs_get_weapon_id(weapon_ent))                // Last Zombie Check        fnCheckLastZombie() }
  // Ham Player Killed Forward public fw_PlayerKilled(victim, attacker, shouldgib) {        // Player killed        g_isalive[victim] = false                // Enable dead players nightvision        set_task(0.1, "spec_nvision", victim)                // Disable nightvision when killed (bugfix)        if (get_pcvar_num(cvar_nvggive) == 0 && g_nvision[victim])        {               if (get_pcvar_num(cvar_customnvg)) remove_task(victim+TASK_NVISION)               else if (g_nvisionenabled[victim]) set_user_gnvision(victim, 0)               g_nvision[victim] = false               g_nvisionenabled[victim] = false        }                // Turn off nightvision when killed (bugfix)        if (get_pcvar_num(cvar_nvggive) == 2 && g_nvision[victim] && g_nvisionenabled[victim])        {               if (get_pcvar_num(cvar_customnvg)) remove_task(victim+TASK_NVISION)               else set_user_gnvision(victim, 0)               g_nvisionenabled[victim] = false        }                // Turn off custom flashlight when killed        if (g_cached_customflash)        {               // Turn it off               g_flashlight[victim] = false               g_flashbattery[victim] = 100                              // Remove previous tasks               remove_task(victim+TASK_CHARGE)               remove_task(victim+TASK_FLASH)        }                // Stop bleeding/burning/aura when killed        if (g_zombie[victim])        {               remove_task(victim+TASK_BLOOD)               remove_task(victim+TASK_AURA)               remove_task(victim+TASK_BURN)        }                // Nemesis explodes!        if (g_nemesis[victim])               SetHamParamInteger(3, 2)                // Get deathmatch mode status and whether the player killed himself        static selfkill        selfkill = (victim == attacker || !is_user_valid_connected(attacker)) ? true : false                // Respawn if deathmatch is enabled        if (get_pcvar_num(cvar_deathmatch))        {               // Respawn on suicide?               if (selfkill && !get_pcvar_num(cvar_respawnonsuicide))                      return;                              // Respawn if only the last human is left?               if (!get_pcvar_num(cvar_respawnafterlast) && fnGetHumans() <= 1)                      return;                              // Respawn if human/zombie/nemesis/survivor?               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)))                      return;                              // Respawn as zombie?               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))                      g_respawn_as_zombie[victim] = true                              // Set the respawn task               set_task(get_pcvar_float(cvar_spawndelay), "respawn_player_task", victim+TASK_SPAWN)        }                // Killed by a non-player entity or self killed        if (selfkill) return;                // Ignore Nemesis/Survivor Frags?        if ((g_nemesis[attacker] && get_pcvar_num(cvar_nemignorefrags)) || (g_survivor[attacker] && get_pcvar_num(cvar_survignorefrags)))               RemoveFrags(attacker, victim)                // Zombie/nemesis killed human, reward ammo packs        if (g_zombie[attacker] && (!g_nemesis[attacker] || !get_pcvar_num(cvar_nemignoreammo)))               g_ammopacks[attacker] += get_pcvar_num(cvar_ammoinfect)                // Human killed zombie, add up the extra frags for kill        if (!g_zombie[attacker] && get_pcvar_num(cvar_fragskill) > 1)               UpdateFrags(attacker, victim, get_pcvar_num(cvar_fragskill) - 1, 0, 0)                // Zombie killed human, add up the extra frags for kill        if (g_zombie[attacker] && get_pcvar_num(cvar_fragsinfect) > 1)               UpdateFrags(attacker, victim, get_pcvar_num(cvar_fragsinfect) - 1, 0, 0) }
  // Ham Player Killed Post Forward public zp_user_infected_post(id, infector)  {  if (!fnGetHumans())  { server_cmd("terminate_round timer")  }  } public fw_PlayerKilled_Post() {        // Last Zombie Check        fnCheckLastZombie() }
  // Ham Take Damage Forward public fw_TakeDamage(victim, inflictor, attacker, Float:damage, damage_type) {        // Non-player damage or self damage        if (victim == attacker || !is_user_valid_connected(attacker))               return HAM_IGNORED;                // New round starting or round ended        if (g_newround || g_endround)               return HAM_SUPERCEDE;                // Victim shouldn't take damage or victim is frozen        if (g_nodamage[victim] || g_frozen[victim])               return HAM_SUPERCEDE;                // Prevent friendly fire        if (g_zombie[attacker] == g_zombie[victim])               return HAM_SUPERCEDE;                // Attacker is human...        if (!g_zombie[attacker])        {               // Armor multiplier for the final damage on normal zombies               if (!g_nemesis[victim])               {                      damage *= get_pcvar_float(cvar_zombiearmor)                      SetHamParamFloat(4, damage)               }                              // Reward ammo packs               if (!g_survivor[attacker] || !get_pcvar_num(cvar_survignoreammo))               {                      // Store damage dealt                      g_damagedealt[attacker] += floatround(damage)                                            // Reward ammo packs for every [ammo damage] dealt                      while (g_damagedealt[attacker] > get_pcvar_num(cvar_ammodamage))                      {                             g_ammopacks[attacker]++                             g_damagedealt[attacker] -= get_pcvar_num(cvar_ammodamage)                      }               }                              return HAM_IGNORED;        }                // Attacker is zombie...                // Prevent infection/damage by HE grenade (bugfix)        if (damage_type & DMG_HEGRENADE)               return HAM_SUPERCEDE;                // Nemesis?        if (g_nemesis[attacker])        {               // Ignore nemesis damage override if damage comes from a 3rd party entity               // (to prevent this from affecting a sub-plugin's rockets e.g.)               if (inflictor == attacker)               {                      // Set nemesis damage                      SetHamParamFloat(4, get_pcvar_float(cvar_nemdamage))               }                              return HAM_IGNORED;        }                // Last human or not an infection round          if (g_survround || g_nemround || g_swarmround || g_plagueround)              return HAM_IGNORED; // human is killed                // Does human armor need to be reduced before infecting?        if (get_pcvar_num(cvar_humanarmor))        {               // Get victim armor               static Float:armor               pev(victim, pev_armorvalue, armor)                              // Block the attack if he has some               if (armor > 0.0)               {                      emit_sound(victim, CHAN_BODY, sound_armorhit, 1.0, ATTN_NORM, 0, PITCH_NORM)                      set_pev(victim, pev_armorvalue, floatmax(0.0, armor - damage))                      return HAM_SUPERCEDE;               }        }                // Infection allowed        zombieme(victim, attacker, 0, 0, 1) // turn into zombie        return HAM_SUPERCEDE; }
  // Ham Take Damage Post Forward public fw_TakeDamage_Post(victim) {        // --- Check if victim should be Pain Shock Free ---                // Check if proper CVARs are enabled        if (g_zombie[victim])        {               if (g_nemesis[victim])               {                      if (!get_pcvar_num(cvar_nempainfree)) return;               }               else               {                      switch (get_pcvar_num(cvar_zombiepainfree))                      {                             case 0: return;                             case 2: if (!g_lastzombie[victim]) return;                      }               }        }        else        {               if (g_survivor[victim])               {                      if (!get_pcvar_num(cvar_survpainfree)) return;               }               else return;        }                // Set pain shock free offset        set_pdata_float(victim, OFFSET_PAINSHOCK, 1.0, OFFSET_LINUX) }
  // Ham Trace Attack Forward public fw_TraceAttack(victim, attacker, Float:damage, Float:direction[3], tracehandle, damage_type) {        // Non-player damage or self damage        if (victim == attacker || !is_user_valid_connected(attacker))               return HAM_IGNORED;                // New round starting or round ended        if (g_newround || g_endround)               return HAM_SUPERCEDE;                // Victim shouldn't take damage or victim is frozen        if (g_nodamage[victim] || g_frozen[victim])               return HAM_SUPERCEDE;                // Prevent friendly fire        if (g_zombie[attacker] == g_zombie[victim])               return HAM_SUPERCEDE;                // Victim isn't a zombie or not bullet damage, nothing else to do here        if (!g_zombie[victim] || !(damage_type & DMG_BULLET))               return HAM_IGNORED;                // If zombie hitzones are enabled, check whether we hit an allowed one        if (get_pcvar_num(cvar_hitzones) && !g_nemesis[victim] && !(get_pcvar_num(cvar_hitzones) & (1<<get_tr2(tracehandle, TR_iHitgroup))))               return HAM_SUPERCEDE;                // Knockback disabled, nothing else to do here        if (!get_pcvar_num(cvar_knockback))               return HAM_IGNORED;                // Nemesis knockback disabled, nothing else to do here        if (g_nemesis[victim] && get_pcvar_float(cvar_nemknockback) == 0.0)               return HAM_IGNORED;                // Get whether the victim is in a crouch state        static ducking        ducking = pev(victim, pev_flags) & (FL_DUCKING | FL_ONGROUND) == (FL_DUCKING | FL_ONGROUND)                // Zombie knockback when ducking disabled        if (ducking && get_pcvar_float(cvar_knockbackducking) == 0.0)               return HAM_IGNORED;                // Get distance between players        static origin1[3], origin2[3]        get_user_origin(victim, origin1)        get_user_origin(attacker, origin2)                // Max distance exceeded        if (get_distance(origin1, origin2) > get_pcvar_num(cvar_knockbackdist))               return HAM_IGNORED;                // Get victim's velocity        static Float:velocity[3]        pev(victim, pev_velocity, velocity)                // Use damage on knockback calculation        if (get_pcvar_num(cvar_knockbackdamage))               xs_vec_mul_scalar(direction, damage, direction)                // Use weapon power on knockback calculation        if (get_pcvar_num(cvar_knockbackpower) && kb_weapon_power[g_currentweapon[attacker]] > 0.0)               xs_vec_mul_scalar(direction, kb_weapon_power[g_currentweapon[attacker]], direction)                // Apply ducking knockback multiplier        if (ducking)               xs_vec_mul_scalar(direction, get_pcvar_float(cvar_knockbackducking), direction)                // Apply zombie class/nemesis knockback multiplier        if (g_nemesis[victim])               xs_vec_mul_scalar(direction, get_pcvar_float(cvar_nemknockback), direction)        else               xs_vec_mul_scalar(direction, g_zombie_knockback[victim], direction)                // Add up the new vector        xs_vec_add(velocity, direction, direction)                // Should knockback also affect vertical velocity?        if (!get_pcvar_num(cvar_knockbackzvel))               direction[2] = velocity[2]                // Set the knockback'd victim's velocity        set_pev(victim, pev_velocity, direction)                return HAM_IGNORED; }
  // Ham Use Stationary Gun Forward public fw_UseStationary(entity, caller, activator, use_type) {        // Prevent zombies from using stationary guns        if (use_type == USE_USING && is_user_valid_connected(caller) && g_zombie[caller])               return HAM_SUPERCEDE;                return HAM_IGNORED; }
  // Ham Use Stationary Gun Post Forward public fw_UseStationary_Post(entity, caller, activator, use_type) {        // Someone stopped using a stationary gun        if (use_type == USE_STOPPED && is_user_valid_connected(caller))               replace_weapon_models(caller, g_currentweapon[caller]) // replace weapon models (bugfix) }
  // Ham Use Pushable Forward public fw_UsePushable() {        // Prevent speed bug with pushables?        if (get_pcvar_num(cvar_blockpushables))               return HAM_SUPERCEDE;                return HAM_IGNORED; }
  // Ham Weapon Touch Forward public fw_TouchWeapon(weapon, id) {        // Not a player        if (!is_user_valid_connected(id))               return HAM_IGNORED;                // Dont pickup weapons if zombie or survivor (+PODBot MM fix)        if (g_zombie[id] || (g_survivor[id] && !g_isbot[id]))               return HAM_SUPERCEDE;                return HAM_IGNORED; }
  // Ham Weapon Pickup Forward public fw_AddPlayerItem(id, weapon_ent) {        // HACK: Retrieve our custom extra ammo from the weapon        static extra_ammo        extra_ammo = pev(weapon_ent, PEV_ADDITIONAL_AMMO)                // If present        if (extra_ammo)        {               // Get weapon's id               static weaponid               weaponid = cs_get_weapon_id(weapon_ent)                              // Add to player's bpammo               ExecuteHamB(Ham_GiveAmmo, id, extra_ammo, AMMOTYPE[weaponid], MAXBPAMMO[weaponid])               set_pev(weapon_ent, PEV_ADDITIONAL_AMMO, 0)        } }
  // Ham Weapon Deploy Forward public fw_Item_Deploy_Post(weapon_ent) {        // Get weapon's owner        static owner        owner = fm_cs_get_weapon_ent_owner(weapon_ent)                // Get weapon's id        static weaponid        weaponid = cs_get_weapon_id(weapon_ent)                // Store current weapon's id for reference        g_currentweapon[owner] = weaponid                // Replace weapon models with custom ones        replace_weapon_models(owner, weaponid)                // Zombie not holding an allowed weapon for some reason        if (g_zombie[owner] && !((1<<weaponid) & ZOMBIE_ALLOWED_WEAPONS_BITSUM))        {               // Switch to knife               g_currentweapon[owner] = CSW_KNIFE               engclient_cmd(owner, "weapon_knife")        } }
  // WeaponMod bugfix //forward wpn_gi_reset_weapon(id); public wpn_gi_reset_weapon(id) {        // Replace knife model        replace_weapon_models(id, CSW_KNIFE) }
  // Client joins the game public client_putinserver(id) {        // Plugin disabled?        if (!g_pluginenabled) return;                // Player joined        g_isconnected[id] = true                // Cache player's name        get_user_name(id, g_playername[id], charsmax(g_playername[]))                // Initialize player vars        reset_vars(id, 1)                // Load player stats?        if (get_pcvar_num(cvar_statssave)) load_stats(id)                // Set some tasks for humans only        if (!is_user_bot(id))        {               // Set the custom HUD display task               set_task(1.0, "ShowHUD", id+TASK_SHOWHUD, _, _, "b")                              // Disable minmodels for clients to see zombies properly               set_task(5.0, "disable_minmodels", id)        }        else        {               // Set bot flag               g_isbot[id] = true                              // CZ bots seem to use a different "classtype" for player entities               // (or something like that) which needs to be hooked separately               if (!g_hamczbots && cvar_botquota)               {                      // Set a task to let the private data initialize                      set_task(0.1, "register_ham_czbots", id)               }        } }
  // Client leaving public fw_ClientDisconnect(id) {        // Check that we still have both humans and zombies to keep the round going        if (g_isalive[id]) check_round(id)                // Temporarily save player stats?        if (get_pcvar_num(cvar_statssave)) save_stats(id)                // Remove previous tasks        remove_task(id+TASK_TEAM)        remove_task(id+TASK_MODEL)        remove_task(id+TASK_FLASH)        remove_task(id+TASK_CHARGE)        remove_task(id+TASK_SPAWN)        remove_task(id+TASK_BLOOD)        remove_task(id+TASK_AURA)        remove_task(id+TASK_BURN)        remove_task(id+TASK_NVISION)        remove_task(id+TASK_SHOWHUD)                if (g_handle_models_on_separate_ent)        {               // Remove custom model entities               fm_remove_model_ents(id)        }                // Player left, clear cached flags        g_isconnected[id] = false        g_isbot[id] = false        g_isalive[id] = false }
  // Client left public fw_ClientDisconnect_Post() {        // Last Zombie Check        fnCheckLastZombie() }
  // Client Kill Forward public fw_ClientKill() {        // Prevent players from killing themselves?        if (get_pcvar_num(cvar_blocksuicide))               return FMRES_SUPERCEDE;                return FMRES_IGNORED; }
  // Emit Sound Forward public fw_EmitSound(id, channel, const sample[], Float:volume, Float:attn, flags, pitch) {        // Block all those unneeeded hostage sounds        if (sample[0] == 'h' && sample[1] == 'o' && sample[2] == 's' && sample[3] == 't' && sample[4] == 'a' && sample[5] == 'g' && sample[6] == 'e')               return FMRES_SUPERCEDE;                // Replace these next sounds for zombies only        if (!is_user_valid_connected(id) || !g_zombie[id])               return FMRES_IGNORED;                static sound[64]                // Zombie being hit        if (sample[7] == 'b' && sample[8] == 'h' && sample[9] == 'i' && sample[10] == 't')        {               if (g_nemesis[id])               {                      ArrayGetString(nemesis_pain, random_num(0, ArraySize(nemesis_pain) - 1), sound, charsmax(sound))                      emit_sound(id, channel, sound, volume, attn, flags, pitch)               }               else               {                      ArrayGetString(zombie_pain, random_num(0, ArraySize(zombie_pain) - 1), sound, charsmax(sound))                      emit_sound(id, channel, sound, volume, attn, flags, pitch)               }               return FMRES_SUPERCEDE;        }                // Zombie attacks with knife        if (sample[8] == 'k' && sample[9] == 'n' && sample[10] == 'i')        {               if (sample[14] == 's' && sample[15] == 'l' && sample[16] == 'a') // slash               {                      ArrayGetString(zombie_miss_slash, random_num(0, ArraySize(zombie_miss_slash) - 1), sound, charsmax(sound))                      emit_sound(id, channel, sound, volume, attn, flags, pitch)                      return FMRES_SUPERCEDE;               }               if (sample[14] == 'h' && sample[15] == 'i' && sample[16] == 't') // hit               {                      if (sample[17] == 'w') // wall                      {                             ArrayGetString(zombie_miss_wall, random_num(0, ArraySize(zombie_miss_wall) - 1), sound, charsmax(sound))                             emit_sound(id, channel, sound, volume, attn, flags, pitch)                             return FMRES_SUPERCEDE;                      }                      else                      {                             ArrayGetString(zombie_hit_normal, random_num(0, ArraySize(zombie_hit_normal) - 1), sound, charsmax(sound))                             emit_sound(id, channel, sound, volume, attn, flags, pitch)                             return FMRES_SUPERCEDE;                      }               }               if (sample[14] == 's' && sample[15] == 't' && sample[16] == 'a') // stab               {                      ArrayGetString(zombie_hit_stab, random_num(0, ArraySize(zombie_hit_stab) - 1), sound, charsmax(sound))                      emit_sound(id, channel, sound, volume, attn, flags, pitch)                      return FMRES_SUPERCEDE;               }        }                // Zombie dies        if (sample[7] == 'd' && ((sample[8] == 'i' && sample[9] == 'e') || (sample[8] == 'e' && sample[9] == 'a')))        {               ArrayGetString(zombie_die, random_num(0, ArraySize(zombie_die) - 1), sound, charsmax(sound))               emit_sound(id, channel, sound, volume, attn, flags, pitch)               return FMRES_SUPERCEDE;        }                // Zombie falls off        if (sample[10] == 'f' && sample[11] == 'a' && sample[12] == 'l' && sample[13] == 'l')        {               ArrayGetString(zombie_fall, random_num(0, ArraySize(zombie_fall) - 1), sound, charsmax(sound))               emit_sound(id, channel, sound, volume, attn, flags, pitch)               return FMRES_SUPERCEDE;        }                return FMRES_IGNORED; }
  // Forward Set ClientKey Value -prevent CS from changing player models- public fw_SetClientKeyValue(id, const infobuffer[], const key[]) {        // Block CS model changes        if (key[0] == 'm' && key[1] == 'o' && key[2] == 'd' && key[3] == 'e' && key[4] == 'l')               return FMRES_SUPERCEDE;                return FMRES_IGNORED; }
  // Forward Client User Info Changed -prevent players from changing models- public fw_ClientUserInfoChanged(id) {        // Cache player's name        get_user_name(id, g_playername[id], charsmax(g_playername[]))                if (!g_handle_models_on_separate_ent)        {               // Get current model               static currentmodel[32]               fm_cs_get_user_model(id, currentmodel, charsmax(currentmodel))                              // If they're different, set model again               if (!equal(currentmodel, g_playermodel[id]) && !task_exists(id+TASK_MODEL))                      fm_cs_set_user_model(id+TASK_MODEL)        } }
  // Forward Get Game Description public fw_GetGameDescription() {        // Return the mod name so it can be easily identified        forward_return(FMV_STRING, g_modname)                return FMRES_SUPERCEDE; }
  // Forward Set Model public fw_SetModel(entity, const model[]) {        // We don't care        if (strlen(model) < 8)               return;                // Remove weapons?        if (get_pcvar_float(cvar_removedropped) > 0.0)        {               // Get entity's classname               static classname[10]               pev(entity, pev_classname, classname, charsmax(classname))                              // Check if it's a weapon box               if (equal(classname, "weaponbox"))               {                      // They get automatically removed when thinking                      set_pev(entity, pev_nextthink, get_gametime() + get_pcvar_float(cvar_removedropped))                      return;               }        }                // Narrow down our matches a bit        if (model[7] != 'w' || model[8] != '_')               return;                // Get damage time of grenade        static Float:dmgtime        pev(entity, pev_dmgtime, dmgtime)                // Grenade not yet thrown        if (dmgtime == 0.0)               return;                // Get whether grenade's owner is a zombie        if (g_zombie[pev(entity, pev_owner)])        {               if (model[9] == 'h' && model[10] == 'e' && get_pcvar_num(cvar_extrainfbomb)) // Infection Bomb               {                      // Give it a glow                      fm_set_rendering(entity, kRenderFxGlowShell, 0, 200, 0, kRenderNormal, 16);                                            // And a colored trail                      message_begin(MSG_BROADCAST, SVC_TEMPENTITY)                      write_byte(TE_BEAMFOLLOW) // TE id                      write_short(entity) // entity                      write_short(g_trailSpr) // sprite                      write_byte(10) // life                      write_byte(10) // width                      write_byte(0) // r                      write_byte(200) // g                      write_byte(0) // b                      write_byte(200) // brightness                      message_end()                                            // Set grenade type on the thrown grenade entity                      set_pev(entity, PEV_NADE_TYPE, NADE_TYPE_INFECTION)               }        }        else if (model[9] == 'h' && model[10] == 'e' && get_pcvar_num(cvar_firegrenades)) // Napalm Grenade        {               // Give it a glow               fm_set_rendering(entity, kRenderFxGlowShell, 200, 0, 0, kRenderNormal, 16);                              // And a colored trail               message_begin(MSG_BROADCAST, SVC_TEMPENTITY)               write_byte(TE_BEAMFOLLOW) // TE id               write_short(entity) // entity               write_short(g_trailSpr) // sprite               write_byte(10) // life               write_byte(10) // width               write_byte(200) // r               write_byte(0) // g               write_byte(0) // b               write_byte(200) // brightness               message_end()                              // Set grenade type on the thrown grenade entity               set_pev(entity, PEV_NADE_TYPE, NADE_TYPE_NAPALM)        }        else if (model[9] == 'f' && model[10] == 'l' && get_pcvar_num(cvar_frostgrenades)) // Frost Grenade        {               // Give it a glow               fm_set_rendering(entity, kRenderFxGlowShell, 0, 100, 200, kRenderNormal, 16);                              // And a colored trail               message_begin(MSG_BROADCAST, SVC_TEMPENTITY)               write_byte(TE_BEAMFOLLOW) // TE id               write_short(entity) // entity               write_short(g_trailSpr) // sprite               write_byte(10) // life               write_byte(10) // width               write_byte(0) // r               write_byte(100) // g               write_byte(200) // b               write_byte(200) // brightness               message_end()                              // Set grenade type on the thrown grenade entity               set_pev(entity, PEV_NADE_TYPE, NADE_TYPE_FROST)        }        else if (model[9] == 's' && model[10] == 'm' && get_pcvar_num(cvar_flaregrenades)) // Flare        {               // Build flare's color               static rgb[3]               switch (get_pcvar_num(cvar_flarecolor))               {                      case 0: // white                      {                             rgb[0] = 255 // r                             rgb[1] = 255 // g                             rgb[2] = 255 // b                      }                      case 1: // red                      {                             rgb[0] = random_num(50,255) // r                             rgb[1] = 0 // g                             rgb[2] = 0 // b                      }                      case 2: // green                      {                             rgb[0] = 0 // r                             rgb[1] = random_num(50,255) // g                             rgb[2] = 0 // b                      }                      case 3: // blue                      {                             rgb[0] = 0 // r                             rgb[1] = 0 // g                             rgb[2] = random_num(50,255) // b                      }                      case 4: // random (all colors)                      {                             rgb[0] = random_num(50,200) // r                             rgb[1] = random_num(50,200) // g                             rgb[2] = random_num(50,200) // b                      }                      case 5: // random (r,g,b)                      {                             switch (random_num(1, 3))                             {                                    case 1: // red                                    {                                           rgb[0] = random_num(50,255) // r                                           rgb[1] = 0 // g                                           rgb[2] = 0 // b                                    }                                    case 2: // green                                    {                                           rgb[0] = 0 // r                                           rgb[1] = random_num(50,255) // g                                           rgb[2] = 0 // b                                    }                                    case 3: // blue                                    {                                           rgb[0] = 0 // r                                           rgb[1] = 0 // g                                           rgb[2] = random_num(50,255) // b                                    }                             }                      }               }                              // Give it a glow               fm_set_rendering(entity, kRenderFxGlowShell, rgb[0], rgb[1], rgb[2], kRenderNormal, 16);                              // And a colored trail               message_begin(MSG_BROADCAST, SVC_TEMPENTITY)               write_byte(TE_BEAMFOLLOW) // TE id               write_short(entity) // entity               write_short(g_trailSpr) // sprite               write_byte(10) // life               write_byte(10) // width               write_byte(rgb[0]) // r               write_byte(rgb[1]) // g               write_byte(rgb[2]) // b               write_byte(200) // brightness               message_end()                              // Set grenade type on the thrown grenade entity               set_pev(entity, PEV_NADE_TYPE, NADE_TYPE_FLARE)                              // Set flare color on the thrown grenade entity               set_pev(entity, PEV_FLARE_COLOR, rgb)        } }
  // Ham Grenade Think Forward public fw_ThinkGrenade(entity) {        // Invalid entity        if (!pev_valid(entity)) return HAM_IGNORED;                // Get damage time of grenade        static Float:dmgtime, Float:current_time        pev(entity, pev_dmgtime, dmgtime)        current_time = get_gametime()                // Check if it's time to go off        if (dmgtime > current_time)               return HAM_IGNORED;                // Check if it's one of our custom nades        switch (pev(entity, PEV_NADE_TYPE))        {               case NADE_TYPE_INFECTION: // Infection Bomb               {                      infection_explode(entity)                      return HAM_SUPERCEDE;               }               case NADE_TYPE_NAPALM: // Napalm Grenade               {                      fire_explode(entity)                      return HAM_SUPERCEDE;               }               case NADE_TYPE_FROST: // Frost Grenade               {                      frost_explode(entity)                      return HAM_SUPERCEDE;               }               case NADE_TYPE_FLARE: // Flare               {                      // Get its duration                      static duration                      duration = pev(entity, PEV_FLARE_DURATION)                                            // Already went off, do lighting loop for the duration of PEV_FLARE_DURATION                      if (duration > 0)                      {                             // Check whether this is the last loop                             if (duration == 1)                             {                                    // Get rid of the flare entity                                    engfunc(EngFunc_RemoveEntity, entity)                                    return HAM_SUPERCEDE;                             }                                                          // Light it up!                             flare_lighting(entity, duration)                                                          // Set time for next loop                             set_pev(entity, PEV_FLARE_DURATION, --duration)                             set_pev(entity, pev_dmgtime, current_time + 5.0)                      }                      // Light up when it's stopped on ground                      else if ((pev(entity, pev_flags) & FL_ONGROUND) && fm_get_speed(entity) < 10)                      {                             // Flare sound                             static sound[64]                             ArrayGetString(grenade_flare, random_num(0, ArraySize(grenade_flare) - 1), sound, charsmax(sound))                             emit_sound(entity, CHAN_WEAPON, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)                                                          // Set duration and start lightning loop on next think                             set_pev(entity, PEV_FLARE_DURATION, 1 + get_pcvar_num(cvar_flareduration)/5)                             set_pev(entity, pev_dmgtime, current_time + 0.1)                      }                      else                      {                             // Delay explosion until we hit ground                             set_pev(entity, pev_dmgtime, current_time + 0.5)                      }               }        }                return HAM_IGNORED; }
  // Forward CmdStart public fw_CmdStart(id, handle) {        // Not alive        if (!g_isalive[id])               return;                // This logic looks kinda weird, but it should work in theory...        // p = g_zombie[id], q = g_survivor[id], r = g_cached_customflash        // ?p v q v (殆 ^ r)) <==> 殆 ^ 段 ^ (p v 毒)        if (!g_zombie[id] && !g_survivor[id] && (g_zombie[id] || !g_cached_customflash))               return;                // Check if it's a flashlight impulse        if (get_uc(handle, UC_Impulse) != IMPULSE_FLASHLIGHT)               return;                // Block it I say!        set_uc(handle, UC_Impulse, 0)                // Should human's custom flashlight be turned on?        if (!g_zombie[id] && !g_survivor[id] && g_flashbattery[id] > 2 && get_gametime() - g_lastflashtime[id] > 1.2)        {               // Prevent calling flashlight too quickly (bugfix)               g_lastflashtime[id] = get_gametime()                              // Toggle custom flashlight               g_flashlight[id] = !(g_flashlight[id])                              // Play flashlight toggle sound               emit_sound(id, CHAN_ITEM, sound_flashlight, 1.0, ATTN_NORM, 0, PITCH_NORM)                              // Update flashlight status on the HUD               message_begin(MSG_ONE, g_msgFlashlight, _, id)               write_byte(g_flashlight[id]) // toggle               write_byte(g_flashbattery[id]) // battery               message_end()                              // Remove previous tasks               remove_task(id+TASK_CHARGE)               remove_task(id+TASK_FLASH)                              // Set the flashlight charge task               set_task(1.0, "flashlight_charge", id+TASK_CHARGE, _, _, "b")                              // Call our custom flashlight task if enabled               if (g_flashlight[id]) set_task(0.1, "set_user_flashlight", id+TASK_FLASH, _, _, "b")        } }
  // Forward Player PreThink public fw_PlayerPreThink(id) {        // Not alive        if (!g_isalive[id])               return;                // If player view any menu then store it        static view, menu, newmenu, menupage        view = player_menu_info(id, menu, newmenu, menupage)        if (view)        {               if (g_menu_last_data[id][0] == 8)                      g_menu_last_data[id][1] = menupage        }                // Silent footsteps for zombies?        if (g_cached_zombiesilent && g_zombie[id] && !g_nemesis[id])               set_pev(id, pev_flTimeStepSound, STEPTIME_SILENT)                // Set Player MaxSpeed        if (g_frozen[id])        {               set_pev(id, pev_velocity, Float:{0.0,0.0,0.0}) // stop motion               set_pev(id, pev_maxspeed, 1.0) // prevent from moving               return; // shouldn't leap while frozen        }        else if (g_freezetime)        {               return; // shouldn't leap while in freezetime        }        else        {               if (g_zombie[id])               {                      if (g_nemesis[id])                             set_pev(id, pev_maxspeed, g_cached_nemspd)                      else                             set_pev(id, pev_maxspeed, g_zombie_spd[id])               }               else               {                      if (g_survivor[id])                             set_pev(id, pev_maxspeed, g_cached_survspd)                      else                             set_pev(id, pev_maxspeed, g_cached_humanspd)               }        }                // --- Check if player should leap ---                // Check if proper CVARs are enabled and retrieve leap settings        static Float:cooldown, Float:current_time        if (g_zombie[id])        {               if (g_nemesis[id])               {                      if (!g_cached_leapnemesis) return;                      cooldown = g_cached_leapnemesiscooldown               }               else               {                      switch (g_cached_leapzombies)                      {                             case 0: return;                             case 2: if (!g_firstzombie[id]) return;                             case 3: if (!g_lastzombie[id]) return;                      }                      cooldown = g_cached_leapzombiescooldown               }        }        else        {               if (g_survivor[id])               {                      if (!g_cached_leapsurvivor) return;                      cooldown = g_cached_leapsurvivorcooldown               }               else return;        }                current_time = get_gametime()                // Cooldown not over yet        if (current_time - g_lastleaptime[id] < cooldown)               return;                // Not doing a longjump (don't perform check for bots, they leap automatically)        if (!g_isbot[id] && !(pev(id, pev_button) & (IN_JUMP | IN_DUCK) == (IN_JUMP | IN_DUCK)))               return;                // Not on ground or not enough speed        if (!(pev(id, pev_flags) & FL_ONGROUND) || fm_get_speed(id) < 80)               return;                static Float:velocity[3]                // Make velocity vector        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)                // Set custom height        velocity[2] = g_survivor[id] ? get_pcvar_float(cvar_leapsurvivorheight) : g_nemesis[id] ? get_pcvar_float(cvar_leapnemesisheight) : get_pcvar_float(cvar_leapzombiesheight)                // Apply the new velocity        set_pev(id, pev_velocity, velocity)                // Update last leap time        g_lastleaptime[id] = current_time }
  /*================================================================================  [Client Commands] =================================================================================*/
  // Say "/zpmenu" public clcmd_saymenu(id) {        show_menu_game(id) // show game menu }
  // Say "/unstuck" public clcmd_sayunstuck(id) {        menu_game(id, 3) // try to get unstuck }
  // Nightvision toggle public clcmd_nightvision(id) {        if (g_nvision[id])        {               // Enable-disable               g_nvisionenabled[id] = !(g_nvisionenabled[id])                              // Custom nvg?               if (get_pcvar_num(cvar_customnvg))               {                      remove_task(id+TASK_NVISION)                      if (g_nvisionenabled[id]) set_task(0.1, "set_user_nvision", id+TASK_NVISION, _, _, "b")               }               else                      set_user_gnvision(id, g_nvisionenabled[id])        }                return PLUGIN_HANDLED; }
  // Weapon Drop public clcmd_drop(id) {        // Survivor should stick with its weapon        if (g_survivor[id])               return PLUGIN_HANDLED;                return PLUGIN_CONTINUE; }
  // Buy BP Ammo public clcmd_buyammo(id) {        // Not alive or infinite ammo setting enabled        if (!g_isalive[id] || get_pcvar_num(cvar_infammo))               return PLUGIN_HANDLED;                // Not human        if (g_zombie[id])        {               zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_HUMAN_ONLY")               return PLUGIN_HANDLED;        }                // Not enough ammo packs        if (g_ammopacks[id] < 1)        {               zp_colored_print(id, "^x04[ZP]^x01 %L", id, "NOT_ENOUGH_AMMO")               return PLUGIN_HANDLED;        }                // Get user weapons        static weapons[32], num, i, currentammo, weaponid, refilled        num = 0 // reset passed weapons count (bugfix)        refilled = false        get_user_weapons(id, weapons, num)                // Loop through them and give the right ammo type        for (i = 0; i < num; i++)        {               // Prevents re-indexing the array               weaponid = weapons                              // Primary and secondary only               if (MAXBPAMMO[weaponid] > 2)               {                      // Get current ammo of the weapon                      currentammo = cs_get_user_bpammo(id, weaponid)                                            // Give additional ammo                      ExecuteHamB(Ham_GiveAmmo, id, BUYAMMO[weaponid], AMMOTYPE[weaponid], MAXBPAMMO[weaponid])                                            // Check whether we actually refilled the weapon's ammo                      if (cs_get_user_bpammo(id, weaponid) - currentammo > 0) refilled = true               }        }                // Weapons already have full ammo        if (!refilled) return PLUGIN_HANDLED;                // Deduce ammo packs, play clip purchase sound, and notify player        g_ammopacks[id]--        emit_sound(id, CHAN_ITEM, sound_buyammo, 1.0, ATTN_NORM, 0, PITCH_NORM)        zp_colored_print(id, "^x04[ZP]^x01 %L", id, "AMMO_BOUGHT")                return PLUGIN_HANDLED; }
  // Block Team Change public clcmd_changeteam(id) {        static team        team = fm_cs_get_user_team(id)                // Unless it's a spectator joining the game        if (team == FM_CS_TEAM_SPECTATOR || team == FM_CS_TEAM_UNASSIGNED)               return PLUGIN_CONTINUE;                // Pressing 'M' (chooseteam) ingame should show the main menu instead        show_menu_game(id)        return PLUGIN_HANDLED; }
  /*================================================================================  [Menus] =================================================================================*/
  // Game Menu show_menu_game(id) {        static menu[250], len, userflags        len = 0        userflags = get_user_flags(id)                // Title        len += formatex(menu[len], charsmax(menu) - len, "\y%s^n^n", g_modname)                // 1. Buy weapons        if (get_pcvar_num(cvar_buycustom) && !(WPN_MAXIDS == 0 && ArraySize(g_secondary_items) == 0))               len += formatex(menu[len], charsmax(menu) - len, "\r1.\w %L^n", id, "MENU_BUY")        else               len += formatex(menu[len], charsmax(menu) - len, "\d1. %L^n", id, "MENU_BUY")                // 2. Extra items        if (get_pcvar_num(cvar_extraitems) && g_isalive[id])               len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L^n", id, "MENU_EXTRABUY")        else               len += formatex(menu[len], charsmax(menu) - len, "\d2. %L^n", id, "MENU_EXTRABUY")                // 3. Zombie class        if (get_pcvar_num(cvar_zclasses))               len += formatex(menu[len], charsmax(menu) - len, "\r3.\w %L^n", id,"MENU_ZCLASS")        else               len += formatex(menu[len], charsmax(menu) - len, "\d3. %L^n", id,"MENU_ZCLASS")                // 4. Unstuck        if (g_isalive[id])               len += formatex(menu[len], charsmax(menu) - len, "\r4.\w %L^n", id, "MENU_UNSTUCK")        else               len += formatex(menu[len], charsmax(menu) - len, "\d4. %L^n", id, "MENU_UNSTUCK")                // 5. Help        len += formatex(menu[len], charsmax(menu) - len, "\r5.\w %L^n^n", id, "MENU_INFO")                // 6. Join spec        if (!g_isalive[id] || !get_pcvar_num(cvar_blocksuicide) || (userflags & g_access_flag[ACCESS_ADMIN_MENU]))               len += formatex(menu[len], charsmax(menu) - len, "\r6.\w %L^n^n", id, "MENU_SPECTATOR")        else               len += formatex(menu[len], charsmax(menu) - len, "\d6. %L^n^n", id, "MENU_SPECTATOR")                // 9. Admin menu        if (userflags & g_access_flag[ACCESS_ADMIN_MENU])               len += formatex(menu[len], charsmax(menu) - len, "\r9.\w %L", id, "MENU_ADMIN")        else               len += formatex(menu[len], charsmax(menu) - len, "\d9. %L", id, "MENU_ADMIN")                // 0. Exit        len += formatex(menu[len], charsmax(menu) - len, "^n^n\r0.\w %L", id, "MENU_EXIT")                show_menu(id, KEYSMENU, menu, -1, "Game Menu")                g_menu_last_data[id][0] = 1 }
  // Buy Menu 1 public show_menu_buy1(taskid) {        // Get player's id        static id        (taskid > g_maxplayers) ? (id = ID_SPAWN) : (id = taskid);                // Zombies or survivors get no guns        if (!g_isalive[id] || g_zombie[id] || g_survivor[id])               return;                // Bots pick their weapons randomly / Random weapons setting enabled        if (get_pcvar_num(cvar_randweapons) || g_isbot[id])        {               // Check primary weapon items not empty               if (WPN_MAXIDS > 0)                      buy_primary_weapon(id, random_num(0, ArraySize(g_primary_items) - 1))                              if (ArraySize(g_secondary_items) > 0)                      menu_buy2(id, random_num(0, ArraySize(g_secondary_items) - 1))                              return;        }                // Automatic selection enabled for player and menu called on spawn event        if (WPN_AUTO_ON && taskid > g_maxplayers)        {               // Check primary weapon items not empty               if (WPN_MAXIDS > 0)                      buy_primary_weapon(id, WPN_AUTO_PRI)                              if (ArraySize(g_secondary_items) > 0)                      menu_buy2(id, WPN_AUTO_SEC)                              return;        }                // If primary weapon items has nothing then show secondary weapon menu        if (WPN_MAXIDS == 0)        {               show_menu_buy2(id)               return;        }                static menu[300], len, weap, maxloops        len = 0        maxloops = min(WPN_STARTID+7, WPN_MAXIDS)                // Title        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))                // 1-7. Weapon List        for (weap = WPN_STARTID; weap < maxloops; weap++)               len += formatex(menu[len], charsmax(menu) - len, "\r%d.\w %s^n", weap-WPN_STARTID+1, WEAPONNAMES[ArrayGetCell(g_primary_weaponids, weap)])                // 8. Auto Select        len += formatex(menu[len], charsmax(menu) - len, "^n\r8.\w %L \y[%L]", id, "MENU_AUTOSELECT", id, (WPN_AUTO_ON) ? "MOTD_ENABLED" : "MOTD_DISABLED")                // 9. Next/Back - 0. Exit        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")                show_menu(id, KEYSMENU, menu, -1, "Buy Menu 1")                g_menu_last_data[id][0] = 2 }
  // Buy Menu 2 show_menu_buy2(id) {        if (ArraySize(g_secondary_items) == 0)               return;                static menu[250], len, weap, maxloops        len = 0        maxloops = ArraySize(g_secondary_items)                // Title        len += formatex(menu[len], charsmax(menu) - len, "\y%L^n", id, "MENU_BUY2_TITLE")                // 1-6. Weapon List        for (weap = 0; weap < maxloops; weap++)               len += formatex(menu[len], charsmax(menu) - len, "^n\r%d.\w %s", weap+1, WEAPONNAMES[ArrayGetCell(g_secondary_weaponids, weap)])                // 8. Auto Select        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")                // 0. Exit        len += formatex(menu[len], charsmax(menu) - len, "^n^n\r0.\w %L", id, "MENU_EXIT")                show_menu(id, KEYSMENU, menu, -1, "Buy Menu 2")                g_menu_last_data[id][0] = 3 }
  // Extra Items Menu show_menu_extras(id) {        static menuid, menu[128], item, team, buffer[32]                // Title        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")        menuid = menu_create(menu, "menu_extras")                // Item List        for (item = 0; item < g_extraitem_i; item++)        {               // Retrieve item's team               team = ArrayGetCell(g_extraitem_team, item)                              // Item not available to player's team/class               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)))                      continue;                              // Check if it's one of the hardcoded items, check availability, set translated caption               switch (item)               {                      case EXTRA_NVISION:                      {                             if (!get_pcvar_num(cvar_extranvision)) continue;                             formatex(buffer, charsmax(buffer), "%L", id, "MENU_EXTRA1")                      }                      case EXTRA_ANTIDOTE:                      {                             if (!get_pcvar_num(cvar_extraantidote) || g_antidotecounter >= get_pcvar_num(cvar_antidotelimit)) continue;                             formatex(buffer, charsmax(buffer), "%L", id, "MENU_EXTRA2")                      }                      case EXTRA_MADNESS:                      {                             if (!get_pcvar_num(cvar_extramadness) || g_madnesscounter >= get_pcvar_num(cvar_madnesslimit)) continue;                             formatex(buffer, charsmax(buffer), "%L", id, "MENU_EXTRA3")                      }                      case EXTRA_INFBOMB:                      {                             if (!get_pcvar_num(cvar_extrainfbomb) || g_infbombcounter >= get_pcvar_num(cvar_infbomblimit)) continue;                             formatex(buffer, charsmax(buffer), "%L", id, "MENU_EXTRA4")                      }                      default:                      {                             if (item >= EXTRA_WEAPONS_STARTID && item <= EXTRAS_CUSTOM_STARTID-1 && !get_pcvar_num(cvar_extraweapons)) continue;                             ArrayGetString(g_extraitem_name, item, buffer, charsmax(buffer))                      }               }                              // Add Item Name and Cost               formatex(menu, charsmax(menu), "%s \y%d %L", buffer, ArrayGetCell(g_extraitem_cost, item), id, "AMMO_PACKS2")               buffer[0] = item               buffer[1] = 0               menu_additem(menuid, menu, buffer)        }                // No items to display?        if (menu_items(menuid) <= 0)        {               zp_colored_print(id, "^x04[ZP]^x01 %L", id ,"CMD_NOT_EXTRAS")               menu_destroy(menuid)               return;        }                // Back - Next - Exit        formatex(menu, charsmax(menu), "%L", id, "MENU_BACK")        menu_setprop(menuid, MPROP_BACKNAME, menu)        formatex(menu, charsmax(menu), "%L", id, "MENU_NEXT")        menu_setprop(menuid, MPROP_NEXTNAME, menu)        formatex(menu, charsmax(menu), "%L", id, "MENU_EXIT")        menu_setprop(menuid, MPROP_EXITNAME, menu)                menu_display(id, menuid)                g_menu_last_data[id][0] = 4 }
  // Zombie Class Menu public show_menu_zclass(id) {        // Player disconnected        if (!g_isconnected[id])               return;                // Bots pick their zombie class randomly        if (g_isbot[id])        {               g_zombieclassnext[id] = random_num(0, g_zclass_i - 1)               return;        }                static menuid, menu[128], class, buffer[32], buffer2[32]                // Title        formatex(menu, charsmax(menu), "%L\r", id, "MENU_ZCLASS_TITLE")        menuid = menu_create(menu, "menu_zclass")                // Class List        for (class = 0; class < g_zclass_i; class++)        {               // Retrieve name and info               ArrayGetString(g_zclass_name, class, buffer, charsmax(buffer))               ArrayGetString(g_zclass_info, class, buffer2, charsmax(buffer2))                              // Add to menu               if (class == g_zombieclassnext[id])                      formatex(menu, charsmax(menu), "\d%s %s", buffer, buffer2)               else                      formatex(menu, charsmax(menu), "%s \y%s", buffer, buffer2)                              buffer[0] = class               buffer[1] = 0               menu_additem(menuid, menu, buffer)        }                // Back - Next - Exit        formatex(menu, charsmax(menu), "%L", id, "MENU_BACK")        menu_setprop(menuid, MPROP_BACKNAME, menu)        formatex(menu, charsmax(menu), "%L", id, "MENU_NEXT")        menu_setprop(menuid, MPROP_NEXTNAME, menu)        formatex(menu, charsmax(menu), "%L", id, "MENU_EXIT")        menu_setprop(menuid, MPROP_EXITNAME, menu)                menu_display(id, menuid)                g_menu_last_data[id][0] = 5 }
  // Help Menu show_menu_info(id) {        static menu[150]                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")        show_menu(id, KEYSMENU, menu, -1, "Mod Info")                g_menu_last_data[id][0] = 6 }
  // Admin Menu show_menu_admin(id) {        static menu[250], len, userflags        len = 0        userflags = get_user_flags(id)                // Title        len += formatex(menu[len], charsmax(menu) - len, "\y%L^n^n", id, "MENU_ADMIN_TITLE")                // 1. Zombiefy/Humanize command        if (userflags & (g_access_flag[ACCESS_MODE_INFECTION] | g_access_flag[ACCESS_MAKE_ZOMBIE] | g_access_flag[ACCESS_MAKE_HUMAN]))               len += formatex(menu[len], charsmax(menu) - len, "\r1.\w %L^n", id, "MENU_ADMIN1")        else               len += formatex(menu[len], charsmax(menu) - len, "\d1. %L^n", id, "MENU_ADMIN1")                // 2. Nemesis command        if (userflags & (g_access_flag[ACCESS_MODE_NEMESIS] | g_access_flag[ACCESS_MAKE_NEMESIS]))               len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L^n", id, "MENU_ADMIN2")        else               len += formatex(menu[len], charsmax(menu) - len, "\d2. %L^n", id, "MENU_ADMIN2")                // 3. Survivor command        if (userflags & (g_access_flag[ACCESS_MODE_SURVIVOR] | g_access_flag[ACCESS_MAKE_SURVIVOR]))               len += formatex(menu[len], charsmax(menu) - len, "\r3.\w %L^n", id, "MENU_ADMIN3")        else               len += formatex(menu[len], charsmax(menu) - len, "\d3. %L^n", id, "MENU_ADMIN3")                // 4. Respawn command        if (userflags & g_access_flag[ACCESS_RESPAWN_PLAYERS])               len += formatex(menu[len], charsmax(menu) - len, "\r4.\w %L^n", id, "MENU_ADMIN4")        else               len += formatex(menu[len], charsmax(menu) - len, "\d4. %L^n", id, "MENU_ADMIN4")                // 5. Swarm mode command        if ((userflags & g_access_flag[ACCESS_MODE_SWARM]) && allowed_swarm())               len += formatex(menu[len], charsmax(menu) - len, "\r5.\w %L^n", id, "MENU_ADMIN5")        else               len += formatex(menu[len], charsmax(menu) - len, "\d5. %L^n", id, "MENU_ADMIN5")                // 6. Multi infection command        if ((userflags & g_access_flag[ACCESS_MODE_MULTI]) && allowed_multi())               len += formatex(menu[len], charsmax(menu) - len, "\r6.\w %L^n", id, "MENU_ADMIN6")        else               len += formatex(menu[len], charsmax(menu) - len, "\d6. %L^n", id, "MENU_ADMIN6")                // 7. Plague mode command        if ((userflags & g_access_flag[ACCESS_MODE_PLAGUE]) && allowed_plague())               len += formatex(menu[len], charsmax(menu) - len, "\r7.\w %L^n", id, "MENU_ADMIN7")        else               len += formatex(menu[len], charsmax(menu) - len, "\d7. %L^n", id, "MENU_ADMIN7")                // 0. Exit        len += formatex(menu[len], charsmax(menu) - len, "^n\r0.\w %L", id, "MENU_EXIT")                show_menu(id, KEYSMENU, menu, -1, "Admin Menu")                g_menu_last_data[id][0] = 7 }
  // Player List Menu show_menu_player_list(id) {        static menuid, menu[128], player, userflags, buffer[2]        userflags = get_user_flags(id)                // Title        switch (PL_ACTION)        {               case ACTION_ZOMBIEFY_HUMANIZE: formatex(menu, charsmax(menu), "%L\r", id, "MENU_ADMIN1")               case ACTION_MAKE_NEMESIS: formatex(menu, charsmax(menu), "%L\r", id, "MENU_ADMIN2")               case ACTION_MAKE_SURVIVOR: formatex(menu, charsmax(menu), "%L\r", id, "MENU_ADMIN3")               case ACTION_RESPAWN_PLAYER: formatex(menu, charsmax(menu), "%L\r", id, "MENU_ADMIN4")        }        menuid = menu_create(menu, "menu_player_list")                // Player List        for (player = 0; player <= g_maxplayers; player++)        {               // Skip if not connected               if (!g_isconnected[player])                      continue;                              // Format text depending on the action to take               switch (PL_ACTION)               {                      case ACTION_ZOMBIEFY_HUMANIZE: // Zombiefy/Humanize command                      {                             if (g_zombie[player])                             {                                    if (allowed_human(player) && (userflags & g_access_flag[ACCESS_MAKE_HUMAN]))                                           formatex(menu, charsmax(menu), "%s \r[%L]", g_playername[player], id, g_nemesis[player] ? "CLASS_NEMESIS" : "CLASS_ZOMBIE")                                    else                                           formatex(menu, charsmax(menu), "\d%s [%L]", g_playername[player], id, g_nemesis[player] ? "CLASS_NEMESIS" : "CLASS_ZOMBIE")                             }                             else                             {                                    if (allowed_zombie(player) && (g_newround ? (userflags & g_access_flag[ACCESS_MODE_INFECTION]) : (userflags & g_access_flag[ACCESS_MAKE_ZOMBIE])))                                           formatex(menu, charsmax(menu), "%s \y[%L]", g_playername[player], id, g_survivor[player] ? "CLASS_SURVIVOR" : "CLASS_HUMAN")                                    else                                           formatex(menu, charsmax(menu), "\d%s [%L]", g_playername[player], id, g_survivor[player] ? "CLASS_SURVIVOR" : "CLASS_HUMAN")                             }                      }                      case ACTION_MAKE_NEMESIS: // Nemesis command                      {                             if (allowed_nemesis(player) && (g_newround ? (userflags & g_access_flag[ACCESS_MODE_NEMESIS]) : (userflags & g_access_flag[ACCESS_MAKE_NEMESIS])))                             {                                    if (g_zombie[player])                                           formatex(menu, charsmax(menu), "%s \r[%L]", g_playername[player], id, g_nemesis[player] ? "CLASS_NEMESIS" : "CLASS_ZOMBIE")                                    else                                           formatex(menu, charsmax(menu), "%s \y[%L]", g_playername[player], id, g_survivor[player] ? "CLASS_SURVIVOR" : "CLASS_HUMAN")                             }                             else                                    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")                      }                      case ACTION_MAKE_SURVIVOR: // Survivor command                      {                             if (allowed_survivor(player) && (g_newround ? (userflags & g_access_flag[ACCESS_MODE_SURVIVOR]) : (userflags & g_access_flag[ACCESS_MAKE_SURVIVOR])))                             {                                    if (g_zombie[player])                                           formatex(menu, charsmax(menu), "%s \r[%L]", g_playername[player], id, g_nemesis[player] ? "CLASS_NEMESIS" : "CLASS_ZOMBIE")                                    else                                           formatex(menu, charsmax(menu), "%s \y[%L]", g_playername[player], id, g_survivor[player] ? "CLASS_SURVIVOR" : "CLASS_HUMAN")                             }                             else                                    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")                      }                      case ACTION_RESPAWN_PLAYER: // Respawn command                      {                             if (allowed_respawn(player) && (userflags & g_access_flag[ACCESS_RESPAWN_PLAYERS]))                                    formatex(menu, charsmax(menu), "%s", g_playername[player])                             else                                    formatex(menu, charsmax(menu), "\d%s", g_playername[player])                      }               }                              // Add player               buffer[0] = player               buffer[1] = 0               menu_additem(menuid, menu, buffer)        }                // Back - Next - Exit        formatex(menu, charsmax(menu), "%L", id, "MENU_BACK")        menu_setprop(menuid, MPROP_BACKNAME, menu)        formatex(menu, charsmax(menu), "%L", id, "MENU_NEXT")        menu_setprop(menuid, MPROP_NEXTNAME, menu)        formatex(menu, charsmax(menu), "%L", id, "MENU_EXIT")        menu_setprop(menuid, MPROP_EXITNAME, menu)                if (g_menu_last_data[id][0] == 8)               menu_display(id, menuid, g_menu_last_data[id][1])        else               menu_display(id, menuid)                g_menu_last_data[id][0] = 8 }
  /*================================================================================  [Menu Handlers] =================================================================================*/
  // Game Menu public menu_game(id, key) {        switch (key)        {               case 0: // Buy Weapons               {                      // Custom buy menus enabled?                      if (get_pcvar_num(cvar_buycustom))                      {                             // Check primary and secondary weapons are not all empty                             if (WPN_MAXIDS > 0 || ArraySize(g_secondary_items) > 0)                             {                                    // Disable the remember selection setting                                    WPN_AUTO_ON = 0                                    zp_colored_print(id, "^x04[ZP]^x01 %L", id, "BUY_ENABLED")                                                                        // Show menu if player hasn't yet bought anything                                    if (g_canbuy[id]) show_menu_buy1(id)                             }                             else                                    zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOTHING_CAN_CHOOSE")                      }                      else                             zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")               }               case 1: // Extra Items               {                      // Extra items enabled?                      if (get_pcvar_num(cvar_extraitems))                      {                             // Check whether the player is able to buy anything                             if (g_isalive[id])                                    show_menu_extras(id)                             else                                    zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")                      }                      else                             zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_EXTRAS")               }               case 2: // Zombie Classes               {                      // Zombie classes enabled?                      if (get_pcvar_num(cvar_zclasses))                             show_menu_zclass(id)                      else                             zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ZCLASSES")               }               case 3: // Unstuck               {                      // Check if player is stuck                      if (g_isalive[id])                      {                             if (is_player_stuck(id))                             {                                    // Move to an initial spawn                                    if (get_pcvar_num(cvar_randspawn))                                           do_random_spawn(id) // random spawn (including CSDM)                                    else                                           do_random_spawn(id, 1) // regular spawn                             }                             else                                    zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_STUCK")                      }                      else                             zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")               }               case 4: // Help Menu               {                      show_menu_info(id)               }               case 5: // Join Spectator               {                      // Player alive?                      if (g_isalive[id])                      {                             // Prevent abuse by non-admins if block suicide setting is enabled                             if (get_pcvar_num(cvar_blocksuicide) && !(get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MENU]))                             {                                    zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")                                    return PLUGIN_HANDLED;                             }                                                          // Check that we still have both humans and zombies to keep the round going                             check_round(id)                                                          // Kill him before he switches team                             dllfunc(DLLFunc_ClientKill, id)                      }                                            // Temporarily save player stats?                      if (get_pcvar_num(cvar_statssave)) save_stats(id)                                            // Remove previous tasks                      remove_task(id+TASK_TEAM)                      remove_task(id+TASK_MODEL)                      remove_task(id+TASK_FLASH)                      remove_task(id+TASK_CHARGE)                      remove_task(id+TASK_SPAWN)                      remove_task(id+TASK_BLOOD)                      remove_task(id+TASK_AURA)                      remove_task(id+TASK_BURN)                                            // Then move him to the spectator team                      fm_cs_set_user_team(id, FM_CS_TEAM_SPECTATOR)                      fm_user_team_update(id)               }               case 8: // Admin Menu               {                      // Check if player has the required access                      if (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MENU])                             show_menu_admin(id)                      else                             zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")               }        }                return PLUGIN_HANDLED; }
  // Buy Menu 1 public menu_buy1(id, key) {        // Zombies or survivors get no guns        if (!g_isalive[id] || g_zombie[id] || g_survivor[id])               return PLUGIN_HANDLED;                // Special keys / weapon list exceeded        if (key >= MENU_KEY_AUTOSELECT || WPN_SELECTION >= WPN_MAXIDS)        {               switch (key)               {                      case MENU_KEY_AUTOSELECT: // toggle auto select                      {                             WPN_AUTO_ON = 1 - WPN_AUTO_ON                      }                      case MENU_KEY_NEXT: // next/back                      {                             if (WPN_STARTID+7 < WPN_MAXIDS)                                    WPN_STARTID += 7                             else                                    WPN_STARTID = 0                      }                      case MENU_KEY_EXIT: // exit                      {                             return PLUGIN_HANDLED;                      }               }                              // Show buy menu again               show_menu_buy1(id)               return PLUGIN_HANDLED;        }                // Store selected weapon id        WPN_AUTO_PRI = WPN_SELECTION                // Buy primary weapon        buy_primary_weapon(id, WPN_AUTO_PRI)                // Show pistols menu        show_menu_buy2(id)                return PLUGIN_HANDLED; }
  // Buy Primary Weapon buy_primary_weapon(id, selection) {        // Drop previous weapons        drop_weapons(id, 1)        drop_weapons(id, 2)                // Strip off from weapons        fm_strip_user_weapons(id)        fm_give_item(id, "weapon_knife")                // Get weapon's id and name        static weaponid, wname[32]        weaponid = ArrayGetCell(g_primary_weaponids, selection)        ArrayGetString(g_primary_items, selection, wname, charsmax(wname))                // Give the new weapon and full ammo        fm_give_item(id, wname)        ExecuteHamB(Ham_GiveAmmo, id, MAXBPAMMO[weaponid], AMMOTYPE[weaponid], MAXBPAMMO[weaponid])                // Weapons bought        g_canbuy[id] = false                // Give additional items        static i        for (i = 0; i < ArraySize(g_additional_items); i++)        {               ArrayGetString(g_additional_items, i, wname, charsmax(wname))               fm_give_item(id, wname)        } }
  // Buy Menu 2 public menu_buy2(id, key) {               // Zombies or survivors get no guns        if (!g_isalive[id] || g_zombie[id] || g_survivor[id])               return PLUGIN_HANDLED;                // Special keys / weapon list exceeded        if (key >= ArraySize(g_secondary_items))        {               // Toggle autoselect               if (key == MENU_KEY_AUTOSELECT)                      WPN_AUTO_ON = 1 - WPN_AUTO_ON                              // Reshow menu unless user exited               if (key != MENU_KEY_EXIT)                      show_menu_buy2(id)                              return PLUGIN_HANDLED;        }                // Store selected weapon        WPN_AUTO_SEC = key                // Drop secondary gun again, in case we picked another (bugfix)        drop_weapons(id, 2)                // Get weapon's id        static weaponid, wname[32]        weaponid = ArrayGetCell(g_secondary_weaponids, key)        ArrayGetString(g_secondary_items, key, wname, charsmax(wname))                // Give the new weapon and full ammo        fm_give_item(id, wname)        ExecuteHamB(Ham_GiveAmmo, id, MAXBPAMMO[weaponid], AMMOTYPE[weaponid], MAXBPAMMO[weaponid])                if (WPN_MAXIDS == 0)        {               // Weapons bought               g_canbuy[id] = false                              // Give additional items               static i               for (i = 0; i < ArraySize(g_additional_items); i++)               {                      ArrayGetString(g_additional_items, i, wname, charsmax(wname))                      fm_give_item(id, wname)               }        }                return PLUGIN_HANDLED; }
  // Extra Items Menu public menu_extras(id, menuid, item) {        // Menu was closed        if (item == MENU_EXIT)        {               menu_destroy(menuid)               return PLUGIN_HANDLED;        }                // Dead players are not allowed to buy items        if (!g_isalive[id])        {               zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")               menu_destroy(menuid)               return PLUGIN_HANDLED;        }                // Retrieve extra item id        static buffer[2], dummy, itemid        menu_item_getinfo(menuid, item, dummy, buffer, charsmax(buffer), _, _, dummy)        itemid = buffer[0]                // Attempt to buy the item        buy_extra_item(id, itemid)        menu_destroy(menuid)        return PLUGIN_HANDLED; }
  // Buy Extra Item buy_extra_item(id, itemid, ignorecost = 0) {        // Retrieve item's team        static team        team = ArrayGetCell(g_extraitem_team, itemid)                // Check for team/class specific items        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)))        {               zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")               return;        }                // Check for unavailable items        if ((itemid == EXTRA_NVISION && !get_pcvar_num(cvar_extranvision))        || (itemid == EXTRA_ANTIDOTE && (!get_pcvar_num(cvar_extraantidote) || g_antidotecounter >= get_pcvar_num(cvar_antidotelimit)))        || (itemid == EXTRA_MADNESS && (!get_pcvar_num(cvar_extramadness) || g_madnesscounter >= get_pcvar_num(cvar_madnesslimit)))        || (itemid == EXTRA_INFBOMB && (!get_pcvar_num(cvar_extrainfbomb) || g_infbombcounter >= get_pcvar_num(cvar_infbomblimit)))        || (itemid >= EXTRA_WEAPONS_STARTID && itemid <= EXTRAS_CUSTOM_STARTID-1 && !get_pcvar_num(cvar_extraweapons)))        {               zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")               return;        }                // Check for hard coded items with special conditions        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)))        || (itemid == EXTRA_MADNESS && g_nodamage[id]) || (itemid == EXTRA_INFBOMB && (g_endround || g_swarmround || g_nemround || g_survround || g_plagueround)))        {               zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_CANTUSE")               return;        }                // Ignore item's cost?        if (!ignorecost)        {               // Check that we have enough ammo packs //*****               new temp = ArrayGetCell(g_extraitem_cost, itemid)                              //if (g_ammopacks[id] < ArrayGetCell(g_extraitem_cost, itemid))               if (g_ammopacks[id] < temp)               {                      zp_colored_print(id, "^x04[ZP]^x01 %L", id, "NOT_ENOUGH_AMMO")                      return;               }                              // Deduce item cost //*****               //g_ammopacks[id] -= ArrayGetCell(g_extraitem_cost, itemid)               g_ammopacks[id] -= temp        }                // Check which kind of item we're buying        switch (itemid)        {               case EXTRA_NVISION: // Night Vision               {                      g_nvision[id] = true                                            if (!g_isbot[id])                      {                             g_nvisionenabled[id] = true                                                          // Custom nvg?                             if (get_pcvar_num(cvar_customnvg))                             {                                    remove_task(id+TASK_NVISION)                                    set_task(0.1, "set_user_nvision", id+TASK_NVISION, _, _, "b")                             }                             else                                    set_user_gnvision(id, 1)                      }                      else                             cs_set_user_nvg(id, 1)               }               case EXTRA_ANTIDOTE: // Antidote               {                      // Increase antidote purchase count for this round                      g_antidotecounter++                                            humanme(id, 0, 0)               }               case EXTRA_MADNESS: // Zombie Madness               {                      // Increase madness purchase count for this round                      g_madnesscounter++                                            g_nodamage[id] = true                      set_task(0.1, "zombie_aura", id+TASK_AURA, _, _, "b")                      set_task(get_pcvar_float(cvar_madnessduration), "madness_over", id+TASK_BLOOD)                                            static sound[64]                      ArrayGetString(zombie_madness, random_num(0, ArraySize(zombie_madness) - 1), sound, charsmax(sound))                      emit_sound(id, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)               }               case EXTRA_INFBOMB: // Infection Bomb               {                      // Increase infection bomb purchase count for this round                      g_infbombcounter++                                            // Already own one                      if (user_has_weapon(id, CSW_HEGRENADE))                      {                             // Increase BP ammo on it instead                             cs_set_user_bpammo(id, CSW_HEGRENADE, cs_get_user_bpammo(id, CSW_HEGRENADE) + 1)                                                          // Flash ammo in hud                             message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoPickup, _, id)                             write_byte(AMMOID[CSW_HEGRENADE]) // ammo id                             write_byte(1) // ammo amount                             message_end()                                                          // Play clip purchase sound                             emit_sound(id, CHAN_ITEM, sound_buyammo, 1.0, ATTN_NORM, 0, PITCH_NORM)                                                          return; // stop here                      }                                            // Give weapon to the player                      fm_give_item(id, "weapon_hegrenade")               }               default:               {                      if (itemid >= EXTRA_WEAPONS_STARTID && itemid <= EXTRAS_CUSTOM_STARTID-1) // Weapons                      {                             // Get weapon's id and name                             static weaponid, wname[32]                             ArrayGetString(g_extraweapon_items, itemid - EXTRA_WEAPONS_STARTID, wname, charsmax(wname))                             weaponid = cs_weapon_name_to_id(wname)                                                          // If we are giving a primary/secondary weapon                             if (MAXBPAMMO[weaponid] > 2)                             {                                    // Make user drop the previous one                                    if ((1<<weaponid) & PRIMARY_WEAPONS_BIT_SUM)                                           drop_weapons(id, 1)                                    else                                           drop_weapons(id, 2)                                                                        // Give full BP ammo for the new one                                    ExecuteHamB(Ham_GiveAmmo, id, MAXBPAMMO[weaponid], AMMOTYPE[weaponid], MAXBPAMMO[weaponid])                             }                             // If we are giving a grenade which the user already owns                             else if (user_has_weapon(id, weaponid))                             {                                    // Increase BP ammo on it instead                                    cs_set_user_bpammo(id, weaponid, cs_get_user_bpammo(id, weaponid) + 1)                                                                        // Flash ammo in hud                                    message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoPickup, _, id)                                    write_byte(AMMOID[weaponid]) // ammo id                                    write_byte(1) // ammo amount                                    message_end()                                                                        // Play clip purchase sound                                    emit_sound(id, CHAN_ITEM, sound_buyammo, 1.0, ATTN_NORM, 0, PITCH_NORM)                                                                        return; // stop here                             }                                                          // Give weapon to the player                             fm_give_item(id, wname)                      }                      else // Custom additions                      {                             // Item selected forward                             ExecuteForward(g_fwExtraItemSelected, g_fwDummyResult, id, itemid);                                                          // Item purchase blocked, restore buyer's ammo packs //*****                             new temp = ArrayGetCell(g_extraitem_cost, itemid)                                                          if (g_fwDummyResult >= ZP_PLUGIN_HANDLED && !ignorecost)                                    //g_ammopacks[id] += ArrayGetCell(g_extraitem_cost, itemid)                                    g_ammopacks[id] += temp                      }               }        } }
  // Zombie Class Menu public menu_zclass(id, menuid, item) {        // Menu was closed        if (item == MENU_EXIT)        {               menu_destroy(menuid)               return PLUGIN_HANDLED;        }                // Retrieve zombie class id        static buffer[2], dummy, classid        menu_item_getinfo(menuid, item, dummy, buffer, charsmax(buffer), _, _, dummy)        classid = buffer[0]                // Store selection for the next infection        g_zombieclassnext[id] = classid                static name[32]        ArrayGetString(g_zclass_name, g_zombieclassnext[id], name, charsmax(name))                // Show selected zombie class info and stats        zp_colored_print(id, "^x04[ZP]^x01 %L: %s", id, "ZOMBIE_SELECT", name)        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]),        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))                menu_destroy(menuid)        return PLUGIN_HANDLED; }
  // Info Menu public menu_info(id, key) {        static motd[1500], len        len = 0                switch (key)        {               case 0: // General               {                      static weather, lighting[2]                      weather = 0                      get_pcvar_string(cvar_lighting, lighting, charsmax(lighting))                      strtolower(lighting)                                            len += formatex(motd[len], charsmax(motd) - len, "%L ", id, "MOTD_INFO11", "Zombie Plague", PLUGIN_VERSION, "MeRcyLeZZ")                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO12")                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_A")                                            if (g_ambience_fog)                      {                             len += formatex(motd[len], charsmax(motd) - len, (weather < 1) ? " %L" : ". %L", id, "MOTD_FOG")                             weather++                      }                      if (g_ambience_rain)                      {                             len += formatex(motd[len], charsmax(motd) - len, (weather < 1) ? " %L" : ". %L", id, "MOTD_RAIN")                             weather++                      }                      if (g_ambience_snow)                      {                             len += formatex(motd[len], charsmax(motd) - len, (weather < 1) ? " %L" : ". %L", id, "MOTD_SNOW")                             weather++                      }                      if (weather < 1) len += formatex(motd[len], charsmax(motd) - len, " %L", id, "MOTD_DISABLED")                                            len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_B", lighting)                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_C", id, get_pcvar_num(cvar_triggered) ? "MOTD_ENABLED" : "MOTD_DISABLED")                      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)))                      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")                      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")                      if (get_pcvar_num(cvar_deathmatch)) len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_G", floatround(get_pcvar_float(cvar_spawnprotection)))                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_H", id, get_pcvar_num(cvar_randspawn) ? "MOTD_ENABLED" : "MOTD_DISABLED")                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_I", id, get_pcvar_num(cvar_extraitems) ? "MOTD_ENABLED" : "MOTD_DISABLED")                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_J", id, get_pcvar_num(cvar_zclasses) ? "MOTD_ENABLED" : "MOTD_DISABLED")                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_K", id, get_pcvar_num(cvar_customnvg) ? "MOTD_ENABLED" : "MOTD_DISABLED")                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_L", id, g_cached_customflash ? "MOTD_ENABLED" : "MOTD_DISABLED")                                            show_motd(id, motd)               }               case 1: // Humans               {                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2")                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_A", get_pcvar_num(cvar_humanhp))                      if (get_pcvar_num(cvar_humanlasthp) > 0) len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_B", get_pcvar_num(cvar_humanlasthp))                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_C", floatround(g_cached_humanspd))                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_D", floatround(get_pcvar_float(cvar_humangravity) * 800.0))                      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")                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_F", get_pcvar_num(cvar_ammodamage))                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_G", id, get_pcvar_num(cvar_firegrenades) ? "MOTD_ENABLED" : "MOTD_DISABLED")                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_H", id, get_pcvar_num(cvar_frostgrenades) ? "MOTD_ENABLED" : "MOTD_DISABLED")                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_I", id, get_pcvar_num(cvar_flaregrenades) ? "MOTD_ENABLED" : "MOTD_DISABLED")                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_J", id, get_pcvar_num(cvar_knockback) ? "MOTD_ENABLED" : "MOTD_DISABLED")                                            show_motd(id, motd)               }               case 2: // Zombies               {                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3")                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_A", ArrayGetCell(g_zclass_hp, 0))                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_B", floatround(float(ArrayGetCell(g_zclass_hp, 0)) * get_pcvar_float(cvar_zombiefirsthp)))                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_C", floatround(get_pcvar_float(cvar_zombiearmor) * 100.0))                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_D", ArrayGetCell(g_zclass_spd, 0))                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_E", floatround(Float:ArrayGetCell(g_zclass_grav, 0) * 800.0))                      if (get_pcvar_num(cvar_zombiebonushp)) len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_F", get_pcvar_num(cvar_zombiebonushp))                      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")                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_H", id, get_pcvar_num(cvar_zombiebleeding) ? "MOTD_ENABLED" : "MOTD_DISABLED")                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_I", get_pcvar_num(cvar_ammoinfect))                                            show_motd(id, motd)               }               case 3: // Gameplay Modes               {                      static nemhp[5], survhp[5]                                            // Get nemesis and survivor health                      num_to_str(get_pcvar_num(cvar_nemhp), nemhp, charsmax(nemhp))                      num_to_str(get_pcvar_num(cvar_survhp), survhp, charsmax(survhp))                                            len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4")                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_A", id, get_pcvar_num(cvar_nem) ? "MOTD_ENABLED" : "MOTD_DISABLED")                      if (get_pcvar_num(cvar_nem))                      {                             len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_B", get_pcvar_num(cvar_nemchance))                             len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_C", get_pcvar_num(cvar_nemhp) > 0 ? nemhp : "[Auto]")                             len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_D", floatround(g_cached_nemspd))                             len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_E", floatround(get_pcvar_float(cvar_nemgravity) * 800.0))                             len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_F", id, g_cached_leapnemesis ? "MOTD_ENABLED" : "MOTD_DISABLED")                             len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_G", id, get_pcvar_num(cvar_nempainfree) ? "MOTD_ENABLED" : "MOTD_DISABLED")                      }                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_H", id, get_pcvar_num(cvar_surv) ? "MOTD_ENABLED" : "MOTD_DISABLED")                      if (get_pcvar_num(cvar_surv))                      {                             len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_I", get_pcvar_num(cvar_survchance))                             len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_J", get_pcvar_num(cvar_survhp) > 0 ? survhp : "[Auto]")                             len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_K", floatround(g_cached_survspd))                             len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_L", floatround(get_pcvar_float(cvar_survgravity) * 800.0))                             len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_M", id, g_cached_leapsurvivor ? "MOTD_ENABLED" : "MOTD_DISABLED")                             len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_N", id, get_pcvar_num(cvar_survpainfree) ? "MOTD_ENABLED" : "MOTD_DISABLED")                      }                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_O", id, get_pcvar_num(cvar_swarm) ? "MOTD_ENABLED" : "MOTD_DISABLED")                      if (get_pcvar_num(cvar_swarm)) len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_P", get_pcvar_num(cvar_swarmchance))                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_Q", id, get_pcvar_num(cvar_multi) ? "MOTD_ENABLED" : "MOTD_DISABLED")                      if (get_pcvar_num(cvar_multi))                      {                             len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_R", get_pcvar_num(cvar_multichance))                             len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_S", floatround(get_pcvar_float(cvar_multiratio) * 100.0))                      }                      len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_T", id, get_pcvar_num(cvar_plague) ? "MOTD_ENABLED" : "MOTD_DISABLED")                      if (get_pcvar_num(cvar_plague))                      {                             len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_U", get_pcvar_num(cvar_plaguechance))                             len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_V", floatround(get_pcvar_float(cvar_plagueratio) * 100.0))                      }                                            show_motd(id, motd)               }               default: return PLUGIN_HANDLED;        }                // Show help menu again if user wishes to read another topic        show_menu_info(id)                return PLUGIN_HANDLED; }
  // Admin Menu public menu_admin(id, key) {        static userflags        userflags = get_user_flags(id)                switch (key)        {               case ACTION_ZOMBIEFY_HUMANIZE: // Zombiefy/Humanize command               {                      if (userflags & (g_access_flag[ACCESS_MODE_INFECTION] | g_access_flag[ACCESS_MAKE_ZOMBIE] | g_access_flag[ACCESS_MAKE_HUMAN]))                      {                             // Show player list for admin to pick a target                             PL_ACTION = ACTION_ZOMBIEFY_HUMANIZE                             show_menu_player_list(id)                      }                      else                      {                             zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")                             show_menu_admin(id)                      }               }               case ACTION_MAKE_NEMESIS: // Nemesis command               {                      if (userflags & (g_access_flag[ACCESS_MODE_NEMESIS] | g_access_flag[ACCESS_MAKE_NEMESIS]))                      {                             // Show player list for admin to pick a target                             PL_ACTION = ACTION_MAKE_NEMESIS                             show_menu_player_list(id)                      }                      else                      {                             zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")                             show_menu_admin(id)                      }               }               case ACTION_MAKE_SURVIVOR: // Survivor command               {                      if (userflags & (g_access_flag[ACCESS_MODE_SURVIVOR] | g_access_flag[ACCESS_MAKE_SURVIVOR]))                      {                             // Show player list for admin to pick a target                             PL_ACTION = ACTION_MAKE_SURVIVOR                             show_menu_player_list(id)                      }                      else                      {                             zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")                             show_menu_admin(id)                      }               }               case ACTION_RESPAWN_PLAYER: // Respawn command               {                      if (userflags & g_access_flag[ACCESS_RESPAWN_PLAYERS])                      {                             // Show player list for admin to pick a target                             PL_ACTION = ACTION_RESPAWN_PLAYER                             show_menu_player_list(id)                      }                      else                      {                             zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")                             show_menu_admin(id)                      }               }               case ACTION_MODE_SWARM: // Swarm Mode command               {                      if (userflags & g_access_flag[ACCESS_MODE_SWARM])                      {                             if (allowed_swarm())                                    command_swarm(id)                             else                                    zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")                      }                      else                             zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")                                            show_menu_admin(id)               }               case ACTION_MODE_MULTI: // Multiple Infection command               {                      if (userflags & g_access_flag[ACCESS_MODE_MULTI])                      {                             if (allowed_multi())                                    command_multi(id)                             else                                    zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")                      }                      else                             zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")                                            show_menu_admin(id)               }               case ACTION_MODE_PLAGUE: // Plague Mode command               {                      if (userflags & g_access_flag[ACCESS_MODE_PLAGUE])                      {                             if (allowed_plague())                                    command_plague(id)                             else                                    zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")                      }                      else                             zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")                                            show_menu_admin(id)               }        }                return PLUGIN_HANDLED; }
  // Player List Menu public menu_player_list(id, menuid, item) {        // Menu was closed        if (item == MENU_EXIT)        {               menu_destroy(menuid)               show_menu_admin(id)               return PLUGIN_HANDLED;        }                // Retrieve player id        static buffer[2], dummy, playerid        menu_item_getinfo(menuid, item, dummy, buffer, charsmax(buffer), _, _, dummy)        playerid = buffer[0]                // Perform action on player                // Get admin flags        static userflags        userflags = get_user_flags(id)                // Make sure it's still connected        if (g_isconnected[playerid])        {               // Perform the right action if allowed               switch (PL_ACTION)               {                      case ACTION_ZOMBIEFY_HUMANIZE: // Zombiefy/Humanize command                      {                             if (g_zombie[playerid])                             {                                    if (userflags & g_access_flag[ACCESS_MAKE_HUMAN])                                    {                                           if (allowed_human(playerid))                                                  command_human(id, playerid)                                           else                                                  zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")                                    }                                    else                                           zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")                             }                             else                             {                                    if (g_newround ? (userflags & g_access_flag[ACCESS_MODE_INFECTION]) : (userflags & g_access_flag[ACCESS_MAKE_ZOMBIE]))                                    {                                           if (allowed_zombie(playerid))                                                  command_zombie(id, playerid)                                           else                                                  zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")                                    }                                    else                                           zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")                             }                      }                      case ACTION_MAKE_NEMESIS: // Nemesis command                      {                             if (g_newround ? (userflags & g_access_flag[ACCESS_MODE_NEMESIS]) : (userflags & g_access_flag[ACCESS_MAKE_NEMESIS]))                             {                                    if (allowed_nemesis(playerid))                                           command_nemesis(id, playerid)                                    else                                           zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")                             }                             else                                    zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")                      }                      case ACTION_MAKE_SURVIVOR: // Survivor command                      {                             if (g_newround ? (userflags & g_access_flag[ACCESS_MODE_SURVIVOR]) : (userflags & g_access_flag[ACCESS_MAKE_SURVIVOR]))                             {                                    if (allowed_survivor(playerid))                                           command_survivor(id, playerid)                                    else                                           zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")                             }                             else                                    zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")                      }                      case ACTION_RESPAWN_PLAYER: // Respawn command                      {                             if (userflags & g_access_flag[ACCESS_RESPAWN_PLAYERS])                             {                                    if (allowed_respawn(playerid))                                           command_respawn(id, playerid)                                    else                                           zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")                             }                             else                                    zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT_ACCESS")                      }               }        }        else               zp_colored_print(id, "^x04[ZP]^x01 %L", id, "CMD_NOT")                menu_destroy(menuid)        show_menu_player_list(id)        return PLUGIN_HANDLED; }
  /*================================================================================  [Admin Commands] =================================================================================*/
  // zp_toggle [1/0] public cmd_toggle(id, level, cid) {        // Check for access flag - Enable/Disable Mod        if (!cmd_access(id, g_access_flag[ACCESS_ENABLE_MOD], cid, 2))               return PLUGIN_HANDLED;                // Retrieve arguments        new arg[2]        read_argv(1, arg, charsmax(arg))                // Mod already enabled/disabled        if (str_to_num(arg) == g_pluginenabled)               return PLUGIN_HANDLED;                // Set toggle cvar        set_pcvar_num(cvar_toggle, str_to_num(arg))        client_print(id, print_console, "Zombie Plague %L.", id, str_to_num(arg) ? "MOTD_ENABLED" : "MOTD_DISABLED")                // Retrieve map name        new mapname[32]        get_mapname(mapname, charsmax(mapname))                // Restart current map        server_cmd("changelevel %s", mapname)                return PLUGIN_HANDLED; }
  // zp_zombie [target] public cmd_zombie(id, level, cid) {        // Check for access flag depending on the resulting action        if (g_newround)        {               // Start Mode Infection               if (!cmd_access(id, g_access_flag[ACCESS_MODE_INFECTION], cid, 2))                      return PLUGIN_HANDLED;        }        else        {               // Make Zombie               if (!cmd_access(id, g_access_flag[ACCESS_MAKE_ZOMBIE], cid, 2))                      return PLUGIN_HANDLED;        }                // Retrieve arguments        static arg[32], player        read_argv(1, arg, charsmax(arg))        player = cmd_target(id, arg, (CMDTARGET_ONLY_ALIVE | CMDTARGET_ALLOW_SELF))                // Invalid target        if (!player) return PLUGIN_HANDLED;                // Target not allowed to be zombie        if (!allowed_zombie(player))        {               client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")               return PLUGIN_HANDLED        }                command_zombie(id, player)                return PLUGIN_HANDLED; }
  // zp_human [target] public cmd_human(id, level, cid) {        // Check for access flag - Make Human        if (!cmd_access(id, g_access_flag[ACCESS_MAKE_HUMAN], cid, 2))               return PLUGIN_HANDLED;                // Retrieve arguments        static arg[32], player        read_argv(1, arg, charsmax(arg))        player = cmd_target(id, arg, (CMDTARGET_ONLY_ALIVE | CMDTARGET_ALLOW_SELF))                // Invalid target        if (!player) return PLUGIN_HANDLED;                // Target not allowed to be human        if (!allowed_human(player))        {               client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")               return PLUGIN_HANDLED;        }                command_human(id, player)                return PLUGIN_HANDLED; }
  // zp_survivor [target] public cmd_survivor(id, level, cid) {        // Check for access flag depending on the resulting action        if (g_newround)        {               // Start Mode Survivor               if (!cmd_access(id, g_access_flag[ACCESS_MODE_SURVIVOR], cid, 2))                      return PLUGIN_HANDLED;        }        else        {               // Make Survivor               if (!cmd_access(id, g_access_flag[ACCESS_MAKE_SURVIVOR], cid, 2))                      return PLUGIN_HANDLED;        }                // Retrieve arguments        static arg[32], player        read_argv(1, arg, charsmax(arg))        player = cmd_target(id, arg, (CMDTARGET_ONLY_ALIVE | CMDTARGET_ALLOW_SELF))                // Invalid target        if (!player) return PLUGIN_HANDLED;                // Target not allowed to be survivor        if (!allowed_survivor(player))        {               client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")               return PLUGIN_HANDLED;        }                command_survivor(id, player)                return PLUGIN_HANDLED; }
  // zp_nemesis [target] public cmd_nemesis(id, level, cid) {        // Check for access flag depending on the resulting action        if (g_newround)        {               // Start Mode Nemesis               if (!cmd_access(id, g_access_flag[ACCESS_MODE_NEMESIS], cid, 2))                      return PLUGIN_HANDLED;        }        else        {               // Make Nemesis               if (!cmd_access(id, g_access_flag[ACCESS_MAKE_NEMESIS], cid, 2))                      return PLUGIN_HANDLED;        }                // Retrieve arguments        static arg[32], player        read_argv(1, arg, charsmax(arg))        player = cmd_target(id, arg, (CMDTARGET_ONLY_ALIVE | CMDTARGET_ALLOW_SELF))                // Invalid target        if (!player) return PLUGIN_HANDLED;                // Target not allowed to be nemesis        if (!allowed_nemesis(player))        {               client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")               return PLUGIN_HANDLED;        }                command_nemesis(id, player)                return PLUGIN_HANDLED; }
  // zp_respawn [target] public cmd_respawn(id, level, cid) {        // Check for access flag - Respawn        if (!cmd_access(id, g_access_flag[ACCESS_RESPAWN_PLAYERS], cid, 2))               return PLUGIN_HANDLED;                // Retrieve arguments        static arg[32], player        read_argv(1, arg, charsmax(arg))        player = cmd_target(id, arg, CMDTARGET_ALLOW_SELF)                // Invalid target        if (!player) return PLUGIN_HANDLED;                // Target not allowed to be respawned        if (!allowed_respawn(player))        {               client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")               return PLUGIN_HANDLED;        }                command_respawn(id, player)                return PLUGIN_HANDLED; }
  // zp_swarm public cmd_swarm(id, level, cid) {        // Check for access flag - Mode Swarm        if (!cmd_access(id, g_access_flag[ACCESS_MODE_SWARM], cid, 2))               return PLUGIN_HANDLED;                // Swarm mode not allowed        if (!allowed_swarm())        {               client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")               return PLUGIN_HANDLED;        }                command_swarm(id)                return PLUGIN_HANDLED; }
  // zp_multi public cmd_multi(id, level, cid) {        // Check for access flag - Mode Multi        if (!cmd_access(id, g_access_flag[ACCESS_MODE_MULTI], cid, 2))               return PLUGIN_HANDLED;                // Multi infection mode not allowed        if (!allowed_multi())        {               client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")               return PLUGIN_HANDLED;        }                command_multi(id)                return PLUGIN_HANDLED; }
  // zp_plague public cmd_plague(id, level, cid) {        // Check for access flag - Mode Plague        if (!cmd_access(id, g_access_flag[ACCESS_MODE_PLAGUE], cid, 2))               return PLUGIN_HANDLED;                // Plague mode not allowed        if (!allowed_plague())        {               client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")               return PLUGIN_HANDLED;        }                command_plague(id)                return PLUGIN_HANDLED; }
  /*================================================================================  [Message Hooks] =================================================================================*/
  // Current Weapon info public message_cur_weapon(msg_id, msg_dest, msg_entity) {        // Not alive or zombie        if (!g_isalive[msg_entity] || g_zombie[msg_entity])               return;                // Not an active weapon        if (get_msg_arg_int(1) != 1)               return;                // Unlimited clip disabled for class        if (g_survivor[msg_entity] ? get_pcvar_num(cvar_survinfammo) <= 1 : get_pcvar_num(cvar_infammo) <= 1)               return;                // Get weapon's id        static weapon        weapon = get_msg_arg_int(2)                // Unlimited Clip Ammo for this weapon?        if (MAXBPAMMO[weapon] > 2)        {               // Max out clip ammo               cs_set_weapon_ammo(fm_cs_get_current_weapon_ent(msg_entity), MAXCLIP[weapon])                              // HUD should show full clip all the time               set_msg_arg_int(3, get_msg_argtype(3), MAXCLIP[weapon])        } }
  // Take off player's money public message_money(msg_id, msg_dest, msg_entity) {        // Remove money setting enabled?        if (!get_pcvar_num(cvar_removemoney))               return PLUGIN_CONTINUE;                fm_cs_set_user_money(msg_entity, 0)        return PLUGIN_HANDLED; }
  // Fix for the HL engine bug when HP is multiples of 256 public message_health(msg_id, msg_dest, msg_entity) {        // Get player's health        static health        health = get_msg_arg_int(1)                // Don't bother        if (health < 256) return;                // Check if we need to fix it        if (health % 256 == 0)               fm_set_user_health(msg_entity, pev(msg_entity, pev_health) + 1)                // HUD can only show as much as 255 hp        set_msg_arg_int(1, get_msg_argtype(1), 255) }
  // Block flashlight battery messages if custom flashlight is enabled instead public message_flashbat() {        if (g_cached_customflash)               return PLUGIN_HANDLED;                return PLUGIN_CONTINUE; }
  // Flashbangs should only affect zombies public message_screenfade(msg_id, msg_dest, msg_entity) {        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)               return PLUGIN_CONTINUE;                // Nemesis shouldn't be FBed        if (g_zombie[msg_entity] && !g_nemesis[msg_entity])        {               // Set flash color to nighvision's               set_msg_arg_int(4, get_msg_argtype(4), get_pcvar_num(cvar_nvgcolor[0]))               set_msg_arg_int(5, get_msg_argtype(5), get_pcvar_num(cvar_nvgcolor[1]))               set_msg_arg_int(6, get_msg_argtype(6), get_pcvar_num(cvar_nvgcolor[2]))               return PLUGIN_CONTINUE;        }                return PLUGIN_HANDLED; }
  // Prevent spectators' nightvision from being turned off when switching targets, etc. public message_nvgtoggle() {        return PLUGIN_HANDLED; }
  // Set correct model on player corpses public message_clcorpse() {        set_msg_arg_string(1, g_playermodel[get_msg_arg_int(12)]) }
  // Prevent zombies from seeing any weapon pickup icon public message_weappickup(msg_id, msg_dest, msg_entity) {        if (g_zombie[msg_entity])               return PLUGIN_HANDLED;                return PLUGIN_CONTINUE; }
  // Prevent zombies from seeing any ammo pickup icon public message_ammopickup(msg_id, msg_dest, msg_entity) {        if (g_zombie[msg_entity])               return PLUGIN_HANDLED;                return PLUGIN_CONTINUE; }
  // Block hostage HUD display public message_scenario() {        if (get_msg_args() > 1)        {               static sprite[8]               get_msg_arg_string(2, sprite, charsmax(sprite))                              if (equal(sprite, "hostage"))                      return PLUGIN_HANDLED;        }                return PLUGIN_CONTINUE; }
  // Block hostages from appearing on radar public message_hostagepos() {        return PLUGIN_HANDLED; }
  // Block some text messages public message_textmsg() {        static textmsg[22]        get_msg_arg_string(2, textmsg, charsmax(textmsg))                // Game restarting, reset scores and call round end to balance the teams        if (equal(textmsg, "#Game_will_restart_in"))        {               g_scorehumans = 0               g_scorezombies = 0               logevent_round_end()        }        // Block round end related messages        else if (equal(textmsg, "#Hostages_Not_Rescued") || equal(textmsg, "#Round_Draw") || equal(textmsg, "#Terrorists_Win") || equal(textmsg, "#CTs_Win"))        {               return PLUGIN_HANDLED;        }                return PLUGIN_CONTINUE; }
  // Block CS round win audio messages, since we're playing our own instead public message_sendaudio() {        static audio[17]        get_msg_arg_string(2, audio, charsmax(audio))                if(equal(audio[7], "terwin") || equal(audio[7], "ctwin") || equal(audio[7], "rounddraw"))               return PLUGIN_HANDLED;                return PLUGIN_CONTINUE; }
  // Send actual team scores (T = zombies // CT = humans) public message_teamscore() {        static team[2]        get_msg_arg_string(1, team, charsmax(team))                switch (team[0])        {               // CT               case 'C': set_msg_arg_int(2, get_msg_argtype(2), g_scorehumans)               // Terrorist               case 'T': set_msg_arg_int(2, get_msg_argtype(2), g_scorezombies)        } }
  // Team Switch (or player joining a team for first time) public message_teaminfo(msg_id, msg_dest) {        // Only hook global messages        if (msg_dest != MSG_ALL && msg_dest != MSG_BROADCAST) return;                // Don't pick up our own TeamInfo messages for this player (bugfix)        if (g_switchingteam) return;                // Get player's id        static id        id = get_msg_arg_int(1)                // Enable spectators' nightvision if not spawning right away        set_task(0.2, "spec_nvision", id)                // Round didn't start yet, nothing to worry about        if (g_newround) return;                // Get his new team        static team[2]        get_msg_arg_string(2, team, charsmax(team))                // Perform some checks to see if they should join a different team instead        switch (team[0])        {               case 'C': // CT               {                      if (g_survround && fnGetHumans()) // survivor alive --> switch to T and spawn as zombie                      {                             g_respawn_as_zombie[id] = true;                             remove_task(id+TASK_TEAM)                             fm_cs_set_user_team(id, FM_CS_TEAM_T)                             set_msg_arg_string(2, "TERRORIST")                      }                      else if (!fnGetZombies()) // no zombies alive --> switch to T and spawn as zombie                      {                             g_respawn_as_zombie[id] = true;                             remove_task(id+TASK_TEAM)                             fm_cs_set_user_team(id, FM_CS_TEAM_T)                             set_msg_arg_string(2, "TERRORIST")                      }               }               case 'T': // Terrorist               {                      if ((g_swarmround || g_survround) && fnGetHumans()) // survivor alive or swarm round w/ humans --> spawn as zombie                      {                             g_respawn_as_zombie[id] = true;                      }                      else if (fnGetZombies()) // zombies alive --> switch to CT                      {                             remove_task(id+TASK_TEAM)                             fm_cs_set_user_team(id, FM_CS_TEAM_CT)                             set_msg_arg_string(2, "CT")                      }               }        } }
  /*================================================================================  [Main Functions] =================================================================================*/
  // Make Zombie Task public make_zombie_task() {        // Get alive players count        static iPlayersnum        iPlayersnum = fnGetAlive()        // Not enough players, come back later!        if (iPlayersnum < 1)        {               g_time_countdown = 10               remove_task(TASK_MAKEZOMBIE)               set_task(1.0, "make_zombie_task", TASK_MAKEZOMBIE)               return;        }                if (g_time_countdown >= 1)        {               if (g_time_countdown <= 10)               {                      set_hudmessage(255, 255, 255, HUD_EVENT_X, HUD_EVENT_Y + 0.2, 0, 0.0, 3.0, 2.0, 1.0, -1)                      client_print(0, print_center, "%L", LANG_PLAYER, "NOTICE_TIME_COUNTDOWN", g_time_countdown)                      PlaySound(sound_countdown[g_time_countdown - 1])               }                              g_time_countdown -= 1               remove_task(TASK_MAKEZOMBIE)               set_task(1.0, "make_zombie_task", TASK_MAKEZOMBIE)        }        else        {               // Call make a zombie with no specific mode               make_a_zombie(MODE_NONE, 0)        } }
  // Make a Zombie Function make_a_zombie(mode, id) {        // Get alive players count        static iPlayersnum        iPlayersnum = fnGetAlive()                // Not enough players, come back later!        if (iPlayersnum < 1)        {               set_task(1.0, "make_zombie_task", TASK_MAKEZOMBIE)               return;        }                // Round started!        g_newround = false                // Set up some common vars        static forward_id, sound[64], iZombies, iMaxZombies                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)        {               // Survivor Mode               g_survround = true               g_lastmode = MODE_SURVIVOR                              // Choose player randomly?               if (mode == MODE_NONE)                      id = fnGetRandomAlive(random_num(1, iPlayersnum))                              // Remember id for calling our forward later               forward_id = id                              // Turn player into a survivor               humanme(id, 1, 0)                              // Turn the remaining players into zombies               for (id = 1; id <= g_maxplayers; id++)               {                      // Not alive                      if (!g_isalive[id])                             continue;                                            // Survivor or already a zombie                      if (g_survivor[id] || g_zombie[id])                             continue;                                            // Turn into a zombie                      zombieme(id, 0, 0, 1, 0)               }                              // Play survivor sound               ArrayGetString(sound_survivor, random_num(0, ArraySize(sound_survivor) - 1), sound, charsmax(sound))               PlaySound(sound);                              // Show Survivor HUD notice               set_hudmessage(20, 20, 255, HUD_EVENT_X, HUD_EVENT_Y, 1, 0.0, 5.0, 1.0, 1.0, -1)               ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_SURVIVOR", g_playername[forward_id])                              // Mode fully started!               g_modestarted = true                              // Round start forward               ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_SURVIVOR, forward_id);        }        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)        {                             // Swarm Mode               g_swarmround = true               g_lastmode = MODE_SWARM                              // Make sure there are alive players on both teams (BUGFIX)               if (!fnGetAliveTs())               {                      // Move random player to T team                      id = fnGetRandomAlive(random_num(1, iPlayersnum))                      remove_task(id+TASK_TEAM)                      fm_cs_set_user_team(id, FM_CS_TEAM_T)                      fm_user_team_update(id)               }               else if (!fnGetAliveCTs())               {                      // Move random player to CT team                      id = fnGetRandomAlive(random_num(1, iPlayersnum))                      remove_task(id+TASK_TEAM)                      fm_cs_set_user_team(id, FM_CS_TEAM_CT)                      fm_user_team_update(id)               }                              // Turn every T into a zombie               for (id = 1; id <= g_maxplayers; id++)               {                      // Not alive                      if (!g_isalive[id])                             continue;                                            // Not a Terrorist                      if (fm_cs_get_user_team(id) != FM_CS_TEAM_T)                             continue;                                            // Turn into a zombie                      zombieme(id, 0, 0, 1, 0)               }                              // Play swarm sound               ArrayGetString(sound_swarm, random_num(0, ArraySize(sound_swarm) - 1), sound, charsmax(sound))               PlaySound(sound);                              // Show Swarm HUD notice               set_hudmessage(20, 255, 20, HUD_EVENT_X, HUD_EVENT_Y, 1, 0.0, 5.0, 1.0, 1.0, -1)               ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_SWARM")                              // Mode fully started!               g_modestarted = true                              // Round start forward               ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_SWARM, 0);        }        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)        {               // Multi Infection Mode               g_lastmode = MODE_MULTI                              // iMaxZombies is rounded up, in case there aren't enough players               iMaxZombies = floatround(iPlayersnum*get_pcvar_float(cvar_multiratio), floatround_ceil)               iZombies = 0                              // Randomly turn iMaxZombies players into zombies               while (iZombies < iMaxZombies)               {                      // Keep looping through all players                      if (++id > g_maxplayers) id = 1                                            // Dead or already a zombie                      if (!g_isalive[id] || g_zombie[id])                             continue;                                            // Random chance                      if (random_num(0, 1))                      {                             // Turn into a zombie                             zombieme(id, 0, 0, 1, 0)                             iZombies++                      }               }                              // Turn the remaining players into humans               for (id = 1; id <= g_maxplayers; id++)               {                      // Only those of them who aren't zombies                      if (!g_isalive[id] || g_zombie[id])                             continue;                                            // Switch to CT                      if (fm_cs_get_user_team(id) != FM_CS_TEAM_CT) // need to change team?                      {                             remove_task(id+TASK_TEAM)                             fm_cs_set_user_team(id, FM_CS_TEAM_CT)                             fm_user_team_update(id)                      }               }                              // Play multi infection sound               ArrayGetString(sound_multi, random_num(0, ArraySize(sound_multi) - 1), sound, charsmax(sound))               PlaySound(sound);                              // Show Multi Infection HUD notice               set_hudmessage(200, 50, 0, HUD_EVENT_X, HUD_EVENT_Y, 1, 0.0, 5.0, 1.0, 1.0, -1)               ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_MULTI")                              // Mode fully started!               g_modestarted = true                              // Round start forward               ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_MULTI, 0);        }        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        && 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)        {               // Plague Mode               g_plagueround = true               g_lastmode = MODE_PLAGUE                              // Turn specified amount of players into Survivors               static iSurvivors, iMaxSurvivors               iMaxSurvivors = get_pcvar_num(cvar_plaguesurvnum)               iSurvivors = 0                              while (iSurvivors < iMaxSurvivors)               {                      // Choose random guy                      id = fnGetRandomAlive(random_num(1, iPlayersnum))                                            // Already a survivor?                      if (g_survivor[id])                             continue;                                            // If not, turn him into one                      humanme(id, 1, 0)                      iSurvivors++                                            // Apply survivor health multiplier                      fm_set_user_health(id, floatround(float(pev(id, pev_health)) * get_pcvar_float(cvar_plaguesurvhpmulti)))               }                              // Turn specified amount of players into Nemesis               static iNemesis, iMaxNemesis               iMaxNemesis = get_pcvar_num(cvar_plaguenemnum)               iNemesis = 0                              while (iNemesis < iMaxNemesis)               {                      // Choose random guy                      id = fnGetRandomAlive(random_num(1, iPlayersnum))                                            // Already a survivor or nemesis?                      if (g_survivor[id] || g_nemesis[id])                             continue;                                            // If not, turn him into one                      zombieme(id, 0, 1, 0, 0)                      iNemesis++                                            // Apply nemesis health multiplier                      fm_set_user_health(id, floatround(float(pev(id, pev_health)) * get_pcvar_float(cvar_plaguenemhpmulti)))               }                              // iMaxZombies is rounded up, in case there aren't enough players               iMaxZombies = floatround((iPlayersnum-(get_pcvar_num(cvar_plaguenemnum)+get_pcvar_num(cvar_plaguesurvnum)))*get_pcvar_float(cvar_plagueratio), floatround_ceil)               iZombies = 0                              // Randomly turn iMaxZombies players into zombies               while (iZombies < iMaxZombies)               {                      // Keep looping through all players                      if (++id > g_maxplayers) id = 1                                            // Dead or already a zombie or survivor                      if (!g_isalive[id] || g_zombie[id] || g_survivor[id])                             continue;                                            // Random chance                      if (random_num(0, 1))                      {                             // Turn into a zombie                             zombieme(id, 0, 0, 1, 0)                             iZombies++                      }               }                              // Turn the remaining players into humans               for (id = 1; id <= g_maxplayers; id++)               {                      // Only those of them who arent zombies or survivor                      if (!g_isalive[id] || g_zombie[id] || g_survivor[id])                             continue;                                            // Switch to CT                      if (fm_cs_get_user_team(id) != FM_CS_TEAM_CT) // need to change team?                      {                             remove_task(id+TASK_TEAM)                             fm_cs_set_user_team(id, FM_CS_TEAM_CT)                             fm_user_team_update(id)                      }               }                              // Play plague sound               ArrayGetString(sound_plague, random_num(0, ArraySize(sound_plague) - 1), sound, charsmax(sound))               PlaySound(sound);                              // Show Plague HUD notice               set_hudmessage(0, 50, 200, HUD_EVENT_X, HUD_EVENT_Y, 1, 0.0, 5.0, 1.0, 1.0, -1)               ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_PLAGUE")                              // Mode fully started!               g_modestarted = true                              // Round start forward               ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_PLAGUE, 0);        }        else        {               // Single Infection Mode or Nemesis Mode                              // Choose player randomly?               if (mode == MODE_NONE)                      id = fnGetRandomAlive(random_num(1, iPlayersnum))                              // Remember id for calling our forward later               forward_id = id                              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)               {                      // Nemesis Mode                      g_nemround = true                      g_lastmode = MODE_NEMESIS                                            // Turn player into nemesis                      zombieme(id, 0, 1, 0, 0)               }               else               {                      // Single Infection Mode                      g_lastmode = MODE_INFECTION                                            // Turn player into the first zombie                      zombieme(id, 0, 0, 0, 0)               }                              // Remaining players should be humans (CTs)               for (id = 1; id <= g_maxplayers; id++)               {                      // Not alive                      if (!g_isalive[id])                             continue;                                            // First zombie/nemesis                      if (g_zombie[id])                             continue;                                            // Switch to CT                      if (fm_cs_get_user_team(id) != FM_CS_TEAM_CT) // need to change team?                      {                             remove_task(id+TASK_TEAM)                             fm_cs_set_user_team(id, FM_CS_TEAM_CT)                             fm_user_team_update(id)                      }               }                              if (g_nemround)               {                      // Play Nemesis sound                      ArrayGetString(sound_nemesis, random_num(0, ArraySize(sound_nemesis) - 1), sound, charsmax(sound))                      PlaySound(sound);                                            // Show Nemesis HUD notice                      set_hudmessage(255, 20, 20, HUD_EVENT_X, HUD_EVENT_Y, 1, 0.0, 5.0, 1.0, 1.0, -1)                      ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_NEMESIS", g_playername[forward_id])                                            // Mode fully started!                      g_modestarted = true                                            // Round start forward                      ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_NEMESIS, forward_id);               }               else               {                      // 播放第一隻喪屍出現時的聲音                      PlaySound(sound_first_zombie[random_num(0, sizeof sound_first_zombie -1)]);                                            // Show First Zombie HUD notice                      set_hudmessage(255, 0, 0, HUD_EVENT_X, HUD_EVENT_Y, 0, 0.0, 5.0, 1.0, 1.0, -1)                      ShowSyncHudMsg(0, g_MsgSync, "%L",LANG_PLAYER, "NOTICE_FIRST", g_playername[forward_id])                                            // Mode fully started!                      g_modestarted = true                                            // Round start forward                      ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_INFECTION, forward_id);               }        }                // Start ambience sounds after a mode begins        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))        {               remove_task(TASK_AMBIENCESOUNDS)               set_task(2.0, "ambience_sound_effects", TASK_AMBIENCESOUNDS)        } }
  // Zombie Me Function (player id, infector, turn into a nemesis, silent mode, deathmsg and rewards) zombieme(id, infector, nemesis, silentmode, rewards) {        // User infect attempt forward        ExecuteForward(g_fwUserInfect_attempt, g_fwDummyResult, id, infector, nemesis)                // One or more plugins blocked the infection. Only allow this after making sure it's        // not going to leave us with no zombies. Take into account a last player leaving case.        // BUGFIX: only allow after a mode has started, to prevent blocking first zombie e.g.        if (g_fwDummyResult >= ZP_PLUGIN_HANDLED && g_modestarted && fnGetZombies() > g_lastplayerleaving)               return;                // Pre user infect forward        ExecuteForward(g_fwUserInfected_pre, g_fwDummyResult, id, infector, nemesis)                // Show zombie class menu if they haven't chosen any (e.g. just connected)        if (g_zombieclassnext[id] == ZCLASS_NONE && get_pcvar_num(cvar_zclasses))               set_task(0.2, "show_menu_zclass", id)                // Set selected zombie class        g_zombieclass[id] = g_zombieclassnext[id]        // If no class selected yet, use the first (default) one        if (g_zombieclass[id] == ZCLASS_NONE) g_zombieclass[id] = 0                // Way to go...        g_zombie[id] = true        g_nemesis[id] = false        g_survivor[id] = false        g_firstzombie[id] = false                // Remove survivor's aura (bugfix)        set_pev(id, pev_effects, pev(id, pev_effects) &~ EF_BRIGHTLIGHT)                // Remove spawn protection (bugfix)        g_nodamage[id] = false        set_pev(id, pev_effects, pev(id, pev_effects) &~ EF_NODRAW)                // Reset burning duration counter (bugfix)        g_burning_duration[id] = 0                // Show deathmsg and reward infector?        if (rewards && infector)        {               // Send death notice and fix the "dead" attrib on scoreboard               SendDeathMsg(infector, id)               FixDeadAttrib(id)                              // Reward frags, deaths, health, and ammo packs               UpdateFrags(infector, id, get_pcvar_num(cvar_fragsinfect), 1, 1)               g_ammopacks[infector] += get_pcvar_num(cvar_ammoinfect)               fm_set_user_health(infector, pev(infector, pev_health) + get_pcvar_num(cvar_zombiebonushp))        }                // Cache speed, knockback, and name for player's class        g_zombie_spd[id] = float(ArrayGetCell(g_zclass_spd, g_zombieclass[id]))        g_zombie_knockback[id] = Float:ArrayGetCell(g_zclass_kb, g_zombieclass[id])        ArrayGetString(g_zclass_name, g_zombieclass[id], g_zombie_classname[id], charsmax(g_zombie_classname[]))                // Set zombie attributes based on the mode        static sound[64]        if (!silentmode)        {               if (nemesis)               {                      // Nemesis                      g_nemesis[id] = true                                            // Set health [0 = auto]                      if (get_pcvar_num(cvar_nemhp) == 0)                      {                             if (get_pcvar_num(cvar_nembasehp) == 0)                                    fm_set_user_health(id, ArrayGetCell(g_zclass_hp, 0) * fnGetAlive())                             else                                    fm_set_user_health(id, get_pcvar_num(cvar_nembasehp) * fnGetAlive())                      }                      else                             fm_set_user_health(id, get_pcvar_num(cvar_nemhp))                                            // Set gravity, unless frozen                      if (!g_frozen[id]) set_pev(id, pev_gravity, get_pcvar_float(cvar_nemgravity))               }               else if (fnGetZombies() == 1)               {                      // First zombie                      g_firstzombie[id] = true                                            // Set health and gravity, unless frozen                      fm_set_user_health(id, floatround(float(ArrayGetCell(g_zclass_hp, g_zombieclass[id])) * get_pcvar_float(cvar_zombiefirsthp)))                      if (!g_frozen[id]) set_pev(id, pev_gravity, Float:ArrayGetCell(g_zclass_grav, g_zombieclass[id]))                                            // Infection sound                      ArrayGetString(zombie_infect, random_num(0, ArraySize(zombie_infect) - 1), sound, charsmax(sound))                      emit_sound(id, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)               }               else               {                      // Infected by someone                                            // Set health and gravity, unless frozen                      fm_set_user_health(id, ArrayGetCell(g_zclass_hp, g_zombieclass[id]))                      if (!g_frozen[id]) set_pev(id, pev_gravity, Float:ArrayGetCell(g_zclass_grav, g_zombieclass[id]))                                            // Infection sound                      ArrayGetString(zombie_infect, random_num(0, ArraySize(zombie_infect) - 1), sound, charsmax(sound))                      emit_sound(id, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)                                            // Show Infection HUD notice                      set_hudmessage(255, 0, 0, HUD_INFECT_X, HUD_INFECT_Y, 0, 0.0, 5.0, 1.0, 1.0, -1)                                            if (infector) // infected by someone?                             ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_INFECT2", g_playername[id], g_playername[infector])                      else                             ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_INFECT", g_playername[id])               }        }        else        {               // Silent mode, no HUD messages, no infection sounds                              // Set health and gravity, unless frozen               fm_set_user_health(id, ArrayGetCell(g_zclass_hp, g_zombieclass[id]))               if (!g_frozen[id]) set_pev(id, pev_gravity, Float:ArrayGetCell(g_zclass_grav, g_zombieclass[id]))        }                // Remove previous tasks        remove_task(id+TASK_MODEL)        remove_task(id+TASK_BLOOD)        remove_task(id+TASK_AURA)        remove_task(id+TASK_BURN)                // Switch to T        if (fm_cs_get_user_team(id) != FM_CS_TEAM_T) // need to change team?        {               remove_task(id+TASK_TEAM)               fm_cs_set_user_team(id, FM_CS_TEAM_T)               fm_user_team_update(id)        }                // Custom models stuff        static currentmodel[32], tempmodel[32], already_has_model, i, iRand, size        already_has_model = false                if (g_handle_models_on_separate_ent)        {               // Set the right model               if (g_nemesis[id])               {                      iRand = random_num(0, ArraySize(model_nemesis) - 1)                      ArrayGetString(model_nemesis, iRand, g_playermodel[id], charsmax(g_playermodel[]))                      if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_nemesis, iRand))               }               else               {                      if (get_pcvar_num(cvar_adminmodelszombie) && (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS]))                      {                             iRand = random_num(0, ArraySize(model_admin_zombie) - 1)                             ArrayGetString(model_admin_zombie, iRand, g_playermodel[id], charsmax(g_playermodel[]))                             if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_admin_zombie, iRand))                      }                      else                      {                             iRand = random_num(ArrayGetCell(g_zclass_modelsstart, g_zombieclass[id]), ArrayGetCell(g_zclass_modelsend, g_zombieclass[id]) - 1)                             ArrayGetString(g_zclass_playermodel, iRand, g_playermodel[id], charsmax(g_playermodel[]))                             if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_zclass_modelindex, iRand))                      }               }                              // Set model on player model entity               fm_set_playermodel_ent(id)                              // Nemesis glow / remove glow on player model entity, unless frozen               if (!g_frozen[id])               {                      if (g_nemesis[id] && get_pcvar_num(cvar_nemglow))                             fm_set_rendering(g_ent_playermodel[id], kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 25)                      else                             fm_set_rendering(g_ent_playermodel[id])               }        }        else        {               // Get current model for comparing it with the current one               fm_cs_get_user_model(id, currentmodel, charsmax(currentmodel))                              // Set the right model, after checking that we don't already have it               if (g_nemesis[id])               {                      size = ArraySize(model_nemesis)                      for (i = 0; i < size; i++)                      {                             ArrayGetString(model_nemesis, i, tempmodel, charsmax(tempmodel))                             if (equal(currentmodel, tempmodel)) already_has_model = true                      }                                            if (!already_has_model)                      {                             iRand = random_num(0, size - 1)                             ArrayGetString(model_nemesis, iRand, g_playermodel[id], charsmax(g_playermodel[]))                             if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_nemesis, iRand))                      }               }               else               {                      if (get_pcvar_num(cvar_adminmodelszombie) && (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS]))                      {                             size = ArraySize(model_admin_zombie)                             for (i = 0; i < size; i++)                             {                                    ArrayGetString(model_admin_zombie, i, tempmodel, charsmax(tempmodel))                                    if (equal(currentmodel, tempmodel)) already_has_model = true                             }                                                          if (!already_has_model)                             {                                    iRand = random_num(0, size - 1)                                    ArrayGetString(model_admin_zombie, iRand, g_playermodel[id], charsmax(g_playermodel[]))                                    if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_admin_zombie, iRand))                             }                      }                      else                      { //*****                             new temp1 = ArrayGetCell(g_zclass_modelsstart, g_zombieclass[id])                             new temp2 = ArrayGetCell(g_zclass_modelsend, g_zombieclass[id])                                                          //for (i = ArrayGetCell(g_zclass_modelsstart, g_zombieclass[id]); i < ArrayGetCell(g_zclass_modelsend, g_zombieclass[id]); i++)                             for (i = temp1; i < temp2; i++)                             {                                    ArrayGetString(g_zclass_playermodel, i, tempmodel, charsmax(tempmodel))                                    if (equal(currentmodel, tempmodel)) already_has_model = true                             }                                                          if (!already_has_model)                             {                                    iRand = random_num(ArrayGetCell(g_zclass_modelsstart, g_zombieclass[id]), ArrayGetCell(g_zclass_modelsend, g_zombieclass[id]) - 1)                                    ArrayGetString(g_zclass_playermodel, iRand, g_playermodel[id], charsmax(g_playermodel[]))                                    if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_zclass_modelindex, iRand))                             }                      }               }                              // Need to change the model?               if (!already_has_model)               {                      // An additional delay is offset at round start                      // since SVC_BAD is more likely to be triggered there                      if (g_newround)                             set_task(5.0 * g_modelchange_delay, "fm_user_model_update", id+TASK_MODEL)                      else                             fm_user_model_update(id+TASK_MODEL)               }                              // Nemesis glow / remove glow, unless frozen               if (!g_frozen[id])               {                      if (g_nemesis[id] && get_pcvar_num(cvar_nemglow))                             fm_set_rendering(id, kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 25)                      else                             fm_set_rendering(id)               }        }                // Remove any zoom (bugfix)        cs_set_user_zoom(id, CS_RESET_ZOOM, 1)                // Remove armor        set_pev(id, pev_armorvalue, 0.0)                // Drop weapons when infected        drop_weapons(id, 1)        drop_weapons(id, 2)                // Strip zombies from guns and give them a knife        fm_strip_user_weapons(id)        fm_give_item(id, "weapon_knife")                // Fancy effects        infection_effects(id)                // Nemesis aura task        if (g_nemesis[id] && get_pcvar_num(cvar_nemaura))               set_task(0.1, "zombie_aura", id+TASK_AURA, _, _, "b")                // Give Zombies Night Vision?        if (get_pcvar_num(cvar_nvggive))        {               g_nvision[id] = true                              if (!g_isbot[id])               {                      // Turn on Night Vision automatically?                      if (get_pcvar_num(cvar_nvggive) == 1)                      {                             g_nvisionenabled[id] = true                                                          // Custom nvg?                             if (get_pcvar_num(cvar_customnvg))                             {                                    remove_task(id+TASK_NVISION)                                    set_task(0.1, "set_user_nvision", id+TASK_NVISION, _, _, "b")                             }                             else                                    set_user_gnvision(id, 1)                      }                      // Turn off nightvision when infected (bugfix)                      else if (g_nvisionenabled[id])                      {                             if (get_pcvar_num(cvar_customnvg)) remove_task(id+TASK_NVISION)                             else set_user_gnvision(id, 0)                             g_nvisionenabled[id] = false                      }               }               else                      cs_set_user_nvg(id, 1); // turn on NVG for bots        }        // Disable nightvision when infected (bugfix)        else if (g_nvision[id])        {               if (g_isbot[id]) cs_set_user_nvg(id, 0) // Turn off NVG for bots               if (get_pcvar_num(cvar_customnvg)) remove_task(id+TASK_NVISION)               else if (g_nvisionenabled[id]) set_user_gnvision(id, 0)               g_nvision[id] = false               g_nvisionenabled[id] = false        }                // Set custom FOV?        if (get_pcvar_num(cvar_zombiefov) != 90 && get_pcvar_num(cvar_zombiefov) != 0)        {               message_begin(MSG_ONE, g_msgSetFOV, _, id)               write_byte(get_pcvar_num(cvar_zombiefov)) // fov angle               message_end()        }                // Call the bloody task        if (!g_nemesis[id] && get_pcvar_num(cvar_zombiebleeding))               set_task(0.7, "make_blood", id+TASK_BLOOD, _, _, "b")                // Idle sounds task        if (!g_nemesis[id])               set_task(random_float(50.0, 70.0), "zombie_play_idle", id+TASK_BLOOD, _, _, "b")                // Turn off zombie's flashlight        turn_off_flashlight(id)                // Post user infect forward        ExecuteForward(g_fwUserInfected_post, g_fwDummyResult, id, infector, nemesis)                // Last Zombie Check        fnCheckLastZombie() }
  // Function Human Me (player id, turn into a survivor, silent mode) humanme(id, survivor, silentmode) {        // User humanize attempt forward        ExecuteForward(g_fwUserHumanize_attempt, g_fwDummyResult, id, survivor)                // One or more plugins blocked the "humanization". Only allow this after making sure it's        // not going to leave us with no humans. Take into account a last player leaving case.        // BUGFIX: only allow after a mode has started, to prevent blocking first survivor e.g.        if (g_fwDummyResult >= ZP_PLUGIN_HANDLED && g_modestarted && fnGetHumans() > g_lastplayerleaving)               return;                // Pre user humanize forward        ExecuteForward(g_fwUserHumanized_pre, g_fwDummyResult, id, survivor)                // Remove previous tasks        remove_task(id+TASK_MODEL)        remove_task(id+TASK_BLOOD)        remove_task(id+TASK_AURA)        remove_task(id+TASK_BURN)        remove_task(id+TASK_NVISION)                // Reset some vars        g_zombie[id] = false        g_nemesis[id] = false        g_survivor[id] = false        g_firstzombie[id] = false        g_canbuy[id] = true        g_nvision[id] = false        g_nvisionenabled[id] = false                // Remove survivor's aura (bugfix)        set_pev(id, pev_effects, pev(id, pev_effects) &~ EF_BRIGHTLIGHT)                // Remove spawn protection (bugfix)        g_nodamage[id] = false        set_pev(id, pev_effects, pev(id, pev_effects) &~ EF_NODRAW)                // Reset burning duration counter (bugfix)        g_burning_duration[id] = 0                // Drop previous weapons        drop_weapons(id, 1)        drop_weapons(id, 2)                // Strip off from weapons        fm_strip_user_weapons(id)        fm_give_item(id, "weapon_knife")                // Set human attributes based on the mode        if (survivor)        {               // Survivor               g_survivor[id] = true                              // Set Health [0 = auto]               if (get_pcvar_num(cvar_survhp) == 0)               {                      if (get_pcvar_num(cvar_survbasehp) == 0)                             fm_set_user_health(id, get_pcvar_num(cvar_humanhp) * fnGetAlive())                      else                             fm_set_user_health(id, get_pcvar_num(cvar_survbasehp) * fnGetAlive())               }               else                      fm_set_user_health(id, get_pcvar_num(cvar_survhp))                              // Set gravity, unless frozen               if (!g_frozen[id]) set_pev(id, pev_gravity, get_pcvar_float(cvar_survgravity))                              // Give survivor his own weapon               static survweapon[32]               get_pcvar_string(cvar_survweapon, survweapon, charsmax(survweapon))               fm_give_item(id, survweapon)               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)])                              // Turn off his flashlight               turn_off_flashlight(id)                              // Give the survivor a bright light               if (get_pcvar_num(cvar_survaura)) set_pev(id, pev_effects, pev(id, pev_effects) | EF_BRIGHTLIGHT)                              // Survivor bots will also need nightvision to see in the dark               if (g_isbot[id])               {                      g_nvision[id] = true                      cs_set_user_nvg(id, 1)               }        }        else        {               // Human taking an antidote                              // Set health               fm_set_user_health(id, get_pcvar_num(cvar_humanhp))                              // Set gravity, unless frozen               if (!g_frozen[id]) set_pev(id, pev_gravity, get_pcvar_float(cvar_humangravity))                              // Show custom buy menu?               if (get_pcvar_num(cvar_buycustom))                      set_task(0.2, "show_menu_buy1", id+TASK_SPAWN)                              // Silent mode = no HUD messages, no antidote sound               if (!silentmode)               {                      // Antidote sound                      static sound[64]                      ArrayGetString(sound_antidote, random_num(0, ArraySize(sound_antidote) - 1), sound, charsmax(sound))                      emit_sound(id, CHAN_ITEM, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)                                            // Show Antidote HUD notice                      set_hudmessage(0, 0, 255, HUD_INFECT_X, HUD_INFECT_Y, 0, 0.0, 5.0, 1.0, 1.0, -1)                      ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_ANTIDOTE", g_playername[id])               }        }                // Switch to CT        if (fm_cs_get_user_team(id) != FM_CS_TEAM_CT) // need to change team?        {               remove_task(id+TASK_TEAM)               fm_cs_set_user_team(id, FM_CS_TEAM_CT)               fm_user_team_update(id)        }                // Custom models stuff        static currentmodel[32], tempmodel[32], already_has_model, i, iRand, size        already_has_model = false                if (g_handle_models_on_separate_ent)        {               // Set the right model               if (g_survivor[id])               {                      iRand = random_num(0, ArraySize(model_survivor) - 1)                      ArrayGetString(model_survivor, iRand, g_playermodel[id], charsmax(g_playermodel[]))                      if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_survivor, iRand))               }               else               {                      if (get_pcvar_num(cvar_adminmodelshuman) && (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS]))                      {                             iRand = random_num(0, ArraySize(model_admin_human) - 1)                             ArrayGetString(model_admin_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))                             if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_admin_human, iRand))                      }                      else                      {                             iRand = random_num(0, ArraySize(model_human) - 1)                             ArrayGetString(model_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))                             if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_human, iRand))                      }               }                              // Set model on player model entity               fm_set_playermodel_ent(id)                              // Set survivor glow / remove glow on player model entity, unless frozen               if (!g_frozen[id])               {                      if (g_survivor[id] && get_pcvar_num(cvar_survglow))                             fm_set_rendering(g_ent_playermodel[id], kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 25)                      else                             fm_set_rendering(g_ent_playermodel[id])               }        }        else        {               // Get current model for comparing it with the current one               fm_cs_get_user_model(id, currentmodel, charsmax(currentmodel))                              // Set the right model, after checking that we don't already have it               if (g_survivor[id])               {                      size = ArraySize(model_survivor)                      for (i = 0; i < size; i++)                      {                             ArrayGetString(model_survivor, i, tempmodel, charsmax(tempmodel))                             if (equal(currentmodel, tempmodel)) already_has_model = true                      }                                            if (!already_has_model)                      {                             iRand = random_num(0, size - 1)                             ArrayGetString(model_survivor, iRand, g_playermodel[id], charsmax(g_playermodel[]))                             if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_survivor, iRand))                      }               }               else               {                      if (get_pcvar_num(cvar_adminmodelshuman) && (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS]))                      {                             size = ArraySize(model_admin_human)                             for (i = 0; i < size; i++)                             {                                    ArrayGetString(model_admin_human, i, tempmodel, charsmax(tempmodel))                                    if (equal(currentmodel, tempmodel)) already_has_model = true                             }                                                          if (!already_has_model)                             {                                    iRand = random_num(0, size - 1)                                    ArrayGetString(model_admin_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))                                    if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_admin_human, iRand))                             }                      }                      else                      {                             size = ArraySize(model_human)                             for (i = 0; i < size; i++)                             {                                    ArrayGetString(model_human, i, tempmodel, charsmax(tempmodel))                                    if (equal(currentmodel, tempmodel)) already_has_model = true                             }                                                          if (!already_has_model)                             {                                    iRand = random_num(0, size - 1)                                    ArrayGetString(model_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))                                    if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_human, iRand))                             }                      }               }                              // Need to change the model?               if (!already_has_model)               {                      // An additional delay is offset at round start                      // since SVC_BAD is more likely to be triggered there                      if (g_newround)                             set_task(5.0 * g_modelchange_delay, "fm_user_model_update", id+TASK_MODEL)                      else                             fm_user_model_update(id+TASK_MODEL)               }                              // Set survivor glow / remove glow, unless frozen               if (!g_frozen[id])               {                      if (g_survivor[id] && get_pcvar_num(cvar_survglow))                             fm_set_rendering(id, kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 25)                      else                             fm_set_rendering(id)               }        }                // Restore FOV?        if (get_pcvar_num(cvar_zombiefov) != 90 && get_pcvar_num(cvar_zombiefov) != 0)        {               message_begin(MSG_ONE, g_msgSetFOV, _, id)               write_byte(90) // angle               message_end()        }                // Disable nightvision        if (g_isbot[id]) cs_set_user_nvg(id, 0)        else if (!get_pcvar_num(cvar_customnvg) && g_nvisionenabled[id]) set_user_gnvision(id, 0)                // Post user humanize forward        ExecuteForward(g_fwUserHumanized_post, g_fwDummyResult, id, survivor)                // Last Zombie Check        fnCheckLastZombie() }
  /*================================================================================  [Other Functions and Tasks] =================================================================================*/
  public cache_cvars() {        g_cached_zombiesilent = get_pcvar_num(cvar_zombiesilent)        g_cached_customflash = get_pcvar_num(cvar_customflash)        g_cached_humanspd = get_pcvar_float(cvar_humanspd)        g_cached_nemspd = get_pcvar_float(cvar_nemspd)        g_cached_survspd = get_pcvar_float(cvar_survspd)        g_cached_leapzombies = get_pcvar_num(cvar_leapzombies)        g_cached_leapzombiescooldown = get_pcvar_float(cvar_leapzombiescooldown)        g_cached_leapnemesis = get_pcvar_num(cvar_leapnemesis)        g_cached_leapnemesiscooldown = get_pcvar_float(cvar_leapnemesiscooldown)        g_cached_leapsurvivor = get_pcvar_num(cvar_leapsurvivor)        g_cached_leapsurvivorcooldown = get_pcvar_float(cvar_leapsurvivorcooldown) }
  load_customization_from_files() {        // Build customization file path        new path[64]        get_configsdir(path, charsmax(path))        format(path, charsmax(path), "%s/%s", path, ZP_CUSTOMIZATION_FILE)                // File not present        if (!file_exists(path))        {               new error[100]               formatex(error, charsmax(error), "Cannot load customization file %s!", path)               set_fail_state(error)               return;        }                // Set up some vars to hold parsing info        new linedata[1024], key[64], value[960], section, teams                // Open customization file for reading        new file = fopen(path, "rt")                while (file && !feof(file))        {               // Read one line at a time               fgets(file, linedata, charsmax(linedata))                              // Replace newlines with a null character to prevent headaches               replace(linedata, charsmax(linedata), "^n", "")                              // Blank line or comment               if (!linedata[0] || linedata[0] == ';') continue;                              // New section starting               if (linedata[0] == '[')               {                      section++                      continue;               }                              // Get key and value(s)               strtok(linedata, key, charsmax(key), value, charsmax(value), '=')                              // Trim spaces               trim(key)               trim(value)                              switch (section)               {                      case SECTION_ACCESS_FLAGS:                      {                             if (equal(key, "ENABLE/DISABLE MOD"))                                    g_access_flag[ACCESS_ENABLE_MOD] = read_flags(value)                             else if (equal(key, "ADMIN MENU"))                                    g_access_flag[ACCESS_ADMIN_MENU] = read_flags(value)                             else if (equal(key, "START MODE INFECTION"))                                    g_access_flag[ACCESS_MODE_INFECTION] = read_flags(value)                             else if (equal(key, "START MODE NEMESIS"))                                    g_access_flag[ACCESS_MODE_NEMESIS] = read_flags(value)                             else if (equal(key, "START MODE SURVIVOR"))                                    g_access_flag[ACCESS_MODE_SURVIVOR] = read_flags(value)                             else if (equal(key, "START MODE SWARM"))                                    g_access_flag[ACCESS_MODE_SWARM] = read_flags(value)                             else if (equal(key, "START MODE MULTI"))                                    g_access_flag[ACCESS_MODE_MULTI] = read_flags(value)                             else if (equal(key, "START MODE PLAGUE"))                                    g_access_flag[ACCESS_MODE_PLAGUE] = read_flags(value)                             else if (equal(key, "MAKE ZOMBIE"))                                    g_access_flag[ACCESS_MAKE_ZOMBIE] = read_flags(value)                             else if (equal(key, "MAKE HUMAN"))                                    g_access_flag[ACCESS_MAKE_HUMAN] = read_flags(value)                             else if (equal(key, "MAKE NEMESIS"))                                    g_access_flag[ACCESS_MAKE_NEMESIS] = read_flags(value)                             else if (equal(key, "MAKE SURVIVOR"))                                    g_access_flag[ACCESS_MAKE_SURVIVOR] = read_flags(value)                             else if (equal(key, "RESPAWN PLAYERS"))                                    g_access_flag[ACCESS_RESPAWN_PLAYERS] = read_flags(value)                             else if (equal(key, "ADMIN MODELS"))                                    g_access_flag[ACCESS_ADMIN_MODELS] = read_flags(value)                      }                      case SECTION_PLAYER_MODELS:                      {                             if (equal(key, "HUMAN"))                             {                                    // Parse models                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to models array                                           ArrayPushString(model_human, key)                                    }                             }                             else if (equal(key, "NEMESIS"))                             {                                    // Parse models                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to models array                                           ArrayPushString(model_nemesis, key)                                    }                             }                             else if (equal(key, "SURVIVOR"))                             {                                    // Parse models                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to models array                                           ArrayPushString(model_survivor, key)                                    }                             }                             else if (equal(key, "ADMIN ZOMBIE"))                             {                                    // Parse models                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to models array                                           ArrayPushString(model_admin_zombie, key)                                    }                             }                             else if (equal(key, "ADMIN HUMAN"))                             {                                    // Parse models                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to models array                                           ArrayPushString(model_admin_human, key)                                    }                             }                             else if (equal(key, "FORCE CONSISTENCY"))                                    g_force_consistency = str_to_num(value)                             else if (equal(key, "SAME MODELS FOR ALL"))                                    g_same_models_for_all = str_to_num(value)                             else if (g_same_models_for_all && equal(key, "ZOMBIE"))                             {                                    // Parse models                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to models array                                           ArrayPushString(g_zclass_playermodel, key)                                                                                      // Precache model and retrieve its modelindex                                           formatex(linedata, charsmax(linedata), "models/player/%s/%s.mdl", key, key)                                           ArrayPushCell(g_zclass_modelindex, engfunc(EngFunc_PrecacheModel, linedata))                                           if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, linedata)                                           if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, linedata)                                    }                             }                      }                      case SECTION_WEAPON_MODELS:                      {                             if (equal(key, "V_KNIFE HUMAN"))                                    copy(model_vknife_human, charsmax(model_vknife_human), value)                             else if (equal(key, "V_KNIFE NEMESIS"))                                    copy(model_vknife_nemesis, charsmax(model_vknife_nemesis), value)                             else if (equal(key, "V_M249 SURVIVOR"))                                    copy(model_vm249_survivor, charsmax(model_vm249_survivor), value)                             else if (equal(key, "GRENADE INFECT"))                                    copy(model_grenade_infect, charsmax(model_grenade_infect), value)                             else if (equal(key, "GRENADE FIRE"))                                    copy(model_grenade_fire, charsmax(model_grenade_fire), value)                             else if (equal(key, "GRENADE FROST"))                                    copy(model_grenade_frost, charsmax(model_grenade_frost), value)                             else if (equal(key, "GRENADE FLARE"))                                    copy(model_grenade_flare, charsmax(model_grenade_flare), value)                             else if (equal(key, "V_KNIFE ADMIN HUMAN"))                                    copy(model_vknife_admin_human, charsmax(model_vknife_admin_human), value)                             else if (equal(key, "V_KNIFE ADMIN ZOMBIE"))                                    copy(model_vknife_admin_zombie, charsmax(model_vknife_admin_zombie), value)                      }                      case SECTION_GRENADE_SPRITES:                      {                             if (equal(key, "TRAIL"))                                    copy(sprite_grenade_trail, charsmax(sprite_grenade_trail), value)                             else if (equal(key, "RING"))                                    copy(sprite_grenade_ring, charsmax(sprite_grenade_ring), value)                             else if (equal(key, "FIRE"))                                    copy(sprite_grenade_fire, charsmax(sprite_grenade_fire), value)                             else if (equal(key, "SMOKE"))                                    copy(sprite_grenade_smoke, charsmax(sprite_grenade_smoke), value)                             else if (equal(key, "GLASS"))                                    copy(sprite_grenade_glass, charsmax(sprite_grenade_glass), value)                      }                      case SECTION_SOUNDS:                      {                             if (equal(key, "WIN ZOMBIES"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(sound_win_zombies, key)                                    }                             }                             else if (equal(key, "WIN HUMANS"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(sound_win_humans, key)                                    }                             }                             else if (equal(key, "WIN NO ONE"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(sound_win_no_one, key)                                    }                             }                             else if (equal(key, "ZOMBIE INFECT"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(zombie_infect, key)                                    }                             }                             else if (equal(key, "ZOMBIE PAIN"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(zombie_pain, key)                                    }                             }                             else if (equal(key, "NEMESIS PAIN"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(nemesis_pain, key)                                    }                             }                             else if (equal(key, "ZOMBIE DIE"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(zombie_die, key)                                    }                             }                             else if (equal(key, "ZOMBIE FALL"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(zombie_fall, key)                                    }                             }                             else if (equal(key, "ZOMBIE MISS SLASH"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(zombie_miss_slash, key)                                    }                             }                             else if (equal(key, "ZOMBIE MISS WALL"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(zombie_miss_wall, key)                                    }                             }                             else if (equal(key, "ZOMBIE HIT NORMAL"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(zombie_hit_normal, key)                                    }                             }                             else if (equal(key, "ZOMBIE HIT STAB"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(zombie_hit_stab, key)                                    }                             }                             else if (equal(key, "ZOMBIE IDLE"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(zombie_idle, key)                                    }                             }                             else if (equal(key, "ZOMBIE IDLE LAST"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(zombie_idle_last, key)                                    }                             }                             else if (equal(key, "ZOMBIE MADNESS"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(zombie_madness, key)                                    }                             }                             else if (equal(key, "ROUND NEMESIS"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(sound_nemesis, key)                                    }                             }                             else if (equal(key, "ROUND SURVIVOR"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(sound_survivor, key)                                    }                             }                             else if (equal(key, "ROUND SWARM"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(sound_swarm, key)                                    }                             }                             else if (equal(key, "ROUND MULTI"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(sound_multi, key)                                    }                             }                             else if (equal(key, "ROUND PLAGUE"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(sound_plague, key)                                    }                             }                             else if (equal(key, "GRENADE INFECT EXPLODE"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(grenade_infect, key)                                    }                             }                             else if (equal(key, "GRENADE INFECT PLAYER"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(grenade_infect_player, key)                                    }                             }                             else if (equal(key, "GRENADE FIRE EXPLODE"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(grenade_fire, key)                                    }                             }                             else if (equal(key, "GRENADE FIRE PLAYER"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(grenade_fire_player, key)                                    }                             }                             else if (equal(key, "GRENADE FROST EXPLODE"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(grenade_frost, key)                                    }                             }                             else if (equal(key, "GRENADE FROST PLAYER"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(grenade_frost_player, key)                                    }                             }                             else if (equal(key, "GRENADE FROST BREAK"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(grenade_frost_break, key)                                    }                             }                             else if (equal(key, "GRENADE FLARE"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(grenade_flare, key)                                    }                             }                             else if (equal(key, "ANTIDOTE"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(sound_antidote, key)                                    }                             }                             else if (equal(key, "THUNDER"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(sound_thunder, key)                                    }                             }                      }                      case SECTION_AMBIENCE_SOUNDS:                      {                             if (equal(key, "INFECTION ENABLE"))                                    g_ambience_sounds[AMBIENCE_SOUNDS_INFECTION] = str_to_num(value)                             else if (g_ambience_sounds[AMBIENCE_SOUNDS_INFECTION] && equal(key, "INFECTION SOUNDS"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(sound_ambience1, key)                                           ArrayPushCell(sound_ambience1_ismp3, equal(key[strlen(key)-4], ".mp3") ? 1 : 0)                                    }                             }                             else if (g_ambience_sounds[AMBIENCE_SOUNDS_INFECTION] && equal(key, "INFECTION DURATIONS"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushCell(sound_ambience1_duration, str_to_num(key))                                    }                             }                             else if (equal(key, "NEMESIS ENABLE"))                                    g_ambience_sounds[AMBIENCE_SOUNDS_NEMESIS] = str_to_num(value)                             else if (g_ambience_sounds[AMBIENCE_SOUNDS_NEMESIS] && equal(key, "NEMESIS SOUNDS"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(sound_ambience2, key)                                           ArrayPushCell(sound_ambience2_ismp3, equal(key[strlen(key)-4], ".mp3") ? 1 : 0)                                    }                             }                             else if (g_ambience_sounds[AMBIENCE_SOUNDS_NEMESIS] && equal(key, "NEMESIS DURATIONS"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushCell(sound_ambience2_duration, str_to_num(key))                                    }                             }                             else if (equal(key, "SURVIVOR ENABLE"))                                    g_ambience_sounds[AMBIENCE_SOUNDS_SURVIVOR] = str_to_num(value)                             else if (g_ambience_sounds[AMBIENCE_SOUNDS_SURVIVOR] && equal(key, "SURVIVOR SOUNDS"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(sound_ambience3, key)                                           ArrayPushCell(sound_ambience3_ismp3, equal(key[strlen(key)-4], ".mp3") ? 1 : 0)                                    }                             }                             else if (g_ambience_sounds[AMBIENCE_SOUNDS_SURVIVOR] && equal(key, "SURVIVOR DURATIONS"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushCell(sound_ambience3_duration, str_to_num(key))                                    }                             }                             else if (equal(key, "SWARM ENABLE"))                                    g_ambience_sounds[AMBIENCE_SOUNDS_SWARM] = str_to_num(value)                             else if (g_ambience_sounds[AMBIENCE_SOUNDS_SWARM] && equal(key, "SWARM SOUNDS"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(sound_ambience4, key)                                           ArrayPushCell(sound_ambience4_ismp3, equal(key[strlen(key)-4], ".mp3") ? 1 : 0)                                    }                             }                             else if (g_ambience_sounds[AMBIENCE_SOUNDS_SWARM] && equal(key, "SWARM DURATIONS"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushCell(sound_ambience4_duration, str_to_num(key))                                    }                             }                             else if (equal(key, "PLAGUE ENABLE"))                                    g_ambience_sounds[AMBIENCE_SOUNDS_PLAGUE] = str_to_num(value)                             else if (g_ambience_sounds[AMBIENCE_SOUNDS_PLAGUE] && equal(key, "PLAGUE SOUNDS"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushString(sound_ambience5, key)                                           ArrayPushCell(sound_ambience5_ismp3, equal(key[strlen(key)-4], ".mp3") ? 1 : 0)                                    }                             }                             else if (g_ambience_sounds[AMBIENCE_SOUNDS_PLAGUE] && equal(key, "PLAGUE DURATIONS"))                             {                                    // Parse sounds                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to sounds array                                           ArrayPushCell(sound_ambience5_duration, str_to_num(key))                                    }                             }                      }                      case SECTION_BUY_MENU_WEAPONS:                      {                             if (equal(key, "PRIMARY"))                             {                                    // Parse weapons                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to weapons array                                           ArrayPushString(g_primary_items, key)                                           ArrayPushCell(g_primary_weaponids, cs_weapon_name_to_id(key))                                    }                             }                             else if (equal(key, "SECONDARY"))                             {                                    // Parse weapons                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to weapons array                                           ArrayPushString(g_secondary_items, key)                                           ArrayPushCell(g_secondary_weaponids, cs_weapon_name_to_id(key))                                    }                             }                             else if (equal(key, "ADDITIONAL ITEMS"))                             {                                    // Parse weapons                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to weapons array                                           ArrayPushString(g_additional_items, key)                                    }                             }                      }                      case SECTION_EXTRA_ITEMS_WEAPONS:                      {                             if (equal(key, "NAMES"))                             {                                    // Parse weapon items                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to weapons array                                           ArrayPushString(g_extraweapon_names, key)                                    }                             }                             else if (equal(key, "ITEMS"))                             {                                    // Parse weapon items                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to weapons array                                           ArrayPushString(g_extraweapon_items, key)                                    }                             }                             else if (equal(key, "COSTS"))                             {                                    // Parse weapon items                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to weapons array                                           ArrayPushCell(g_extraweapon_costs, str_to_num(key))                                    }                             }                      }                      case SECTION_HARD_CODED_ITEMS_COSTS:                      {                             if (equal(key, "NIGHT VISION"))                                    g_extra_costs2[EXTRA_NVISION] = str_to_num(value)                             else if (equal(key, "ANTIDOTE"))                                    g_extra_costs2[EXTRA_ANTIDOTE] = str_to_num(value)                             else if (equal(key, "ZOMBIE MADNESS"))                                    g_extra_costs2[EXTRA_MADNESS] = str_to_num(value)                             else if (equal(key, "INFECTION BOMB"))                                    g_extra_costs2[EXTRA_INFBOMB] = str_to_num(value)                      }                      case SECTION_WEATHER_EFFECTS:                      {                             if (equal(key, "RAIN"))                                    g_ambience_rain = str_to_num(value)                             else if (equal(key, "SNOW"))                                    g_ambience_snow = str_to_num(value)                             else if (equal(key, "FOG"))                                    g_ambience_fog = str_to_num(value)                             else if (equal(key, "FOG DENSITY"))                                    copy(g_fog_density, charsmax(g_fog_density), value)                             else if (equal(key, "FOG COLOR"))                                    copy(g_fog_color, charsmax(g_fog_color), value)                      }                      case SECTION_SKY:                      {                             if (equal(key, "ENABLE"))                                    g_sky_enable = str_to_num(value)                             else if (equal(key, "SKY NAMES"))                             {                                    // Parse sky names                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to skies array                                           ArrayPushString(g_sky_names, key)                                                                                      // Preache custom sky files                                           formatex(linedata, charsmax(linedata), "gfx/env/%sbk.tga", key)                                           engfunc(EngFunc_PrecacheGeneric, linedata)                                           formatex(linedata, charsmax(linedata), "gfx/env/%sdn.tga", key)                                           engfunc(EngFunc_PrecacheGeneric, linedata)                                           formatex(linedata, charsmax(linedata), "gfx/env/%sft.tga", key)                                           engfunc(EngFunc_PrecacheGeneric, linedata)                                           formatex(linedata, charsmax(linedata), "gfx/env/%slf.tga", key)                                           engfunc(EngFunc_PrecacheGeneric, linedata)                                           formatex(linedata, charsmax(linedata), "gfx/env/%srt.tga", key)                                           engfunc(EngFunc_PrecacheGeneric, linedata)                                           formatex(linedata, charsmax(linedata), "gfx/env/%sup.tga", key)                                           engfunc(EngFunc_PrecacheGeneric, linedata)                                    }                             }                      }                      case SECTION_LIGHTNING:                      {                             if (equal(key, "LIGHTS"))                             {                                    // Parse lights                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to lightning array                                           ArrayPushString(lights_thunder, key)                                    }                             }                      }                      case SECTION_ZOMBIE_DECALS:                      {                             if (equal(key, "DECALS"))                             {                                    // Parse decals                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to zombie decals array                                           ArrayPushCell(zombie_decals, str_to_num(key))                                    }                             }                      }                      case SECTION_KNOCKBACK:                      {                             // Format weapon entity name                             strtolower(key)                             format(key, charsmax(key), "weapon_%s", key)                                                          // Add value to knockback power array                             kb_weapon_power[cs_weapon_name_to_id(key)] = str_to_float(value)                      }                      case SECTION_OBJECTIVE_ENTS:                      {                             if (equal(key, "CLASSNAMES"))                             {                                    // Parse classnames                                    while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                                    {                                           // Trim spaces                                           trim(key)                                           trim(value)                                                                                      // Add to objective ents array                                           ArrayPushString(g_objective_ents, key)                                    }                             }                      }                      case SECTION_SVC_BAD:                      {                             if (equal(key, "MODELCHANGE DELAY"))                                    g_modelchange_delay = str_to_float(value)                             else if (equal(key, "HANDLE MODELS ON SEPARATE ENT"))                                    g_handle_models_on_separate_ent = str_to_num(value)                             else if (equal(key, "SET MODELINDEX OFFSET"))                                    g_set_modelindex_offset = str_to_num(value)                      }               }        }        if (file) fclose(file)                // Build zombie classes file path        get_configsdir(path, charsmax(path))        format(path, charsmax(path), "%s/%s", path, ZP_ZOMBIECLASSES_FILE)                // Parse if present        if (file_exists(path))        {               // Open zombie classes file for reading               file = fopen(path, "rt")                              while (file && !feof(file))               {                      // Read one line at a time                      fgets(file, linedata, charsmax(linedata))                                            // Replace newlines with a null character to prevent headaches                      replace(linedata, charsmax(linedata), "^n", "")                                            // Blank line or comment                      if (!linedata[0] || linedata[0] == ';') continue;                                            // New class starting                      if (linedata[0] == '[')                      {                             // Remove first and last characters (braces)                             linedata[strlen(linedata) - 1] = 0                             copy(linedata, charsmax(linedata), linedata[1])                                                          // Store its real name for future reference                             ArrayPushString(g_zclass2_realname, linedata)                             continue;                      }                                            // Get key and value(s)                      strtok(linedata, key, charsmax(key), value, charsmax(value), '=')                                            // Trim spaces                      trim(key)                      trim(value)                                            if (equal(key, "NAME"))                             ArrayPushString(g_zclass2_name, value)                      else if (equal(key, "INFO"))                             ArrayPushString(g_zclass2_info, value)                      else if (equal(key, "MODELS"))                      {                             // Set models start index                             ArrayPushCell(g_zclass2_modelsstart, ArraySize(g_zclass2_playermodel))                                                          // Parse class models                             while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                             {                                    // Trim spaces                                    trim(key)                                    trim(value)                                                                        // Add to class models array                                    ArrayPushString(g_zclass2_playermodel, key)                                    ArrayPushCell(g_zclass2_modelindex, -1)                             }                                                          // Set models end index                             ArrayPushCell(g_zclass2_modelsend, ArraySize(g_zclass2_playermodel))                      }                      else if (equal(key, "CLAWMODEL"))                             ArrayPushString(g_zclass2_clawmodel, value)                      else if (equal(key, "HEALTH"))                             ArrayPushCell(g_zclass2_hp, str_to_num(value))                      else if (equal(key, "SPEED"))                             ArrayPushCell(g_zclass2_spd, str_to_num(value))                      else if (equal(key, "GRAVITY"))                             ArrayPushCell(g_zclass2_grav, str_to_float(value))                      else if (equal(key, "KNOCKBACK"))                             ArrayPushCell(g_zclass2_kb, str_to_float(value))               }               if (file) fclose(file)        }                // Build extra items file path        get_configsdir(path, charsmax(path))        format(path, charsmax(path), "%s/%s", path, ZP_EXTRAITEMS_FILE)                // Parse if present        if (file_exists(path))        {               // Open extra items file for reading               file = fopen(path, "rt")                              while (file && !feof(file))               {                      // Read one line at a time                      fgets(file, linedata, charsmax(linedata))                                            // Replace newlines with a null character to prevent headaches                      replace(linedata, charsmax(linedata), "^n", "")                                            // Blank line or comment                      if (!linedata[0] || linedata[0] == ';') continue;                                            // New item starting                      if (linedata[0] == '[')                      {                             // Remove first and last characters (braces)                             linedata[strlen(linedata) - 1] = 0                             copy(linedata, charsmax(linedata), linedata[1])                                                          // Store its real name for future reference                             ArrayPushString(g_extraitem2_realname, linedata)                             continue;                      }                                            // Get key and value(s)                      strtok(linedata, key, charsmax(key), value, charsmax(value), '=')                                            // Trim spaces                      trim(key)                      trim(value)                                            if (equal(key, "NAME"))                             ArrayPushString(g_extraitem2_name, value)                      else if (equal(key, "COST"))                             ArrayPushCell(g_extraitem2_cost, str_to_num(value))                      else if (equal(key, "TEAMS"))                      {                             // Clear teams bitsum                             teams = 0                                                          // Parse teams                             while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))                             {                                    // Trim spaces                                    trim(key)                                    trim(value)                                                                        if (equal(key, ZP_TEAM_NAMES[ZP_TEAM_ZOMBIE]))                                           teams |= ZP_TEAM_ZOMBIE                                    else if (equal(key, ZP_TEAM_NAMES[ZP_TEAM_HUMAN]))                                           teams |= ZP_TEAM_HUMAN                                    else if (equal(key, ZP_TEAM_NAMES[ZP_TEAM_NEMESIS]))                                           teams |= ZP_TEAM_NEMESIS                                    else if (equal(key, ZP_TEAM_NAMES[ZP_TEAM_SURVIVOR]))                                           teams |= ZP_TEAM_SURVIVOR                             }                                                          // Add to teams array                             ArrayPushCell(g_extraitem2_team, teams)                      }               }               if (file) fclose(file)        } }
  save_customization() {        new i, k, buffer[512]                // Build zombie classes file path        new path[64]        get_configsdir(path, charsmax(path))        format(path, charsmax(path), "%s/%s", path, ZP_ZOMBIECLASSES_FILE)                // Open zombie classes file for appending data        new file = fopen(path, "at"), size = ArraySize(g_zclass_name)                // Add any new zombie classes data at the end if needed        for (i = 0; i < size; i++)        {               if (ArrayGetCell(g_zclass_new, i))               {                      // Add real name                      ArrayGetString(g_zclass_name, i, buffer, charsmax(buffer))                      format(buffer, charsmax(buffer), "^n[%s]", buffer)                      fputs(file, buffer)                                            // Add caption                      ArrayGetString(g_zclass_name, i, buffer, charsmax(buffer))                      format(buffer, charsmax(buffer), "^nNAME = %s", buffer)                      fputs(file, buffer)                                            // Add info                      ArrayGetString(g_zclass_info, i, buffer, charsmax(buffer))                      format(buffer, charsmax(buffer), "^nINFO = %s", buffer)                      fputs(file, buffer)                       //*****                      new temp1 = ArrayGetCell(g_zclass_modelsstart, i)                      new temp2 = ArrayGetCell(g_zclass_modelsend, i)                                            // Add models                      //for (k = ArrayGetCell(g_zclass_modelsstart, i); k < ArrayGetCell(g_zclass_modelsend, i); k++)                      for (k = temp1; k < temp2; k++)                      { //*****                             new temp3 = ArrayGetCell(g_zclass_modelsstart, i)                                                          //if (k == ArrayGetCell(g_zclass_modelsstart, i))                             if (k == temp3)                             {                                    // First model, overwrite buffer                                    ArrayGetString(g_zclass_playermodel, k, buffer, charsmax(buffer))                             }                             else                             {                                    // Successive models, append to buffer                                    ArrayGetString(g_zclass_playermodel, k, path, charsmax(path))                                    format(buffer, charsmax(buffer), "%s , %s", buffer, path)                             }                      }                      format(buffer, charsmax(buffer), "^nMODELS = %s", buffer)                      fputs(file, buffer)                                            // Add clawmodel                      ArrayGetString(g_zclass_clawmodel, i, buffer, charsmax(buffer))                      format(buffer, charsmax(buffer), "^nCLAWMODEL = %s", buffer)                      fputs(file, buffer)                                            // Add health                      formatex(buffer, charsmax(buffer), "^nHEALTH = %d", ArrayGetCell(g_zclass_hp, i))                      fputs(file, buffer)                                            // Add speed                      formatex(buffer, charsmax(buffer), "^nSPEED = %d", ArrayGetCell(g_zclass_spd, i))                      fputs(file, buffer)                                            // Add gravity                      formatex(buffer, charsmax(buffer), "^nGRAVITY = %.2f", Float:ArrayGetCell(g_zclass_grav, i))                      fputs(file, buffer)                                            // Add knockback                      formatex(buffer, charsmax(buffer), "^nKNOCKBACK = %.2f^n", Float:ArrayGetCell(g_zclass_kb, i))                      fputs(file, buffer)               }        }        fclose(file)                // Build extra items file path        get_configsdir(path, charsmax(path))        format(path, charsmax(path), "%s/%s", path, ZP_EXTRAITEMS_FILE)                // Open extra items file for appending data        file = fopen(path, "at")        size = ArraySize(g_extraitem_name)                // Add any new extra items data at the end if needed        for (i = EXTRAS_CUSTOM_STARTID; i < size; i++)        {               if (ArrayGetCell(g_extraitem_new, i))               {                      // Add real name                      ArrayGetString(g_extraitem_name, i, buffer, charsmax(buffer))                      format(buffer, charsmax(buffer), "^n[%s]", buffer)                      fputs(file, buffer)                                            // Add caption                      ArrayGetString(g_extraitem_name, i, buffer, charsmax(buffer))                      format(buffer, charsmax(buffer), "^nNAME = %s", buffer)                      fputs(file, buffer)                                            // Add cost                      formatex(buffer, charsmax(buffer), "^nCOST = %d", ArrayGetCell(g_extraitem_cost, i))                      fputs(file, buffer)                                            // Add team                      formatex(buffer, charsmax(buffer), "^nTEAMS = %s^n", ZP_TEAM_NAMES[ArrayGetCell(g_extraitem_team, i)])                      fputs(file, buffer)               }        }        fclose(file)                // Free arrays containing class/item overrides        ArrayDestroy(g_zclass2_realname)        ArrayDestroy(g_zclass2_name)        ArrayDestroy(g_zclass2_info)        ArrayDestroy(g_zclass2_modelsstart)        ArrayDestroy(g_zclass2_modelsend)        ArrayDestroy(g_zclass2_playermodel)        ArrayDestroy(g_zclass2_modelindex)        ArrayDestroy(g_zclass2_clawmodel)        ArrayDestroy(g_zclass2_hp)        ArrayDestroy(g_zclass2_spd)        ArrayDestroy(g_zclass2_grav)        ArrayDestroy(g_zclass2_kb)        ArrayDestroy(g_zclass_new)        ArrayDestroy(g_extraitem2_realname)        ArrayDestroy(g_extraitem2_name)        ArrayDestroy(g_extraitem2_cost)        ArrayDestroy(g_extraitem2_team)        ArrayDestroy(g_extraitem_new) }
  // Register Ham Forwards for CZ bots public register_ham_czbots(id) {        // Make sure it's a CZ bot and it's still connected        if (g_hamczbots || !g_isconnected[id] || !get_pcvar_num(cvar_botquota))               return;                RegisterHamFromEntity(Ham_Spawn, id, "fw_PlayerSpawn_Post", 1)        RegisterHamFromEntity(Ham_Killed, id, "fw_PlayerKilled")        RegisterHamFromEntity(Ham_Killed, id, "fw_PlayerKilled_Post", 1)        RegisterHamFromEntity(Ham_TakeDamage, id, "fw_TakeDamage")        RegisterHamFromEntity(Ham_TakeDamage, id, "fw_TakeDamage_Post", 1)        RegisterHamFromEntity(Ham_TraceAttack, id, "fw_TraceAttack")                // Ham forwards for CZ bots succesfully registered        g_hamczbots = true                // If the bot has already spawned, call the forward manually for him        if (is_user_alive(id)) fw_PlayerSpawn_Post(id) }
  // Disable minmodels task public disable_minmodels(id) {        if (!g_isconnected[id]) return;        client_cmd(id, "cl_minmodels 0") }
  // Bots automatically buy extra items public bot_buy_extras(taskid) {        // Nemesis or Survivor bots have nothing to buy by default        if (!g_isalive[ID_SPAWN] || g_survivor[ID_SPAWN] || g_nemesis[ID_SPAWN])               return;                if (!g_zombie[ID_SPAWN]) // human bots        {               // Attempt to buy Night Vision               buy_extra_item(ID_SPAWN, EXTRA_NVISION)                              // Attempt to buy a weapon               buy_extra_item(ID_SPAWN, random_num(EXTRA_WEAPONS_STARTID, EXTRAS_CUSTOM_STARTID-1))        }        else // zombie bots        {               // Attempt to buy an Antidote               buy_extra_item(ID_SPAWN, EXTRA_ANTIDOTE)        } }
  // Refill BP Ammo Task public refill_bpammo(const args[], id) {        // Player died or turned into a zombie        if (!g_isalive[id] || g_zombie[id])               return;                set_msg_block(g_msgAmmoPickup, BLOCK_ONCE)        ExecuteHamB(Ham_GiveAmmo, id, MAXBPAMMO[REFILL_WEAPONID], AMMOTYPE[REFILL_WEAPONID], MAXBPAMMO[REFILL_WEAPONID]) }
  // Balance Teams Task balance_teams() {        // Get amount of users playing        static iPlayersnum        iPlayersnum = fnGetPlaying()                // No players, don't bother        if (iPlayersnum < 1) return;                // Split players evenly        static iTerrors, iMaxTerrors, id, team[33]        iMaxTerrors = iPlayersnum/2        iTerrors = 0                // First, set everyone to CT        for (id = 1; id <= g_maxplayers; id++)        {               // Skip if not connected               if (!g_isconnected[id])                      continue;                              team[id] = fm_cs_get_user_team(id)                              // Skip if not playing               if (team[id] == FM_CS_TEAM_SPECTATOR || team[id] == FM_CS_TEAM_UNASSIGNED)                      continue;                              // Set team               remove_task(id+TASK_TEAM)               fm_cs_set_user_team(id, FM_CS_TEAM_CT)               team[id] = FM_CS_TEAM_CT        }                // Then randomly set half of the players to Terrorists        while (iTerrors < iMaxTerrors)        {               // Keep looping through all players               if (++id > g_maxplayers) id = 1                              // Skip if not connected               if (!g_isconnected[id])                      continue;                              // Skip if not playing or already a Terrorist               if (team[id] != FM_CS_TEAM_CT)                      continue;                              // Random chance               if (random_num(0, 1))               {                      fm_cs_set_user_team(id, FM_CS_TEAM_T)                      team[id] = FM_CS_TEAM_T                      iTerrors++               }        } }
  // Welcome Message Task public welcome_msg() {        // Show mod info        zp_colored_print(0, "^x01**** ^x04%s^x01 ****", g_modname)        zp_colored_print(0, "^x04[ZP]^x01 %L", LANG_PLAYER, "NOTICE_INFO1")        if (!get_pcvar_num(cvar_infammo)) zp_colored_print(0, "^x04[ZP]^x01 %L", LANG_PLAYER, "NOTICE_INFO2")                // Show T-virus HUD notice        set_hudmessage(0, 125, 200, HUD_EVENT_X, HUD_EVENT_Y, 0, 0.0, 3.0, 2.0, 1.0, -1)        ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_VIRUS_FREE") }
  // Respawn Player Task public respawn_player_task(taskid) {        // Get player's team        static team        team = fm_cs_get_user_team(ID_SPAWN)                // Respawn player automatically if allowed on current round        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)))        {               // Infection rounds = none of the above               if (!get_pcvar_num(cvar_allowrespawninfection) && !g_survround && !g_nemround && !g_swarmround && !g_plagueround)                      return;                              // Override respawn as zombie setting on nemesis and survivor rounds               if (g_survround) g_respawn_as_zombie[ID_SPAWN] = true               else if (g_nemround) g_respawn_as_zombie[ID_SPAWN] = false                              respawn_player_manually(ID_SPAWN)        } }
  // Respawn Player Manually (called after respawn checks are done) respawn_player_manually(id) {        // Set proper team before respawning, so that the TeamInfo message that's sent doesn't confuse PODBots        if (g_respawn_as_zombie[id])               fm_cs_set_user_team(id, FM_CS_TEAM_T)        else               fm_cs_set_user_team(id, FM_CS_TEAM_CT)                // Respawning a player has never been so easy        ExecuteHamB(Ham_CS_RoundRespawn, id) }
  // Check Round Task -check that we still have both zombies and humans on a round- check_round(leaving_player) {        // Round ended or make_a_zombie task still active        if (g_endround || task_exists(TASK_MAKEZOMBIE))               return;                // Get alive players count        static iPlayersnum, id        iPlayersnum = fnGetAlive()                // Last alive player, don't bother        if (iPlayersnum < 2)               return;                // Last zombie disconnecting        if (g_zombie[leaving_player] && fnGetZombies() == 1)        {               // Only one CT left, don't bother               if (fnGetHumans() == 1 && fnGetCTs() == 1)                      return;                              // Pick a random one to take his place               while ((id = fnGetRandomAlive(random_num(1, iPlayersnum))) == leaving_player ) { /* keep looping */ }                              // Show last zombie left notice               zp_colored_print(0, "^x04[ZP]^x01 %L", LANG_PLAYER, "LAST_ZOMBIE_LEFT", g_playername[id])                              // Set player leaving flag               g_lastplayerleaving = true                              // Turn into a Nemesis or just a zombie?               if (g_nemesis[leaving_player])                      zombieme(id, 0, 1, 0, 0)               else                      zombieme(id, 0, 0, 0, 0)                              // Remove player leaving flag               g_lastplayerleaving = false                              // If Nemesis, set chosen player's health to that of the one who's leaving               if (get_pcvar_num(cvar_keephealthondisconnect) && g_nemesis[leaving_player])                      fm_set_user_health(id, pev(leaving_player, pev_health))        }                // Last human disconnecting        else if (!g_zombie[leaving_player] && fnGetHumans() == 1)        {               // Only one T left, don't bother               if (fnGetZombies() == 1 && fnGetTs() == 1)                      return;                              // Pick a random one to take his place               while ((id = fnGetRandomAlive(random_num(1, iPlayersnum))) == leaving_player ) { /* keep looping */ }                              // Show last human left notice               zp_colored_print(0, "^x04[ZP]^x01 %L", LANG_PLAYER, "LAST_HUMAN_LEFT", g_playername[id])                              // Set player leaving flag               g_lastplayerleaving = true                              // Turn into a Survivor or just a human?               if (g_survivor[leaving_player])                      humanme(id, 1, 0)               else                      humanme(id, 0, 0)                              // Remove player leaving flag               g_lastplayerleaving = false                              // If Survivor, set chosen player's health to that of the one who's leaving               if (get_pcvar_num(cvar_keephealthondisconnect) && g_survivor[leaving_player])                      fm_set_user_health(id, pev(leaving_player, pev_health))        } }
  // Lighting Effects Task public lighting_effects() {        // Cache some CVAR values at every 5 secs        cache_cvars()                // Get lighting style        static lighting[2]        get_pcvar_string(cvar_lighting, lighting, charsmax(lighting))        strtolower(lighting)                // Lighting disabled? ["0"]        if (lighting[0] == '0')               return;                // Darkest light settings?        if (lighting[0] >= 'a' && lighting[0] <= 'd')        {               static thunderclap_in_progress, Float:thunder               thunderclap_in_progress = task_exists(TASK_THUNDER)               thunder = get_pcvar_float(cvar_thunder)                              // Set thunderclap tasks if not existant               if (thunder > 0.0 && !task_exists(TASK_THUNDER_PRE) && !thunderclap_in_progress)               {                      g_lights_i = 0                      ArrayGetString(lights_thunder, random_num(0, ArraySize(lights_thunder) - 1), g_lights_cycle, charsmax(g_lights_cycle))                      g_lights_cycle_len = strlen(g_lights_cycle)                      set_task(thunder, "thunderclap", TASK_THUNDER_PRE)               }                              // Set lighting only when no thunderclaps are going on               if (!thunderclap_in_progress) engfunc(EngFunc_LightStyle, 0, lighting)        }        else        {               // Remove thunderclap tasks               remove_task(TASK_THUNDER_PRE)               remove_task(TASK_THUNDER)                              // Set lighting               engfunc(EngFunc_LightStyle, 0, lighting)        } }
  // Thunderclap task public thunderclap() {        // Play thunder sound        if (g_lights_i == 0)        {               static sound[64]               ArrayGetString(sound_thunder, random_num(0, ArraySize(sound_thunder) - 1), sound, charsmax(sound))               PlaySound(sound)        }                // Set lighting        static light[2]        light[0] = g_lights_cycle[g_lights_i]        engfunc(EngFunc_LightStyle, 0, light)                g_lights_i++                // Lighting cycle end?        if (g_lights_i >= g_lights_cycle_len)        {               remove_task(TASK_THUNDER)               lighting_effects()        }        // Lighting cycle start?        else if (!task_exists(TASK_THUNDER))               set_task(0.1, "thunderclap", TASK_THUNDER, _, _, "b") }
  // Ambience Sound Effects Task public ambience_sound_effects(taskid) {        // Play a random sound depending on the round        static sound[64], iRand, duration, ismp3                if (g_nemround) // Nemesis Mode        {               iRand = random_num(0, ArraySize(sound_ambience2) - 1)               ArrayGetString(sound_ambience2, iRand, sound, charsmax(sound))               duration = ArrayGetCell(sound_ambience2_duration, iRand)               ismp3 = ArrayGetCell(sound_ambience2_ismp3, iRand)        }        else if (g_survround) // Survivor Mode        {               iRand = random_num(0, ArraySize(sound_ambience3) - 1)               ArrayGetString(sound_ambience3, iRand, sound, charsmax(sound))               duration = ArrayGetCell(sound_ambience3_duration, iRand)               ismp3 = ArrayGetCell(sound_ambience3_ismp3, iRand)        }        else if (g_swarmround) // Swarm Mode        {               iRand = random_num(0, ArraySize(sound_ambience4) - 1)               ArrayGetString(sound_ambience4, iRand, sound, charsmax(sound))               duration = ArrayGetCell(sound_ambience4_duration, iRand)               ismp3 = ArrayGetCell(sound_ambience4_ismp3, iRand)        }        else if (g_plagueround) // Plague Mode        {               iRand = random_num(0, ArraySize(sound_ambience5) - 1)               ArrayGetString(sound_ambience5, iRand, sound, charsmax(sound))               duration = ArrayGetCell(sound_ambience5_duration, iRand)               ismp3 = ArrayGetCell(sound_ambience5_ismp3, iRand)        }        else // Infection Mode        {               iRand = random_num(0, ArraySize(sound_ambience1) - 1)               ArrayGetString(sound_ambience1, iRand, sound, charsmax(sound))               duration = ArrayGetCell(sound_ambience1_duration, iRand)               ismp3 = ArrayGetCell(sound_ambience1_ismp3, iRand)        }                // Play it on clients        if (ismp3)               client_cmd(0, "mp3 play ^"sound/%s^"", sound)        else               PlaySound(sound)                // Set the task for when the sound is done playing        set_task(float(duration), "ambience_sound_effects", TASK_AMBIENCESOUNDS) }
  // Ambience Sounds Stop Task ambience_sound_stop() {        client_cmd(0, "mp3 stop; stopsound") }
  // Flashlight Charge Task public flashlight_charge(taskid) {        // Drain or charge?        if (g_flashlight[ID_CHARGE])               g_flashbattery[ID_CHARGE] -= get_pcvar_num(cvar_flashdrain)        else               g_flashbattery[ID_CHARGE] += get_pcvar_num(cvar_flashcharge)                // Battery fully charged        if (g_flashbattery[ID_CHARGE] >= 100)        {               // Don't exceed 100%               g_flashbattery[ID_CHARGE] = 100                              // Update flashlight battery on HUD               message_begin(MSG_ONE, g_msgFlashBat, _, ID_CHARGE)               write_byte(100) // battery               message_end()                              // Task not needed anymore               remove_task(taskid);               return;        }                // Battery depleted        if (g_flashbattery[ID_CHARGE] <= 0)        {               // Turn it off               g_flashlight[ID_CHARGE] = false               g_flashbattery[ID_CHARGE] = 0                              // Play flashlight toggle sound               emit_sound(ID_CHARGE, CHAN_ITEM, sound_flashlight, 1.0, ATTN_NORM, 0, PITCH_NORM)                              // Update flashlight status on HUD               message_begin(MSG_ONE, g_msgFlashlight, _, ID_CHARGE)               write_byte(0) // toggle               write_byte(0) // battery               message_end()                              // Remove flashlight task for this player               remove_task(ID_CHARGE+TASK_FLASH)        }        else        {               // Update flashlight battery on HUD               message_begin(MSG_ONE_UNRELIABLE, g_msgFlashBat, _, ID_CHARGE)               write_byte(g_flashbattery[ID_CHARGE]) // battery               message_end()        } }
  // Remove Spawn Protection Task public remove_spawn_protection(taskid) {        // Not alive        if (!g_isalive[ID_SPAWN])               return;                // Remove spawn protection        g_nodamage[ID_SPAWN] = false        set_pev(ID_SPAWN, pev_effects, pev(ID_SPAWN, pev_effects) & ~EF_NODRAW) }
  // Hide Player's Money Task public task_hide_money(taskid) {        // Not alive        if (!g_isalive[ID_SPAWN])               return;                // Hide money        message_begin(MSG_ONE, g_msgHideWeapon, _, ID_SPAWN)        write_byte(HIDE_MONEY) // what to hide bitsum        message_end()                // Hide the HL crosshair that's drawn        message_begin(MSG_ONE, g_msgCrosshair, _, ID_SPAWN)        write_byte(0) // toggle        message_end() }
  // Turn Off Flashlight and Restore Batteries turn_off_flashlight(id) {        // Restore batteries for the next use        fm_cs_set_user_batteries(id, 100)                // Check if flashlight is on        if (pev(id, pev_effects) & EF_DIMLIGHT)        {               // Turn it off               set_pev(id, pev_impulse, IMPULSE_FLASHLIGHT)        }        else        {               // Clear any stored flashlight impulse (bugfix)               set_pev(id, pev_impulse, 0)        }                // Turn off custom flashlight        if (g_cached_customflash)        {               // Turn it off               g_flashlight[id] = false               g_flashbattery[id] = 100                              // Update flashlight HUD               message_begin(MSG_ONE, g_msgFlashlight, _, id)               write_byte(0) // toggle               write_byte(100) // battery               message_end()                              // Remove previous tasks               remove_task(id+TASK_CHARGE)               remove_task(id+TASK_FLASH)        } }
  // Infection Bomb Explosion infection_explode(ent) {        // Round ended (bugfix)        if (g_endround) return;                // Get origin        static Float:originF[3]        pev(ent, pev_origin, originF)                // Make the explosion        create_blast(originF)                // Infection nade explode sound        static sound[64]        ArrayGetString(grenade_infect, random_num(0, ArraySize(grenade_infect) - 1), sound, charsmax(sound))        emit_sound(ent, CHAN_WEAPON, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)                // Get attacker        static attacker        attacker = pev(ent, pev_owner)                // Collisions        static victim        victim = -1                while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, NADE_EXPLOSION_RADIUS)) != 0)        {               // Only effect alive non-spawnprotected humans               if (!is_user_valid_alive(victim) || g_zombie[victim] || g_nodamage[victim])                      continue;                              // Last human is killed               if (fnGetHumans() == 1)               {                      ExecuteHamB(Ham_Killed, victim, attacker, 0)                      continue;               }                              // Infected victim's sound               ArrayGetString(grenade_infect_player, random_num(0, ArraySize(grenade_infect_player) - 1), sound, charsmax(sound))               emit_sound(victim, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)                              // Turn into zombie               zombieme(victim, attacker, 0, 1, 1)        }                // Get rid of the grenade        engfunc(EngFunc_RemoveEntity, ent) }
  // Fire Grenade Explosion fire_explode(ent) {        // Get origin        static Float:originF[3]        pev(ent, pev_origin, originF)                // Make the explosion        create_blast2(originF)                // Fire nade explode sound        static sound[64]        ArrayGetString(grenade_fire, random_num(0, ArraySize(grenade_fire) - 1), sound, charsmax(sound))        emit_sound(ent, CHAN_WEAPON, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)                // Collisions        static victim        victim = -1                while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, NADE_EXPLOSION_RADIUS)) != 0)        {               // Only effect alive zombies               if (!is_user_valid_alive(victim) || !g_zombie[victim] || g_nodamage[victim])                      continue;                              // Heat icon?               if (get_pcvar_num(cvar_hudicons))               {                      message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, _, victim)                      write_byte(0) // damage save                      write_byte(0) // damage take                      write_long(DMG_BURN) // damage type                      write_coord(0) // x                      write_coord(0) // y                      write_coord(0) // z                      message_end()               }                              if (g_nemesis[victim]) // fire duration (nemesis is fire resistant)                      g_burning_duration[victim] += get_pcvar_num(cvar_fireduration)               else                      g_burning_duration[victim] += get_pcvar_num(cvar_fireduration) * 5                              // Set burning task on victim if not present               if (!task_exists(victim+TASK_BURN))                      set_task(0.2, "burning_flame", victim+TASK_BURN, _, _, "b")        }                // Get rid of the grenade        engfunc(EngFunc_RemoveEntity, ent) }
  // Frost Grenade Explosion frost_explode(ent) {        // Get origin        static Float:originF[3]        pev(ent, pev_origin, originF)                // Make the explosion        create_blast3(originF)                // Frost nade explode sound        static sound[64]        ArrayGetString(grenade_frost, random_num(0, ArraySize(grenade_frost) - 1), sound, charsmax(sound))        emit_sound(ent, CHAN_WEAPON, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)                // Collisions        static victim        victim = -1                while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, NADE_EXPLOSION_RADIUS)) != 0)        {               // Only effect alive unfrozen zombies               if (!is_user_valid_alive(victim) || !g_zombie[victim] || g_frozen[victim] || g_nodamage[victim])                      continue;                              // Nemesis shouldn't be frozen               if (g_nemesis[victim])               {                      // Get player's origin                      static origin2[3]                      get_user_origin(victim, origin2)                                            // Broken glass sound                      ArrayGetString(grenade_frost_break, random_num(0, ArraySize(grenade_frost_break) - 1), sound, charsmax(sound))                      emit_sound(victim, CHAN_BODY, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)                                            // Glass shatter                      message_begin(MSG_PVS, SVC_TEMPENTITY, origin2)                      write_byte(TE_BREAKMODEL) // TE id                      write_coord(origin2[0]) // x                      write_coord(origin2[1]) // y                      write_coord(origin2[2]+24) // z                      write_coord(16) // size x                      write_coord(16) // size y                      write_coord(16) // size z                      write_coord(random_num(-50, 50)) // velocity x                      write_coord(random_num(-50, 50)) // velocity y                      write_coord(25) // velocity z                      write_byte(10) // random velocity                      write_short(g_glassSpr) // model                      write_byte(10) // count                      write_byte(25) // life                      write_byte(BREAK_GLASS) // flags                      message_end()                                            continue;               }                              // Freeze icon?               if (get_pcvar_num(cvar_hudicons))               {                      message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, _, victim)                      write_byte(0) // damage save                      write_byte(0) // damage take                      write_long(DMG_DROWN) // damage type - DMG_FREEZE                      write_coord(0) // x                      write_coord(0) // y                      write_coord(0) // z                      message_end()               }                              // Light blue glow while frozen               if (g_handle_models_on_separate_ent)                      fm_set_rendering(g_ent_playermodel[victim], kRenderFxGlowShell, 0, 100, 200, kRenderNormal, 25)               else                      fm_set_rendering(victim, kRenderFxGlowShell, 0, 100, 200, kRenderNormal, 25)                              // Freeze sound               ArrayGetString(grenade_frost_player, random_num(0, ArraySize(grenade_frost_player) - 1), sound, charsmax(sound))               emit_sound(victim, CHAN_BODY, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)                              // Add a blue tint to their screen               message_begin(MSG_ONE, g_msgScreenFade, _, victim)               write_short(0) // duration               write_short(0) // hold time               write_short(FFADE_STAYOUT) // fade type               write_byte(0) // red               write_byte(50) // green               write_byte(200) // blue               write_byte(100) // alpha               message_end()                              // Prevent from jumping               if (pev(victim, pev_flags) & FL_ONGROUND)                      set_pev(victim, pev_gravity, 999999.9) // set really high               else                      set_pev(victim, pev_gravity, 0.000001) // no gravity                              // Set a task to remove the freeze               g_frozen[victim] = true;               set_task(get_pcvar_float(cvar_freezeduration), "remove_freeze", victim)        }                // Get rid of the grenade        engfunc(EngFunc_RemoveEntity, ent) }
  // Remove freeze task public remove_freeze(id) {        // Not alive or not frozen anymore        if (!g_isalive[id] || !g_frozen[id])               return;                // Unfreeze        g_frozen[id] = false;                // Restore gravity        if (g_zombie[id])        {               if (g_nemesis[id])                      set_pev(id, pev_gravity, get_pcvar_float(cvar_nemgravity))               else                      set_pev(id, pev_gravity, Float:ArrayGetCell(g_zclass_grav, g_zombieclass[id]))        }        else        {               if (g_survivor[id])                      set_pev(id, pev_gravity, get_pcvar_float(cvar_survgravity))               else                      set_pev(id, pev_gravity, get_pcvar_float(cvar_humangravity))        }                // Restore rendering        if (g_handle_models_on_separate_ent)        {               // Nemesis or Survivor glow / remove glow on player model entity               if (g_nemesis[id] && get_pcvar_num(cvar_nemglow))                      fm_set_rendering(g_ent_playermodel[id], kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 25)               else if (g_survivor[id] && get_pcvar_num(cvar_survglow))                      fm_set_rendering(g_ent_playermodel[id], kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 25)               else                      fm_set_rendering(g_ent_playermodel[id])        }        else        {               // Nemesis or Survivor glow / remove glow               if (g_nemesis[id] && get_pcvar_num(cvar_nemglow))                      fm_set_rendering(id, kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 25)               else if (g_survivor[id] && get_pcvar_num(cvar_survglow))                      fm_set_rendering(id, kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 25)               else                      fm_set_rendering(id)        }                // Gradually remove screen's blue tint        message_begin(MSG_ONE, g_msgScreenFade, _, id)        write_short(UNIT_SECOND) // duration        write_short(0) // hold time        write_short(FFADE_IN) // fade type        write_byte(0) // red        write_byte(50) // green        write_byte(200) // blue        write_byte(100) // alpha        message_end()                // Broken glass sound        static sound[64]        ArrayGetString(grenade_frost_break, random_num(0, ArraySize(grenade_frost_break) - 1), sound, charsmax(sound))        emit_sound(id, CHAN_BODY, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)                // Get player's origin        static origin2[3]        get_user_origin(id, origin2)                // Glass shatter        message_begin(MSG_PVS, SVC_TEMPENTITY, origin2)        write_byte(TE_BREAKMODEL) // TE id        write_coord(origin2[0]) // x        write_coord(origin2[1]) // y        write_coord(origin2[2]+24) // z        write_coord(16) // size x        write_coord(16) // size y        write_coord(16) // size z        write_coord(random_num(-50, 50)) // velocity x        write_coord(random_num(-50, 50)) // velocity y        write_coord(25) // velocity z        write_byte(10) // random velocity        write_short(g_glassSpr) // model        write_byte(10) // count        write_byte(25) // life        write_byte(BREAK_GLASS) // flags        message_end()                ExecuteForward(g_fwUserUnfrozen, g_fwDummyResult, id); }
  // Remove Stuff Task public remove_stuff() {        static ent                // Remove rotating doors        if (get_pcvar_num(cvar_removedoors) > 0)        {               ent = -1;               while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "func_door_rotating")) != 0)                      engfunc(EngFunc_SetOrigin, ent, Float:{8192.0 ,8192.0 ,8192.0})        }                // Remove all doors        if (get_pcvar_num(cvar_removedoors) > 1)        {               ent = -1;               while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "func_door")) != 0)                      engfunc(EngFunc_SetOrigin, ent, Float:{8192.0 ,8192.0 ,8192.0})        }                // Triggered lights        if (!get_pcvar_num(cvar_triggered))        {               ent = -1               while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "light")) != 0)               {                      dllfunc(DLLFunc_Use, ent, 0); // turn off the light                      set_pev(ent, pev_targetname, 0) // prevent it from being triggered               }        } }
  // Set Custom Weapon Models replace_weapon_models(id, weaponid) {        switch (weaponid)        {               case CSW_KNIFE: // Custom knife models               {                      if (g_zombie[id])                      {                             if (g_nemesis[id]) // Nemesis                             {                                    set_pev(id, pev_viewmodel2, model_vknife_nemesis)                                    set_pev(id, pev_weaponmodel2, "")                             }                             else // Zombies                             {                                    // Admin knife models?                                    if (get_pcvar_num(cvar_adminknifemodelszombie) && get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS])                                    {                                           set_pev(id, pev_viewmodel2, model_vknife_admin_zombie)                                           set_pev(id, pev_weaponmodel2, "")                                    }                                    else                                    {                                           static clawmodel[100]                                           ArrayGetString(g_zclass_clawmodel, g_zombieclass[id], clawmodel, charsmax(clawmodel))                                           format(clawmodel, charsmax(clawmodel), "models/zombie_plague/%s", clawmodel)                                           set_pev(id, pev_viewmodel2, clawmodel)                                           set_pev(id, pev_weaponmodel2, "")                                    }                             }                      }                      else // Humans                      {                             // Admin knife models?                             if (get_pcvar_num(cvar_adminknifemodelshuman) && get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS])                             {                                    set_pev(id, pev_viewmodel2, model_vknife_admin_human)                                    set_pev(id, pev_weaponmodel2, "")                             }                             else                             {                                    set_pev(id, pev_viewmodel2, model_vknife_human)                                    set_pev(id, pev_weaponmodel2, "models/p_knife.mdl")                             }                      }               }               case CSW_M249: // Survivor's M249               {                      if (g_survivor[id])                             set_pev(id, pev_viewmodel2, model_vm249_survivor)               }               case CSW_HEGRENADE: // Infection bomb or fire grenade               {                      if (g_zombie[id])                             set_pev(id, pev_viewmodel2, model_grenade_infect)                      else                             set_pev(id, pev_viewmodel2, model_grenade_fire)               }               case CSW_FLASHBANG: // Frost grenade               {                      set_pev(id, pev_viewmodel2, model_grenade_frost)               }               case CSW_SMOKEGRENADE: // Flare grenade               {                      set_pev(id, pev_viewmodel2, model_grenade_flare)               }        }                // Update model on weaponmodel ent        if (g_handle_models_on_separate_ent) fm_set_weaponmodel_ent(id) }
  // Reset Player Vars reset_vars(id, resetall) {        g_zombie[id] = false        g_nemesis[id] = false        g_survivor[id] = false        g_firstzombie[id] = false        g_lastzombie[id] = false        g_lasthuman[id] = false        g_frozen[id] = false        g_nodamage[id] = false        g_respawn_as_zombie[id] = false        g_nvision[id] = false        g_nvisionenabled[id] = false        g_flashlight[id] = false        g_flashbattery[id] = 100        g_canbuy[id] = true        g_burning_duration[id] = 0                if (resetall)        {               g_ammopacks[id] = get_pcvar_num(cvar_startammopacks)               g_zombieclass[id] = ZCLASS_NONE               g_zombieclassnext[id] = ZCLASS_NONE               g_damagedealt[id] = 0               WPN_AUTO_ON = 0        } }
  // Set spectators nightvision public spec_nvision(id) {        // Not connected, alive, or bot        if (!g_isconnected[id] || g_isalive[id] || g_isbot[id])               return;                // Give Night Vision?        if (get_pcvar_num(cvar_nvggive))        {               g_nvision[id] = true                              // Turn on Night Vision automatically?               if (get_pcvar_num(cvar_nvggive) == 1)               {                      g_nvisionenabled[id] = true                                            // Custom nvg?                      if (get_pcvar_num(cvar_customnvg))                      {                             remove_task(id+TASK_NVISION)                             set_task(0.1, "set_user_nvision", id+TASK_NVISION, _, _, "b")                      }                      else                             set_user_gnvision(id, 1)               }        } }
  // Show HUD Task public ShowHUD(taskid) {        static id        id = ID_SHOWHUD;                // Player died?        if (!g_isalive[id])        {               // Get spectating target               id = pev(id, PEV_SPEC_TARGET)                              // Target not alive               if (!g_isalive[id]) return;        }                // Format classname        static class[32], red, green, blue                if (g_zombie[id]) // zombies        {               red = 200               green = 250               blue = 0                              if (g_nemesis[id])                      formatex(class, charsmax(class), "%L", ID_SHOWHUD, "CLASS_NEMESIS")               else                      copy(class, charsmax(class), g_zombie_classname[id])        }        else // humans        {               red = 0               green = 0               blue = 255                              if (g_survivor[id])                      formatex(class, charsmax(class), "%L", ID_SHOWHUD, "CLASS_SURVIVOR")               else                      formatex(class, charsmax(class), "%L", ID_SHOWHUD, "CLASS_HUMAN")        }                // Spectating someone else?        if (id != ID_SHOWHUD)        {               // Show name, health, class, and ammo packs               set_hudmessage(255, 255, 255, HUD_SPECT_X, HUD_SPECT_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)               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])        }        else        {               // Show health, class and ammo packs               set_hudmessage(red, green, blue, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)               ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync2, "%L: %d - %L %s - %L %d", id, "ZOMBIE_ATTRIB1", pev(ID_SHOWHUD, pev_health), ID_SHOWHUD, "CLASS_CLASS", class, ID_SHOWHUD, "AMMO_PACKS1", g_ammopacks[ID_SHOWHUD])        } }
  // Play idle zombie sounds public zombie_play_idle(taskid) {        // Round ended/new one starting        if (g_endround || g_newround)               return;                static sound[64]                // Last zombie?        if (g_lastzombie[ID_BLOOD])        {               ArrayGetString(zombie_idle_last, random_num(0, ArraySize(zombie_idle_last) - 1), sound, charsmax(sound))               emit_sound(ID_BLOOD, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)        }        else        {               ArrayGetString(zombie_idle, random_num(0, ArraySize(zombie_idle) - 1), sound, charsmax(sound))               emit_sound(ID_BLOOD, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)        } }
  // Madness Over Task public madness_over(taskid) {        g_nodamage[ID_BLOOD] = false }
  // Place user at a random spawn do_random_spawn(id, regularspawns = 0) {        static hull, sp_index, i                // Get whether the player is crouching        hull = (pev(id, pev_flags) & FL_DUCKING) ? HULL_HEAD : HULL_HUMAN                // Use regular spawns?        if (!regularspawns)        {               // No spawns?               if (!g_spawnCount)                      return;                              // Choose random spawn to start looping at               sp_index = random_num(0, g_spawnCount - 1)                              // Try to find a clear spawn               for (i = sp_index + 1; /*no condition*/; i++)               {                      // Start over when we reach the end                      if (i >= g_spawnCount) i = 0                                            // Free spawn space?                      if (is_hull_vacant(g_spawns, hull))                      {                             // Engfunc_SetOrigin is used so ent's mins and maxs get updated instantly                             engfunc(EngFunc_SetOrigin, id, g_spawns)                             break;                      }                                            // Loop completed, no free space found                      if (i == sp_index) break;               }        }        else        {               // No spawns?               if (!g_spawnCount2)                      return;                              // Choose random spawn to start looping at               sp_index = random_num(0, g_spawnCount2 - 1)                              // Try to find a clear spawn               for (i = sp_index + 1; /*no condition*/; i++)               {                      // Start over when we reach the end                      if (i >= g_spawnCount2) i = 0                                            // Free spawn space?                      if (is_hull_vacant(g_spawns2, hull))                      {                             // Engfunc_SetOrigin is used so ent's mins and maxs get updated instantly                             engfunc(EngFunc_SetOrigin, id, g_spawns2)                             break;                      }                                            // Loop completed, no free space found                      if (i == sp_index) break;               }        } }
  // Get Zombies -returns alive zombies number- fnGetZombies() {        static iZombies, id        iZombies = 0                for (id = 1; id <= g_maxplayers; id++)        {               if (g_isalive[id] && g_zombie[id])                      iZombies++        }                return iZombies; }
  // Get Humans -returns alive humans number- fnGetHumans() {        static iHumans, id        iHumans = 0                for (id = 1; id <= g_maxplayers; id++)        {               if (g_isalive[id] && !g_zombie[id])                      iHumans++        }                return iHumans; }
  // Get Nemesis -returns alive nemesis number- fnGetNemesis() {        static iNemesis, id        iNemesis = 0                for (id = 1; id <= g_maxplayers; id++)        {               if (g_isalive[id] && g_nemesis[id])                      iNemesis++        }                return iNemesis; }
  // Get Survivors -returns alive survivors number- fnGetSurvivors() {        static iSurvivors, id        iSurvivors = 0                for (id = 1; id <= g_maxplayers; id++)        {               if (g_isalive[id] && g_survivor[id])                      iSurvivors++        }                return iSurvivors; }
  // Get Alive -returns alive players number- fnGetAlive() {        static iAlive, id        iAlive = 0                for (id = 1; id <= g_maxplayers; id++)        {               if (g_isalive[id])                      iAlive++        }                return iAlive; }
  // Get Random Alive -returns index of alive player number n - fnGetRandomAlive(n) {        static iAlive, id        iAlive = 0                for (id = 1; id <= g_maxplayers; id++)        {               if (g_isalive[id])                      iAlive++                              if (iAlive == n)                      return id;        }                return -1; }
  // Get Playing -returns number of users playing- fnGetPlaying() {        static iPlaying, id, team        iPlaying = 0                for (id = 1; id <= g_maxplayers; id++)        {               if (g_isconnected[id])               {                      team = fm_cs_get_user_team(id)                                            if (team != FM_CS_TEAM_SPECTATOR && team != FM_CS_TEAM_UNASSIGNED)                             iPlaying++               }        }                return iPlaying; }
  // Get CTs -returns number of CTs connected- fnGetCTs() {        static iCTs, id        iCTs = 0                for (id = 1; id <= g_maxplayers; id++)        {               if (g_isconnected[id])               {                                           if (fm_cs_get_user_team(id) == FM_CS_TEAM_CT)                             iCTs++               }        }                return iCTs; }
  // Get Ts -returns number of Ts connected- fnGetTs() {        static iTs, id        iTs = 0                for (id = 1; id <= g_maxplayers; id++)        {               if (g_isconnected[id])               {                                           if (fm_cs_get_user_team(id) == FM_CS_TEAM_T)                             iTs++               }        }                return iTs; }
  // Get Alive CTs -returns number of CTs alive- fnGetAliveCTs() {        static iCTs, id        iCTs = 0                for (id = 1; id <= g_maxplayers; id++)        {               if (g_isalive[id])               {                                           if (fm_cs_get_user_team(id) == FM_CS_TEAM_CT)                             iCTs++               }        }                return iCTs; }
  // Get Alive Ts -returns number of Ts alive- fnGetAliveTs() {        static iTs, id        iTs = 0                for (id = 1; id <= g_maxplayers; id++)        {               if (g_isalive[id])               {                                           if (fm_cs_get_user_team(id) == FM_CS_TEAM_T)                             iTs++               }        }                return iTs; }
  // Last Zombie Check -check for last zombie and set its flag- fnCheckLastZombie() {        static id        for (id = 1; id <= g_maxplayers; id++)        {               // Last zombie               if (g_isalive[id] && g_zombie[id] && !g_nemesis[id] && fnGetZombies() == 1)               {                      if (!g_lastzombie[id])                      {                             // Last zombie forward                             ExecuteForward(g_fwUserLastZombie, g_fwDummyResult, id);                      }                      g_lastzombie[id] = true               }               else                      g_lastzombie[id] = false                              // Last human               if (g_isalive[id] && !g_zombie[id] && !g_survivor[id] && fnGetHumans() == 1)               {                      if (!g_lasthuman[id])                      {                             // Last human forward                             ExecuteForward(g_fwUserLastHuman, g_fwDummyResult, id);                                                          // Reward extra hp                             fm_set_user_health(id, pev(id, pev_health) + get_pcvar_num(cvar_humanlasthp))                      }                      g_lasthuman[id] = true               }               else                      g_lasthuman[id] = false        } }
  // Save player's stats to database save_stats(id) {        // Check whether there is another record already in that slot        if (db_name[id][0] && !equal(g_playername[id], db_name[id]))        {               // If DB size is exceeded, write over old records               if (db_slot_i >= sizeof db_name)                      db_slot_i = g_maxplayers+1                              // Move previous record onto an additional save slot               copy(db_name[db_slot_i], charsmax(db_name[]), db_name[id])               db_ammopacks[db_slot_i] = db_ammopacks[id]               db_zombieclass[db_slot_i] = db_zombieclass[id]               db_slot_i++        }                // Now save the current player stats        copy(db_name[id], charsmax(db_name[]), g_playername[id]) // name        db_ammopacks[id] = g_ammopacks[id]  // ammo packs        db_zombieclass[id] = g_zombieclassnext[id] // zombie class }
  // Load player's stats from database (if a record is found) load_stats(id) {        // Look for a matching record        static i        for (i = 0; i < sizeof db_name; i++)        {               if (equal(g_playername[id], db_name))               {                      // Bingo!                      g_ammopacks[id] = db_ammopacks                      g_zombieclass[id] = db_zombieclass                      g_zombieclassnext[id] = db_zombieclass                      return;               }        } }
  // Checks if a player is allowed to be zombie allowed_zombie(id) {        if ((g_zombie[id] && !g_nemesis[id]) || g_endround || !g_isalive[id] || task_exists(TASK_WELCOMEMSG) || (!g_newround && !g_zombie[id] && fnGetHumans() == 1))               return false;                return true; }
  // Checks if a player is allowed to be human allowed_human(id) {        if ((!g_zombie[id] && !g_survivor[id]) || g_endround || !g_isalive[id] || task_exists(TASK_WELCOMEMSG) || (!g_newround && g_zombie[id] && fnGetZombies() == 1))               return false;                return true; }
  // Checks if a player is allowed to be survivor allowed_survivor(id) {        if (g_endround || g_survivor[id] || !g_isalive[id] || task_exists(TASK_WELCOMEMSG) || (!g_newround && g_zombie[id] && fnGetZombies() == 1))               return false;                return true; }
  // Checks if a player is allowed to be nemesis allowed_nemesis(id) {        if (g_endround || g_nemesis[id] || !g_isalive[id] || task_exists(TASK_WELCOMEMSG) || (!g_newround && !g_zombie[id] && fnGetHumans() == 1))               return false;                return true; }
  // Checks if a player is allowed to respawn allowed_respawn(id) {        static team        team = fm_cs_get_user_team(id)                if (g_endround || team == FM_CS_TEAM_SPECTATOR || team == FM_CS_TEAM_UNASSIGNED || g_isalive[id])               return false;                return true; }
  // Checks if swarm mode is allowed allowed_swarm() {        if (g_endround || !g_newround || task_exists(TASK_WELCOMEMSG))               return false;                return true; }
  // Checks if multi infection mode is allowed allowed_multi() {        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())               return false;                return true; }
  // Checks if plague mode is allowed allowed_plague() {        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        || 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)               return false;                return true; }
  // Admin Command. zp_zombie command_zombie(id, player) {        // Show activity?        switch (get_pcvar_num(cvar_showactivity))        {               case 1: client_print(0, print_chat, "ADMIN - %s %L", g_playername[player], LANG_PLAYER, "CMD_INFECT")               case 2: client_print(0, print_chat, "ADMIN %s - %s %L", g_playername[id], g_playername[player], LANG_PLAYER, "CMD_INFECT")        }                // Log to Zombie Plague log file?        if (get_pcvar_num(cvar_logcommands))        {               static logdata[100], authid[32], ip[16]               get_user_authid(id, authid, charsmax(authid))               get_user_ip(id, ip, charsmax(ip), 1)               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)               log_to_file("zombieplague.log", logdata)        }                // New round?        if (g_newround)        {               // Set as first zombie               remove_task(TASK_MAKEZOMBIE)               make_a_zombie(MODE_INFECTION, player)        }        else        {               // Just infect               zombieme(player, 0, 0, 0, 0)        } }
  // Admin Command. zp_human command_human(id, player) {        // Show activity?        switch (get_pcvar_num(cvar_showactivity))        {               case 1: client_print(0, print_chat, "ADMIN - %s %L", g_playername[player], LANG_PLAYER, "CMD_DISINFECT")               case 2: client_print(0, print_chat, "ADMIN %s - %s %L", g_playername[id], g_playername[player], LANG_PLAYER, "CMD_DISINFECT")        }                // Log to Zombie Plague log file?        if (get_pcvar_num(cvar_logcommands))        {               static logdata[100], authid[32], ip[16]               get_user_authid(id, authid, charsmax(authid))               get_user_ip(id, ip, charsmax(ip), 1)               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)               log_to_file("zombieplague.log", logdata)        }                // Turn to human        humanme(player, 0, 0) }
  // Admin Command. zp_survivor command_survivor(id, player) {        // Show activity?        switch (get_pcvar_num(cvar_showactivity))        {               case 1: client_print(0, print_chat, "ADMIN - %s %L", g_playername[player], LANG_PLAYER, "CMD_SURVIVAL")               case 2: client_print(0, print_chat, "ADMIN %s - %s %L", g_playername[id], g_playername[player], LANG_PLAYER, "CMD_SURVIVAL")        }                 // Log to Zombie Plague log file?        if (get_pcvar_num(cvar_logcommands))        {               static logdata[100], authid[32], ip[16]               get_user_authid(id, authid, charsmax(authid))               get_user_ip(id, ip, charsmax(ip), 1)               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)               log_to_file("zombieplague.log", logdata)        }                // New round?        if (g_newround)        {               // Set as first survivor               remove_task(TASK_MAKEZOMBIE)               make_a_zombie(MODE_SURVIVOR, player)        }        else        {               // Turn player into a Survivor               humanme(player, 1, 0)        } }
  // Admin Command. zp_nemesis command_nemesis(id, player) {        // Show activity?        switch (get_pcvar_num(cvar_showactivity))        {               case 1: client_print(0, print_chat, "ADMIN - %s %L", g_playername[player], LANG_PLAYER, "CMD_NEMESIS")               case 2: client_print(0, print_chat, "ADMIN %s - %s %L", g_playername[id], g_playername[player], LANG_PLAYER, "CMD_NEMESIS")        }                // Log to Zombie Plague log file?        if (get_pcvar_num(cvar_logcommands))        {               static logdata[100], authid[32], ip[16]               get_user_authid(id, authid, charsmax(authid))               get_user_ip(id, ip, charsmax(ip), 1)               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)               log_to_file("zombieplague.log", logdata)        }                // New round?        if (g_newround)        {               // Set as first nemesis               remove_task(TASK_MAKEZOMBIE)               make_a_zombie(MODE_NEMESIS, player)        }        else        {               // Turn player into a Nemesis               zombieme(player, 0, 1, 0, 0)        } }
  // Admin Command. zp_respawn command_respawn(id, player) {        // Show activity?        switch (get_pcvar_num(cvar_showactivity))        {               case 1: client_print(0, print_chat, "ADMIN - %s %L", g_playername[player], LANG_PLAYER, "CMD_RESPAWN")               case 2: client_print(0, print_chat, "ADMIN %s - %s %L", g_playername[id], g_playername[player], LANG_PLAYER, "CMD_RESPAWN")        }                // Log to Zombie Plague log file?        if (get_pcvar_num(cvar_logcommands))        {               static logdata[100], authid[32], ip[16]               get_user_authid(id, authid, charsmax(authid))               get_user_ip(id, ip, charsmax(ip), 1)               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)               log_to_file("zombieplague.log", logdata)        }                // Respawn as zombie?        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))               g_respawn_as_zombie[player] = true                // Override respawn as zombie setting on nemesis and survivor rounds        if (g_survround) g_respawn_as_zombie[player] = true        else if (g_nemround) g_respawn_as_zombie[player] = false                respawn_player_manually(player); }
  // Admin Command. zp_swarm command_swarm(id) {        // Show activity?        switch (get_pcvar_num(cvar_showactivity))        {               case 1: client_print(0, print_chat, "ADMIN - %L", LANG_PLAYER, "CMD_SWARM")               case 2: client_print(0, print_chat, "ADMIN %s - %L", g_playername[id], LANG_PLAYER, "CMD_SWARM")        }                // Log to Zombie Plague log file?        if (get_pcvar_num(cvar_logcommands))        {               static logdata[100], authid[32], ip[16]               get_user_authid(id, authid, charsmax(authid))               get_user_ip(id, ip, charsmax(ip), 1)               formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %L (Players: %d/%d)", g_playername[id], authid, ip, LANG_SERVER, "CMD_SWARM", fnGetPlaying(), g_maxplayers)               log_to_file("zombieplague.log", logdata)        }                // Call Swarm Mode        remove_task(TASK_MAKEZOMBIE)        make_a_zombie(MODE_SWARM, 0) }
  // Admin Command. zp_multi command_multi(id) {        // Show activity?        switch (get_pcvar_num(cvar_showactivity))        {               case 1: client_print(0, print_chat, "ADMIN - %L", LANG_PLAYER, "CMD_MULTI")               case 2: client_print(0, print_chat, "ADMIN %s - %L", g_playername[id], LANG_PLAYER, "CMD_MULTI")        }                // Log to Zombie Plague log file?        if (get_pcvar_num(cvar_logcommands))        {               static logdata[100], authid[32], ip[16]               get_user_authid(id, authid, charsmax(authid))               get_user_ip(id, ip, charsmax(ip), 1)               formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %L (Players: %d/%d)", g_playername[id], authid, ip, LANG_SERVER,"CMD_MULTI", fnGetPlaying(), g_maxplayers)               log_to_file("zombieplague.log", logdata)        }                // Call Multi Infection        remove_task(TASK_MAKEZOMBIE)        make_a_zombie(MODE_MULTI, 0) }
  // Admin Command. zp_plague command_plague(id) {        // Show activity?        switch (get_pcvar_num(cvar_showactivity))        {               case 1: client_print(0, print_chat, "ADMIN - %L", LANG_PLAYER, "CMD_PLAGUE")               case 2: client_print(0, print_chat, "ADMIN %s - %L", g_playername[id], LANG_PLAYER, "CMD_PLAGUE")        }                // Log to Zombie Plague log file?        if (get_pcvar_num(cvar_logcommands))        {               static logdata[100], authid[32], ip[16]               get_user_authid(id, authid, charsmax(authid))               get_user_ip(id, ip, charsmax(ip), 1)               formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %L (Players: %d/%d)", g_playername[id], authid, ip, LANG_SERVER,"CMD_PLAGUE", fnGetPlaying(), g_maxplayers)               log_to_file("zombieplague.log", logdata)        }                // Call Plague Mode        remove_task(TASK_MAKEZOMBIE)        make_a_zombie(MODE_PLAGUE, 0) }
  /*================================================================================  [Custom Natives] =================================================================================*/
  // Native: zp_get_user_zombie public native_get_user_zombie(id) {        return g_zombie[id]; }
  // Native: zp_get_user_nemesis public native_get_user_nemesis(id) {        return g_nemesis[id]; }
  // Native: zp_get_user_survivor public native_get_user_survivor(id) {        return g_survivor[id]; }
  public native_get_user_first_zombie(id) {        return g_firstzombie[id]; }
  // Native: zp_get_user_last_zombie public native_get_user_last_zombie(id) {        return g_lastzombie[id]; }
  // Native: zp_get_user_last_human public native_get_user_last_human(id) {        return g_lasthuman[id]; }
  // Native: zp_get_user_zombie_class public native_get_user_zombie_class(id) {        return g_zombieclass[id]; }
  // Native: zp_get_user_next_class public native_get_user_next_class(id) {        return g_zombieclassnext[id]; }
  // Native: zp_set_user_zombie_class public native_set_user_zombie_class(id, classid) {        if (classid < 0 || classid >= g_zclass_i)               return 0;                g_zombieclassnext[id] = classid        return 1; }
  // Native: zp_get_user_ammo_packs public native_get_user_ammo_packs(id) {        return g_ammopacks[id]; }
  // Native: zp_set_user_ammo_packs public native_set_user_ammo_packs(id, amount) {        g_ammopacks[id] = amount; }
  // Native: zp_get_zombie_maxhealth public native_get_zombie_maxhealth(id) {        // ZP disabled        if (!g_pluginenabled)               return -1;                if (g_zombie[id] && !g_nemesis[id])        {               if (g_firstzombie[id])                      return floatround(float(ArrayGetCell(g_zclass_hp, g_zombieclass[id])) * get_pcvar_float(cvar_zombiefirsthp));               else                      return ArrayGetCell(g_zclass_hp, g_zombieclass[id]);        }        return -1; }
  // Native: zp_get_user_batteries public native_get_user_batteries(id) {        return g_flashbattery[id]; }
  // Native: zp_set_user_batteries public native_set_user_batteries(id, value) {        // ZP disabled        if (!g_pluginenabled)               return;                g_flashbattery[id] = clamp(value, 0, 100);                if (g_cached_customflash)        {               // Set the flashlight charge task to update battery status               remove_task(id+TASK_CHARGE)               set_task(1.0, "flashlight_charge", id+TASK_CHARGE, _, _, "b")        } }
  // Native: zp_get_user_nightvision public native_get_user_nightvision(id) {        return g_nvision[id]; }
  // Native: zp_set_user_nightvision public native_set_user_nightvision(id, set) {        // ZP disabled        if (!g_pluginenabled)               return;                if (set)        {               g_nvision[id] = true                              if (!g_isbot[id])               {                      g_nvisionenabled[id] = true                                            // Custom nvg?                      if (get_pcvar_num(cvar_customnvg))                      {                             remove_task(id+TASK_NVISION)                             set_task(0.1, "set_user_nvision", id+TASK_NVISION, _, _, "b")                      }                      else                             set_user_gnvision(id, 1)               }               else                      cs_set_user_nvg(id, 1)        }        else        {               // Turn off NVG for bots               if (g_isbot[id]) cs_set_user_nvg(id, 0);               if (get_pcvar_num(cvar_customnvg)) remove_task(id+TASK_NVISION)               else if (g_nvisionenabled[id]) set_user_gnvision(id, 0)               g_nvision[id] = false               g_nvisionenabled[id] = false        } }
  // Native: zp_infect_user public native_infect_user(id, infector, silent, rewards) {        // ZP disabled        if (!g_pluginenabled)               return -1;                // Not allowed to be zombie        if (!allowed_zombie(id))               return 0;                // New round?        if (g_newround)        {               // Set as first zombie               remove_task(TASK_MAKEZOMBIE)               make_a_zombie(MODE_INFECTION, id)        }        else        {               // Just infect (plus some checks)               zombieme(id, is_user_valid_alive(infector) ? infector : 0, 0, (silent == 1) ? 1 : 0, (rewards == 1) ? 1 : 0)        }                return 1; }
  // Native: zp_disinfect_user public native_disinfect_user(id, silent) {        // ZP disabled        if (!g_pluginenabled)               return -1;                // Not allowed to be human        if (!allowed_human(id))               return 0;                // Turn to human        humanme(id, 0, (silent == 1) ? 1 : 0)        return 1; }
  // Native: zp_make_user_nemesis public native_make_user_nemesis(id) {        // ZP disabled        if (!g_pluginenabled)               return -1;                // Not allowed to be nemesis        if (!allowed_nemesis(id))               return 0;                // New round?        if (g_newround)        {               // Set as first nemesis               remove_task(TASK_MAKEZOMBIE)               make_a_zombie(MODE_NEMESIS, id)        }        else        {               // Turn player into a Nemesis               zombieme(id, 0, 1, 0, 0)        }                return 1; }
  // Native: zp_make_user_survivor public native_make_user_survivor(id) {        // ZP disabled        if (!g_pluginenabled)               return -1;                // Not allowed to be survivor        if (!allowed_survivor(id))               return 0;                // New round?        if (g_newround)        {               // Set as first survivor               remove_task(TASK_MAKEZOMBIE)               make_a_zombie(MODE_SURVIVOR, id)        }        else        {               // Turn player into a Survivor               humanme(id, 1, 0)        }                return 1; }
  // Native: zp_respawn_user public native_respawn_user(id, team) {        // ZP disabled        if (!g_pluginenabled)               return -1;                // Invalid player        if (!is_user_valid_connected(id))               return 0;                // Respawn not allowed        if (!allowed_respawn(id))               return 0;                // Respawn as zombie?        g_respawn_as_zombie[id] = (team == ZP_TEAM_ZOMBIE) ? true : false                // Respawnish!        respawn_player_manually(id)        return 1; }
  // Native: zp_force_buy_extra_item public native_force_buy_extra_item(id, itemid, ignorecost) {        // ZP disabled        if (!g_pluginenabled)               return -1;                if (itemid < 0 || itemid >= g_extraitem_i)               return 0;                buy_extra_item(id, itemid, ignorecost)        return 1; }
  // Native: zp_has_round_started public native_has_round_started() {        if (g_newround) return 0; // not started        if (g_modestarted) return 1; // started        return 2; // starting }
  // Native: zp_is_nemesis_round public native_is_nemesis_round() {        return g_nemround; }
  // Native: zp_is_survivor_round public native_is_survivor_round() {        return g_survround; }
  // Native: zp_is_swarm_round public native_is_swarm_round() {        return g_swarmround; }
  // Native: zp_is_plague_round public native_is_plague_round() {        return g_plagueround; }
  // Native: zp_get_zombie_count public native_get_zombie_count() {        return fnGetZombies(); }
  // Native: zp_get_human_count public native_get_human_count() {        return fnGetHumans(); }
  // Native: zp_get_nemesis_count public native_get_nemesis_count() {        return fnGetNemesis(); }
  // Native: zp_get_survivor_count public native_get_survivor_count() {        return fnGetSurvivors(); }
  // Native: zp_register_extra_item public native_register_extra_item(const name[], cost, team) {        // ZP disabled        if (!g_pluginenabled)               return -1;                // Arrays not yet initialized        if (!g_arrays_created)               return -1;                // For backwards compatibility        if (team == ZP_TEAM_ANY)               team = ZP_TEAM_ZOMBIE|ZP_TEAM_HUMAN                // Strings passed byref        param_convert(1)                // Add the item        ArrayPushString(g_extraitem_name, name)        ArrayPushCell(g_extraitem_cost, cost)        ArrayPushCell(g_extraitem_team, team)                // Set temporary new item flag        ArrayPushCell(g_extraitem_new, 1)                // Override extra items data with our customizations        new i, buffer[32], size = ArraySize(g_extraitem2_realname)        for (i = 0; i < size; i++)        {               ArrayGetString(g_extraitem2_realname, i, buffer, charsmax(buffer))                              // Check if this is the intended item to override               if (!equal(name, buffer))                      continue;                              // Remove new item flag               ArraySetCell(g_extraitem_new, g_extraitem_i, 0)                              // Replace caption               ArrayGetString(g_extraitem2_name, i, buffer, charsmax(buffer))               ArraySetString(g_extraitem_name, g_extraitem_i, buffer)                              // Replace cost               buffer[0] = ArrayGetCell(g_extraitem2_cost, i)               ArraySetCell(g_extraitem_cost, g_extraitem_i, buffer[0])                              // Replace team               buffer[0] = ArrayGetCell(g_extraitem2_team, i)               ArraySetCell(g_extraitem_team, g_extraitem_i, buffer[0])        }                // Increase registered items counter        g_extraitem_i++                // Return id under which we registered the item        return g_extraitem_i-1; }
  // Function: zp_register_extra_item (to be used within this plugin only) native_register_extra_item2(const name[], cost, team) {        // Add the item        ArrayPushString(g_extraitem_name, name)        ArrayPushCell(g_extraitem_cost, cost)        ArrayPushCell(g_extraitem_team, team)                // Set temporary new item flag        ArrayPushCell(g_extraitem_new, 1)                // Increase registered items counter        g_extraitem_i++ }
  // Native: zp_register_zombie_class public native_register_zombie_class(const name[], const info[], const model[], const clawmodel[], hp, speed, Float:gravity, Float:knockback) {        // ZP disabled        if (!g_pluginenabled)               return -1;                // Arrays not yet initialized        if (!g_arrays_created)               return -1;                // Strings passed byref        param_convert(1)        param_convert(2)        param_convert(3)        param_convert(4)                // Add the class        ArrayPushString(g_zclass_name, name)        ArrayPushString(g_zclass_info, info)                // Using same zombie models for all classes?        if (g_same_models_for_all)        {               ArrayPushCell(g_zclass_modelsstart, 0)               ArrayPushCell(g_zclass_modelsend, ArraySize(g_zclass_playermodel))        }        else        {               ArrayPushCell(g_zclass_modelsstart, ArraySize(g_zclass_playermodel))               ArrayPushString(g_zclass_playermodel, model)               ArrayPushCell(g_zclass_modelsend, ArraySize(g_zclass_playermodel))               ArrayPushCell(g_zclass_modelindex, -1)        }                ArrayPushString(g_zclass_clawmodel, clawmodel)        ArrayPushCell(g_zclass_hp, hp)        ArrayPushCell(g_zclass_spd, speed)        ArrayPushCell(g_zclass_grav, gravity)        ArrayPushCell(g_zclass_kb, knockback)                // Set temporary new class flag        ArrayPushCell(g_zclass_new, 1)                // Override zombie classes data with our customizations        new i, k, buffer[32], Float:buffer2, nummodels_custom, nummodels_default, prec_mdl[100], size = ArraySize(g_zclass2_realname)        for (i = 0; i < size; i++)        {               ArrayGetString(g_zclass2_realname, i, buffer, charsmax(buffer))                              // Check if this is the intended class to override               if (!equal(name, buffer))                      continue;                              // Remove new class flag               ArraySetCell(g_zclass_new, g_zclass_i, 0)                              // Replace caption               ArrayGetString(g_zclass2_name, i, buffer, charsmax(buffer))               ArraySetString(g_zclass_name, g_zclass_i, buffer)                              // Replace info               ArrayGetString(g_zclass2_info, i, buffer, charsmax(buffer))               ArraySetString(g_zclass_info, g_zclass_i, buffer)                              // Replace models, unless using same models for all classes               if (!g_same_models_for_all)               {                      nummodels_custom = ArrayGetCell(g_zclass2_modelsend, i) - ArrayGetCell(g_zclass2_modelsstart, i)                      nummodels_default = ArrayGetCell(g_zclass_modelsend, g_zclass_i) - ArrayGetCell(g_zclass_modelsstart, g_zclass_i)                                            // Replace each player model and model index                      for (k = 0; k < min(nummodels_custom, nummodels_default); k++)                      {                             ArrayGetString(g_zclass2_playermodel, ArrayGetCell(g_zclass2_modelsstart, i) + k, buffer, charsmax(buffer))                             ArraySetString(g_zclass_playermodel, ArrayGetCell(g_zclass_modelsstart, g_zclass_i) + k, buffer)                                                          // Precache player model and replace its modelindex with the real one                             formatex(prec_mdl, charsmax(prec_mdl), "models/player/%s/%s.mdl", buffer, buffer)                             ArraySetCell(g_zclass_modelindex, ArrayGetCell(g_zclass_modelsstart, g_zclass_i) + k, engfunc(EngFunc_PrecacheModel, prec_mdl))                             if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, prec_mdl)                             if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, prec_mdl)                      }                                            // We have more custom models than what we can accommodate,                      // Let's make some space...                      if (nummodels_custom > nummodels_default)                      {                             for (k = nummodels_default; k < nummodels_custom; k++)                             {                                    ArrayGetString(g_zclass2_playermodel, ArrayGetCell(g_zclass2_modelsstart, i) + k, buffer, charsmax(buffer))                                    ArrayInsertStringAfter(g_zclass_playermodel, ArrayGetCell(g_zclass_modelsstart, g_zclass_i) + k - 1, buffer)                                                                        // Precache player model and retrieve its modelindex                                    formatex(prec_mdl, charsmax(prec_mdl), "models/player/%s/%s.mdl", buffer, buffer)                                    ArrayInsertCellAfter(g_zclass_modelindex, ArrayGetCell(g_zclass_modelsstart, g_zclass_i) + k - 1, engfunc(EngFunc_PrecacheModel, prec_mdl))                                    if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, prec_mdl)                                    if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, prec_mdl)                             }                                                          // Fix models end index for this class                             ArraySetCell(g_zclass_modelsend, g_zclass_i, ArrayGetCell(g_zclass_modelsend, g_zclass_i) + (nummodels_custom - nummodels_default))                      }                                            /* --- Not needed since classes can't have more than 1 default model for now ---                      // We have less custom models than what this class has by default,                      // Get rid of those extra entries...                      if (nummodels_custom < nummodels_default)                      {                             for (k = nummodels_custom; k < nummodels_default; k++)                             {                                    ArrayDeleteItem(g_zclass_playermodel, ArrayGetCell(g_zclass_modelsstart, g_zclass_i) + nummodels_custom)                             }                                                          // Fix models end index for this class                             ArraySetCell(g_zclass_modelsend, g_zclass_i, ArrayGetCell(g_zclass_modelsend, g_zclass_i) - (nummodels_default - nummodels_custom))                      }                      */               }                              // Replace clawmodel               ArrayGetString(g_zclass2_clawmodel, i, buffer, charsmax(buffer))               ArraySetString(g_zclass_clawmodel, g_zclass_i, buffer)                              // Precache clawmodel               formatex(prec_mdl, charsmax(prec_mdl), "models/zombie_plague/%s", buffer)               engfunc(EngFunc_PrecacheModel, prec_mdl)                              // Replace health               buffer[0] = ArrayGetCell(g_zclass2_hp, i)               ArraySetCell(g_zclass_hp, g_zclass_i, buffer[0])                              // Replace speed               buffer[0] = ArrayGetCell(g_zclass2_spd, i)               ArraySetCell(g_zclass_spd, g_zclass_i, buffer[0])                              // Replace gravity               buffer2 = Float:ArrayGetCell(g_zclass2_grav, i)               ArraySetCell(g_zclass_grav, g_zclass_i, buffer2)                              // Replace knockback               buffer2 = Float:ArrayGetCell(g_zclass2_kb, i)               ArraySetCell(g_zclass_kb, g_zclass_i, buffer2)        }                // If class was not overriden with customization data        if (ArrayGetCell(g_zclass_new, g_zclass_i))        {               // If not using same models for all classes               if (!g_same_models_for_all)               {                      // Precache default class model and replace modelindex with the real one                      formatex(prec_mdl, charsmax(prec_mdl), "models/player/%s/%s.mdl", model, model)                      ArraySetCell(g_zclass_modelindex, ArrayGetCell(g_zclass_modelsstart, g_zclass_i), engfunc(EngFunc_PrecacheModel, prec_mdl))                      if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, prec_mdl)                      if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, prec_mdl)               }                              // Precache default clawmodel               formatex(prec_mdl, charsmax(prec_mdl), "models/zombie_plague/%s", clawmodel)               engfunc(EngFunc_PrecacheModel, prec_mdl)        }                // Increase registered classes counter        g_zclass_i++                // Return id under which we registered the class        return g_zclass_i-1; }
  // Native: zp_get_extra_item_id public native_get_extra_item_id(const name[]) {        // ZP disabled        if (!g_pluginenabled)               return -1;                // Strings passed byref        param_convert(1)                // Loop through every item        static i, item_name[32]        for (i = 0; i < g_extraitem_i; i++)        {               ArrayGetString(g_extraitem_name, i, item_name, charsmax(item_name))                              // Check if this is the item to retrieve               if (equali(name, item_name))                      return i;        }                return -1; }
  // Native: zp_get_zombie_class_id public native_get_zombie_class_id(const name[]) {        // ZP disabled        if (!g_pluginenabled)               return -1;                // Strings passed byref        param_convert(1)                // Loop through every class        static i, class_name[32]        for (i = 0; i < g_zclass_i; i++)        {               ArrayGetString(g_zclass_name, i, class_name, charsmax(class_name))                              // Check if this is the class to retrieve               if (equali(name, class_name))                      return i;        }                return -1; }
  /*================================================================================  [Custom Messages] =================================================================================*/
  // Custom Night Vision public set_user_nvision(taskid) {        // Get player's origin        static origin[3]        get_user_origin(ID_NVISION, origin)                // Nightvision message        message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, _, ID_NVISION)        write_byte(TE_DLIGHT) // TE id        write_coord(origin[0]) // x        write_coord(origin[1]) // y        write_coord(origin[2]) // z        write_byte(get_pcvar_num(cvar_nvgsize)) // radius                // Nemesis / Madness / Spectator in nemesis round        if (g_nemesis[ID_NVISION] || (g_zombie[ID_NVISION] && g_nodamage[ID_NVISION]) || (!g_isalive[ID_NVISION] && g_nemround))        {               write_byte(get_pcvar_num(cvar_nemnvgcolor[0])) // r               write_byte(get_pcvar_num(cvar_nemnvgcolor[1])) // g               write_byte(get_pcvar_num(cvar_nemnvgcolor[2])) // b        }        // Human / Spectator in normal round        else if (!g_zombie[ID_NVISION] || !g_isalive[ID_NVISION])        {               write_byte(get_pcvar_num(cvar_humnvgcolor[0])) // r               write_byte(get_pcvar_num(cvar_humnvgcolor[1])) // g               write_byte(get_pcvar_num(cvar_humnvgcolor[2])) // b        }        // Zombie        else        {               write_byte(get_pcvar_num(cvar_nvgcolor[0])) // r               write_byte(get_pcvar_num(cvar_nvgcolor[1])) // g               write_byte(get_pcvar_num(cvar_nvgcolor[2])) // b        }                write_byte(2) // life        write_byte(0) // decay rate        message_end() }
  // Game Nightvision set_user_gnvision(id, toggle) {        // Toggle NVG message        message_begin(MSG_ONE, g_msgNVGToggle, _, id)        write_byte(toggle) // toggle        message_end() }
  // Custom Flashlight public set_user_flashlight(taskid) {        // Get player and aiming origins        static Float:originF[3], Float:destoriginF[3]        pev(ID_FLASH, pev_origin, originF)        fm_get_aim_origin(ID_FLASH, destoriginF)                // Max distance check        if (get_distance_f(originF, destoriginF) > get_pcvar_float(cvar_flashdist))               return;                // Send to all players?        if (get_pcvar_num(cvar_flashshowall))               engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, destoriginF, 0)        else               message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, _, ID_FLASH)                // Flashlight        write_byte(TE_DLIGHT) // TE id        engfunc(EngFunc_WriteCoord, destoriginF[0]) // x        engfunc(EngFunc_WriteCoord, destoriginF[1]) // y        engfunc(EngFunc_WriteCoord, destoriginF[2]) // z        write_byte(get_pcvar_num(cvar_flashsize)) // radius        write_byte(get_pcvar_num(cvar_flashcolor[0])) // r        write_byte(get_pcvar_num(cvar_flashcolor[1])) // g        write_byte(get_pcvar_num(cvar_flashcolor[2])) // b        write_byte(3) // life        write_byte(0) // decay rate        message_end() }
  // Infection special effects infection_effects(id) {        // Screen fade? (unless frozen)        if (!g_frozen[id] && get_pcvar_num(cvar_infectionscreenfade))        {               message_begin(MSG_ONE_UNRELIABLE, g_msgScreenFade, _, id)               write_short(UNIT_SECOND) // duration               write_short(0) // hold time               write_short(FFADE_IN) // fade type               if (g_nemesis[id])               {                      write_byte(get_pcvar_num(cvar_nemnvgcolor[0])) // r                      write_byte(get_pcvar_num(cvar_nemnvgcolor[1])) // g                      write_byte(get_pcvar_num(cvar_nemnvgcolor[2])) // b               }               else               {                      write_byte(get_pcvar_num(cvar_nvgcolor[0])) // r                      write_byte(get_pcvar_num(cvar_nvgcolor[1])) // g                      write_byte(get_pcvar_num(cvar_nvgcolor[2])) // b               }               write_byte (255) // alpha               message_end()        }                // Screen shake?        if (get_pcvar_num(cvar_infectionscreenshake))        {               message_begin(MSG_ONE_UNRELIABLE, g_msgScreenShake, _, id)               write_short(UNIT_SECOND*4) // amplitude               write_short(UNIT_SECOND*2) // duration               write_short(UNIT_SECOND*10) // frequency               message_end()        }                // Infection icon?        if (get_pcvar_num(cvar_hudicons))        {               message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, _, id)               write_byte(0) // damage save               write_byte(0) // damage take               write_long(DMG_NERVEGAS) // damage type - DMG_RADIATION               write_coord(0) // x               write_coord(0) // y               write_coord(0) // z               message_end()        }                // Get player's origin        static origin[3]        get_user_origin(id, origin)                // Tracers?        if (get_pcvar_num(cvar_infectiontracers))        {               message_begin(MSG_PVS, SVC_TEMPENTITY, origin)               write_byte(TE_IMPLOSION) // TE id               write_coord(origin[0]) // x               write_coord(origin[1]) // y               write_coord(origin[2]) // z               write_byte(128) // radius               write_byte(20) // count               write_byte(3) // duration               message_end()        }                // Particle burst?        if (get_pcvar_num(cvar_infectionparticles))        {               message_begin(MSG_PVS, SVC_TEMPENTITY, origin)               write_byte(TE_PARTICLEBURST) // TE id               write_coord(origin[0]) // x               write_coord(origin[1]) // y               write_coord(origin[2]) // z               write_short(50) // radius               write_byte(70) // color               write_byte(3) // duration (will be randomized a bit)               message_end()        }                // Light sparkle?        if (get_pcvar_num(cvar_infectionsparkle))        {               message_begin(MSG_PVS, SVC_TEMPENTITY, origin)               write_byte(TE_DLIGHT) // TE id               write_coord(origin[0]) // x               write_coord(origin[1]) // y               write_coord(origin[2]) // z               write_byte(20) // radius               write_byte(get_pcvar_num(cvar_nvgcolor[0])) // r               write_byte(get_pcvar_num(cvar_nvgcolor[1])) // g               write_byte(get_pcvar_num(cvar_nvgcolor[2])) // b               write_byte(2) // life               write_byte(0) // decay rate               message_end()        } }
  // Nemesis/madness aura task public zombie_aura(taskid) {        // Not nemesis, not in zombie madness        if (!g_nemesis[ID_AURA] && !g_nodamage[ID_AURA])        {               // Task not needed anymore               remove_task(taskid);               return;        }                // Get player's origin        static origin[3]        get_user_origin(ID_AURA, origin)                // Colored Aura        message_begin(MSG_PVS, SVC_TEMPENTITY, origin)        write_byte(TE_DLIGHT) // TE id        write_coord(origin[0]) // x        write_coord(origin[1]) // y        write_coord(origin[2]) // z        write_byte(20) // radius        write_byte(get_pcvar_num(cvar_nemnvgcolor[0])) // r        write_byte(get_pcvar_num(cvar_nemnvgcolor[1])) // g        write_byte(get_pcvar_num(cvar_nemnvgcolor[2])) // b        write_byte(2) // life        write_byte(0) // decay rate        message_end() }
  // Make zombies leave footsteps and bloodstains on the floor public make_blood(taskid) {        // Only bleed when moving on ground        if (!(pev(ID_BLOOD, pev_flags) & FL_ONGROUND) || fm_get_speed(ID_BLOOD) < 80)               return;                // Get user origin        static Float:originF[3]        pev(ID_BLOOD, pev_origin, originF)                // If ducking set a little lower        if (pev(ID_BLOOD, pev_bInDuck))               originF[2] -= 18.0        else               originF[2] -= 36.0                // Send the decal message        engfunc(EngFunc_MessageBegin, MSG_PAS, SVC_TEMPENTITY, originF, 0)        write_byte(TE_WORLDDECAL) // TE id        engfunc(EngFunc_WriteCoord, originF[0]) // x        engfunc(EngFunc_WriteCoord, originF[1]) // y        engfunc(EngFunc_WriteCoord, originF[2]) // z        write_byte(ArrayGetCell(zombie_decals, random_num(0, ArraySize(zombie_decals) - 1)) + (g_czero * 12)) // random decal number (offsets +12 for CZ)        message_end() }
  // Flare Lighting Effects flare_lighting(entity, duration) {        // Get origin and color        static Float:originF[3], color[3]        pev(entity, pev_origin, originF)        pev(entity, PEV_FLARE_COLOR, color)                // Lighting        engfunc(EngFunc_MessageBegin, MSG_PAS, SVC_TEMPENTITY, originF, 0)        write_byte(TE_DLIGHT) // TE id        engfunc(EngFunc_WriteCoord, originF[0]) // x        engfunc(EngFunc_WriteCoord, originF[1]) // y        engfunc(EngFunc_WriteCoord, originF[2]) // z        write_byte(get_pcvar_num(cvar_flaresize)) // radius        write_byte(color[0]) // r        write_byte(color[1]) // g        write_byte(color[2]) // b        write_byte(51) //life        write_byte((duration < 2) ? 3 : 0) //decay rate        message_end()                // Sparks        engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)        write_byte(TE_SPARKS) // TE id        engfunc(EngFunc_WriteCoord, originF[0]) // x        engfunc(EngFunc_WriteCoord, originF[1]) // y        engfunc(EngFunc_WriteCoord, originF[2]) // z        message_end() }
  // Burning Flames public burning_flame(taskid) {        // Get player origin and flags        static origin[3], flags        get_user_origin(ID_BURN, origin)        flags = pev(ID_BURN, pev_flags)                // Madness mode - in water - burning stopped        if (g_nodamage[ID_BURN] || (flags & FL_INWATER) || g_burning_duration[ID_BURN] < 1)        {               // Smoke sprite               message_begin(MSG_PVS, SVC_TEMPENTITY, origin)               write_byte(TE_SMOKE) // TE id               write_coord(origin[0]) // x               write_coord(origin[1]) // y               write_coord(origin[2]-50) // z               write_short(g_smokeSpr) // sprite               write_byte(random_num(15, 20)) // scale               write_byte(random_num(10, 20)) // framerate               message_end()                              // Task not needed anymore               remove_task(taskid);               return;        }                // Randomly play burning zombie scream sounds (not for nemesis)        if (!g_nemesis[ID_BURN] && !random_num(0, 20))        {               static sound[64]               ArrayGetString(grenade_fire_player, random_num(0, ArraySize(grenade_fire_player) - 1), sound, charsmax(sound))               emit_sound(ID_BURN, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)        }                // Fire slow down, unless nemesis        if (!g_nemesis[ID_BURN] && (flags & FL_ONGROUND) && get_pcvar_float(cvar_fireslowdown) > 0.0)        {               static Float:velocity[3]               pev(ID_BURN, pev_velocity, velocity)               xs_vec_mul_scalar(velocity, get_pcvar_float(cvar_fireslowdown), velocity)               set_pev(ID_BURN, pev_velocity, velocity)        }                // Get player's health        static health        health = pev(ID_BURN, pev_health)                // Take damage from the fire        if (health - floatround(get_pcvar_float(cvar_firedamage), floatround_ceil) > 0)               fm_set_user_health(ID_BURN, health - floatround(get_pcvar_float(cvar_firedamage), floatround_ceil))                // Flame sprite        message_begin(MSG_PVS, SVC_TEMPENTITY, origin)        write_byte(TE_SPRITE) // TE id        write_coord(origin[0]+random_num(-5, 5)) // x        write_coord(origin[1]+random_num(-5, 5)) // y        write_coord(origin[2]+random_num(-10, 10)) // z        write_short(g_flameSpr) // sprite        write_byte(random_num(5, 10)) // scale        write_byte(200) // brightness        message_end()                // Decrease burning duration counter        g_burning_duration[ID_BURN]-- }
  // Infection Bomb: Green Blast create_blast(const Float:originF[3]) {        // Smallest ring        engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)        write_byte(TE_BEAMCYLINDER) // TE id        engfunc(EngFunc_WriteCoord, originF[0]) // x        engfunc(EngFunc_WriteCoord, originF[1]) // y        engfunc(EngFunc_WriteCoord, originF[2]) // z        engfunc(EngFunc_WriteCoord, originF[0]) // x axis        engfunc(EngFunc_WriteCoord, originF[1]) // y axis        engfunc(EngFunc_WriteCoord, originF[2]+385.0) // z axis        write_short(g_exploSpr) // sprite        write_byte(0) // startframe        write_byte(0) // framerate        write_byte(4) // life        write_byte(60) // width        write_byte(0) // noise        write_byte(0) // red        write_byte(200) // green        write_byte(0) // blue        write_byte(200) // brightness        write_byte(0) // speed        message_end()                // Medium ring        engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)        write_byte(TE_BEAMCYLINDER) // TE id        engfunc(EngFunc_WriteCoord, originF[0]) // x        engfunc(EngFunc_WriteCoord, originF[1]) // y        engfunc(EngFunc_WriteCoord, originF[2]) // z        engfunc(EngFunc_WriteCoord, originF[0]) // x axis        engfunc(EngFunc_WriteCoord, originF[1]) // y axis        engfunc(EngFunc_WriteCoord, originF[2]+470.0) // z axis        write_short(g_exploSpr) // sprite        write_byte(0) // startframe        write_byte(0) // framerate        write_byte(4) // life        write_byte(60) // width        write_byte(0) // noise        write_byte(0) // red        write_byte(200) // green        write_byte(0) // blue        write_byte(200) // brightness        write_byte(0) // speed        message_end()                // Largest ring        engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)        write_byte(TE_BEAMCYLINDER) // TE id        engfunc(EngFunc_WriteCoord, originF[0]) // x        engfunc(EngFunc_WriteCoord, originF[1]) // y        engfunc(EngFunc_WriteCoord, originF[2]) // z        engfunc(EngFunc_WriteCoord, originF[0]) // x axis        engfunc(EngFunc_WriteCoord, originF[1]) // y axis        engfunc(EngFunc_WriteCoord, originF[2]+555.0) // z axis        write_short(g_exploSpr) // sprite        write_byte(0) // startframe        write_byte(0) // framerate        write_byte(4) // life        write_byte(60) // width        write_byte(0) // noise        write_byte(0) // red        write_byte(200) // green        write_byte(0) // blue        write_byte(200) // brightness        write_byte(0) // speed        message_end() }
  // Fire Grenade: Fire Blast create_blast2(const Float:originF[3]) {        // Smallest ring        engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)        write_byte(TE_BEAMCYLINDER) // TE id        engfunc(EngFunc_WriteCoord, originF[0]) // x        engfunc(EngFunc_WriteCoord, originF[1]) // y        engfunc(EngFunc_WriteCoord, originF[2]) // z        engfunc(EngFunc_WriteCoord, originF[0]) // x axis        engfunc(EngFunc_WriteCoord, originF[1]) // y axis        engfunc(EngFunc_WriteCoord, originF[2]+385.0) // z axis        write_short(g_exploSpr) // sprite        write_byte(0) // startframe        write_byte(0) // framerate        write_byte(4) // life        write_byte(60) // width        write_byte(0) // noise        write_byte(200) // red        write_byte(100) // green        write_byte(0) // blue        write_byte(200) // brightness        write_byte(0) // speed        message_end()                // Medium ring        engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)        write_byte(TE_BEAMCYLINDER) // TE id        engfunc(EngFunc_WriteCoord, originF[0]) // x        engfunc(EngFunc_WriteCoord, originF[1]) // y        engfunc(EngFunc_WriteCoord, originF[2]) // z        engfunc(EngFunc_WriteCoord, originF[0]) // x axis        engfunc(EngFunc_WriteCoord, originF[1]) // y axis        engfunc(EngFunc_WriteCoord, originF[2]+470.0) // z axis        write_short(g_exploSpr) // sprite        write_byte(0) // startframe        write_byte(0) // framerate        write_byte(4) // life        write_byte(60) // width        write_byte(0) // noise        write_byte(200) // red        write_byte(50) // green        write_byte(0) // blue        write_byte(200) // brightness        write_byte(0) // speed        message_end()                // Largest ring        engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)        write_byte(TE_BEAMCYLINDER) // TE id        engfunc(EngFunc_WriteCoord, originF[0]) // x        engfunc(EngFunc_WriteCoord, originF[1]) // y        engfunc(EngFunc_WriteCoord, originF[2]) // z        engfunc(EngFunc_WriteCoord, originF[0]) // x axis        engfunc(EngFunc_WriteCoord, originF[1]) // y axis        engfunc(EngFunc_WriteCoord, originF[2]+555.0) // z axis        write_short(g_exploSpr) // sprite        write_byte(0) // startframe        write_byte(0) // framerate        write_byte(4) // life        write_byte(60) // width        write_byte(0) // noise        write_byte(200) // red        write_byte(0) // green        write_byte(0) // blue        write_byte(200) // brightness        write_byte(0) // speed        message_end() }
  // Frost Grenade: Freeze Blast create_blast3(const Float:originF[3]) {        // Smallest ring        engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)        write_byte(TE_BEAMCYLINDER) // TE id        engfunc(EngFunc_WriteCoord, originF[0]) // x        engfunc(EngFunc_WriteCoord, originF[1]) // y        engfunc(EngFunc_WriteCoord, originF[2]) // z        engfunc(EngFunc_WriteCoord, originF[0]) // x axis        engfunc(EngFunc_WriteCoord, originF[1]) // y axis        engfunc(EngFunc_WriteCoord, originF[2]+385.0) // z axis        write_short(g_exploSpr) // sprite        write_byte(0) // startframe        write_byte(0) // framerate        write_byte(4) // life        write_byte(60) // width        write_byte(0) // noise        write_byte(0) // red        write_byte(100) // green        write_byte(200) // blue        write_byte(200) // brightness        write_byte(0) // speed        message_end()                // Medium ring        engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)        write_byte(TE_BEAMCYLINDER) // TE id        engfunc(EngFunc_WriteCoord, originF[0]) // x        engfunc(EngFunc_WriteCoord, originF[1]) // y        engfunc(EngFunc_WriteCoord, originF[2]) // z        engfunc(EngFunc_WriteCoord, originF[0]) // x axis        engfunc(EngFunc_WriteCoord, originF[1]) // y axis        engfunc(EngFunc_WriteCoord, originF[2]+470.0) // z axis        write_short(g_exploSpr) // sprite        write_byte(0) // startframe        write_byte(0) // framerate        write_byte(4) // life        write_byte(60) // width        write_byte(0) // noise        write_byte(0) // red        write_byte(100) // green        write_byte(200) // blue        write_byte(200) // brightness        write_byte(0) // speed        message_end()                // Largest ring        engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)        write_byte(TE_BEAMCYLINDER) // TE id        engfunc(EngFunc_WriteCoord, originF[0]) // x        engfunc(EngFunc_WriteCoord, originF[1]) // y        engfunc(EngFunc_WriteCoord, originF[2]) // z        engfunc(EngFunc_WriteCoord, originF[0]) // x axis        engfunc(EngFunc_WriteCoord, originF[1]) // y axis        engfunc(EngFunc_WriteCoord, originF[2]+555.0) // z axis        write_short(g_exploSpr) // sprite        write_byte(0) // startframe        write_byte(0) // framerate        write_byte(4) // life        write_byte(60) // width        write_byte(0) // noise        write_byte(0) // red        write_byte(100) // green        write_byte(200) // blue        write_byte(200) // brightness        write_byte(0) // speed        message_end() }
  // Fix Dead Attrib on scoreboard FixDeadAttrib(id) {        message_begin(MSG_BROADCAST, g_msgScoreAttrib)        write_byte(id) // id        write_byte(0) // attrib        message_end() }
  // Send Death Message for infections SendDeathMsg(attacker, victim) {        message_begin(MSG_BROADCAST, g_msgDeathMsg)        write_byte(attacker) // killer        write_byte(victim) // victim        write_byte(0) // headshot flag        write_string("knife") // killer's weapon        message_end() }
  // Update Player Frags and Deaths UpdateFrags(attacker, victim, frags, deaths, scoreboard) {        // Set attacker frags        set_pev(attacker, pev_frags, float(pev(attacker, pev_frags) + frags))                // Set victim deaths        fm_cs_set_user_deaths(victim, cs_get_user_deaths(victim) + deaths)                // Update scoreboard with attacker and victim info        if (scoreboard)        {               message_begin(MSG_BROADCAST, g_msgScoreInfo)               write_byte(attacker) // id               write_short(pev(attacker, pev_frags)) // frags               write_short(cs_get_user_deaths(attacker)) // deaths               write_short(0) // class?               write_short(fm_cs_get_user_team(attacker)) // team               message_end()                              message_begin(MSG_BROADCAST, g_msgScoreInfo)               write_byte(victim) // id               write_short(pev(victim, pev_frags)) // frags               write_short(cs_get_user_deaths(victim)) // deaths               write_short(0) // class?               write_short(fm_cs_get_user_team(victim)) // team               message_end()        } }
  // Remove Player Frags (when Nemesis/Survivor ignore_frags cvar is enabled) RemoveFrags(attacker, victim) {        // Remove attacker frags        set_pev(attacker, pev_frags, float(pev(attacker, pev_frags) - 1))                // Remove victim deaths        fm_cs_set_user_deaths(victim, cs_get_user_deaths(victim) - 1) }
  // Plays a sound on clients PlaySound(const sound[]) {        client_cmd(0, "spk ^"%s^"", sound) }
  // Prints a colored message to target (use 0 for everyone), supports ML formatting. // Note: I still need to make something like gungame's LANG_PLAYER_C to avoid unintended // argument replacement when a function passes -1 (it will be considered a LANG_PLAYER) zp_colored_print(target, const message[], any:...) {        static buffer[512], i, argscount        argscount = numargs()                // Send to everyone        if (!target)        {               static player               for (player = 1; player <= g_maxplayers; player++)               {                      // Not connected                      if (!g_isconnected[player])                             continue;                                            // Remember changed arguments                      static changed[5], changedcount // [5] = max LANG_PLAYER occurencies                      changedcount = 0                                            // Replace LANG_PLAYER with player id                      for (i = 2; i < argscount; i++)                      {                             if (getarg(i) == LANG_PLAYER)                             {                                    setarg(i, 0, player)                                    changed[changedcount] = i                                    changedcount++                             }                      }                                            // Format message for player                      vformat(buffer, charsmax(buffer), message, 3)                                            // Send it                      message_begin(MSG_ONE_UNRELIABLE, g_msgSayText, _, player)                      write_byte(player)                      write_string(buffer)                      message_end()                                            // Replace back player id's with LANG_PLAYER                      for (i = 0; i < changedcount; i++)                             setarg(changed, 0, LANG_PLAYER)               }        }        // Send to specific target        else        {               /*               // Not needed since you should set the ML argument               // to the player's id for a targeted print message                              // Replace LANG_PLAYER with player id               for (i = 2; i < argscount; i++)               {                      if (getarg(i) == LANG_PLAYER)                             setarg(i, 0, target)               }               */                              // Format message for player               vformat(buffer, charsmax(buffer), message, 3)                              // Send it               message_begin(MSG_ONE, g_msgSayText, _, target)               write_byte(target)               write_string(buffer)               message_end()        } }
  /*================================================================================  [Stocks] =================================================================================*/
  // Set an entity's key value (from fakemeta_util) stock fm_set_kvd(entity, const key[], const value[], const classname[]) {        set_kvd(0, KV_ClassName, classname)        set_kvd(0, KV_KeyName, key)        set_kvd(0, KV_Value, value)        set_kvd(0, KV_fHandled, 0)
         dllfunc(DLLFunc_KeyValue, entity, 0) }
  // Set entity's rendering type (from fakemeta_util) stock fm_set_rendering(entity, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16) {        static Float:color[3]        color[0] = float(r)        color[1] = float(g)        color[2] = float(b)                set_pev(entity, pev_renderfx, fx)        set_pev(entity, pev_rendercolor, color)        set_pev(entity, pev_rendermode, render)        set_pev(entity, pev_renderamt, float(amount)) }
  // Get entity's speed (from fakemeta_util) stock fm_get_speed(entity) {        static Float:velocity[3]        pev(entity, pev_velocity, velocity)                return floatround(vector_length(velocity)); }
  // Get entity's aim origins (from fakemeta_util) stock fm_get_aim_origin(id, Float:origin[3]) {        static Float:origin1F[3], Float:origin2F[3]        pev(id, pev_origin, origin1F)        pev(id, pev_view_ofs, origin2F)        xs_vec_add(origin1F, origin2F, origin1F)
         pev(id, pev_v_angle, origin2F);        engfunc(EngFunc_MakeVectors, origin2F)        global_get(glb_v_forward, origin2F)        xs_vec_mul_scalar(origin2F, 9999.0, origin2F)        xs_vec_add(origin1F, origin2F, origin2F)
         engfunc(EngFunc_TraceLine, origin1F, origin2F, 0, id, 0)        get_tr2(0, TR_vecEndPos, origin) }
  // Find entity by its owner (from fakemeta_util) stock fm_find_ent_by_owner(entity, const classname[], owner) {        while ((entity = engfunc(EngFunc_FindEntityByString, entity, "classname", classname)) && pev(entity, pev_owner) != owner) { /* keep looping */ }        return entity; }
  // Set player's health (from fakemeta_util) stock fm_set_user_health(id, health) {        (health > 0) ? set_pev(id, pev_health, float(health)) : dllfunc(DLLFunc_ClientKill, id); }
  // Give an item to a player (from fakemeta_util) stock fm_give_item(id, const item[]) {        static ent        ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, item))        if (!pev_valid(ent)) return;                static Float:originF[3]        pev(id, pev_origin, originF)        set_pev(ent, pev_origin, originF)        set_pev(ent, pev_spawnflags, pev(ent, pev_spawnflags) | SF_NORESPAWN)        dllfunc(DLLFunc_Spawn, ent)                static save        save = pev(ent, pev_solid)        dllfunc(DLLFunc_Touch, ent, id)        if (pev(ent, pev_solid) != save)               return;                engfunc(EngFunc_RemoveEntity, ent) }
  // Strip user weapons (from fakemeta_util) stock fm_strip_user_weapons(id) {        static ent        ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "player_weaponstrip"))        if (!pev_valid(ent)) return;                dllfunc(DLLFunc_Spawn, ent)        dllfunc(DLLFunc_Use, ent, id)        engfunc(EngFunc_RemoveEntity, ent) }
  // Collect random spawn points stock load_spawns() {        // Check for CSDM spawns of the current map        new cfgdir[32], mapname[32], filepath[100], linedata[64]        get_configsdir(cfgdir, charsmax(cfgdir))        get_mapname(mapname, charsmax(mapname))        formatex(filepath, charsmax(filepath), "%s/csdm/%s.spawns.cfg", cfgdir, mapname)                // Load CSDM spawns if present        if (file_exists(filepath))        {               new csdmdata[10][6], file = fopen(filepath,"rt")                              while (file && !feof(file))               {                      fgets(file, linedata, charsmax(linedata))                                            // invalid spawn                      if(!linedata[0] || str_count(linedata,' ') < 2) continue;                                            // get spawn point data                      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)                                            // origin                      g_spawns[g_spawnCount][0] = floatstr(csdmdata[0])                      g_spawns[g_spawnCount][1] = floatstr(csdmdata[1])                      g_spawns[g_spawnCount][2] = floatstr(csdmdata[2])                                            // increase spawn count                      g_spawnCount++                      if (g_spawnCount >= sizeof g_spawns) break;               }               if (file) fclose(file)        }        else        {               // Collect regular spawns               collect_spawns_ent("info_player_start")               collect_spawns_ent("info_player_deathmatch")        }                // Collect regular spawns for non-random spawning unstuck        collect_spawns_ent2("info_player_start")        collect_spawns_ent2("info_player_deathmatch") }
  // Collect spawn points from entity origins stock collect_spawns_ent(const classname[]) {        new ent = -1        while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", classname)) != 0)        {               // get origin               new Float:originF[3]               pev(ent, pev_origin, originF)               g_spawns[g_spawnCount][0] = originF[0]               g_spawns[g_spawnCount][1] = originF[1]               g_spawns[g_spawnCount][2] = originF[2]                              // increase spawn count               g_spawnCount++               if (g_spawnCount >= sizeof g_spawns) break;        } }
  // Collect spawn points from entity origins stock collect_spawns_ent2(const classname[]) {        new ent = -1        while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", classname)) != 0)        {               // get origin               new Float:originF[3]               pev(ent, pev_origin, originF)               g_spawns2[g_spawnCount2][0] = originF[0]               g_spawns2[g_spawnCount2][1] = originF[1]               g_spawns2[g_spawnCount2][2] = originF[2]                              // increase spawn count               g_spawnCount2++               if (g_spawnCount2 >= sizeof g_spawns2) break;        } }
  // Drop primary/secondary weapons stock drop_weapons(id, dropwhat) {        // Get user weapons        static weapons[32], num, i, weaponid        num = 0 // reset passed weapons count (bugfix)        get_user_weapons(id, weapons, num)                // Loop through them and drop primaries or secondaries        for (i = 0; i < num; i++)        {               // Prevent re-indexing the array               weaponid = weapons                              if ((dropwhat == 1 && ((1<<weaponid) & PRIMARY_WEAPONS_BIT_SUM)) || (dropwhat == 2 && ((1<<weaponid) & SECONDARY_WEAPONS_BIT_SUM)))               {                      // Get weapon entity                      static wname[32], weapon_ent                      get_weaponname(weaponid, wname, charsmax(wname))                      weapon_ent = fm_find_ent_by_owner(-1, wname, id)                                            // Hack: store weapon bpammo on PEV_ADDITIONAL_AMMO                      set_pev(weapon_ent, PEV_ADDITIONAL_AMMO, cs_get_user_bpammo(id, weaponid))                                            // Player drops the weapon and looses his bpammo                      engclient_cmd(id, "drop", wname)                      cs_set_user_bpammo(id, weaponid, 0)               }        } }
  // Stock by (probably) Twilight Suzuka -counts number of chars in a string stock str_count(const str[], searchchar) {        new count, i, len = strlen(str)                for (i = 0; i <= len; i++)        {               if(str == searchchar)                      count++        }                return count; }
  // Checks if a space is vacant (credits to VEN) stock is_hull_vacant(Float:origin[3], hull) {        engfunc(EngFunc_TraceHull, origin, origin, 0, hull, 0, 0)                if (!get_tr2(0, TR_StartSolid) && !get_tr2(0, TR_AllSolid) && get_tr2(0, TR_InOpen))               return true;                return false; }
  // Check if a player is stuck (credits to VEN) stock is_player_stuck(id) {        static Float:originF[3]        pev(id, pev_origin, originF)                engfunc(EngFunc_TraceHull, originF, originF, 0, (pev(id, pev_flags) & FL_DUCKING) ? HULL_HEAD : HULL_HUMAN, id, 0)                if (get_tr2(0, TR_StartSolid) || get_tr2(0, TR_AllSolid) || !get_tr2(0, TR_InOpen))               return true;                return false; }
  // Simplified get_weaponid (CS only) stock cs_weapon_name_to_id(const weapon[]) {        static i        for (i = 0; i < sizeof WEAPONENTNAMES; i++)        {               if (equal(weapon, WEAPONENTNAMES))                      return i;        }                return 0; }
  // Get User Current Weapon Entity stock fm_cs_get_current_weapon_ent(id) {        return get_pdata_cbase(id, OFFSET_ACTIVE_ITEM, OFFSET_LINUX); }
  // Get Weapon Entity's Owner stock fm_cs_get_weapon_ent_owner(ent) {        return get_pdata_cbase(ent, OFFSET_WEAPONOWNER, OFFSET_LINUX_WEAPONS); }
  // Set User Deaths stock fm_cs_set_user_deaths(id, value) {        set_pdata_int(id, OFFSET_CSDEATHS, value, OFFSET_LINUX) }
  // Get User Team stock fm_cs_get_user_team(id) {        return get_pdata_int(id, OFFSET_CSTEAMS, OFFSET_LINUX); }
  // Set a Player's Team stock fm_cs_set_user_team(id, team) {        set_pdata_int(id, OFFSET_CSTEAMS, team, OFFSET_LINUX) }
  // Set User Money stock fm_cs_set_user_money(id, value) {        set_pdata_int(id, OFFSET_CSMONEY, value, OFFSET_LINUX) }
  // Set User Flashlight Batteries stock fm_cs_set_user_batteries(id, value) {        set_pdata_int(id, OFFSET_FLASHLIGHT_BATTERY, value, OFFSET_LINUX) }
  // Update Player's Team on all clients (adding needed delays) stock fm_user_team_update(id) {        static Float:current_time        current_time = get_gametime()                if (current_time - g_teams_targettime >= 0.1)        {               set_task(0.1, "fm_cs_set_user_team_msg", id+TASK_TEAM)               g_teams_targettime = current_time + 0.1        }        else        {               set_task((g_teams_targettime + 0.1) - current_time, "fm_cs_set_user_team_msg", id+TASK_TEAM)               g_teams_targettime = g_teams_targettime + 0.1        } }
  // Send User Team Message public fm_cs_set_user_team_msg(taskid) {        // Note to self: this next message can now be received by other plugins                // Set the switching team flag        g_switchingteam = true                // Tell everyone my new team        emessage_begin(MSG_ALL, g_msgTeamInfo)        ewrite_byte(ID_TEAM) // player        ewrite_string(CS_TEAM_NAMES[fm_cs_get_user_team(ID_TEAM)]) // team        emessage_end()                // Done switching team        g_switchingteam = false }
  // Set the precached model index (updates hitboxes server side) stock fm_cs_set_user_model_index(id, value) {        set_pdata_int(id, OFFSET_MODELINDEX, value, OFFSET_LINUX) }
  // Set Player Model on Entity stock fm_set_playermodel_ent(id) {        // Make original player entity invisible without hiding shadows or firing effects        fm_set_rendering(id, kRenderFxNone, 255, 255, 255, kRenderTransTexture, 1)                // Format model string        static model[100]        formatex(model, charsmax(model), "models/player/%s/%s.mdl", g_playermodel[id], g_playermodel[id])                // Set model on entity or make a new one if unexistant        if (!pev_valid(g_ent_playermodel[id]))        {               g_ent_playermodel[id] = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))               if (!pev_valid(g_ent_playermodel[id])) return;                              set_pev(g_ent_playermodel[id], pev_classname, MODEL_ENT_CLASSNAME)               set_pev(g_ent_playermodel[id], pev_movetype, MOVETYPE_FOLLOW)               set_pev(g_ent_playermodel[id], pev_aiment, id)               set_pev(g_ent_playermodel[id], pev_owner, id)        }                engfunc(EngFunc_SetModel, g_ent_playermodel[id], model) }
  // Set Weapon Model on Entity stock fm_set_weaponmodel_ent(id) {        // Get player's p_ weapon model        static model[100]        pev(id, pev_weaponmodel2, model, charsmax(model))                // Set model on entity or make a new one if unexistant        if (!pev_valid(g_ent_weaponmodel[id]))        {               g_ent_weaponmodel[id] = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))               if (!pev_valid(g_ent_weaponmodel[id])) return;                              set_pev(g_ent_weaponmodel[id], pev_classname, WEAPON_ENT_CLASSNAME)               set_pev(g_ent_weaponmodel[id], pev_movetype, MOVETYPE_FOLLOW)               set_pev(g_ent_weaponmodel[id], pev_aiment, id)               set_pev(g_ent_weaponmodel[id], pev_owner, id)        }                engfunc(EngFunc_SetModel, g_ent_weaponmodel[id], model) }
  // Remove Custom Model Entities stock fm_remove_model_ents(id) {        // Remove "playermodel" ent if present        if (pev_valid(g_ent_playermodel[id]))        {               engfunc(EngFunc_RemoveEntity, g_ent_playermodel[id])               g_ent_playermodel[id] = 0        }        // Remove "weaponmodel" ent if present        if (pev_valid(g_ent_weaponmodel[id]))        {               engfunc(EngFunc_RemoveEntity, g_ent_weaponmodel[id])               g_ent_weaponmodel[id] = 0        } }
  // Set User Model public fm_cs_set_user_model(taskid) {        set_user_info(ID_MODEL, "model", g_playermodel[ID_MODEL]) }
  // Get User Model -model passed byref- stock fm_cs_get_user_model(player, model[], len) {        get_user_info(player, "model", model, len) }
  // Update Player's Model on all clients (adding needed delays) public fm_user_model_update(taskid) {        static Float:current_time        current_time = get_gametime()                if (current_time - g_models_targettime >= g_modelchange_delay)        {               fm_cs_set_user_model(taskid)               g_models_targettime = current_time        }        else        {               set_task((g_models_targettime + g_modelchange_delay) - current_time, "fm_cs_set_user_model", taskid)               g_models_targettime = g_models_targettime + g_modelchange_delay        } } 
                    
                    
                     
        
                   | 
                 
                
                  
              
                
                   
                    
                   | 
                 
                
                  
                    
                      x0
                      
                     
                    
                  
                    [7 樓]
                    
                    
                     From:臺灣中華電信股份有限公司 |  Posted:2013-12-31 22:49 | 
                    
                     | 
                 
               
                   | 
                 
                 
        
        
                
        
        
                
        
       |