Hello, I'm thinking about getting the main function of ZP 3:59 and "paste" in a new sma to create a style "Infection HideNSeek"
Code:
/*================================================================================
***********************************************
********** [Zombie Plague Mod 3.5] ************
***********************************************
(c) Copyright 2008 by MeRcyLeZZ
----------------------
-*- Licensing Info -*-
----------------------
This file is provided "as-is" and comes with no warranties of any kind.
You are free to use, redistribute and/or modify this plugin to your
liking with the following restrictions:
* You cannot alter/remove/replace the register_plugin() call
* You cannot alter/remove/replace any credits info
* You cannot alter/remove/replace this license
-------------------
-*- Description -*-
-------------------
Zombie Plague is a Counter-Strike plugin developed under AMX Mod X, in
where humans and zombies are confronted. It is based on the original
infection mod, but it takes the concept to a new level by introducing:
* New Gameplay Modes: Nemesis, Survivor, Multiple Infection, Swarm Mode
* Zombie Classes: a total of six, each with his own strengths
* Ammo Packs: awarded to skilled players, can be used to purchase goods
* Custom Grenades: Fire, Frost, Flare, and Infection Bomb
* Deathmatch Mode: players may respawn as zombies, humans, or randomly
* Admin commands: can be performed through an easy ingame menu
* Special GFX Effects: from the HL Engine
* Customizable Models and Sounds
It also brings many customization through CVARS:
* Change nightvision/flashlight colors and size
* Adjust in-game lightning (thunderclaps available on pitch black mode)
* Set zombies/humans health, speed, gravity, ammo pack rewards, and more
* Enable unlimited ammo or knockback for weapons
* Enable random spawning (CSDM-spawns friendly)
* Separately enable and customize the new gameplay modes to your liking
---------------
-*- History -*-
---------------
As only few people may know, I started this project back on December
2007, when the free infection mods around were quite buggy. When I first
decided to remake one of those, I came across many problems and realized
I had little to no experience at AMXX scripting, and therefore, agreed
that the best way to get it done would be starting from scratch.
Not after spending over a week looking at many plugins (mainly Zombie
Swarm) and scarce tutorials, I managed to have all the basic stuff
working quite well (even though the code itself was really messy). The
following months were spent polishing things up and trying to fulfill new
original ideas.
In the meantime I had the chance to try the plugin out on a 32 man server.
This meant a huge progress on development, we ran into lots of testing
and fixing server crashes, but finally this turned out to be more than
the simple infection mod I had originally planned it to be.
The reason this project was kept private for such a long time was not
only for its uniqueness, but because I felt like it wasn't ready to take
the next step yet. However, the plugin has come a long way now. I've
spent the last days improving and commenting the source code, adding as
many customization as I could, and I'm glad to say I'm finally making it
freely available.
The only thing I ask for return is to keep my name in the plugin.
-Enjoy!
-------------
-*- Media -*-
-------------
* Gameplay Video 1: http://www.youtube.com/watch?v=HFUyF7-_uzw
* Gameplay Video 2: http://www.youtube.com/watch?v=XByif6Mti-w
--------------------
-*- Requirements -*-
--------------------
* Mods: Counter-Strike 1.6 or Condition-Zero
* AMXX: version 1.8.0 (build 3660) or higher
* Modules: FakeMeta, HamSandwich
--------------------
-*- Installation -*-
--------------------
Just extract all the contents from the .zip file to your server's mod
directory ("cstrike" or "czero"). Make sure to keep folder structure.
-------------------------------
-*- 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 by looking at the beginning of the .sma for the
"Plugin Customization" section. Once you're done making your changes,
remember to recompile!
----------------------
-*- Admin Commands -*-
----------------------
The following console commands are available:
* zp_zombie <name> - Turn someone into a Zombie
* zp_human <name> - Turn someone back to Human
* zp_nemesis <name> - Turn someone into a Nemesis (*)
* zp_survivor <name> - Turn someone into a Survivor (*)
* zp_respawn <name> - Respawn someone
* zp_swarm - Start Swarm Mode (*)
* zp_multi - Start Multi Infection (*)
(*) - These commands can only be used at round start, that is, when
the T-Virus notice is shown on screen.
-------------------
-*- InGame Menu -*-
-------------------
Players can access the mod menu by typing "zpmenu" in the 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 any
of the console commands.
----------------------
-*- 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.
----------------------
-*- Zombie Classes -*-
----------------------
There are six zombie classes by default:
* 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 the most health when infecting.
* Rage Zombie: emits a radioactive green glow.
-------------------
-*- Extra Items -*-
-------------------
Besides weapons, players can buy the following items:
* Night Vision: makes you able to see in the dark, lasts a single round.
* T-Virus Antidote: makes you turn back to your human form.
* Zombie Madness: you develop a powerful shield for a short time.
* Infection Bomb: infects anyone within its explosion radius.
--------------------
-*- Contact Info -*-
--------------------
For the official Zombie Plague thread visit:
http://forums.alliedmods.net/showthread.php?t=72505
For personal contact you can send me an email at:
[email protected]
---------------
-*- 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: 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
* ML Translations: DKs (BP), JahMan (PL), DA (DE)
* Everyone who enjoys killing zombies!
------------------
-*- Change Log -*-
------------------
* till 1.0: (Dec 2007)
- First Release: most of the basic stuff done.
- Added: random spawning, HP display on hud, lightning setting,
simple buy menu, custom nightvision, admin commands, Nemesis
and Survivor modes, glow and leap settings for them.
* till 2.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.
* till 3.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.
* till 3.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.
=================================================================================*/
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <hamsandwich>
#include <xs>
/*================================================================================
[Plugin Customization]
=================================================================================*/
// Access Flag Required to use Admin Commands
const ACCESS_FLAG = ADMIN_BAN
// Player Models (randomly chosen, add as many as you want) -32 chars max per model-
new const model_zombie_class1[][] = { "zombie_source" } // Zombie (Classic)
new const model_zombie_class2[][] = { "zombie_source" } // Zombie (Raptor)
new const model_zombie_class3[][] = { "zombie_source" } // Zombie (Poison)
new const model_zombie_class4[][] = { "zombie_source" } // Zombie (Fat)
new const model_zombie_class5[][] = { "zombie_source" } // Zombie (Leech)
new const model_zombie_class6[][] = { "zombie_source" } // Zombie (Rage)
new const model_nemesis[][] = { "zombie_source" } // Nemesis
new const model_human[][] = { "arctic", "guerilla", "leet", "terror", "gign", "gsg9", "sas", "urban" } // Human
new const model_admin[][] = { "vip" } // Admin
// Custom Weapon Models
new const model_vknife_zombie[] = { "models/zombie_plague/v_knife_zombie.mdl" }
new const model_pknife_zombie[] = { "" }
new const model_vknife_nemesis[] = { "models/zombie_plague/v_knife_zombie.mdl" }
new const model_pknife_nemesis[] = { "" }
new const model_grenade_infect[] = { "models/zombie_plague/v_grenade_infect.mdl" }
new const model_grenade_fire[] = { "models/zombie_plague/v_grenade_fire.mdl" }
new const model_grenade_frost[] = { "models/zombie_plague/v_grenade_frost.mdl" }
new const model_grenade_flare[] = { "models/zombie_plague/v_grenade_flare.mdl" }
// Sound list (randomly chosen, add as many as you want)
new const sound_win_zombies[][] = { "ambience/the_horror1.wav", "ambience/the_horror3.wav", "ambience/the_horror4.wav" }
new const sound_win_humans[][] = { "zombie_plague/win_humans1.wav", "zombie_plague/win_humans2.wav" }
new const sound_win_no_one[][] = { "" }
new const zombie_infect[][] = { "zombie_plague/zombie_infec1.wav", "zombie_plague/zombie_infec2.wav", "zombie_plague/zombie_infec3.wav", "scientist/c1a0_sci_catscream.wav", "scientist/scream01.wav" }
new const zombie_pain[][] = { "zombie_plague/zombie_pain1.wav", "zombie_plague/zombie_pain2.wav", "zombie_plague/zombie_pain3.wav", "zombie_plague/zombie_pain4.wav", "zombie_plague/zombie_pain5.wav" }
new const nemesis_pain[][] = { "zombie_plague/nemesis_pain1.wav", "zombie_plague/nemesis_pain2.wav", "zombie_plague/nemesis_pain3.wav" }
new const zombie_die[][] = { "zombie_plague/zombie_die1.wav", "zombie_plague/zombie_die2.wav", "zombie_plague/zombie_die3.wav", "zombie_plague/zombie_die4.wav", "zombie_plague/zombie_die5.wav" }
new const zombie_fall[][] = { "zombie_plague/zombie_fall1.wav" }
new const zombie_idle[][] = { "nihilanth/nil_now_die.wav", "nihilanth/nil_slaves.wav", "nihilanth/nil_alone.wav", "zombie_plague/zombie_brains1.wav", "zombie_plague/zombie_brains2.wav" }
new const zombie_idle_last[][] = { "nihilanth/nil_thelast.wav" }
new const zombie_madness[][] = { "zombie_plague/zombie_madness1.wav" }
new const sound_nemesis[][] = { "zombie_plague/nemesis1.wav", "zombie_plague/nemesis2.wav" }
new const sound_survivor[][] = { "zombie_plague/survivor1.wav", "zombie_plague/survivor2.wav" }
new const sound_swarm[][] = { "ambience/the_horror2.wav" }
new const sound_multi[][] = { "ambience/the_horror2.wav" }
new const grenade_infect[][] = { "zombie_plague/grenade_infect.wav" }
new const grenade_infect_player[][] = { "scientist/scream20.wav", "scientist/scream22.wav", "scientist/scream05.wav" }
new const grenade_fire[][] = { "zombie_plague/grenade_explode.wav" }
new const grenade_fire_player[][] = { "zombie_plague/zombie_burn3.wav","zombie_plague/zombie_burn4.wav","zombie_plague/zombie_burn5.wav","zombie_plague/zombie_burn6.wav","zombie_plague/zombie_burn7.wav" }
new const grenade_frost[][] = { "warcraft3/frostnova.wav" }
new const grenade_frost_player[][] = { "warcraft3/impalehit.wav" }
new const grenade_frost_break[][] = { "warcraft3/impalelaunch1.wav" }
new const grenade_flare[][] = { "items/nvg_on.wav" }
new const sound_antidote[][] = { "items/smallmedkit1.wav" }
new const sound_thunder[][] = { "zombie_plague/thunder1.wav", "zombie_plague/thunder2.wav" }
// Uncomment the following line to enable ambience sounds
//#define AMBIENCE_SOUNDS
#if defined AMBIENCE_SOUNDS // Ambience Sounds List (only .wav and .mp3 formats supported)
new const sound_ambience[][] = { "zombie_plague/ambience.wav" }
new const Float:sound_ambience_duration[] = { 17.0 } // duration in seconds
#endif
// Buy Menu: Primary Weapons (9 max)
new const g_primary_names[][] = { "SG-552 Commando", "Steyr AUG A1", "M4A1 Carbine", "AK-47 Kalashnikov", "IMI Galil", "Famas", "M3 Super 90", "XM1014 M4", "MP5 Navy" }
new const g_primary_classes[][] = { "Rifle", "Rifle", "Rifle", "Rifle", "Rifle", "Rifle", "Shotgun", "Shotgun", "SMG" }
new const g_primary_items[][] = { "weapon_sg552", "weapon_aug", "weapon_m4a1", "weapon_ak47", "weapon_galil", "weapon_famas", "weapon_m3", "weapon_xm1014", "weapon_mp5navy" }
// Buy Menu: Secondary Weapons (9 max)
new const g_secondary_names[][] = { "Glock 18C", "USP .45 ACP Tactical", "P228", "Desert Eagle .50 AE", "FiveseveN", "Dual 96G Elite Berettas" }
new const g_secondary_classes[][] = { "Pistol", "Pistol", "Pistol", "Pistol", "Pistol", "Pistol" }
new const g_secondary_items[][] = { "weapon_glock18", "weapon_usp", "weapon_p228", "weapon_deagle", "weapon_fiveseven", "weapon_elite" }
// Additional Items to give after buying all weapons (e.g. grenades)
new const g_additional_items[][] = { "weapon_hegrenade", "weapon_flashbang", "weapon_smokegrenade" }
// Extra Items: Weapons and their costs (5 max)
new const g_extra_names[][] = { "Fire Grenade", "AWP Sniper", "M249 Machinegun", "SG550 Auto-Sniper", "G3SG1 Auto-Sniper" }
new const g_extra_items[][] = { "weapon_hegrenade", "weapon_awp", "weapon_m249", "weapon_sg550", "weapon_g3sg1" }
new const g_extra_costs[] = { 6, 8, 10, 12, 12 }
// Extra Items: costs for Night Vision, Antidote, Zombie Madness, and Infection Bomb
new const g_extra_costs2[] = { 15, 15, 17, 20 }
// Weather Effects: uncomment a line to have the desired effect
//#define AMBIENCE_RAIN // Rain
//#define AMBIENCE_SNOW // Snow
//#define AMBIENCE_FOG // Fog
#if defined AMBIENCE_FOG // Fog Customization (if enabled)
new const FOG_DENSITY[] = "0.0018" // Density
new const FOG_COLOR[] = "128 128 128" // Color: Red Green Blue
#endif
// Sky Names (randomly chosen, add as many as you want)
new const skynames[][] = { "space" }
// Thunderclap Lightning Cycles
new const lights_thunder1[][] = { "i" ,"j", "k", "l", "m", "n", "o", "n", "m", "l", "k", "j", "i", "h", "g", "f", "e", "d", "c", "b", "a"}
new const lights_thunder2[][] = { "k", "l", "m", "l", "k", "j", "i", "h", "g", "f", "e", "d", "c", "b", "a", "a", "b", "c", "d", "e", "d", "c", "b", "a"}
new const lights_thunder3[][] = { "b", "c", "d", "e", "f", "e", "d", "c", "i" ,"j", "k", "l", "m", "l", "k", "j", "i", "h", "g", "f", "e", "d", "c", "b", "a"}
// Decal List for Zombie Bloodstains/Footsteps
new const zombie_decals[] = { 99, 107, 108, 184, 185, 186, 187, 188, 189 }
// Multipliers for zombie classes as follows: (percents)
// Classic, Raptor, Poison, Fat, Leech, Rage
new const zombie_multihp[] = { 100, 50, 75, 150, 75, 125 }
new const zombie_multispd[] = { 100, 120, 100, 80, 100, 110 }
new const zombie_multigrav[] = { 100, 100, 75, 100, 100, 87 }
new const zombie_multiknockback[] = { 100, 150, 125, 50, 125, 100 }
// Knockback Power values for all weapons
// Note: to disable knockback power on a specific weapon use a negative value
new const Float:kb_weapon_power[] =
{
-1.0, // ---
2.4, // P228
-1.0, // ---
6.5, // SCOUT
-1.0, // ---
8.0, // XM1014
-1.0, // ---
2.3, // MAC10
5.0, // AUG
-1.0, // ---
2.4, // ELITE
2.0, // FIVESEVEN
2.4, // UMP45
5.3, // SG550
5.5, // GALIL
5.5, // FAMAS
2.2, // USP
2.0, // GLOCK18
10.0, // AWP
2.5, // MP5NAVY
5.2, // M249
8.0, // M3
5.0, // M4A1
2.4, // TMP
6.5, // G3SG1
-1.0, // ---
5.3, // DEAGLE
5.0, // SG552
6.0, // AK47
-1.0, // ---
2.0 // P90
}
// Objective entites and anything that would affect plugin gameplay
new const g_objective_ents[][] = { "func_bomb_target", "info_bomb_target", "info_vip_start", "func_vip_safetyzone", "func_escapezone", "hostage_entity",
"monster_scientist", "func_hostage_rescue", "info_hostage_rescue", "env_fog", "env_rain", "env_snow", "func_vehicle", "item_longjump" }
// ***************************************************************
// *** If you experience many SVC_BAD kicks, try the following ***
// ***************************************************************
// 1. Increase the delay between model changes here: (eg. set it to 0.5)
const Float:MODELCHANGE_DELAY = 0.2
// 2. If the above doesn't help, uncomment the following line:
//#define HANDLE_MODELS_ON_SEPARATE_ENT // experimental, uses more CPU
// ---------------------------------------------------------------
// ------------------ Customization ends here!! ------------------
// ---------------------------------------------------------------
/*================================================================================
[Offsets and Constants]
=================================================================================*/
// Plugin Version
new const PLUGIN_VERSION[] = "3.59"
// Task offsets
const MODEL_TASK = 2000
const TEAM_TASK = 2100
const SPAWN_TASK = 2200
const BLOOD_TASK = 2300
const NVISION_TASK = 2400
const CHARGE_TASK = 2500
const SHOWHUD_TASK = 2600
const NADES_TASK = 2700
const MAKEZOMBIE_TASK = 2800
const WELCOMEMSG_TASK = 2900
const THUNDER_PRE_TASK = 3000
const THUNDER_TASK = 3100
// IDs inside tasks
#define ID_MODEL (taskid - MODEL_TASK)
#define ID_TEAM (taskid - TEAM_TASK)
#define ID_SPAWN (taskid - SPAWN_TASK)
#define ID_BLOOD (taskid - BLOOD_TASK)
#define ID_NVISION (taskid - NVISION_TASK)
#define ID_CHARGE (taskid - CHARGE_TASK)
#define ID_SHOWHUD (taskid - SHOWHUD_TASK)
// For player list menu handlers
#define PL_STARTID (g_menu_item[id][0])
#define PL_ACTION (g_menu_item[id][1])
#define PL_TARGET (key+g_menu_item[id][0]+1)
// Hard coded extra items
enum
{
EXTRA_NVISION = 0,
EXTRA_ANTIDOTE,
EXTRA_MADNESS,
EXTRA_INFBOMB
}
// CS Offsets
#if cellbits == 32
const OFFSET_CSTEAMS = 114
const OFFSET_CSMONEY = 115
const OFFSET_NVGOGGLES = 129
const OFFSET_ZOOMTYPE = 363
const OFFSET_CSDEATHS = 444
const OFFSET_AWM_AMMO = 377
const OFFSET_SCOUT_AMMO = 378
const OFFSET_PARA_AMMO = 379
const OFFSET_FAMAS_AMMO = 380
const OFFSET_M3_AMMO = 381
const OFFSET_USP_AMMO = 382
const OFFSET_FIVESEVEN_AMMO = 383
const OFFSET_DEAGLE_AMMO = 384
const OFFSET_P228_AMMO = 385
const OFFSET_GLOCK_AMMO = 386
const OFFSET_FLASH_AMMO = 387
const OFFSET_HE_AMMO = 388
const OFFSET_SMOKE_AMMO = 389
const OFFSET_C4_AMMO = 390
const OFFSET_CLIPAMMO = 51
#else
const OFFSET_CSTEAMS = 139
const OFFSET_CSMONEY = 140
const OFFSET_NVGOGGLES = 155
const OFFSET_ZOOMTYPE = 402
const OFFSET_CSDEATHS = 493
const OFFSET_AWM_AMMO = 426
const OFFSET_SCOUT_AMMO = 427
const OFFSET_PARA_AMMO = 428
const OFFSET_FAMAS_AMMO = 429
const OFFSET_M3_AMMO = 430
const OFFSET_USP_AMMO = 431
const OFFSET_FIVESEVEN_AMMO = 432
const OFFSET_DEAGLE_AMMO = 433
const OFFSET_P228_AMMO = 434
const OFFSET_GLOCK_AMMO = 435
const OFFSET_FLASH_AMMO = 46
const OFFSET_HE_AMMO = 437
const OFFSET_SMOKE_AMMO = 438
const OFFSET_C4_AMMO = 439
const OFFSET_CLIPAMMO = 65
#endif
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
{
CS_TEAM_UNASSIGNED = 0,
CS_TEAM_T,
CS_TEAM_CT,
CS_TEAM_SPECTATOR
}
// Other consts
const HIDE_MONEY = (1<<5)
const ATTRIB_BOMB = (1<<1)
const DMG_HEGRENADE = (1<<24)
const CS_NO_ZOOM = 0x5A
// Max BP ammo for weapons
new const MAXAMMO[] = { -1, 52, -1, 90, -1, 32, 1, 100, 90, -1, 120, 100, 100, 90, 90, 90, 100, 120,
30, 120, 200, 32, 90, 120, 90, -1, 35, 90, 90, -1, 100 }
// 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, 2, 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 }
// 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))
// Menu keys
const KEYSMENU = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)
/*================================================================================
[Global Variables]
=================================================================================*/
// Stupid compiler
#pragma unused g_models_i
// Player vars
new g_zombie[33] // is zombie
new g_nemesis[33] // is nemesis
new g_survivor[33] // is surivor
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_currentweapon[33] // current weapon the player is holding
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 g_spec_target[33] // last spectator target (for game nvg fix)
new g_spec_first_person[33] // was player spectating on first person (for game nvg fix)
new g_restorevel[33], Float:g_velocity[33][3] // Pain Shock Free vars
new g_switchingteam[33] // is switching team
new g_playermodel[33][33] // current model's short name [player][model]
// Game vars
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_scorezombies, g_scorehumans // team scores
new g_spawnCount // available spawn points count
new Float:g_spawns[128][3] // spawn points data
new g_lights_i // thunderclap lightning cycle counter
new Float:g_models_i // delay between Model Change messages
new Float:g_teams_i // delay between Team Change messages
new g_MsgSync, g_MsgSync2 // message sync objects
new g_trailSpr, g_exploSpr, g_flameSpr, g_glassSpr // grenade sprites
new g_modname[32]
new g_maxplayers // max players count
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 // spawn forward handle
new g_menu_item[33][2] // starting indices for player list menus
// Database vars (used to save players stats in case they get disconnected)
new db_name[100][64] // player name [slot id][player name]
new db_ammopacks[100] // ammo pack count [slot id]
new db_zombieclass[100] // zombie class [slot id]
new db_slot_i // additional saved slots count (should start on maxplayers+1)
// Message IDs vars
new g_msgScoreInfo, g_msgSetFOV, g_msgScreenFade, g_msgDeathMsg, g_msgScoreAttrib, g_msgAmmoPickup,
g_msgNVGToggle, g_msgFlashlight, g_msgFlashBat, g_msgTeamInfo, g_msgSendAudio
// CVAR pointers
new cvar_hp, cvar_firsthp, cvar_speed, cvar_lightning, cvar_gravity, cvar_removemoney,
cvar_thunder, cvar_fov_angle, cvar_bonushp, cvar_cflash, cvar_knockback, cvar_survleap,
cvar_nem, cvar_nemchance, cvar_nemhp, cvar_nemglow, cvar_surv, cvar_cnvg, cvar_nemleap,
cvar_nemgravity, cvar_flashsize, cvar_survglow, cvar_ammodamage, cvar_armor, cvar_dropwpn,
cvar_nempainfree, cvar_nemspd, cvar_survchance, cvar_survhp, cvar_survspd, cvar_humanspd,
cvar_swarmchance, cvar_flashdrain, cvar_bleeding, cvar_removedoors, cvar_survpainfree,
cvar_randspawn, cvar_multi, cvar_multichance, cvar_infammo, cvar_swarm, cvar_ammoinfect,
cvar_painfree, cvar_knockbackpower, cvar_freezeduration, cvar_triggered, cvar_deathmatch,
cvar_firegrenades, cvar_frostgrenades, cvar_survgravity, cvar_humanhp, cvar_logcommands,
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_firstleap, cvar_flaresize, cvar_botquota, cvar_spawndelay,
cvar_nemnvgcolor[3], cvar_flashcolor[3], cvar_nvgcolor[3]
/*================================================================================
[Precache and Init]
=================================================================================*/
public plugin_precache()
{
new i, playermodel[100]
// Custom player models
for (i = 0; i < sizeof model_zombie_class1; i++)
{
formatex(playermodel, sizeof playermodel - 1, "models/player/%s/%s.mdl", model_zombie_class1[i], model_zombie_class1[i])
engfunc(EngFunc_PrecacheModel, playermodel)
}
for (i = 0; i < sizeof model_zombie_class2; i++)
{
formatex(playermodel, sizeof playermodel - 1, "models/player/%s/%s.mdl", model_zombie_class2[i], model_zombie_class2[i])
engfunc(EngFunc_PrecacheModel, playermodel)
}
for (i = 0; i < sizeof model_zombie_class3; i++)
{
formatex(playermodel, sizeof playermodel - 1, "models/player/%s/%s.mdl", model_zombie_class3[i], model_zombie_class3[i])
engfunc(EngFunc_PrecacheModel, playermodel)
}
for (i = 0; i < sizeof model_zombie_class4; i++)
{
formatex(playermodel, sizeof playermodel - 1, "models/player/%s/%s.mdl", model_zombie_class4[i], model_zombie_class4[i])
engfunc(EngFunc_PrecacheModel, playermodel)
}
for (i = 0; i < sizeof model_zombie_class5; i++)
{
formatex(playermodel, sizeof playermodel - 1, "models/player/%s/%s.mdl", model_zombie_class5[i], model_zombie_class5[i])
engfunc(EngFunc_PrecacheModel, playermodel)
}
for (i = 0; i < sizeof model_zombie_class6; i++)
{
formatex(playermodel, sizeof playermodel - 1, "models/player/%s/%s.mdl", model_zombie_class6[i], model_zombie_class6[i])
engfunc(EngFunc_PrecacheModel, playermodel)
}
for (i = 0; i < sizeof model_nemesis; i++)
{
formatex(playermodel, sizeof playermodel - 1, "models/player/%s/%s.mdl", model_nemesis[i], model_nemesis[i])
engfunc(EngFunc_PrecacheModel, playermodel)
}
for (i = 0; i < sizeof model_human; i++)
{
formatex(playermodel, sizeof playermodel - 1, "models/player/%s/%s.mdl", model_human[i], model_human[i])
engfunc(EngFunc_PrecacheModel, playermodel)
}
for (i = 0; i < sizeof model_admin; i++)
{
formatex(playermodel, sizeof playermodel - 1, "models/player/%s/%s.mdl", model_admin[i], model_admin[i])
engfunc(EngFunc_PrecacheModel, playermodel)
}
// Custom weapon models
engfunc(EngFunc_PrecacheModel, model_vknife_zombie)
engfunc(EngFunc_PrecacheModel, model_pknife_zombie)
engfunc(EngFunc_PrecacheModel, model_vknife_nemesis)
engfunc(EngFunc_PrecacheModel, model_pknife_nemesis)
engfunc(EngFunc_PrecacheModel, model_grenade_infect)
engfunc(EngFunc_PrecacheModel, model_grenade_fire)
engfunc(EngFunc_PrecacheModel, model_grenade_frost)
engfunc(EngFunc_PrecacheModel, model_grenade_flare)
// Custom sounds
for (i = 0; i < sizeof sound_thunder; i++)
engfunc(EngFunc_PrecacheSound, sound_thunder[i])
for (i = 0; i < sizeof zombie_idle; i++)
engfunc(EngFunc_PrecacheSound, zombie_idle[i])
for (i = 0; i < sizeof zombie_idle_last; i++)
engfunc(EngFunc_PrecacheSound, zombie_idle_last[i])
for (i = 0; i < sizeof zombie_infect; i++)
engfunc(EngFunc_PrecacheSound, zombie_infect[i])
for (i = 0; i < sizeof zombie_die; i++)
engfunc(EngFunc_PrecacheSound, zombie_die[i])
for (i = 0; i < sizeof zombie_pain; i++)
engfunc(EngFunc_PrecacheSound, zombie_pain[i])
for (i = 0; i < sizeof nemesis_pain; i++)
engfunc(EngFunc_PrecacheSound, nemesis_pain[i])
for (i = 0; i < sizeof zombie_fall; i++)
engfunc(EngFunc_PrecacheSound, zombie_fall[i])
for (i = 0; i < sizeof zombie_madness; i++)
engfunc(EngFunc_PrecacheSound, zombie_madness[i])
for (i = 0; i < sizeof sound_nemesis; i++)
engfunc(EngFunc_PrecacheSound, sound_nemesis[i])
for (i = 0; i < sizeof sound_survivor; i++)
engfunc(EngFunc_PrecacheSound, sound_survivor[i])
for (i = 0; i < sizeof sound_swarm; i++)
engfunc(EngFunc_PrecacheSound, sound_swarm[i])
for (i = 0; i < sizeof sound_multi; i++)
engfunc(EngFunc_PrecacheSound, sound_multi[i])
for (i = 0; i < sizeof grenade_infect; i++)
engfunc(EngFunc_PrecacheSound, grenade_infect[i])
for (i = 0; i < sizeof grenade_infect_player; i++)
engfunc(EngFunc_PrecacheSound, grenade_infect_player[i])
for (i = 0; i < sizeof grenade_fire; i++)
engfunc(EngFunc_PrecacheSound, grenade_fire[i])
for (i = 0; i < sizeof grenade_fire_player; i++)
engfunc(EngFunc_PrecacheSound, grenade_fire_player[i])
for (i = 0; i < sizeof grenade_frost; i++)
engfunc(EngFunc_PrecacheSound, grenade_frost[i])
for (i = 0; i < sizeof grenade_frost_player; i++)
engfunc(EngFunc_PrecacheSound, grenade_frost_player[i])
for (i = 0; i < sizeof grenade_frost_break; i++)
engfunc(EngFunc_PrecacheSound, grenade_frost_break[i])
for (i = 0; i < sizeof grenade_flare; i++)
engfunc(EngFunc_PrecacheSound, grenade_flare[i])
for (i = 0; i < sizeof sound_antidote; i++)
engfunc(EngFunc_PrecacheSound, sound_antidote[i])
#if defined AMBIENCE_SOUNDS
for (i = 0; i < sizeof sound_ambience; i++)
engfunc(EngFunc_PrecacheSound, sound_ambience[i])
#endif
// Custom models/sprites for grenades
g_trailSpr = engfunc(EngFunc_PrecacheModel, "sprites/laserbeam.spr")
g_exploSpr = engfunc(EngFunc_PrecacheModel, "sprites/shockwave.spr")
g_flameSpr = engfunc(EngFunc_PrecacheModel, "sprites/flame.spr")
g_glassSpr = engfunc(EngFunc_PrecacheModel, "models/glassgibs.mdl")
#if defined AMBIENCE_FOG
new ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "env_fog"))
fm_set_kvd(ent, "density", FOG_DENSITY, "env_fog")
fm_set_kvd(ent, "rendercolor", FOG_COLOR, "env_fog")
#endif
#if defined AMBIENCE_RAIN
engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "env_rain"))
#endif
#if defined AMBIENCE_SNOW
engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "env_snow"))
#endif
// Fake BombSite (to force round ending)
engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_bomb_target"))
// Prevent some entities from spawning
g_fwSpawn = register_forward(FM_Spawn, "fw_Spawn")
}
public plugin_init()
{
// Register plugin call
register_plugin("Zombie Plague", PLUGIN_VERSION, "MeRcyLeZZ")
// Language files
register_dictionary("zombie_plague.txt")
// Events
register_event("HLTV", "event_round_start", "a", "1=0", "2=0")
register_logevent("event_round_end", 2, "1=Round_End")
register_event("SpecHealth2", "event_spect_target", "bd")
register_event("TextMsg", "event_spect_mode", "b")
// Forwards
RegisterHam(Ham_Spawn, "player", "fw_PlayerSpawn", 1)
RegisterHam(Ham_Killed, "player", "fw_Killed")
RegisterHam(Ham_TakeDamage, "player", "fw_TakeDamage")
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_pushable", "fw_PushBox")
RegisterHam(Ham_Touch,"weaponbox", "fw_WeaponTouch")
RegisterHam(Ham_Touch,"armoury_entity", "fw_WeaponTouch")
RegisterHam(Ham_Touch,"weapon_shield", "fw_WeaponTouch")
register_forward(FM_EmitSound, "fw_EmitSound")
#if !defined HANDLE_MODELS_ON_SEPARATE_ENT
register_forward(FM_SetClientKeyValue, "fw_SetClientKeyValue")
register_forward(FM_ClientUserInfoChanged, "fw_ClientUserInfoChanged")
#endif
register_forward(FM_GetGameDescription, "fw_GameDesc")
register_forward(FM_CmdStart, "fw_CmdStart")
register_forward(FM_CreateNamedEntity, "fw_CreateNamedEntity")
register_forward(FM_SetModel, "fw_SetModel")
register_forward(FM_PlayerPreThink, "fw_PreThink")
register_forward(FM_PlayerPreThink, "fw_PreThink_Post", 1)
unregister_forward(FM_Spawn, g_fwSpawn)
// Client commands
register_clcmd("say","clcmd_say")
register_clcmd("say_team","clcmd_say")
register_clcmd("nightvision","clcmd_nvgtoggle")
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("Buy Menu 1", KEYSMENU, "menu_buy1")
register_menu("Buy Menu 2", KEYSMENU, "menu_buy2")
register_menu("Zombie Menu", KEYSMENU, "menu_zombie")
register_menu("Game Menu", KEYSMENU, "menu_game")
register_menu("Extra Items", KEYSMENU, "menu_extras")
register_menu("Mod Info", KEYSMENU, "menu_info")
register_menu("Admin Menu", KEYSMENU, "menu_admin")
register_menu("Player List Menu", KEYSMENU, "menu_player_list")
// Admin commands
register_concmd("zp_zombie", "cmd_zombie", ACCESS_FLAG, "<name> - Turn someone into a Zombie")
register_concmd("zp_human", "cmd_human", ACCESS_FLAG, "<name> - Turn someone back to Human")
register_concmd("zp_nemesis", "cmd_nemesis", ACCESS_FLAG, "<name> - Turn someone into a Nemesis")
register_concmd("zp_survivor", "cmd_survivor", ACCESS_FLAG, "<name> - Turn someone into a Survivor")
register_concmd("zp_respawn", "cmd_respawn", ACCESS_FLAG, "<name> - Respawn someone")
register_concmd("zp_swarm", "cmd_swarm", ACCESS_FLAG, " - Start Swarm Mode")
register_concmd("zp_multi", "cmd_multi", ACCESS_FLAG, " - Start Multi Infection")
// 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_msgNVGToggle = get_user_msgid("NVGToggle")
g_msgFlashlight = get_user_msgid("Flashlight")
g_msgFlashBat = get_user_msgid("FlashBat")
g_msgAmmoPickup = get_user_msgid("AmmoPickup")
g_msgSendAudio = get_user_msgid("SendAudio")
// Message hooks
register_message(get_user_msgid("CurWeapon"), "message_cur_weapon")
register_message(get_user_msgid("Money"), "message_money")
register_message(get_user_msgid("Health"), "message_health")
register_message(get_user_msgid("HideWeapon"), "message_hideweapon")
register_message(g_msgFlashBat, "message_flashbat")
register_message(g_msgScreenFade, "message_screenfade")
register_message(g_msgScoreAttrib, "message_scoreattrib")
register_message(get_user_msgid("StatusIcon"), "message_statusicon")
#if defined HANDLE_MODELS_ON_SEPARATE_ENT
register_message(get_user_msgid("ClCorpse"), "message_clcorpse")
#endif
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("BombDrop"), "message_bombdrop")
register_message(get_user_msgid("TextMsg"), "message_textmsg")
register_message(g_msgSendAudio, "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_lightning = register_cvar("zp_lightning", "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_deathmatch = register_cvar("zp_deathmatch", "0")
cvar_spawndelay = register_cvar("zp_spawn_delay", "5")
cvar_spawnprotection = register_cvar("zp_spawn_protection", "5")
cvar_randspawn = register_cvar("zp_random_spawn", "1")
cvar_removemoney = register_cvar("zp_remove_money", "1")
cvar_extraitems = register_cvar("zp_extra_items", "1")
cvar_zclasses = register_cvar("zp_zombie_classes", "1")
// CVARS - Flashlight and Nightvision
cvar_cnvg = 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_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_cflash = register_cvar("zp_flash_custom", "0")
cvar_flashsize = register_cvar("zp_flash_size", "10")
cvar_flashdrain = register_cvar("zp_flash_drain", "1")
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")
// 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_infammo = register_cvar("zp_human_unlimited_ammo", "0")
cvar_dropwpn = register_cvar("zp_human_drop_weapons", "2")
cvar_ammodamage = register_cvar("zp_human_damage_reward", "500")
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_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 - 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")
// CVARS - Zombies
cvar_hp = register_cvar("zp_zombie_health","1800")
cvar_firsthp = register_cvar("zp_zombie_fhealth","3600")
cvar_armor = register_cvar("zp_zombie_armor","0.75")
cvar_speed = register_cvar("zp_zombie_speed","190")
cvar_gravity = register_cvar("zp_zombie_gravity","1.0")
cvar_bonushp = register_cvar("zp_zombie_infect_health","100")
cvar_fov_angle = register_cvar("zp_zombie_fov","110")
cvar_firstleap = register_cvar("zp_zombie_first_leap", "0")
cvar_painfree = register_cvar("zp_zombie_painfree","2")
cvar_bleeding = register_cvar("zp_zombie_bleeding","1")
cvar_ammoinfect = register_cvar("zp_zombie_infect_reward","1")
// CVARS - Nemesis
cvar_nem = register_cvar("zp_nem_enabled","1")
cvar_nemchance = register_cvar("zp_nem_chance","20")
cvar_nemhp = register_cvar("zp_nem_health","0")
cvar_nemspd = register_cvar("zp_nem_speed","250")
cvar_nemgravity = register_cvar("zp_nem_gravity","0.5")
cvar_nemglow = register_cvar("zp_nem_glow","1")
cvar_nemleap = register_cvar("zp_nem_leap","1")
cvar_nempainfree = register_cvar("zp_nem_painfree", "0")
cvar_nemignorefrags = register_cvar("zp_nem_ignore_frags", "0")
// CVARS - Survivor
cvar_surv = register_cvar("zp_surv_enabled","1")
cvar_survchance = register_cvar("zp_surv_chance","20")
cvar_survhp = register_cvar("zp_surv_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_survleap = register_cvar("zp_surv_leap","0")
cvar_survpainfree = register_cvar("zp_surv_painfree", "1")
cvar_survignorefrags = register_cvar("zp_surv_ignore_frags", "0")
// CVARS - Swarm Mode
cvar_swarm = register_cvar("zp_swarm_enabled", "1")
cvar_swarmchance = register_cvar("zp_swarm_chance","20")
// CVARS - Multi Infection
cvar_multi = register_cvar("zp_multi_enabled", "1")
cvar_multichance = register_cvar("zp_multi_chance","20")
cvar_multiratio = register_cvar("zp_multi_ratio", "0.15")
// 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)
// Check for CSDM spawns of the current map
new mapname[32], cfgdir[32], filepath[100], linedata[64]
get_configsdir(cfgdir, sizeof cfgdir - 1);
get_mapname(mapname, sizeof mapname - 1);
formatex(filepath, sizeof filepath - 1, "%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, sizeof linedata - 1);
// 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
{
// if not, collect regular spawns
collect_spawns("info_player_start")
collect_spawns("info_player_deathmatch")
}
// Execute config file (zombieplague.cfg)
server_cmd("exec %s/zombieplague.cfg", cfgdir)
// Set a random skybox
set_cvar_string("sv_skyname", skynames[random_num(0, sizeof skynames - 1)])
// Disable sky lightning so it doesn't mess up our custom lightning
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()
// Call Round Start
set_task(1.0, "event_round_start");
// Lightning task
set_task(2.0, "lightning_effects")
#if defined AMBIENCE_SOUNDS
set_task(3.0, "ambience_sound_effects")
#endif
// Format mod name
formatex(g_modname, sizeof g_modname - 1, "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, sizeof mymod - 1);
if (equal(mymod, "czero")) g_czero = 1;
}
/*================================================================================
[Main Events]
=================================================================================*/
// Round Start Event
public event_round_start()
{
// Remove all tasks bound to custom nades (as they're removed on new round)
remove_task(NADES_TASK);
// Remove doors and/or lights
set_task(0.2, "remove_stuff")
// New round starting
g_newround = true
g_endround = false
g_survround = false
g_nemround = false
g_swarmround = false
g_teams_i = 0.0 // reset team change count
g_models_i = 0.0 // reset model change count
// Show welcome message and T-Virus notice
remove_task(WELCOMEMSG_TASK)
set_task(2.0, "welcome_msg", WELCOMEMSG_TASK)
// Set a new "Make Zombie Task"
remove_task(MAKEZOMBIE_TASK)
set_task(2.0+random_float(get_pcvar_float(cvar_warmup), get_pcvar_float(cvar_warmup)+3.0), "make_zombie_task", MAKEZOMBIE_TASK)
}
// Round End Event
public event_round_end()
{
// Save player's stats on round end
static id
for (id = 1; id <= g_maxplayers; id++)
{
if (!is_user_connected(id))
continue; // skip if not connected
if (fm_get_user_team(id) == CS_TEAM_SPECTATOR || fm_get_user_team(id) == CS_TEAM_UNASSIGNED)
continue; // skip if not playing
save_stats(id)
}
// Round ended
g_endround = true
g_teams_i = 0.0 // reset teams change count
g_models_i = 0.0 // reset model change count
// Stop old tasks (if any)
remove_task(WELCOMEMSG_TASK)
remove_task(MAKEZOMBIE_TASK)
// Balance the teams
set_task(0.1, "balance_teams")
// Show HUD notice, play win sound, update team scores...
if (!fnGetZombies())
{
// Human team wins
set_hudmessage(0, 0, 200, -1.0, 0.25, 0, 0.0, 3.0, 2.0, 1.0, -1)
ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "WIN_HUMAN")
PlaySound(sound_win_humans[random_num(0, sizeof sound_win_humans -1)])
g_scorehumans++
}
else if (!fnGetHumans())
{
// Zombie team wins
set_hudmessage(200, 0, 0, -1.0, 0.25, 0, 0.0, 3.0, 2.0, 1.0, -1)
ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "WIN_ZOMBIE")
PlaySound(sound_win_zombies[random_num(0, sizeof sound_win_zombies -1)])
g_scorezombies++
}
else
{
// No one wins
set_hudmessage(0, 200, 0, -1.0, 0.25, 0, 0.0, 3.0, 2.0, 1.0, -1)
ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "WIN_NO_ONE")
PlaySound(sound_win_no_one[random_num(0, sizeof sound_win_no_one -1)])
// Screen fade effect
message_begin(MSG_BROADCAST, g_msgScreenFade)
write_short(12288) // Duration
write_short(12288) // Hold time
write_short(0x0001) // Fade type
write_byte (0) // Red
write_byte (0) // Green
write_byte (0) // Blue
write_byte (255) // Alpha
message_end()
}
}
// Event Spectator Mode
public event_spect_mode(id)
{
if (get_pcvar_num(cvar_cnvg)) // custom night vision isn't affected by this
return;
static specmode[12] // get text message string
read_data(2, specmode, sizeof specmode - 1)
if (!equal(specmode, "#Spec_Mode", 10)) // not a spectator mode event
return;
if (g_spec_first_person[id]) // if last mode was first person
{
if (g_nvisionenabled[id]) // and nvg was on
set_user_gnvision(id, 1); // we need to restore it
g_spec_first_person[id] = false;
}
if (specmode[10] == '4') // First Person Mode
g_spec_first_person[id] = true
}
// Event Spectator Target
public event_spect_target(id)
{
if (get_pcvar_num(cvar_cnvg) || !id) // custom night vision isn't affected by this
return;
// If previous target died and nvg was on
if (g_nvisionenabled[id] && !is_user_alive(g_spec_target[id]))
set_user_gnvision(id, 1); // we need to restore it
g_spec_target[id] = read_data(2); // update last spectator target
}
/*================================================================================
[Main Forwards]
=================================================================================*/
// Client disconnect
public client_disconnect(id)
{
// Check that we still have both humans and zombies to keep the round going
if (is_user_alive(id)) check_round(id);
// Save player stats
save_stats(id)
// Remove previous tasks
remove_task(id+TEAM_TASK)
remove_task(id+MODEL_TASK)
remove_task(id+CHARGE_TASK)
remove_task(id+SPAWN_TASK)
remove_task(id+BLOOD_TASK)
remove_task(id+NVISION_TASK)
remove_task(id+SHOWHUD_TASK)
// Last Zombie Check
set_task(0.1, "fnCheckLastZombie")
}
// Client joins the game
public client_putinserver(id)
{
// Initialize player vars
reset_vars(id, 1)
// Try load player stats
load_stats(id)
// Set the custom HUD display task
set_task(3.0, "ShowHUD", id+SHOWHUD_TASK)
// CZ bots seem to use a different "classtype" for player entities
// (or something like that) which needs to be hooked separately
if (cvar_botquota && !g_hamczbots) set_task(0.1, "register_ham_czbots", id)
}
// Entity Spawn Forward
public fw_Spawn(entity)
{
// Get classname
static classname[32]
pev(entity, pev_classname, classname, sizeof classname - 1)
// Check whether it needs to be removed
static i
for (i = 0; i < sizeof g_objective_ents; i++)
{
if (equal(classname, g_objective_ents[i]))
{
engfunc(EngFunc_RemoveEntity, entity)
return FMRES_SUPERCEDE
}
}
return FMRES_IGNORED
}
// Ham Player Spawn Forward
public fw_PlayerSpawn(id)
{
if (!is_user_alive(id)) // not alive
return;
// Remove previous tasks
remove_task(id+SPAWN_TASK)
remove_task(id+TEAM_TASK)
remove_task(id+MODEL_TASK)
remove_task(id+BLOOD_TASK)
remove_task(id+CHARGE_TASK)
// Spawn randomly?
if (get_pcvar_num(cvar_randspawn)) do_random_spawn(id)
// Respawn as zombie?
if (g_respawn_as_zombie[id] && !g_newround)
{
reset_vars(id, 0) // reset player vars
zombieme(id, 0, 0) // make him zombie right away
return;
}
// Reset player vars
reset_vars(id, 0)
// Turn off NVG for bots
if (is_user_bot(id)) fm_set_bot_nvg(id, 0);
fm_set_user_health(id, get_pcvar_num(cvar_humanhp)) // set health
set_pev(id, pev_gravity, get_pcvar_float(cvar_humangravity)) // set gravity
#if defined HANDLE_MODELS_ON_SEPARATE_ENT
// Set the right model
if (get_user_flags(id) & ACCESS_FLAG)
copy(g_playermodel[id], 32, model_admin[random_num(0, sizeof model_admin -1)])
else
copy(g_playermodel[id], 32, model_human[random_num(0, sizeof model_human -1)])
fm_set_user_model_ent(id) // set model on player_model entity
fm_set_rendering(fm_find_ent_by_owner(-1, "player_model", id)); // remove glow on player_model entity
fm_set_rendering(id, kRenderFxNone, 255, 255, 255, kRenderTransTexture, 0) // make original player entity invisible
#else
// Set the right model, but check that we don't have it already
static currentmodel[33], already_has_model, i
already_has_model = false;
fm_get_user_model(id, currentmodel, sizeof currentmodel - 1); // get current model
if (get_user_flags(id) & ACCESS_FLAG)
{
for (i = 0; i < sizeof model_admin; i++)
if (equal(model_admin[i], currentmodel)) already_has_model = true;
if (!already_has_model) copy(g_playermodel[id], 32, model_admin[random_num(0, sizeof model_admin -1)])
}
else
{
for (i = 0; i < sizeof model_human; i++)
if (equal(model_human[i], currentmodel)) already_has_model = true;
if (!already_has_model) copy(g_playermodel[id], 32, model_human[random_num(0, sizeof model_human -1)])
}
if (!already_has_model) // need to change the model?
{
if (g_newround) // round start?
{
set_task(0.1+(MODELCHANGE_DELAY*2)+g_models_i, "fm_set_user_model", id+MODEL_TASK) // set model with a delay
g_models_i += MODELCHANGE_DELAY;
}
else
{
fm_set_user_model(id+MODEL_TASK) // set model instantly
}
}
fm_set_rendering(id); // remove glow
#endif
set_task(0.5, "show_menu_buy1", id+SPAWN_TASK); // show buy menu
set_task(10.5, "show_menu_buy1", id+SPAWN_TASK); // re-show in case it gets overlapped
// Respawn player in case he dies by worldspawn or something
set_task(5.0, "respawn_player", id+SPAWN_TASK)
// Enable spawn protection for humans spawning mid-round
if (!g_newround && get_pcvar_num(cvar_spawnprotection))
{
g_nodamage[id] = true; // dont take any damage
set_pev(id, pev_effects, pev(id, pev_effects) | EF_NODRAW) // make temporarily invisible
set_task(get_pcvar_float(cvar_spawnprotection), "remove_spawn_protection", id+SPAWN_TASK)
}
// Last Zombie Check
set_task(0.1, "fnCheckLastZombie")
}
// Ham Player Killed Forward
public fw_Killed(victim, attacker, shouldgib)
{
set_task(0.2, "spec_nvision", victim) // enable dead players nightvision
set_task(0.1, "fnCheckLastZombie") // Last Zombie Check
if (g_zombie[victim]) // stop bleeding/burning when killed
remove_task(victim+BLOOD_TASK)
if (g_nemesis[victim]) // nemesis explodes!
SetHamParamInteger(3, 2)
// Killed by a non-player entity or self killed
if (victim == attacker || !is_user_connected(attacker))
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)
if (g_zombie[attacker] && !g_nemesis[attacker]) // zombie killed human, reward ammo packs
g_ammopacks[attacker] += get_pcvar_num(cvar_ammoinfect)
// Respawn if Deathmatch is enabled
if (get_pcvar_num(cvar_deathmatch))
{
set_task(get_pcvar_float(cvar_spawndelay), "respawn_player", victim+SPAWN_TASK)
if ((get_pcvar_num(cvar_deathmatch) == 2) || (get_pcvar_num(cvar_deathmatch) == 3 && random_num(0, 1)))
g_respawn_as_zombie[victim] = true // respawn as zombie
}
}
// Ham Take Damage Forward (inflictor = weapon)
public fw_TakeDamage(victim, inflictor, attacker, Float:damage, damage_type)
{
if (victim == attacker || !is_user_connected(attacker)) // non-player damage or self damage
return HAM_IGNORED
if (g_newround || g_endround) // new round starting or round ended, cant attack
return HAM_SUPERCEDE
if (g_nodamage[victim] || g_frozen[victim]) // victim shouldn't take damage or victim is frozen
return HAM_SUPERCEDE
if (g_zombie[attacker] == g_zombie[victim]) // prevent team killing
return HAM_SUPERCEDE
if (!g_zombie[attacker] && g_zombie[victim]) // human attacks zombie
{
if (!g_nemesis[victim]) // armor multiplier for the final damage on normal zombies
{
damage *= get_pcvar_float(cvar_armor)
SetHamParamFloat(4, damage)
}
// Reward ammo packs (survivor doesn't get any)
if (!g_survivor[attacker])
{
// 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);
// Bots automatically buy extra items
if (is_user_bot(attacker)) set_task(0.1, "bot_buy_extras", attacker)
}
}
return HAM_IGNORED
}
if (g_nemesis[attacker] && !g_zombie[victim]) // nemesis one-hit kill
{
SetHamParamFloat(4, 255.0) // set a higher damage
return HAM_IGNORED
}
if (g_zombie[attacker] && !g_zombie[victim]) // zombie attacks human
{
if (damage_type & DMG_HEGRENADE) // prevent infection by HE grenade (bugfix)
return HAM_SUPERCEDE
if (g_swarmround || fnGetHumans() == 1) // last human or swarm round
{
return HAM_IGNORED // human is killed
}
else
{
SendDeathMsg(attacker, victim); // send death notice
FixDeadAttrib(victim) // fix the "dead" attrib on scoreboard
UpdateFrags(attacker, victim); // add corresponding frags and deaths
// Infect the victim
zombieme(victim, 0, 0)
// Ammo packs given to zombie for infection
g_ammopacks[attacker] += get_pcvar_num(cvar_ammoinfect)
// Attacker gets HP bonus for the infection
if (g_zombieclass[attacker] != 4) // 3x bonus for leech zombie
fm_set_user_health(attacker, pev(attacker, pev_health)+get_pcvar_num(cvar_bonushp))
else
fm_set_user_health(attacker, pev(attacker, pev_health)+(get_pcvar_num(cvar_bonushp)*3))
return HAM_SUPERCEDE
}
}
return HAM_IGNORED
}
// Ham Trace Attack Forward
public fw_TraceAttack(victim, attacker, Float:damage, Float:direction[3], tracehandle, damagetype)
{
if (!get_pcvar_num(cvar_knockback)) // knockback disabled
return;
if (!(damagetype & DMG_BULLET)) // not bullet damage
return;
if (victim == attacker || !is_user_connected(attacker)) // non-player damage or self damage
return;
if (g_zombie[attacker] || !g_zombie[victim] || g_nemesis[victim]) // only for humans attacking a zombie
return;
if (!get_pcvar_num(cvar_knockbackducking) && (pev(victim, pev_flags) & FL_DUCKING)) // zombie is ducking
return;
// Get victim's velocity
static Float:velocity1[3], Float:velocity2[3]
pev(victim, pev_velocity, velocity1)
xs_vec_copy(velocity1, velocity2)
// 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)
// Add up the new vector
xs_vec_add(direction, velocity1, velocity1)
// Should knockback affect vertical velocity?
if (!get_pcvar_num(cvar_knockbackzvel))
velocity1[2] = velocity2[2]
// Set the knockback'd victim's velocity
set_pev(victim, pev_velocity, velocity1)
}
// Ham Use Stationary Gun Forward
public fw_UseStationary(entity, caller, activator, use_type)
{
if (!is_user_connected(caller)) // not a player
return HAM_IGNORED;
if (use_type == 2 && g_zombie[caller]) // prevent zombies from using stationary guns
return HAM_SUPERCEDE
if (use_type == 0) // someone stopped using stationary gun
set_task(0.1, "replace_models", caller); // replace weapon models (bugfix)
return HAM_IGNORED
}
// Ham Use Pushable
public fw_PushBox()
{
// prevent speed bug with boxes, etc.
return HAM_SUPERCEDE
}
// Ham Weapon Touch Forward
public fw_WeaponTouch(weapon, id)
{
if (!is_user_connected(id)) // not a player
return HAM_IGNORED
if (g_zombie[id] || g_survivor[id]) // dont pickup weapons if zombie or survivor
return HAM_SUPERCEDE
return HAM_IGNORED
}
// Emit Sound Forward
public fw_EmitSound(id, channel, const sample[], Float:volume, Float:attn, flags, pitch)
{
if (!is_user_connected(id) || !g_zombie[id]) // replace these sounds for zombies only
return FMRES_IGNORED
if ((sample[7] == 'd' && sample[8] == 'i' && sample[9] == 'e') || (sample[7] == 'd' && sample[8] == 'e' && sample[9] == 'a') || (sample[10] == 'd' && sample[11] == 'i' && sample[12] == 'e')) // die
{
engfunc(EngFunc_EmitSound, id, channel, zombie_die[random_num(0, sizeof zombie_die - 1)], volume, attn, flags, pitch)
return FMRES_SUPERCEDE
}
if (sample[7] == 'b' && sample[8] == 'h' && sample[9] == 'i' && sample[10] == 't') // being hit
{
if (g_nemesis[id])
engfunc(EngFunc_EmitSound, id, channel, nemesis_pain[random_num(0, sizeof nemesis_pain - 1)], volume, attn, flags, pitch)
else
engfunc(EngFunc_EmitSound, id, channel, zombie_pain[random_num(0, sizeof zombie_pain - 1)], volume, attn, flags, pitch)
return FMRES_SUPERCEDE
}
if (sample[10] == 'f' && sample[11] == 'a' && sample[12] == 'l' && sample[13] == 'l') // fall off
{
engfunc(EngFunc_EmitSound, id, channel, zombie_fall[random_num(0, sizeof zombie_fall - 1)], volume, attn, flags, pitch)
return FMRES_SUPERCEDE
}
return FMRES_IGNORED
}
#if !defined HANDLE_MODELS_ON_SEPARATE_ENT
// Forward Set ClientKey Value -prevent CS from changing player models-
public fw_SetClientKeyValue(id, infobuffer, const key[])
{
if (equal(key, "model")) // block CS model change
return FMRES_SUPERCEDE;
return FMRES_IGNORED;
}
// Forward Client User Info Changed -prevent players from changing models-
public fw_ClientUserInfoChanged(id)
{
static currentmodel[33] // get current model
fm_get_user_model(id, currentmodel, sizeof currentmodel - 1);
// If they're different, set model again
if (!equal(currentmodel, g_playermodel[id]) && !task_exists(id+MODEL_TASK))
fm_set_user_model(id+MODEL_TASK)
}
#endif
// Forward Game Description
public fw_GameDesc()
{
// Return the new mod name
forward_return(FMV_STRING, g_modname)
return FMRES_SUPERCEDE
}
// Forward CmdStart
public fw_CmdStart(id, handle)
{
if (!is_user_alive(id)) // not alive
return FMRES_IGNORED
// Get impulse id
static impulseid
impulseid = get_uc(handle, UC_Impulse)
if (impulseid == 100) // impulse 100 = flashlight
{
// Block it for zombies, survivor (and override it for humans when custom flashlight is on)
if (g_zombie[id] || g_survivor[id] || (!g_zombie[id] && get_pcvar_num(cvar_cflash)))
{
if (!g_zombie[id] && !g_survivor[id]) // human's custom flashlight should be turned on instead
{
// Turn custom flashlight on/off
g_flashlight[id] ? (g_flashlight[id] = 0) : (g_flashlight[id] = 1)
// Set the flashlight charge task if not running yet
if (!task_exists(id+CHARGE_TASK)) set_task(1.0, "flashlight_charge", id+CHARGE_TASK)
// 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();
// Turn off original flashlight if active
set_pev(id, pev_effects, pev(id, pev_effects) & ~EF_DIMLIGHT);
// Play flashlight toggle sound
engfunc(EngFunc_EmitSound, id, CHAN_ITEM, "items/flashlight1.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)
// Finally call our custom flashlight task
set_user_flashlight(id)
}
set_uc(handle, UC_Impulse, 0) // block the impulse
return FMRES_SUPERCEDE
}
}
return FMRES_IGNORED
}
// Forward Create Named Entity
public fw_CreateNamedEntity(classid)
{
static classname[10]
engfunc(EngFunc_SzFromIndex, classid, classname, sizeof classname - 1)
// Prevent c4 from spawning
if (classname[7] == 'c' && classname[8] == '4')
return FMRES_SUPERCEDE
return FMRES_IGNORED
}
// Forward Set Model
public fw_SetModel(entity, const model[])
{
// Get grenade's gravity
static Float:gravity
pev(entity, pev_gravity, gravity)
// Grenade not yet thrown
if (gravity == 0.0)
return;
if (equal(model[7], "w_hegrenade.mdl"))
{
static id // get grenade owner
id = pev(entity, pev_owner)
if (g_zombie[id]) // [ZOMBIE] - Infection Grenade
{
// 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);
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();
// Prevent hegrenade from exploding
set_pev(entity, pev_nextthink, get_gametime()+10.0);
static args[1] // our task params
args[0] = entity; // entity id
// Actual explode event
set_task(1.5, "infection_explode", NADES_TASK, args, sizeof args)
}
else if (get_pcvar_num(cvar_firegrenades)) // [HUMAN] - Fire 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);
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();
// Prevent hegrenade from exploding
set_pev(entity, pev_nextthink, get_gametime()+10.0);
static args[1] // our task params
args[0] = entity; // entity id
// Actual explode event
set_task(1.5, "fire_explode", NADES_TASK, args, sizeof args)
}
}
else if (equal(model[7], "w_flashbang.mdl") && 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);
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();
// Prevent flashbang from exploding
set_pev(entity, pev_nextthink, get_gametime()+10.0);
static args[1] // our task params
args[0] = entity; // entity id
// Actual explode event
set_task(1.5, "frost_explode", NADES_TASK, args, sizeof args)
}
else if (equal(model[7], "w_smokegrenade.mdl") && get_pcvar_num(cvar_flaregrenades)) // Flare
{
static args[5] // our task params
args[0] = entity; // entity id
args[1] = get_pcvar_num(cvar_flareduration)/5; // duration
switch (get_pcvar_num(cvar_flarecolor))
{
case 0: // white
{
args[2] = 255 // r
args[3] = 255 // g
args[4] = 255 // b
}
case 1: // red
{
args[2] = random_num(50,255) // r
args[3] = 0 // g
args[4] = 0 // b
}
case 2: // green
{
args[2] = 0 // r
args[3] = random_num(50,255) // g
args[4] = 0 // b
}
case 3: // blue
{
args[2] = 0 // r
args[3] = 0 // g
args[4] = random_num(50,255) // b
}
case 4: // random
{
args[2] = random_num(50,200) // r
args[3] = random_num(50,200) // g
args[4] = random_num(50,200) // b
}
}
// Give it a glow
fm_set_rendering(entity, kRenderFxGlowShell, args[2], args[3], args[4], kRenderNormal, 16);
// And a colored trail
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BEAMFOLLOW);
write_short(entity); // entity
write_short(g_trailSpr);// sprite
write_byte(10); // life
write_byte(10); // width
write_byte(args[2]); // r
write_byte(args[3]); // g
write_byte(args[4]); // b
write_byte(200); // brightness
message_end();
// Prevent smokegrenade from exploding
set_pev(entity, pev_nextthink, get_gametime()+10.0);
// Actual explode event
set_task(1.5, "flare_explode", NADES_TASK, args, sizeof args)
}
}
// Forward Client PreThink
public fw_PreThink(id)
{
if (!is_user_alive(id)) // not alive
return;
// Silent footsteps
if (g_zombie[id] && !g_nemesis[id] && g_zombieclass[id] != 5)
set_pev(id, pev_flTimeStepSound, 999)
// 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
}
else
{
if (g_zombie[id])
{
if (g_nemesis[id])
set_pev(id, pev_maxspeed, get_pcvar_float(cvar_nemspd))
else
set_pev(id, pev_maxspeed, get_pcvar_float(cvar_speed)*zombie_multispd[g_zombieclass[id]]/100)
}
else
{
if (g_survivor[id])
set_pev(id, pev_maxspeed, get_pcvar_float(cvar_survspd))
else
set_pev(id, pev_maxspeed, get_pcvar_float(cvar_humanspd))
}
}
// Pain Shock Free for zombies/nemesis/survivor (if enabled)
if (g_zombie[id] || g_survivor[id])
{
if (pev(id, pev_flags) & FL_ONGROUND)
{
if (g_nemesis[id] && !get_pcvar_num(cvar_nempainfree)) // Nemesis cvar not enabled
return;
if (g_survivor[id] && !get_pcvar_num(cvar_survpainfree)) // Survivor cvar not enabled
return;
if (get_pcvar_num(cvar_painfree) == 0 && g_zombie[id] && !g_nemesis[id]) // Zombie cvar not enabled
return;
if (get_pcvar_num(cvar_painfree) == 2 && g_zombie[id] && !g_nemesis[id] && !g_lastzombie[id]) // not the last zombie
return;
pev(id, pev_velocity, g_velocity[id])
g_restorevel[id] = true
}
}
}
// Forward Client PreThink Post
public fw_PreThink_Post(id) {
if (!is_user_alive(id)) // not alive
return FMRES_IGNORED
if (g_restorevel[id]) // Pain Shock Free: restore velocity if needed
{
g_restorevel[id] = false
if (!(FL_ONTRAIN & pev(id, pev_flags)))
{
// NOTE: within DLL PlayerPreThink Jump() function is called;
// there is a conveyor velocity addiction we should care of
static ent
ent = pev(id, pev_groundentity);
if (pev_valid(ent) && (FL_CONVEYOR & pev(ent, pev_flags)))
{
static Float:tempvel[3]
pev(id, pev_basevelocity, tempvel)
xs_vec_add(g_velocity[id], tempvel, g_velocity[id])
}
set_pev(id, pev_velocity, g_velocity[id])
return FMRES_HANDLED
}
}
return FMRES_IGNORED
}
/*================================================================================
[Client Commands]
=================================================================================*/
// Say
public clcmd_say(id)
{
static text[8]
read_args(text, sizeof text - 1)
if (equali(text[1], "zpmenu", 6) || equali(text[2], "zpmenu", 6))
show_menu_game(id); // show game menu
}
// Nightvision toggle
public clcmd_nvgtoggle(id)
{
/*
// PODBots didn't trigger this event after all, guess this isn't necessary...
if (is_user_bot(id)) return PLUGIN_CONTINUE;
*/
if (g_nvision[id])
{
// Enable-disable
g_nvisionenabled[id] ? (g_nvisionenabled[id] = 0) : (g_nvisionenabled[id] = 1);
if (get_pcvar_num(cvar_cnvg)) // custom nvg?
{
remove_task(id+NVISION_TASK);
set_user_nvision(id+NVISION_TASK)
}
else set_user_gnvision(id, g_nvisionenabled[id])
}
return PLUGIN_HANDLED
}
// Drop a Weapon
public clcmd_drop(id)
{
if (g_survivor[id]) // survivor should stick with m249
return PLUGIN_HANDLED
return PLUGIN_CONTINUE
}
// Buy BP Ammo
public clcmd_buyammo(id)
{
if (get_pcvar_num(cvar_infammo) || !is_user_alive(id)) // dont bother
return PLUGIN_HANDLED
if (!g_zombie[id]) // only humans buy ammo
{
if (g_ammopacks[id] > 0) // enough ammo packs?
{
g_ammopacks[id]--
engfunc(EngFunc_EmitSound, id, CHAN_ITEM, "items/9mmclip1.wav", 1.0, ATTN_NORM, 0, PITCH_NORM) // ammo sound
client_print(id, print_chat, "[ZP] %L", id, "AMMO_BOUGHT") // tell the player
static weapons[32], num, i
num = 0 // reset passed weapons count (bugfix)
get_user_weapons(id, weapons, num)
for (i = 0; i < num; i++)
{
if ((1<<weapons[i]) & PRIMARY_WEAPONS_BIT_SUM)
{
static currentammo
currentammo = fm_get_user_bpammo(id, weapons[i]) // get current ammo
if (currentammo <= MAXAMMO[weapons[i]]-BUYAMMO[weapons[i]])
{
message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoPickup, _, id); // flash ammo in hud
write_byte(3); // ammo id
write_byte(BUYAMMO[weapons[i]]) // ammo amount
message_end();
fm_set_user_bpammo(id, weapons[i], currentammo + BUYAMMO[weapons[i]]); // increase BP ammo
}
else
{
message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoPickup, _, id); // flash ammo in hud
write_byte(3); // ammo id
write_byte(MAXAMMO[weapons[i]]-currentammo) // ammo amount
message_end();
fm_set_user_bpammo(id, weapons[i], MAXAMMO[weapons[i]]); // reached the limit
}
}
else if ((1<<weapons[i]) & SECONDARY_WEAPONS_BIT_SUM)
{
static currentammo
currentammo = fm_get_user_bpammo(id, weapons[i]) // get current ammo
if (currentammo <= MAXAMMO[weapons[i]]-BUYAMMO[weapons[i]])
{
message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoPickup, _, id); // flash ammo in hud
write_byte(10); // ammo id
write_byte(BUYAMMO[weapons[i]]) // ammo amount
message_end();
fm_set_user_bpammo(id, weapons[i], currentammo + BUYAMMO[weapons[i]]); // increase BP ammo
}
else
{
message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoPickup, _, id); // flash ammo in hud
write_byte(10); // ammo id
write_byte(MAXAMMO[weapons[i]]-currentammo) // ammo amount
message_end();
fm_set_user_bpammo(id, weapons[i], MAXAMMO[weapons[i]]); // reached the limit
}
}
}
}
else
{
client_print(id, print_chat, "[ZP] %L", id, "NOT_ENOUGH_AMMO")
}
}
else
{
client_print(id, print_chat, "[ZP] %L", id, "CMD_HUMAN_ONLY")
}
return PLUGIN_HANDLED
}
// Block Team Change
public clcmd_changeteam(id)
{
// Spectator joins the game
if (fm_get_user_team(id) == CS_TEAM_SPECTATOR || fm_get_user_team(id) == CS_TEAM_UNASSIGNED)
return PLUGIN_CONTINUE
show_menu_game(id); // pressing 'M' (chooseteam) ingame should show the main menu
return PLUGIN_HANDLED
}
/*================================================================================
[Menus]
=================================================================================*/
// Game Menu
public show_menu_game(id)
{
static menu[150]
formatex(menu, sizeof menu - 1, "\yZombie Plague\w^n^n1. %L^n2. %L^n3. %L^n4. %L^n^n5. %L^n^n0. %L", id, "MENU_EXTRABUY", id,"MENU_ZCLASS", id, "MENU_UNSTUCK", id, "MENU_INFO", id, "MENU_ADMIN", id, "MENU_EXIT")
show_menu(id, KEYSMENU, menu, -1, "Game Menu")
}
// Buy Menu 1
public show_menu_buy1(taskid)
{
// Zombies or survivors get no guns
if (g_zombie[ID_SPAWN] || g_survivor[ID_SPAWN] || !g_canbuy[ID_SPAWN] || !is_user_alive(ID_SPAWN))
return;
// Bots pick their weapons randomly
if (is_user_bot(ID_SPAWN))
{
menu_buy1(ID_SPAWN, random_num(0, sizeof g_primary_names - 1))
return;
}
static menu[300], len, i
len = 0
len += formatex(menu[len], sizeof menu - 1 - len, "\y%L^n", ID_SPAWN, "MENU_BUY1_TITLE")
for (i = 0; i < sizeof g_primary_names; i++) len += formatex(menu[len], sizeof menu - 1 - len, "\w^n%d. %s \y%s", i+1, g_primary_names[i], g_primary_classes[i])
len += formatex(menu[len], sizeof menu - 1 - len, "\w^n^n0. %L", ID_SPAWN, "MENU_EXIT")
show_menu(ID_SPAWN, KEYSMENU, menu, 10, "Buy Menu 1")
}
// Buy Menu 2
show_menu_buy2(id)
{
// Bots pick their weapons randomly
if (is_user_bot(id))
{
menu_buy2(id, random_num(0, sizeof g_secondary_names - 1))
return;
}
static menu[300], len, i
len = 0
len += formatex(menu[len], sizeof menu - 1 - len, "\y%L^n", id, "MENU_BUY2_TITLE")
for (i = 0; i < sizeof g_secondary_names; i++) len += formatex(menu[len], sizeof menu - 1 - len, "\w^n%d. %s \y%s", i+1, g_secondary_names[i], g_secondary_classes[i])
len += formatex(menu[len], sizeof menu - 1 - len, "\w^n^n0. %L", id, "MENU_EXIT")
show_menu(id, KEYSMENU, menu, 10, "Buy Menu 2")
}
// Zombie Class Menu
public show_menu_zombie(id)
{
if (!is_user_connected(id)) // player not connected
return;
// Bots pick their zombie class randomly
if (is_user_bot(id))
{
menu_zombie(id, random_num(0, sizeof zombie_multihp - 1))
return;
}
static menu[250], len
len = 0
len += formatex(menu[len], sizeof menu - 1 - len, "\y%L\w^n^n1. %L \y%L\w^n2. %L \y%L\w^n3. %L \y%L\w^n4. %L \y%L\w^n5. %L \y%L", id, "MENU_ZCLASS_TITLE", id, "CLASS_ZOMBIE1", id, "MENU_ZCLASS1", id, "CLASS_ZOMBIE2", id, "MENU_ZCLASS2", id, "CLASS_ZOMBIE3", id, "MENU_ZCLASS3", id, "CLASS_ZOMBIE4", id, "MENU_ZCLASS4", id, "CLASS_ZOMBIE5", id, "MENU_ZCLASS5")
len += formatex(menu[len], sizeof menu - 1 - len, "\w^n6. %L \y %L \w^n^n0. %L", id, "CLASS_ZOMBIE6", id, "MENU_ZCLASS6", id, "MENU_EXIT")
show_menu(id, KEYSMENU, menu, -1, "Zombie Menu")
}
// Extra Items Menu
show_menu_extras(id)
{
static menu[450], len, i
len = 0
len += formatex(menu[len], sizeof menu - 1 - len, "\y%L\r^n^n%L:", id, "MENU_EXTRA_TITLE", id, "CLASS_HUMAN")
for (i = 0; i < sizeof g_extra_names; i++) len += formatex(menu[len], sizeof menu - 1 - len, "\w^n%d. %s \y%d %L", i+1, g_extra_names[i], g_extra_costs[i], id, "AMMO_PACKS2")
len += formatex(menu[len], sizeof menu - 1 - len, "\w^n%d. %L \y%d %L\r^n^n%L:\w^n%d. %L \y%d %L\w^n%d. %L \y%d %L\w^n%d. %L \y%d %L\w^n^n0. %L", i+1, id, "MENU_EXTRA1", g_extra_costs2[EXTRA_NVISION], id, "AMMO_PACKS2", id, "CLASS_ZOMBIE", i+2, id, "MENU_EXTRA2", g_extra_costs2[EXTRA_ANTIDOTE], id, "AMMO_PACKS2", i+3, id, "MENU_EXTRA3", g_extra_costs2[EXTRA_MADNESS], id, "AMMO_PACKS2", i+4, id, "MENU_EXTRA4", g_extra_costs2[EXTRA_INFBOMB], id, "AMMO_PACKS2", id, "MENU_EXIT")
show_menu(id, KEYSMENU, menu, -1, "Extra Items")
}
// Help Menu
public show_menu_info(id)
{
if (!is_user_connected(id)) // player not connected
return;
static menu[100]
formatex(menu, sizeof menu - 1, "\y%L\w^n^n1. %L^n2. %L^n3. %L^n4. %L^n^n0. %L", id, "MENU_INFO_TITLE", id, "MENU_INFO1", id,"MENU_INFO2", id,"MENU_INFO3", id,"MENU_INFO4", id, "MENU_EXIT")
show_menu(id, KEYSMENU, menu, -1, "Mod Info")
}
// Admin Menu
show_menu_admin(id)
{
static menu[200]
formatex(menu, sizeof menu - 1, "\y%L\w^n^n1. %L^n2. %L^n3. %L^n4. %L^n5. %L^n6. %L^n^n0. %L", id, "MENU_ADMIN_TITLE", id, "MENU_ADMIN1", id,"MENU_ADMIN2", id,"MENU_ADMIN3", id,"MENU_ADMIN4", id,"MENU_ADMIN5", id,"MENU_ADMIN6", id, "MENU_EXIT")
show_menu(id, KEYSMENU, menu, -1, "Admin Menu")
}
// Player List Menu
show_menu_player_list(id)
{
static menu[400], len
len = 0
// Title
switch (PL_ACTION)
{
case 0: len += formatex(menu[len], sizeof menu - 1 - len, "\y%L ", id, "MENU_ADMIN1")
case 1: len += formatex(menu[len], sizeof menu - 1 - len, "\y%L ", id, "MENU_ADMIN2")
case 2: len += formatex(menu[len], sizeof menu - 1 - len, "\y%L ", id, "MENU_ADMIN3")
case 3: len += formatex(menu[len], sizeof menu - 1 - len, "\y%L ", id, "MENU_ADMIN4")
}
len += formatex(menu[len], sizeof menu - 1 - len, "\r[%d-%d]^n^n", PL_STARTID+1, (PL_STARTID+7 <= g_maxplayers) ? PL_STARTID+7 : g_maxplayers)
// 1-7. player list
static player
for (player = PL_STARTID+1; (PL_STARTID+7 <= g_maxplayers) ? (player <= PL_STARTID+7) : (player <= g_maxplayers); player++)
{
if (is_user_connected(player))
{
static name[32]
get_user_name(player, name, sizeof name - 1)
switch (PL_ACTION)
{
case 0:
{
if (g_zombie[player])
{
if (allowed_human(player))
len += formatex(menu[len], sizeof menu - 1 - len, "\w%d. %s \r[%L]^n", player-PL_STARTID, name, id, "CLASS_ZOMBIE")
else
len += formatex(menu[len], sizeof menu - 1 - len, "\d%d. %s [%L]^n", player-PL_STARTID, name, id, "CLASS_ZOMBIE")
}
else
{
if (allowed_zombie(player))
len += formatex(menu[len], sizeof menu - 1 - len, "\w%d. %s \y[%L]^n", player-PL_STARTID, name, id, "CLASS_HUMAN")
else
len += formatex(menu[len], sizeof menu - 1 - len, "\d%d. %s [%L]^n", player-PL_STARTID, name, id, "CLASS_HUMAN")
}
}
case 1:
{
if (allowed_nemesis(player))
len += formatex(menu[len], sizeof menu - 1 - len, "\w%d. %s^n", player-PL_STARTID, name)
else
len += formatex(menu[len], sizeof menu - 1 - len, "\d%d. %s^n", player-PL_STARTID, name)
}
case 2:
{
if (allowed_survivor(player))
len += formatex(menu[len], sizeof menu - 1 - len, "\w%d. %s^n", player-PL_STARTID, name)
else
len += formatex(menu[len], sizeof menu - 1 - len, "\d%d. %s^n", player-PL_STARTID, name)
}
case 3:
{
if (allowed_respawn(player))
len += formatex(menu[len], sizeof menu - 1 - len, "\w%d. %s^n", player-PL_STARTID, name)
else
len += formatex(menu[len], sizeof menu - 1 - len, "\d%d. %s^n", player-PL_STARTID, name)
}
}
}
else
{
len += formatex(menu[len], sizeof menu - 1 - len, "\d%d. -----^n", player-PL_STARTID)
}
}
// 8. Back - 9. Next - 0. Exit
len += formatex(menu[len], sizeof menu - 1 - len, "\w^n8. %L^n9. %L^n^n0. %L", id, "MENU_BACK", id, "MENU_NEXT", id, "MENU_EXIT")
show_menu(id, KEYSMENU, menu, -1, "Player List Menu")
}
/*================================================================================
[Menu Handlers]
=================================================================================*/
// Game Menu
public menu_game(id, key)
{
switch (key)
{
case 0: get_pcvar_num(cvar_extraitems) ? show_menu_extras(id) : client_print(id, print_chat, "[ZP] %L", id ,"CMD_NOT_EXTRAS")
case 1: get_pcvar_num(cvar_zclasses) ? show_menu_zombie(id) : client_print(id, print_chat, "[ZP] %L", id ,"CMD_NOT_ZCLASSES")
case 2: is_user_alive(id) && is_player_stuck(id) ? do_random_spawn(id) : client_print(id, print_chat, "[ZP] %L", id ,"CMD_NOT_STUCK")
case 3: show_menu_info(id)
case 4: get_user_flags(id) & ACCESS_FLAG ? show_menu_admin(id) : client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT_ACCESS")
}
return PLUGIN_HANDLED;
}
// Admin Menu
public menu_admin(id, key)
{
switch (key)
{
case 0 .. 3:
{
PL_ACTION = key;
show_menu_player_list(id);
}
case 4:
{
allowed_swarm() ? command_swarm(id) : client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT")
show_menu_admin(id);
}
case 5:
{
allowed_multi() ? command_multi(id) : client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT")
show_menu_admin(id);
}
}
return PLUGIN_HANDLED
}
// Player List Menu
public menu_player_list(id, key)
{
switch (key)
{
case 7: if (PL_STARTID-7 >= 0) PL_STARTID -= 7 // back
case 8: if (PL_STARTID+7 < g_maxplayers) PL_STARTID += 7 // next
case 9: // go back to admin menu
{
show_menu_admin(id);
return PLUGIN_HANDLED
}
default: // perform action on player
{
if (is_user_connected(PL_TARGET))
{
switch (PL_ACTION)
{
case 0:
{
if (g_zombie[PL_TARGET])
{
if (allowed_human(PL_TARGET))
command_human(id, PL_TARGET)
else
client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT")
}
else
{
if (allowed_zombie(PL_TARGET))
command_zombie(id, PL_TARGET)
else
client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT")
}
}
case 1:
{
if (allowed_nemesis(PL_TARGET))
command_nemesis(id, PL_TARGET)
else
client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT")
}
case 2:
{
if (allowed_survivor(PL_TARGET))
command_survivor(id, PL_TARGET)
else
client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT")
}
case 3:
{
if (allowed_respawn(PL_TARGET))
command_respawn(id, PL_TARGET)
else
client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT")
}
}
}
else
{
client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT")
}
}
}
show_menu_player_list(id);
return PLUGIN_HANDLED
}
// Info Menu
public menu_info(id, key)
{
switch (key)
{
case 0:
{
static motd[1000], len, weather, lights[2]
len = 0
weather = 0
get_pcvar_string(cvar_lightning, lights, sizeof lights - 1)
strtolower(lights)
len += formatex(motd[len], sizeof motd - 1 - len, "%L ", id, "MOTD_INFO11", "Zombie Plague", PLUGIN_VERSION, "MeRcyLeZZ")
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO12")
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_A")
#if defined AMBIENCE_FOG
len += formatex(motd[len], sizeof motd - 1 - len, (weather < 1) ? " %L" : ". %L", id, "MOTD_FOG")
weather++
#endif
#if defined AMBIENCE_RAIN
len += formatex(motd[len], sizeof motd - 1 - len, (weather < 1) ? " %L" : ". %L", id, "MOTD_RAIN")
weather++
#endif
#if defined AMBIENCE_SNOW
len += formatex(motd[len], sizeof motd - 1 - len, (weather < 1) ? " %L" : ". %L", id, "MOTD_SNOW")
weather++
#endif
if (weather < 1) len += formatex(motd[len], sizeof motd - 1 - len, " %L", id, "MOTD_DISABLED")
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_B", lights)
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_C", id, get_pcvar_num(cvar_triggered) ? "MOTD_ENABLED" : "MOTD_DISABLED")
if (lights[0] == 'a' && get_pcvar_num(cvar_thunder)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_D", get_pcvar_num(cvar_thunder))
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_E", id, get_pcvar_num(cvar_removedoors) > 0 ? get_pcvar_num(cvar_removedoors) > 1 ? "MOTD_DOORS" : "MOTD_ROTATING" : "MOTD_ENABLED")
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_F", id, get_pcvar_num(cvar_deathmatch) > 0 ? get_pcvar_num(cvar_deathmatch) > 1 ? get_pcvar_num(cvar_deathmatch) > 2 ? "MOTD_ENABLED" : "MOTD_DM_ZOMBIE" : "MOTD_DM_HUMAN" : "MOTD_DISABLED")
if (get_pcvar_num(cvar_deathmatch)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_G", get_pcvar_num(cvar_spawnprotection))
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_H", id, get_pcvar_num(cvar_randspawn) ? "MOTD_ENABLED" : "MOTD_DISABLED")
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_I", id, get_pcvar_num(cvar_extraitems) ? "MOTD_ENABLED" : "MOTD_DISABLED")
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_J", id, get_pcvar_num(cvar_zclasses) ? "MOTD_ENABLED" : "MOTD_DISABLED")
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_K", id, get_pcvar_num(cvar_cnvg) ? "MOTD_ENABLED" : "MOTD_DISABLED")
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO1_L", id, get_pcvar_num(cvar_cflash) ? "MOTD_ENABLED" : "MOTD_DISABLED")
show_motd(id, motd)
}
case 1:
{
static motd[650], len
len = 0
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2")
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_A", get_pcvar_num(cvar_humanhp))
if (get_pcvar_num(cvar_humanlasthp) > 0) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_B", get_pcvar_num(cvar_humanlasthp))
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_C", get_pcvar_num(cvar_humanspd))
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_D", floatround(get_pcvar_float(cvar_humangravity)*800))
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_E", id, get_pcvar_num(cvar_infammo) > 0 ? get_pcvar_num(cvar_infammo) > 1 ? "MOTD_AMMO_CLIP" : "MOTD_AMMO_BP" : "MOTD_LIMITED")
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_F", get_pcvar_num(cvar_ammodamage))
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_G", id, get_pcvar_num(cvar_firegrenades) ? "MOTD_ENABLED" : "MOTD_DISABLED")
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_H", id, get_pcvar_num(cvar_frostgrenades) ? "MOTD_ENABLED" : "MOTD_DISABLED")
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_I", id, get_pcvar_num(cvar_flaregrenades) ? "MOTD_ENABLED" : "MOTD_DISABLED")
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO2_J", id, get_pcvar_num(cvar_knockback) ? "MOTD_ENABLED" : "MOTD_DISABLED")
show_motd(id, motd)
}
case 2:
{
static motd[650], len
len = 0
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3")
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3_A", get_pcvar_num(cvar_hp))
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3_B", get_pcvar_num(cvar_firsthp))
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3_C", floatround(get_pcvar_float(cvar_armor)*100))
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3_D", get_pcvar_num(cvar_speed))
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3_E", floatround(get_pcvar_float(cvar_gravity)*800))
if (get_pcvar_num(cvar_bonushp)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3_F", get_pcvar_num(cvar_bonushp))
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3_G", id, get_pcvar_num(cvar_painfree) > 0 ? get_pcvar_num(cvar_painfree) > 1 ? "MOTD_LASTZOMBIE" : "MOTD_ENABLED" : "MOTD_DISABLED")
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3_H", id, get_pcvar_num(cvar_bleeding) ? "MOTD_ENABLED" : "MOTD_DISABLED")
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO3_I", get_pcvar_num(cvar_ammoinfect))
show_motd(id, motd)
}
case 3:
{
static motd[900], len, nemhp[5], survhp[5]
len = 0
num_to_str(get_pcvar_num(cvar_nemhp), nemhp, sizeof nemhp - 1) // nemesis health
num_to_str(get_pcvar_num(cvar_survhp), survhp, sizeof survhp - 1) // survivor health
len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4")
len += formatex(motd[len], sizeof motd - 1 - 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], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_B", get_pcvar_num(cvar_nemchance))
if (get_pcvar_num(cvar_nem)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_C", get_pcvar_num(cvar_nemhp) > 0 ? nemhp : "[Auto]")
if (get_pcvar_num(cvar_nem)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_D", get_pcvar_num(cvar_nemspd))
if (get_pcvar_num(cvar_nem)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_E", floatround(get_pcvar_float(cvar_nemgravity)*800))
if (get_pcvar_num(cvar_nem)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_F", id, get_pcvar_num(cvar_nemleap) ? "MOTD_ENABLED" : "MOTD_DISABLED")
if (get_pcvar_num(cvar_nem)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_G", id, get_pcvar_num(cvar_nempainfree) ? "MOTD_ENABLED" : "MOTD_DISABLED")
len += formatex(motd[len], sizeof motd - 1 - 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], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_I", get_pcvar_num(cvar_survchance))
if (get_pcvar_num(cvar_surv)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_J", get_pcvar_num(cvar_survhp) > 0 ? survhp : "[Auto]")
if (get_pcvar_num(cvar_surv)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_K", get_pcvar_num(cvar_survspd))
if (get_pcvar_num(cvar_surv)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_L", floatround(get_pcvar_float(cvar_survgravity)*800))
if (get_pcvar_num(cvar_surv)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_M", id, get_pcvar_num(cvar_survleap) ? "MOTD_ENABLED" : "MOTD_DISABLED")
if (get_pcvar_num(cvar_surv)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_N", id, get_pcvar_num(cvar_survpainfree) ? "MOTD_ENABLED" : "MOTD_DISABLED")
len += formatex(motd[len], sizeof motd - 1 - 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], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_P", get_pcvar_num(cvar_swarmchance))
len += formatex(motd[len], sizeof motd - 1 - 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], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_R", get_pcvar_num(cvar_multichance))
if (get_pcvar_num(cvar_multi)) len += formatex(motd[len], sizeof motd - 1 - len, "%L", id, "MOTD_INFO4_S", floatround(get_pcvar_float(cvar_multiratio)*100))
show_motd(id, motd)
}
default: return PLUGIN_HANDLED;
}
set_task(0.2, "show_menu_info", id);
return PLUGIN_HANDLED;
}
// Extra Items Menu
public menu_extras(id, key)
{
// Nemesis or Survivor shouldnt get extra items
if (!is_user_alive(id) || g_survivor[id] || g_nemesis[id])
{
client_print(id, print_chat, "[ZP] %L", id, "CMD_NOT")
return PLUGIN_HANDLED;
}
switch (key)
{
case 0 .. sizeof g_extra_items - 1:
{
if (!g_zombie[id])
{
if (g_ammopacks[id] >= g_extra_costs[key])
{
if (MAXAMMO[get_weaponid(g_extra_items[key])] > 1) // (this adds grenades support)
{
// Drop previous weapon and give BP ammo for the new one
(1<<get_weaponid(g_extra_items[key])) & PRIMARY_WEAPONS_BIT_SUM ? drop_weapons(id, 1) : drop_weapons(id, 2);
fm_set_user_bpammo(id, get_weaponid(g_extra_items[key]), MAXAMMO[get_weaponid(g_extra_items[key])]);
}
fm_give_item(id, g_extra_items[key]);
g_ammopacks[id] -= g_extra_costs[key];
}
else
{
client_print(id, print_chat, "[ZP] %L", id ,"NOT_ENOUGH_AMMO")
}
}
else
{
client_print(id, print_chat, "[ZP] %L", id ,"CMD_HUMAN_ONLY")
}
}
case sizeof g_extra_items + 0:
{
if (!g_zombie[id])
{
if (g_ammopacks[id] >= g_extra_costs2[EXTRA_NVISION])
{
g_nvision[id] = true; // Night Vision
g_nvisionenabled[id] = 1
if (get_pcvar_num(cvar_cnvg)) // custom nvg?
{
remove_task(id+NVISION_TASK);
set_user_nvision(id+NVISION_TASK)
}
else set_user_gnvision(id, 1)
g_ammopacks[id] -= g_extra_costs2[EXTRA_NVISION];
}
else
{
client_print(id, print_chat, "[ZP] %L", id ,"NOT_ENOUGH_AMMO")
}
}
else
{
client_print(id, print_chat, "[ZP] %L", id ,"CMD_HUMAN_ONLY")
}
}
case sizeof g_extra_items + 1:
{
if (g_zombie[id])
{
if (!g_endround && !g_swarmround && !g_nemround && !g_survround && fnGetZombies() > 1)
{
if (g_ammopacks[id] >= g_extra_costs2[EXTRA_ANTIDOTE])
{
humanme(id) // Antidote
g_ammopacks[id] -= g_extra_costs2[EXTRA_ANTIDOTE];
}
else
{
client_print(id, print_chat, "[ZP] %L", id ,"NOT_ENOUGH_AMMO")
}
}
else
{
client_print(id, print_chat, "[ZP] %L", id ,"CMD_NOT_CANTUSE")
}
}
else
{
client_print(id, print_chat, "[ZP] %L", id ,"CMD_ZOMBIE_ONLY")
}
}
case sizeof g_extra_items + 2:
{
if (g_zombie[id])
{
if (!g_swarmround && !g_nemround && !g_survround && !g_nodamage[id])
{
if (g_ammopacks[id] >= g_extra_costs2[EXTRA_MADNESS])
{
g_nodamage[id] = true // Zombie Madness
infectionFX(id) // aura
engfunc(EngFunc_EmitSound, id, CHAN_VOICE, zombie_madness[random_num(0, sizeof zombie_madness - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
set_task(5.0, "madness_over", id+BLOOD_TASK)
g_ammopacks[id] -= g_extra_costs2[EXTRA_MADNESS];
}
else
{
client_print(id, print_chat, "[ZP] %L", id ,"NOT_ENOUGH_AMMO")
}
}
else
{
client_print(id, print_chat, "[ZP] %L", id ,"CMD_NOT_CANTUSE")
}
}
else
{
client_print(id, print_chat, "[ZP] %L", id ,"CMD_ZOMBIE_ONLY")
}
}
case sizeof g_extra_items + 3:
{
if (g_zombie[id])
{
if (!g_swarmround && !g_nemround && !g_survround)
{
if (g_ammopacks[id] >= g_extra_costs2[EXTRA_INFBOMB])
{
fm_give_item(id, "weapon_hegrenade"); // Infection Bomb
g_ammopacks[id] -= g_extra_costs2[EXTRA_INFBOMB];
}
else
{
client_print(id, print_chat, "[ZP] %L", id ,"NOT_ENOUGH_AMMO")
}
}
else
{
client_print(id, print_chat, "[ZP] %L", id ,"CMD_NOT_CANTUSE")
}
}
else
{
client_print(id, print_chat, "[ZP] %L", id ,"CMD_ZOMBIE_ONLY")
}
}
}
return PLUGIN_HANDLED;
}
// Buy Menu 1
public menu_buy1(id, key)
{
// Zombies or survivors get no guns
if (!is_user_alive(id) || g_zombie[id] || g_survivor[id] || !g_canbuy[id])
return PLUGIN_HANDLED;
// Exit
if (key >= sizeof g_primary_names) return PLUGIN_HANDLED;
// 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")
// Give the new weapon
fm_give_item(id, g_primary_items[key])
fm_set_user_bpammo(id, get_weaponid(g_primary_items[key]), MAXAMMO[get_weaponid(g_primary_items[key])])
static i // weapons bought, give additional items
for (i = 0; i < sizeof g_additional_items; i++) fm_give_item(id, g_additional_items[i])
g_canbuy[id] = false
show_menu_buy2(id); // show pistol menu
return PLUGIN_HANDLED;
}
// Buy Menu 2
public menu_buy2(id, key)
{
// Zombies or survivors get no guns
if (!is_user_alive(id) || g_zombie[id] || g_survivor[id])
return PLUGIN_HANDLED;
// Exit
if (key >= sizeof g_secondary_names) return PLUGIN_HANDLED;
// Drop secondary gun again, in case we picked another (bugfix)
drop_weapons(id, 2);
// Give the new weapon
fm_give_item(id, g_secondary_items[key])
fm_set_user_bpammo(id, get_weaponid(g_secondary_items[key]), MAXAMMO[get_weaponid(g_secondary_items[key])])
return PLUGIN_HANDLED;
}
// Zombie Menu
public menu_zombie(id, key)
{
switch (key)
{
case 0: client_print(id, print_chat, "[ZP] %L: %L", id, "ZOMBIE_SELECT", id, "CLASS_ZOMBIE1")
case 1: client_print(id, print_chat, "[ZP] %L: %L", id, "ZOMBIE_SELECT", id, "CLASS_ZOMBIE2")
case 2: client_print(id, print_chat, "[ZP] %L: %L", id, "ZOMBIE_SELECT", id, "CLASS_ZOMBIE3")
case 3: client_print(id, print_chat, "[ZP] %L: %L", id, "ZOMBIE_SELECT", id, "CLASS_ZOMBIE4")
case 4: client_print(id, print_chat, "[ZP] %L: %L", id, "ZOMBIE_SELECT", id, "CLASS_ZOMBIE5")
case 5: client_print(id, print_chat, "[ZP] %L: %L", id, "ZOMBIE_SELECT", id, "CLASS_ZOMBIE6")
default: return PLUGIN_HANDLED;
}
g_zombieclassnext[id] = key;
client_print(id, print_chat, "[ZP] %L: %d %L: %d %L: %d %L: %d%%", id, "ZOMBIE_ATTRIB1", floatround(get_pcvar_float(cvar_hp)*zombie_multihp[g_zombieclassnext[id]]/100), id, "ZOMBIE_ATTRIB2", floatround(get_pcvar_float(cvar_speed)*zombie_multispd[g_zombieclassnext[id]]/100),
id, "ZOMBIE_ATTRIB3", floatround(get_pcvar_float(cvar_gravity)*zombie_multigrav[g_zombieclassnext[id]]/100*800), id, "ZOMBIE_ATTRIB4", zombie_multiknockback[g_zombieclassnext[id]])
return PLUGIN_HANDLED;
}
/*================================================================================
[Admin Commands]
=================================================================================*/
// zp_zombie [target]
public cmd_zombie(id, level, cid)
{
if (!cmd_access(id, level, cid, 2)) // check for access flag
return PLUGIN_HANDLED
static arg[32], player
read_argv(1, arg, sizeof arg - 1)
player = cmd_target(id, arg, 4 | 2) // find target
if (!player) return PLUGIN_HANDLED
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)
{
if (!cmd_access(id, level, cid, 2)) // check for access flag
return PLUGIN_HANDLED
static arg[32], player
read_argv(1, arg, sizeof arg - 1)
player = cmd_target(id, arg, 4 | 2) // find target
if (!player) return PLUGIN_HANDLED
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)
{
if (!cmd_access(id, level, cid, 2)) // check for access flag
return PLUGIN_HANDLED
static arg[32], player
read_argv(1, arg, sizeof arg - 1)
player = cmd_target(id, arg, 4 | 2) // find target
if (!player) return PLUGIN_HANDLED
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)
{
if (!cmd_access(id, level, cid, 2)) // check for access flag
return PLUGIN_HANDLED
static arg[32], player
read_argv(1, arg, sizeof arg - 1)
player = cmd_target(id, arg, 4 | 2) // find target
if (!player) return PLUGIN_HANDLED
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)
{
if (!cmd_access(id, level, cid, 2)) // check for access flag
return PLUGIN_HANDLED
static arg[32], player
read_argv(1, arg, sizeof arg - 1)
player = cmd_target(id, arg, 2) // find target
if (!player) return PLUGIN_HANDLED
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)
{
if (!cmd_access(id, level, cid, 1)) // check for access flag
return PLUGIN_HANDLED
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)
{
if (!cmd_access(id, level, cid, 1)) // check for access flag
return PLUGIN_HANDLED
if (!allowed_multi())
{
client_print(id, print_console, "[ZP] %L", id, "CMD_NOT")
return PLUGIN_HANDLED
}
command_multi(id)
return PLUGIN_HANDLED
}
/*================================================================================
[Message Hooks]
=================================================================================*/
// Current Weapon
public message_cur_weapon(msg_id, msg_dest, msg_entity)
{
// Player not alive or not an active weapon
if (!is_user_alive(msg_entity) || get_msg_arg_int(1) != 1)
return;
static weapon, clip
weapon = get_msg_arg_int(2) // get weapon ID
clip = get_msg_arg_int(3) // get weapon clip
g_currentweapon[msg_entity] = weapon // store weapon id for reference
// Retrieve our custom bpammo from the weapon entity
static wname[32], weapon_ent, extra_ammo
get_weaponname(weapon, wname, sizeof wname - 1);
weapon_ent = fm_find_ent_by_owner(-1, wname, msg_entity); // get weapon entity
extra_ammo = pev(weapon_ent, pev_iuser1); // get additional ammo (hack)
if (extra_ammo) // spare ammo goes to our bpammo (dont exceed max though)
{
fm_set_user_bpammo(msg_entity, weapon, min(fm_get_user_bpammo(msg_entity, weapon)+extra_ammo, MAXAMMO[weapon]))
set_pev(weapon_ent, pev_iuser1, 0)
}
// Unlimited BPAmmo
if ((get_pcvar_num(cvar_infammo) && MAXAMMO[weapon] > 1) || (g_survivor[msg_entity] && weapon == CSW_M249))
{
if (fm_get_user_bpammo(msg_entity, weapon) < MAXAMMO[weapon])
fm_set_user_bpammo(msg_entity, weapon, MAXAMMO[weapon])
}
// Unlimited Clip Ammo
if (get_pcvar_num(cvar_infammo) > 1 || (g_survivor[msg_entity] && weapon == CSW_M249))
{
if (MAXCLIP[weapon] > 2) // skip grenades
{
set_msg_arg_int(3, get_msg_argtype(3), MAXCLIP[weapon]) // HUD should show full clip all the time
if (clip < 2) fm_set_weapon_ammo(weapon_ent, MAXCLIP[weapon]) // refill
}
}
// Bots automatically buy ammo when needed
if (is_user_bot(msg_entity) && !g_zombie[msg_entity] && !g_survround && g_ammopacks[msg_entity] > 0 && MAXCLIP[weapon] > 2 && fm_get_user_bpammo(msg_entity, weapon) <= BUYAMMO[weapon])
clcmd_buyammo(msg_entity);
// Replace custom weapon models
replace_models(msg_entity);
// If zombie is not holding a knife/infection bomb for some reason
if (g_zombie[msg_entity] && weapon != CSW_KNIFE && weapon != CSW_HEGRENADE)
engclient_cmd(msg_entity, "weapon_knife"); // force him to do so
}
// Take off player's money
public message_money(msg_id, msg_dest, msg_entity)
{
if (!get_pcvar_num(cvar_removemoney))
return PLUGIN_CONTINUE;
set_pdata_int(msg_entity, OFFSET_CSMONEY, 0, OFFSET_LINUX);
return PLUGIN_HANDLED;
}
// Fix the HL engine bug when HP is multiples of 256
public message_health(msg_id, msg_dest, msg_entity)
{
static health
health = get_msg_arg_int(1) // get health
if (health < 256) return; // dont bother
if (floatfract(float(health)/256.0) == 0.0) // check if we need to fix it
fm_set_user_health(msg_entity, health+1)
set_msg_arg_int(1, get_msg_argtype(1), 255); // HUD only shows as much as 255 hp
}
// Hide player's money
public message_hideweapon()
{
if (!get_pcvar_num(cvar_removemoney))
return;
set_msg_arg_int(1, get_msg_argtype(1), get_msg_arg_int(1) | HIDE_MONEY);
}
// Block flashlight battery messages when it's not available, or if custom flashlight is enabled instead
public message_flashbat(msg_id, msg_dest, msg_entity)
{
if (get_pcvar_num(cvar_cflash) || !is_user_alive(msg_entity) || g_zombie[msg_entity] || g_survivor[msg_entity])
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;
if (g_zombie[msg_entity] && !g_nemesis[msg_entity]) // nemesis shouldn't be FBed
{
// 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;
}
// Hide bomb carrier on the scoreboard
public message_scoreattrib()
{
if (get_msg_arg_int(2) & ATTRIB_BOMB)
set_msg_arg_int(2, get_msg_argtype(2), get_msg_arg_int(2) & ~ATTRIB_BOMB)
}
// Hide C4 icon display on HUD
public message_statusicon()
{
static sprite[3]
get_msg_arg_string(2, sprite, sizeof sprite - 1)
if(sprite[0] == 'c' && sprite[1] == '4')
return PLUGIN_HANDLED;
return PLUGIN_CONTINUE;
}
#if defined HANDLE_MODELS_ON_SEPARATE_ENT
// Set correct model for player corpses
public message_clcorpse()
{
set_msg_arg_string(1, g_playermodel[get_msg_arg_int(12)])
}
#endif
// Block weapon pickup messsages
public message_weappickup(msg_id, msg_dest, msg_entity)
{
if (g_zombie[msg_entity]) // prevent zombies from seeing any weapon pickup icon
return PLUGIN_HANDLED;
return PLUGIN_CONTINUE;
}
// Block ammo pickup messages
public message_ammopickup(msg_id, msg_dest, msg_entity)
{
if (g_zombie[msg_entity]) // prevent zombies from seeing any ammo pickup icon
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, sizeof sprite - 1)
if (equal(sprite, "hostage"))
return PLUGIN_HANDLED;
}
return PLUGIN_CONTINUE;
}
// Block hostages from appearing on radar
public message_hostagepos()
{
return PLUGIN_HANDLED;
}
// Block bomb dropped message so it doesn't show up in the radar
public message_bombdrop()
{
return PLUGIN_HANDLED;
}
// Block some text messages
public message_textmsg()
{
static textmsg[22]
get_msg_arg_string(2, textmsg, sizeof textmsg - 1);
// 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
event_round_end()
}
// Block bomb/round related messages
else if (equal(textmsg, "#Game_bomb_drop") || equal(textmsg, "#Target_Saved") || equal(textmsg, "#Round_Draw") || equal(textmsg, "#Terrorists_Win") || equal(textmsg, "#CTs_Win"))
{
return PLUGIN_HANDLED;
}
return PLUGIN_CONTINUE;
}
// Block round win audio messages
public message_sendaudio()
{
static audio[17]
get_msg_arg_string(2, audio, sizeof audio - 1)
if(equal(audio, "%!MRAD_terwin") || equal(audio, "%!MRAD_ctwin") || equal(audio, "%!MRAD_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, sizeof team - 1)
if (team[0] == 'C') // CT
set_msg_arg_int(2, get_msg_argtype(2), g_scorehumans);
else if (team[0] == 'T') // Terrorist
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;
static id // get player id
id = get_msg_arg_int(1)
// Don't pick up our own TeamInfo messages for this player (bugfix)
if (g_switchingteam[id]) return;
static team[2] // get his new team
get_msg_arg_string(2, team, sizeof team - 1)
if (team[0] == 'C') // CT
{
if (!g_newround) // round started
{
if (g_survround && fnGetHumans()) // survivor alive --> switch to T and spawn as zombie
{
g_respawn_as_zombie[id] = true;
remove_task(id+TEAM_TASK)
fm_set_user_team(id, 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+TEAM_TASK)
fm_set_user_team(id, CS_TEAM_T)
set_msg_arg_string(2, "Terrorist")
}
}
}
else if (team[0] == 'T') // Terrorist
{
if (!g_newround) // round started
{
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+TEAM_TASK)
fm_set_user_team(id, CS_TEAM_CT)
set_msg_arg_string(2, "CT")
}
}
}
// Enable spectators' nightvision if not spawning
set_task(0.2, "spec_nvision", id)
}
/*================================================================================
[Main Functions]
=================================================================================*/
// Make Zombie Task
public make_zombie_task()
{
// Call make a zombie with playerid MAKEZOMBIE_TASK and no further args
make_a_zombie(MAKEZOMBIE_TASK, 0, 0, 0, 0);
}
// Make a Zombie Function
make_a_zombie(playerid, nem, surv, swarm, multi)
{
// Get alive players count
static iPlayersnum
iPlayersnum = fnGetAlive()
if (iPlayersnum < 1) // not enough players
{
set_task(10.0, "make_zombie_task", MAKEZOMBIE_TASK)
return;
}
g_models_i = 0.0 // reset model change count
g_teams_i = 0.0 // reset teams change count
// round starting
g_newround = false
g_survround = false
g_nemround = false
g_swarmround = false
static id
if ((playerid == MAKEZOMBIE_TASK && random_num(1, get_pcvar_num(cvar_survchance)) == get_pcvar_num(cvar_surv)) || surv) // Survival Chance
{
g_survround = true // survivor round
if (playerid == MAKEZOMBIE_TASK) // choose player randomly?
id = fnGetRandomAlive(random_num(1, iPlayersnum))
else
id = playerid
g_survivor[id] = true // set var
if (get_pcvar_num(cvar_survleap)) // give survivor leap?
fm_give_item(id, "item_longjump")
// Remove previous tasks
remove_task(id+TEAM_TASK)
// Switch to CT
if (fm_get_user_team(id) != CS_TEAM_CT) // need to change team?
{
fm_set_user_team(id, CS_TEAM_CT)
fm_set_user_team_msg(id+TEAM_TASK)
}
// Set Health [0 = auto]
if (!get_pcvar_num(cvar_survhp))
fm_set_user_health(id, fnGetHumans()*get_pcvar_num(cvar_humanhp))
else
fm_set_user_health(id, get_pcvar_num(cvar_survhp))
// Set Gravity
set_pev(id, pev_gravity, get_pcvar_float(cvar_survgravity))
// glow?
if (get_pcvar_num(cvar_survglow))
{
#if defined HANDLE_MODELS_ON_SEPARATE_ENT
fm_set_rendering(fm_find_ent_by_owner(-1, "player_model", id), kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 25)
#else
fm_set_rendering(id, kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 25)
#endif
}
fm_strip_user_weapons(id) // strip player from weapons
fm_give_item(id, "weapon_m249") // give M249 machinegun only
// Turn off his flashlight
turn_off_flashlight(id)
set_task(3.0, "turn_off_flashlight", id) // bugfix
// Give the survivor a bright light
set_pev(id, pev_effects, pev(id, pev_effects) | EF_BRIGHTLIGHT)
// Survivor bots will also need nightvision to see in the dark
if (is_user_bot(id)) fm_set_bot_nvg(id, 1);
// Play survivor sound
PlaySound(sound_survivor[random_num(0, sizeof sound_survivor -1)]);
static name[32]
get_user_name(id, name, sizeof name - 1)
// show Survivor HUD notice
set_hudmessage(20, 20, 255, -1.0, 0.25, 1, 0.0, 5.0, 1.0, 1.0, -1)
ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_SURVIVOR", name)
// Turn the rest of players into zombies
for (id = 1; id <= g_maxplayers; id++)
{
if (!is_user_alive(id)) // skip dead
continue;
if (g_survivor[id]) // skip the survivor
continue;
zombieme(id, 0, 1) // turn into a zombie
}
}
else if ((playerid == MAKEZOMBIE_TASK && random_num(1, get_pcvar_num(cvar_swarmchance)) == get_pcvar_num(cvar_swarm)) || swarm) // Swarm Chance
{
g_swarmround = true // swarm round
// Turn all the T into zombies
for (id = 1; id <= g_maxplayers; id++)
{
if (!is_user_alive(id)) // not alive
continue;
if (fm_get_user_team(id) == CS_TEAM_T) // only Terrorists
zombieme(id, 0, 1) // turn into a zombie
}
// Play swarm sound
PlaySound(sound_swarm[random_num(0, sizeof sound_swarm -1)]);
// Show Swarm HUD notice
set_hudmessage(20, 255, 20, -1.0, 0.25, 1, 0.0, 5.0, 1.0, 1.0, -1)
ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_SWARM")
}
else if ((playerid == MAKEZOMBIE_TASK && random_num(1, get_pcvar_num(cvar_multichance)) == get_pcvar_num(cvar_multi) && floatround(iPlayersnum*get_pcvar_float(cvar_multiratio), floatround_ceil) > 1) || multi) // Multi Infection Chance
{
static iZombies, iMaxZombies
// 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)
{
if (id < g_maxplayers)
id++
else
id = 1
if (!is_user_alive(id) || g_zombie[id]) // dead or already a zombie
continue;
if (random_num(0, 1))
{
zombieme(id, 0, 1) // turn into a zombie
iZombies++
}
}
// Turn the rest of players into humans
for (id = 1; id <= g_maxplayers; id++)
{
if (!is_user_alive(id) || g_zombie[id]) // only those of them who arent zombies
continue
// remove previous tasks
remove_task(id+TEAM_TASK)
// Switch to CT
if (fm_get_user_team(id) != CS_TEAM_CT) // need to change team?
{
fm_set_user_team(id, CS_TEAM_CT)
set_task(0.1+g_teams_i, "fm_set_user_team_msg", id+TEAM_TASK)
g_teams_i += 0.1; // increase teams task count
}
}
// Play multi infection sound
PlaySound(sound_multi[random_num(0, sizeof sound_multi -1)]);
// Show Multi Infection HUD notice
set_hudmessage(200, 50, 0, -1.0, 0.25, 1, 0.0, 5.0, 1.0, 1.0, -1)
ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_MULTI")
}
else
{
// Infection mode (only 1 zombie)
if (playerid == MAKEZOMBIE_TASK) // choose player randomly?
id = fnGetRandomAlive(random_num(1, iPlayersnum))
else
id = playerid
// Nemesis Chance
if ((playerid == MAKEZOMBIE_TASK && random_num(1, get_pcvar_num(cvar_nemchance)) == get_pcvar_num(cvar_nem)) || nem)
{
g_nemround = true // nemesis round
zombieme(id, 1, 0)
}
else
{
zombieme(id, 0, 0) // boring first zombie
}
// Rest of players left as humans (CTs)
for (id = 1; id <= g_maxplayers; id++)
{
if (!is_user_alive(id)) // skip dead
continue;
if (g_zombie[id]) // skip our first zombie
continue;
// Remove previous tasks
remove_task(id+TEAM_TASK)
// Switch to CT
if (fm_get_user_team(id) != CS_TEAM_CT) // need to change team?
{
fm_set_user_team(id, CS_TEAM_CT)
set_task(0.1+g_teams_i, "fm_set_user_team_msg", id+TEAM_TASK)
g_teams_i += 0.1; // increase teams task count
}
}
}
// Last Zombie Check
set_task(0.1, "fnCheckLastZombie")
}
// Zombie Me Function (player id, turn into a nemesis, special mode)
zombieme(id, nemesis, specialmode)
{
if (g_zombie[id]) // already a zombie
return;
// Show zombie class menu if they haven't chosen any (e.g. just connected)
if (g_zombieclass[id] == -1 && get_pcvar_num(cvar_zclasses))
set_task(2.0, "show_menu_zombie", id);
// Set our new zombie class
g_zombieclass[id] = g_zombieclassnext[id];
// Way to go...
g_zombie[id] = true
if (!specialmode) // no special mode
{
if (fnGetZombies() == 1) // first zombie
{
if (nemesis) // nemesis?
{
g_nemesis[id] = true
if (get_pcvar_num(cvar_nemleap)) // give nemesis leap?
fm_give_item(id, "item_longjump")
if (!get_pcvar_num(cvar_nemhp)) // nemesis health
fm_set_user_health(id, 1+get_pcvar_num(cvar_hp)*fnGetHumans())
else
fm_set_user_health(id, get_pcvar_num(cvar_nemhp))
set_pev(id, pev_gravity, get_pcvar_float(cvar_nemgravity)) // nemesis gravity
// Play Nemesis sound
PlaySound(sound_nemesis[random_num(0, sizeof sound_nemesis -1)]);
static name[32]
get_user_name(id, name, sizeof name - 1)
// Show Nemesis HUD notice
set_hudmessage(255, 20, 20, -1.0, 0.25, 1, 0.0, 5.0, 1.0, 1.0, -1)
ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_NEMESIS", name)
}
else
{
// First zombie
fm_set_user_health(id, get_pcvar_num(cvar_firsthp)*zombie_multihp[g_zombieclass[id]]/100)
set_pev(id, pev_gravity, get_pcvar_float(cvar_gravity)*zombie_multigrav[g_zombieclass[id]]/100)
// Play First Zombie sound
engfunc(EngFunc_EmitSound, id, CHAN_VOICE, zombie_infect[random_num(0, sizeof zombie_infect - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
if (get_pcvar_num(cvar_firstleap)) // give leap to First Zombie?
fm_give_item(id, "item_longjump")
static name[32]
get_user_name(id, name, sizeof name - 1)
// Show First Zombie HUD notice
set_hudmessage(255, 0, 0, -1.0, 0.25, 0, 0.0, 5.0, 1.0, 1.0, -1)
ShowSyncHudMsg(0, g_MsgSync, "%L",LANG_PLAYER, "NOTICE_FIRST", name)
}
}
else
{
// Not the first zombie
fm_set_user_health(id, get_pcvar_num(cvar_hp)*zombie_multihp[g_zombieclass[id]]/100)
set_pev(id, pev_gravity, get_pcvar_float(cvar_gravity)*zombie_multigrav[g_zombieclass[id]]/100)
// Play Infection sound
engfunc(EngFunc_EmitSound, id, CHAN_VOICE, zombie_infect[random_num(0, sizeof zombie_infect - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
static name[32]
get_user_name(id, name, sizeof name - 1)
// Show Infection HUD notice
set_hudmessage(255, 0, 0, 0.05, 0.45, 0, 0.0, 5.0, 1.0, 1.0, -1)
ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_INFECT", name)
}
}
else
{
// Survivor/multi infection mode/infection grenade: normal zombie stats, no HUD notice
fm_set_user_health(id, get_pcvar_num(cvar_hp)*zombie_multihp[g_zombieclass[id]]/100)
set_pev(id, pev_gravity, get_pcvar_float(cvar_gravity)*zombie_multigrav[g_zombieclass[id]]/100)
}
// Remove previous tasks
remove_task(id+TEAM_TASK)
remove_task(id+MODEL_TASK)
remove_task(id+BLOOD_TASK)
// Switch to T
if (fm_get_user_team(id) != CS_TEAM_T) // need to change team?
{
if (specialmode) // set a longer delay for survivor/multi infection mode/infection grenade
{
fm_set_user_team(id, CS_TEAM_T);
set_task(0.1+g_teams_i, "fm_set_user_team_msg", id+TEAM_TASK)
g_teams_i += 0.1;
}
else
{
fm_set_user_team(id, CS_TEAM_T)
set_task(0.1, "fm_set_user_team_msg", id+TEAM_TASK)
}
}
#if defined HANDLE_MODELS_ON_SEPARATE_ENT
// Set the right model
if (g_nemesis[id])
copy(g_playermodel[id], 32, model_nemesis[random_num(0, sizeof model_nemesis -1)])
else
{
switch (g_zombieclass[id])
{
case 0: copy(g_playermodel[id], 32, model_zombie_class1[random_num(0, sizeof model_zombie_class1 -1)])
case 1: copy(g_playermodel[id], 32, model_zombie_class2[random_num(0, sizeof model_zombie_class2 -1)])
case 2: copy(g_playermodel[id], 32, model_zombie_class3[random_num(0, sizeof model_zombie_class3 -1)])
case 3: copy(g_playermodel[id], 32, model_zombie_class4[random_num(0, sizeof model_zombie_class4 -1)])
case 4: copy(g_playermodel[id], 32, model_zombie_class5[random_num(0, sizeof model_zombie_class5 -1)])
case 5: copy(g_playermodel[id], 32, model_zombie_class6[random_num(0, sizeof model_zombie_class6 -1)])
}
}
fm_set_user_model_ent(id) // set model on entity
#else
// Set the right model, but check that we don't have it already
static currentmodel[33], already_has_model, i
already_has_model = false;
fm_get_user_model(id, currentmodel, sizeof currentmodel - 1); // get current model
if (g_nemesis[id])
{
for (i = 0; i < sizeof model_nemesis; i++)
if (equal(model_nemesis[i], currentmodel)) already_has_model = true;
if (!already_has_model) copy(g_playermodel[id], 32, model_nemesis[random_num(0, sizeof model_nemesis -1)])
}
else
{
switch (g_zombieclass[id])
{
case 0:
{
for (i = 0; i < sizeof model_zombie_class1; i++)
if (equal(model_zombie_class1[i], currentmodel)) already_has_model = true;
if (!already_has_model) copy(g_playermodel[id], 32, model_zombie_class1[random_num(0, sizeof model_zombie_class1 -1)])
}
case 1:
{
for (i = 0; i < sizeof model_zombie_class2; i++)
if (equal(model_zombie_class2[i], currentmodel)) already_has_model = true;
if (!already_has_model) copy(g_playermodel[id], 32, model_zombie_class2[random_num(0, sizeof model_zombie_class2 -1)])
}
case 2:
{
for (i = 0; i < sizeof model_zombie_class3; i++)
if (equal(model_zombie_class3[i], currentmodel)) already_has_model = true;
if (!already_has_model) copy(g_playermodel[id], 32, model_zombie_class3[random_num(0, sizeof model_zombie_class3 -1)])
}
case 3:
{
for (i = 0; i < sizeof model_zombie_class4; i++)
if (equal(model_zombie_class4[i], currentmodel)) already_has_model = true;
if (!already_has_model) copy(g_playermodel[id], 32, model_zombie_class4[random_num(0, sizeof model_zombie_class4 -1)])
}
case 4:
{
for (i = 0; i < sizeof model_zombie_class5; i++)
if (equal(model_zombie_class5[i], currentmodel)) already_has_model = true;
if (!already_has_model) copy(g_playermodel[id], 32, model_zombie_class5[random_num(0, sizeof model_zombie_class5 -1)])
}
case 5:
{
for (i = 0; i < sizeof model_zombie_class6; i++)
if (equal(model_zombie_class6[i], currentmodel)) already_has_model = true;
if (!already_has_model) copy(g_playermodel[id], 32, model_zombie_class6[random_num(0, sizeof model_zombie_class6 -1)])
}
}
}
if (!already_has_model) // need to change the model?
{
if (specialmode) // longer delay for survivor/multi infection mode/infection grenade
{
set_task(0.1+MODELCHANGE_DELAY+g_models_i, "fm_set_user_model", id+MODEL_TASK) // set model with a delay
g_models_i += MODELCHANGE_DELAY;
}
else
{
fm_set_user_model(id+MODEL_TASK) // set model instantly
}
}
#endif
// Remove any zoom (bugfix)
fm_remove_user_zoom(id)
// Drop weapons when infected?
if (get_pcvar_num(cvar_dropwpn) > 0) drop_weapons(id, 1);
if (get_pcvar_num(cvar_dropwpn) > 1) drop_weapons(id, 2);
fm_strip_user_weapons(id) // strip zombies from guns
fm_give_item(id, "weapon_knife")
// Some fancy effects
fadeFX(id);
infectionFX(id);
// Enable Zombie Night Vision
if (!is_user_bot(id))
{
g_nvision[id] = true
g_nvisionenabled[id] = 1
if (get_pcvar_num(cvar_cnvg)) // custom nvg?
{
remove_task(id+NVISION_TASK);
set_user_nvision(id+NVISION_TASK)
}
else set_user_gnvision(id, 1)
}
else fm_set_bot_nvg(id, 1); // turn on NVG for bots
#if defined HANDLE_MODELS_ON_SEPARATE_ENT
if (g_nemesis[id] && get_pcvar_num(cvar_nemglow)) // nemesis glow
fm_set_rendering(fm_find_ent_by_owner(-1, "player_model", id), kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 25)
if (!g_nemesis[id] && g_zombieclass[id] == 5) // rage zombie glow
fm_set_rendering(fm_find_ent_by_owner(-1, "player_model", id), kRenderFxGlowShell, 0, 255, 0, kRenderNormal, 25)
#else
if (g_nemesis[id] && get_pcvar_num(cvar_nemglow)) // nemesis glow
fm_set_rendering(id, kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 25)
if (!g_nemesis[id] && g_zombieclass[id] == 5) // rage zombie glow
fm_set_rendering(id, kRenderFxGlowShell, 0, 255, 0, kRenderNormal, 25)
#endif
// Set custom FOV
if (get_pcvar_num(cvar_fov_angle) != 90 && get_pcvar_num(cvar_fov_angle) != 0)
{
message_begin(MSG_ONE, g_msgSetFOV, _, id);
write_byte(get_pcvar_num(cvar_fov_angle));
message_end();
}
// Call the bloody task
if (!g_nemesis[id] && get_pcvar_num(cvar_bleeding))
set_task(0.5, "make_blood", id+BLOOD_TASK)
// Idle sounds task
if (!g_nemesis[id])
set_task(random_float(60.0, 120.0), "zombie_play_idle", id+BLOOD_TASK);
// Turn off zombie's flashlight
turn_off_flashlight(id)
set_task(3.0, "turn_off_flashlight", id) // bugfix
// Last Zombie Check
set_task(0.1, "fnCheckLastZombie")
}
// Function Human Me (player id)
humanme(id)
{
if (!g_zombie[id]) // already human
return;
// Remove previous tasks
remove_task(id+TEAM_TASK)
remove_task(id+MODEL_TASK)
remove_task(id+BLOOD_TASK)
// Reset some vars
g_zombie[id] = false
g_nodamage[id] = false
g_canbuy[id] = true
g_nvision[id] = false
g_nvisionenabled[id] = 0
// Switch to CT
if (fm_get_user_team(id) != CS_TEAM_CT) // need to change team?
{
fm_set_user_team(id, CS_TEAM_CT);
fm_set_user_team_msg(id+TEAM_TASK);
}
#if defined HANDLE_MODELS_ON_SEPARATE_ENT
// Set the right model
if (get_user_flags(id) & ACCESS_FLAG)
copy(g_playermodel[id], 32, model_admin[random_num(0, sizeof model_admin -1)])
else
copy(g_playermodel[id], 32, model_human[random_num(0, sizeof model_human -1)])
fm_set_user_model_ent(id) // set model
if (!g_frozen[id]) fm_set_rendering(fm_find_ent_by_owner(-1, "player_model", id)) // remove glow, unless frozen
#else
// Set the right model, but check that we don't have it already
static currentmodel[33], already_has_model, i
already_has_model = false;
fm_get_user_model(id, currentmodel, sizeof currentmodel - 1); // get current model
if (get_user_flags(id) & ACCESS_FLAG)
{
for (i = 0; i < sizeof model_admin; i++)
if (equal(model_admin[i], currentmodel)) already_has_model = true;
if (!already_has_model) copy(g_playermodel[id], 32, model_admin[random_num(0, sizeof model_admin -1)])
}
else
{
for (i = 0; i < sizeof model_human; i++)
if (equal(model_human[i], currentmodel)) already_has_model = true;
if (!already_has_model) copy(g_playermodel[id], 32, model_human[random_num(0, sizeof model_human -1)])
}
if (!already_has_model) fm_set_user_model(id+MODEL_TASK) // set model instantly
if (!g_frozen[id]) fm_set_rendering(id) // remove glow, unless frozen
#endif
// Restore FOV
if (get_pcvar_num(cvar_fov_angle) != 90 && get_pcvar_num(cvar_fov_angle) != 0)
{
message_begin(MSG_ONE, g_msgSetFOV, _, id);
write_byte(90);
message_end();
}
// Disable nightvision
if (is_user_bot(id)) fm_set_bot_nvg(id, 0)
else if (!get_pcvar_num(cvar_cnvg)) set_user_gnvision(id, 0)
// Antidote sound
engfunc(EngFunc_EmitSound, id, CHAN_ITEM, sound_antidote[random_num(0, sizeof sound_antidote - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
// Restore health
fm_set_user_health(id, get_pcvar_num(cvar_humanhp))
// Restore gravity, unless frozen
if (!g_frozen[id]) set_pev(id, pev_gravity, get_pcvar_float(cvar_humangravity))
// Replace custom weapon models
replace_models(id);
// Show buy menu
set_task(0.5, "show_menu_buy1", id+SPAWN_TASK);
set_task(10.5, "show_menu_buy1", id+SPAWN_TASK);
static name[32]
get_user_name(id, name, sizeof name - 1)
// show Antidote HUD notice
set_hudmessage(0, 0, 255, 0.05, 0.45, 0, 0.0, 5.0, 1.0, 1.0, -1)
ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_ANTIDOTE", name)
// Last Zombie Check
set_task(0.1, "fnCheckLastZombie")
}
/*================================================================================
[Other Functions and Tasks]
=================================================================================*/
// 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 || !get_pcvar_num(cvar_botquota) || !is_user_connected(id) || !is_user_bot(id))
return;
RegisterHamFromEntity(Ham_Spawn, id, "fw_PlayerSpawn", 1)
RegisterHamFromEntity(Ham_Killed, id, "fw_Killed")
RegisterHamFromEntity(Ham_TakeDamage, id, "fw_TakeDamage")
RegisterHamFromEntity(Ham_TraceAttack, id, "fw_TraceAttack")
g_hamczbots = true;
}
// Bots automatically buy extra items
public bot_buy_extras(id)
{
if (!is_user_alive(id) || g_zombie[id] || g_survivor[id]) // not alive, zombie, or survivor
return;
// Make a random weapon selection
static key
key = random_num(0, sizeof g_extra_items - 1)
// Attempt to buy the weapon
if (g_ammopacks[id] >= g_extra_costs[key])
{
if (MAXAMMO[get_weaponid(g_extra_items[key])] > 1) // (this adds grenades support)
{
// Drop previous weapon and give BP ammo for the new one
(1<<get_weaponid(g_extra_items[key])) & PRIMARY_WEAPONS_BIT_SUM ? drop_weapons(id, 1) : drop_weapons(id, 2);
fm_set_user_bpammo(id, get_weaponid(g_extra_items[key]), MAXAMMO[get_weaponid(g_extra_items[key])]);
}
fm_give_item(id, g_extra_items[key]);
g_ammopacks[id] -= g_extra_costs[key];
}
// Attempt to buy Night Vision
if (!g_nvision[id] && g_ammopacks[id] >= g_extra_costs2[EXTRA_NVISION])
{
fm_set_bot_nvg(id, 1)
g_ammopacks[id] -= g_extra_costs2[EXTRA_NVISION]
}
}
// Balance Teams Task
public balance_teams()
{
// Get users playing
static iPlayersnum
iPlayersnum = fnGetPlaying()
// No players, don't bother
if (iPlayersnum < 1) return;
static g_team[33], id, iTerrors, iMaxTerrors
iMaxTerrors = iPlayersnum/2
iTerrors = 0
for (id = 1; id <= g_maxplayers; id++) // mark everyone's team as CT
g_team[id] = CS_TEAM_CT;
while (iTerrors < iMaxTerrors) // then randomly mark half of players as Terrorists
{
if (id < g_maxplayers)
id++
else
id = 1
if (!is_user_connected(id))
continue; // skip if not connected
if (fm_get_user_team(id) == CS_TEAM_SPECTATOR || fm_get_user_team(id) == CS_TEAM_UNASSIGNED)
continue; // skip if not playing
if (g_team[id] == CS_TEAM_T)
continue; // already a Terrorist
if (random_num(0, 1))
{
g_team[id] = CS_TEAM_T
iTerrors++
}
}
for (id = 1; id <= g_maxplayers; id++) // actually set everyone's team
{
if (!is_user_connected(id))
continue; // skip if not connected
if (fm_get_user_team(id) == CS_TEAM_SPECTATOR || fm_get_user_team(id) == CS_TEAM_UNASSIGNED)
continue // skip if not playing
// set correct team
remove_task(id+TEAM_TASK)
fm_set_user_team(id, g_team[id])
}
}
// Welcome Message Task
public welcome_msg(id)
{
client_print(0, print_chat, "**** %s by MeRcyLeZZ ****", g_modname)
client_print(0, print_chat, "[ZP] %L", LANG_PLAYER, "NOTICE_INFO1")
if (!get_pcvar_num(cvar_infammo)) client_print(0, print_chat, "[ZP] %L", LANG_PLAYER, "NOTICE_INFO2")
set_hudmessage(0, 125, 200, -1.0, 0.25, 0, 0.0, 3.0, 2.0, 1.0, -1)
ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_VIRUS_FREE") // show T-virus HUD notice
}
// Respawn Player Task
public respawn_player(taskid)
{
// Respawn on infection rounds only
if (!is_user_alive(ID_SPAWN) && !g_endround && !g_survround && !g_swarmround && !g_nemround)
{
g_respawn_as_zombie[ID_SPAWN] ? fm_set_user_team(ID_SPAWN, CS_TEAM_T) : fm_set_user_team(ID_SPAWN, CS_TEAM_CT);
ExecuteHam(Ham_CS_RoundRespawn, ID_SPAWN);
}
}
// Check Round Task -check that we still have both zombies & humans on a round-
check_round(leaving_player)
{
if (!g_endround && !task_exists(MAKEZOMBIE_TASK)) // only if no round end and no make_a_zombie task
{
if (fnGetZombies() == 1 && g_zombie[leaving_player]) // last zombie disconnecting
{
static iPlayersnum
iPlayersnum = fnGetAlive() // how many players alive
if (iPlayersnum <= 1) // dont bother
return;
static id
id = fnGetRandomAlive(random_num(1, iPlayersnum)) // pick random one
if (id != leaving_player)
{
static name[32]
get_user_name(id, name, sizeof name - 1)
client_print(0, print_chat, "[ZP] %L", LANG_PLAYER, "LAST_ZOMBIE_LEFT", name)
zombieme(id, 0, 0); // turn him into a zombie
}
else check_round(leaving_player) // call back function until we pick someone else
}
else if (fnGetHumans() == 1 && !g_zombie[leaving_player]) // last human disconnecting
{
static iPlayersnum
iPlayersnum = fnGetAlive() // how many players alive
if (iPlayersnum <= 1) // dont bother
return;
static id
id = fnGetRandomAlive(random_num(1, iPlayersnum)) // pick random one
if (id != leaving_player)
{
static name[32]
get_user_name(id, name, sizeof name - 1)
client_print(0, print_chat, "[ZP] %L", LANG_PLAYER, "LAST_HUMAN_LEFT", name)
humanme(id); // turn him into a human
}
else check_round(leaving_player) // call back function until we pick someone else
}
}
}
// Lightning Effects Task
public lightning_effects()
{
// Lightning style ["a"-"z"]
static lights[2]
get_pcvar_string(cvar_lightning, lights, sizeof lights - 1)
strtolower(lights)
if (lights[0] == 'a') // pitch black mode
{
if (!task_exists(THUNDER_PRE_TASK) && get_pcvar_num(cvar_thunder)) // enable thunderclaps?
{
switch (random_num(0,2))
{
case 0: set_task(get_pcvar_float(cvar_thunder), "thunder_clap1", THUNDER_PRE_TASK)
case 1: set_task(get_pcvar_float(cvar_thunder), "thunder_clap2", THUNDER_PRE_TASK)
case 2: set_task(get_pcvar_float(cvar_thunder), "thunder_clap3", THUNDER_PRE_TASK)
}
}
if (!task_exists(THUNDER_TASK))
engfunc(EngFunc_LightStyle, 0, lights)
}
else
{
engfunc(EngFunc_LightStyle, 0, lights)
remove_task(THUNDER_PRE_TASK)
remove_task(THUNDER_TASK)
}
set_task(5.0, "lightning_effects")
}
// ThunderClap 1
public thunder_clap1()
{
if (g_lights_i == 0) // play sound
PlaySound(sound_thunder[random_num(0, sizeof sound_thunder - 1)])
engfunc(EngFunc_LightStyle, 0, lights_thunder1[g_lights_i])
g_lights_i++
if (g_lights_i < sizeof lights_thunder1)
set_task(0.1, "thunder_clap1", THUNDER_TASK)
else
g_lights_i = 0;
}
// ThunderClap 2
public thunder_clap2()
{
if (g_lights_i == 0) // play sound
PlaySound(sound_thunder[random_num(0, sizeof sound_thunder - 1)])
engfunc(EngFunc_LightStyle, 0, lights_thunder2[g_lights_i])
g_lights_i++
if (g_lights_i < sizeof lights_thunder2)
set_task(0.1, "thunder_clap2", THUNDER_TASK)
else
g_lights_i = 0;
}
// ThunderClap 3
public thunder_clap3()
{
if (g_lights_i == 0) // play sound
PlaySound(sound_thunder[random_num(0, sizeof sound_thunder - 1)])
engfunc(EngFunc_LightStyle, 0, lights_thunder3[g_lights_i])
g_lights_i++
if (g_lights_i < sizeof lights_thunder3)
set_task(0.1, "thunder_clap3", THUNDER_TASK)
else
g_lights_i = 0;
}
#if defined AMBIENCE_SOUNDS
// Ambience Sound Effects Task
public ambience_sound_effects()
{
static isound
isound = random_num(0, sizeof sound_ambience - 1)
if (equal(sound_ambience[isound][strlen(sound_ambience[isound])-4], ".mp3"))
client_cmd(0, "mp3 play sound/%s", sound_ambience[isound])
else
client_cmd(0, "spk %s", sound_ambience[isound])
set_task(sound_ambience_duration[isound], "ambience_sound_effects")
}
#endif
// Flashlight Charge Task
public flashlight_charge(taskid)
{
// Custom flashlight disabled
if (!get_pcvar_num(cvar_cflash))
return;
// No use for this task when flashlight is not avalable
if (!is_user_alive(ID_CHARGE) || g_zombie[ID_CHARGE] || g_survivor[ID_CHARGE])
return;
// Drain or recharge
if (g_flashlight[ID_CHARGE])
g_flashbattery[ID_CHARGE] -= get_pcvar_num(cvar_flashdrain)
else
g_flashbattery[ID_CHARGE] += 5
// 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_UNRELIABLE, g_msgFlashBat, _, ID_CHARGE);
write_byte(g_flashbattery[ID_CHARGE]);
message_end();
return;
}
// Battery depleted
if (g_flashbattery[ID_CHARGE] <= 0)
{
// Turn it off
g_flashlight[ID_CHARGE] = 0;
g_flashbattery[ID_CHARGE] = 0;
// Update flashlight status on HUD
message_begin(MSG_ONE, g_msgFlashlight, _, ID_CHARGE);
write_byte(g_flashlight[ID_CHARGE]);
write_byte(g_flashbattery[ID_CHARGE]);
message_end();
}
else
{
// Update flashlight battery on HUD
message_begin(MSG_ONE_UNRELIABLE, g_msgFlashBat, _, ID_CHARGE);
write_byte(g_flashbattery[ID_CHARGE]);
message_end();
}
// Keep calling back the task
set_task(1.0, "flashlight_charge", taskid);
}
// Remove Spawn Protection Task
public remove_spawn_protection(taskid)
{
if (!is_user_alive(ID_SPAWN)) // not alive
return;
// Remove spawn protection
g_nodamage[ID_SPAWN] = false;
set_pev(ID_SPAWN, pev_effects, pev(ID_SPAWN, pev_effects) & ~EF_NODRAW)
}
// Madness Over Task
public madness_over(taskid)
{
g_nodamage[ID_BLOOD] = false;
}
// Turn Off Game Flashlight
public turn_off_flashlight(id)
{
if (!is_user_alive(id) || (!g_zombie[id] && !g_survivor[id]))
return;
// Check if flashlight is on
if (pev(id, pev_effects) & EF_DIMLIGHT)
{
// Turn it off
set_pev(id, pev_effects, pev(id, pev_effects) & ~EF_DIMLIGHT);
// Update HUD
message_begin(MSG_ONE, g_msgFlashlight, _, id);
write_byte(0);
write_byte(0);
message_end();
}
}
// Infection Grenade Explosion
public infection_explode(const args[1])
{
// args[0] = entity id
static ent
ent = args[0]
// invalid entity
if (!pev_valid(ent)) return;
// get origin
static origin[3], Float:originF[3]
pev(ent, pev_origin, originF);
FVecIVec(originF, origin);
// explosion
create_blast(origin);
// infection nade sound
engfunc(EngFunc_EmitSound, ent, CHAN_WEAPON, grenade_infect[random_num(0, sizeof grenade_infect - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
// round ended (bugfix)
if (g_endround) return;
// get grenade's owner
static attacker
attacker = pev(ent, pev_owner);
g_models_i = 0.0 // reset model change count
g_teams_i = 0.0 // reset team change count
// collisions
static victim
victim = -1;
while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, 240.0)) != 0)
{
// only effect alive non-spawnprotected humans
if (!is_user_alive(victim) || g_zombie[victim] || g_nodamage[victim])
continue;
if (fnGetHumans() == 1) // last human can't be infected
{
ExecuteHamB(Ham_Killed, victim, attacker, 0) // now it's killed
continue;
}
// infection nade sound
engfunc(EngFunc_EmitSound, victim, CHAN_VOICE, grenade_infect_player[random_num(0, sizeof grenade_infect_player - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
zombieme(victim, 0, 1) // turn into zombie
SendDeathMsg(attacker, victim); // send death notice
UpdateFrags(attacker, victim); // add corresponding frags & deaths
FixDeadAttrib(victim) // fix the "dead" attrib on scoreboard
// ammo packs given to zombie for infection
g_ammopacks[attacker] += get_pcvar_num(cvar_ammoinfect)
// infection HP bonus
if (g_zombieclass[attacker] != 4)
fm_set_user_health(attacker, pev(attacker, pev_health)+get_pcvar_num(cvar_bonushp))
else
fm_set_user_health(attacker, pev(attacker, pev_health)+(get_pcvar_num(cvar_bonushp)*3))
}
// get rid of the old grenade
engfunc(EngFunc_RemoveEntity, ent)
}
// Fire Grenade Explosion
public fire_explode(const args[1])
{
// args[0] = entity id
static ent
ent = args[0]
// invalid entity
if (!pev_valid(ent)) return;
// get origin
static origin[3], Float:originF[3]
pev(ent, pev_origin, originF);
FVecIVec(originF, origin);
// explosion
create_blast2(origin);
// flame nade sound
engfunc(EngFunc_EmitSound, ent, CHAN_WEAPON, grenade_fire[random_num(0, sizeof grenade_fire - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
// collisions
static victim
victim = -1;
while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, 240.0)) != 0)
{
// only effect alive zombies (nemesis takes less burning)
if (!is_user_alive(victim) || !g_zombie[victim] || g_nodamage[victim])
continue;
// our task params
static params[2]
params[0] = victim; // target
if (g_nemesis[victim]) // fire duration
params[1] = get_pcvar_num(cvar_fireduration);
else
params[1] = get_pcvar_num(cvar_fireduration)*5;
// set burning task on him
set_task(0.1, "burning_flame", victim+BLOOD_TASK, params, sizeof params)
}
// get rid of the old grenade
engfunc(EngFunc_RemoveEntity, ent)
}
// Frost Grenade Explosion
public frost_explode(const args[1])
{
// args[0] = entity id
static ent
ent = args[0]
// invalid entity
if (!pev_valid(ent)) return;
// get origin
static origin[3], Float:originF[3]
pev(ent, pev_origin, originF);
FVecIVec(originF, origin);
// explosion
create_blast3(origin);
// frost nade explode sound
engfunc(EngFunc_EmitSound, ent, CHAN_WEAPON, grenade_frost[random_num(0, sizeof grenade_frost - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
// collisions
static victim
victim = -1;
while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, 240.0)) != 0)
{
// only effect alive unfrozen zombies (nemesis is immune)
if (!is_user_alive(victim) || !g_zombie[victim] || g_nemesis[victim] || g_frozen[victim] || g_nodamage[victim])
continue;
// light blue glow while frozen
#if defined HANDLE_MODELS_ON_SEPARATE_ENT
fm_set_rendering(fm_find_ent_by_owner(-1, "player_model", victim), kRenderFxGlowShell, 0, 100, 200, kRenderNormal, 25)
#else
fm_set_rendering(victim, kRenderFxGlowShell, 0, 100, 200, kRenderNormal, 25)
#endif
// play freeze sound
engfunc(EngFunc_EmitSound, victim, CHAN_BODY, grenade_frost_player[random_num(0, sizeof grenade_frost_player - 1)], 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(0x0004); // flags: FFADE_STAYOUT
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
// freeze the victim, and 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 old grenade
engfunc(EngFunc_RemoveEntity, ent)
}
// Remove freeze task
public remove_freeze(id)
{
if (!is_user_alive(id) || !g_frozen[id]) // not alive / not frozen anymore
return;
// unfreeze
g_frozen[id] = false;
// restore normal gravity
if (g_zombie[id])
set_pev(id, pev_gravity, get_pcvar_float(cvar_gravity)*zombie_multigrav[g_zombieclass[id]]/100)
else
set_pev(id, pev_gravity, get_pcvar_float(cvar_humangravity))
// play the broken glass sound
engfunc(EngFunc_EmitSound, id, CHAN_BODY, grenade_frost_break[random_num(0, sizeof grenade_frost_break - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
// remove glow (or just replace it if it's a rage zombie)
#if defined HANDLE_MODELS_ON_SEPARATE_ENT
if (g_zombie[id] && g_zombieclass[id] == 5)
fm_set_rendering(fm_find_ent_by_owner(-1, "player_model", id), kRenderFxGlowShell, 0, 255, 0, kRenderNormal, 25)
else
fm_set_rendering(fm_find_ent_by_owner(-1, "player_model", id))
#else
if (g_zombie[id] && g_zombieclass[id] == 5)
fm_set_rendering(id, kRenderFxGlowShell, 0, 255, 0, kRenderNormal, 25)
else
fm_set_rendering(id)
#endif
// clear screen fade
message_begin(MSG_ONE, g_msgScreenFade, _, id);
write_short(0); // duration
write_short(0); // hold time
write_short(0); // flags
write_byte(0); // red
write_byte(0); // green
write_byte(0); // blue
write_byte(0); // alpha
message_end();
// get player's origin
static origin[3], Float:originF[3]
pev(id, pev_origin, originF)
FVecIVec(originF, origin)
// glass shatter
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BREAKMODEL);
write_coord(origin[0]); // x
write_coord(origin[1]); // y
write_coord(origin[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(0x01); // flags: BREAK_GLASS
message_end();
}
// Flare "Explosion"
public flare_explode(const args[5])
{
// args[0] = entity id
// args[1] = duration
// args[2] = r
// args[3] = g
// args[4] = b
static ent
ent = args[0]
// invalid entity
if (!pev_valid(ent)) return;
// Light up when it's stopped on ground
if ((pev(ent, pev_flags) & FL_ONGROUND) && fm_get_speed(ent) < 10)
{
// flare sound
engfunc(EngFunc_EmitSound, ent, CHAN_WEAPON, grenade_flare[random_num(0, sizeof grenade_flare - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
// prevent smokegrenade from exploding
set_pev(ent, pev_nextthink, get_gametime()+10.0);
// call our lightning task
set_task(0.1, "flare_lightning", NADES_TASK, args, sizeof args)
}
else
{
// prevent smokegrenade from exploding
set_pev(ent, pev_nextthink, get_gametime()+10.0);
// not on ground, keep looping
set_task(0.5, "flare_explode", NADES_TASK, args, sizeof args)
}
}
// Remove Stuff Task
public remove_stuff()
{
static ent
// Doors
if (get_pcvar_num(cvar_removedoors) > 0) // remove rotating doors only
{
ent = -1;
while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "func_door_rotating")) != 0)
engfunc(EngFunc_SetOrigin, ent, Float:{8192.0,8192.0,8192.0})
}
if (get_pcvar_num(cvar_removedoors) > 1) // remove all doors
{
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) // disable light triggers
{
dllfunc(DLLFunc_Use, ent, 0); // turn off the light
set_pev(ent, pev_targetname, 0) // prevent it from being triggered
}
}
}
// Set Custom Weapon Models
public replace_models(id)
{
if (!is_user_alive(id)) // not alive
return;
if (g_currentweapon[id] == CSW_KNIFE) // custom knife models
{
if (g_zombie[id] && !g_newround && !g_endround)
{
if (g_nemesis[id])
{
set_pev(id, pev_viewmodel2, model_vknife_nemesis)
set_pev(id, pev_weaponmodel2, model_pknife_nemesis)
}
else
{
set_pev(id, pev_viewmodel2, model_vknife_zombie)
set_pev(id, pev_weaponmodel2, model_pknife_zombie)
}
}
else
{
set_pev(id, pev_viewmodel2, "models/v_knife.mdl")
set_pev(id, pev_weaponmodel2, "models/p_knife.mdl")
}
}
else if (g_currentweapon[id] == CSW_HEGRENADE) // infection bomb or fire grenade
{
if (g_zombie[id] && !g_newround && !g_endround)
set_pev(id, pev_viewmodel2, model_grenade_infect)
else
set_pev(id, pev_viewmodel2, model_grenade_fire)
}
else if (g_currentweapon[id] == CSW_FLASHBANG) // frost grenade
set_pev(id, pev_viewmodel2, model_grenade_frost)
else if (g_currentweapon[id] == CSW_SMOKEGRENADE) // flare grenade
set_pev(id, pev_viewmodel2, model_grenade_flare)
#if defined HANDLE_MODELS_ON_SEPARATE_ENT
static model[64]
pev(id, pev_weaponmodel2, model, sizeof model - 1) // get weapon model
fm_set_weapon_model_ent(id, model) // set correct model on weapon_model entity
#endif
}
// Reset Player Vars
reset_vars(id, resetall)
{
g_zombie[id] = false
g_nemesis[id] = false
g_survivor[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] = 0
g_flashlight[id] = 0
g_flashbattery[id] = 100
g_canbuy[id] = true
if (resetall)
{
g_ammopacks[id] = 5
g_zombieclass[id] = -1
g_zombieclassnext[id] = 0
g_damagedealt[id] = 0
}
}
// Set spectators nightvision
public spec_nvision(id)
{
if (!is_user_connected(id) || is_user_alive(id) || is_user_bot(id)) // not connected, not dead, or bot
return;
g_nvision[id] = true; // give spectator nvision
g_nvisionenabled[id] = 1
if (get_pcvar_num(cvar_cnvg)) // custom nvg?
{
remove_task(id+NVISION_TASK);
set_user_nvision(id+NVISION_TASK)
}
else set_user_gnvision(id, 1)
}
// Show HUD Task
public ShowHUD(taskid)
{
static id
id = ID_SHOWHUD;
if (!is_user_alive(id)) // player dead
{
id = pev(id, pev_iuser2); // get spectating target
if (!is_user_alive(id)) // target not alive
{
set_task(1.0 , "ShowHUD" , taskid) // call back the task
return;
}
}
static class[16], red, green, blue
if (!g_zombie[id])
{
red = 0
green = 0
blue = 255
if (g_survivor[id])
copy(class, sizeof class - 1, "CLASS_SURVIVOR")
else
copy(class, sizeof class - 1, "CLASS_HUMAN")
}
else
{
red = 200
green = 250
blue = 0
if (g_nemesis[id])
copy(class, sizeof class - 1, "CLASS_NEMESIS")
else
{
switch (g_zombieclass[id])
{
case 0: copy(class, sizeof class - 1, "CLASS_ZOMBIE1")
case 1: copy(class, sizeof class - 1, "CLASS_ZOMBIE2")
case 2: copy(class, sizeof class - 1, "CLASS_ZOMBIE3")
case 3: copy(class, sizeof class - 1, "CLASS_ZOMBIE4")
case 4: copy(class, sizeof class - 1, "CLASS_ZOMBIE5")
case 5: copy(class, sizeof class - 1, "CLASS_ZOMBIE6")
}
}
}
if (id != ID_SHOWHUD) // spectating
{
static name[32]
get_user_name(id, name, sizeof name - 1) // get target name
set_hudmessage(255, 255, 255, 0.7, 0.8, 0, 6.0, 1.1, 0.0, 0.0, -1)
ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync2, "%L %s^nHP: %d - %L %L", ID_SHOWHUD, "SPECTATING", name, pev(id, pev_health), ID_SHOWHUD, "CLASS_CLASS", ID_SHOWHUD, class) // show name, health, and class
}
else // player's own HUD display
{
set_hudmessage(red, green, blue, 0.02, 0.9, 0, 6.0, 1.1, 0.0, 0.0, -1)
ShowSyncHudMsg(id, g_MsgSync2, "%L: %d - %L %L - %L %d", id, "ZOMBIE_ATTRIB1", pev(id, pev_health), id, "CLASS_CLASS", id, class, id, "AMMO_PACKS1", g_ammopacks[id]) // show health, class and ammo
}
set_task(1.0, "ShowHUD", taskid) // keep calling back the task
}
// Make zombies leave footsteps and bloodstains on the floor task
public make_blood(taskid)
{
// only bleed when moving on ground
if (fm_get_speed(ID_BLOOD) < 100 || !(pev(ID_BLOOD, pev_flags) & FL_ONGROUND))
{
set_task(0.5, "make_blood", taskid) // keep calling back the task
return;
}
// get user origin
static origin[3], Float:originF[3]
pev(ID_BLOOD, pev_origin, originF);
FVecIVec(originF, origin);
// if ducking set a little lower
if (pev(ID_BLOOD, pev_bInDuck))
origin[2] -= 18
else
origin[2] -= 36
// send the decal message
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_WORLDDECAL)
write_coord(origin[0]) // x
write_coord(origin[1]) // y
write_coord(origin[2]) // z
write_byte(zombie_decals[random_num(0, sizeof zombie_decals - 1)] + (g_czero*12)) // random decal number (offsets +12 for CZ)
message_end()
// keep calling back the task
set_task(0.5, "make_blood", taskid);
}
// Play idle zombie sounds
public zombie_play_idle(taskid)
{
if (g_endround || g_newround) // round ended/new one starting
return;
if (g_lastzombie[ID_BLOOD]) // last zombie sound
engfunc(EngFunc_EmitSound, ID_BLOOD, CHAN_VOICE, zombie_idle_last[random_num(0, sizeof zombie_idle_last - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
else
engfunc(EngFunc_EmitSound, ID_BLOOD, CHAN_VOICE, zombie_idle[random_num(0, sizeof zombie_idle - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
set_task(random_float(60.0, 120.0), "zombie_play_idle", taskid);
}
// Place a user at a random spawn
do_random_spawn(id)
{
if (!g_spawnCount) // no spawns
return;
static sp_index, i
sp_index = random_num(0, g_spawnCount-1); // random spawn
for (i = sp_index + 1; i != 999; i++)
{
// start over when we reach the end
if (i >= g_spawnCount) i = 0;
// loop completed, no free space found
if (i == sp_index) break;
// free spawn space?
if (is_hull_vacant(g_spawns[i],HULL_HUMAN))
{
engfunc(EngFunc_SetOrigin, id, g_spawns[i]);
break;
}
}
}
// Get Zombies -returns alive zombies number-
fnGetZombies()
{
static iZombies, id
iZombies = 0 // our counter
for (id = 1; id <= g_maxplayers; id++)
{
if (is_user_alive(id) && g_zombie[id])
iZombies++
}
return iZombies
}
// Get Humans -returns alive humans number-
fnGetHumans()
{
static iHumans, id
iHumans = 0 // our counter
for (id = 1; id <= g_maxplayers; id++)
{
if (is_user_alive(id) && !g_zombie[id])
iHumans++
}
return iHumans
}
// Get Alive -returns alive players number-
fnGetAlive()
{
static iAlive, id
iAlive = 0 // our counter
for (id = 1; id <= g_maxplayers; id++)
{
if (is_user_alive(id))
iAlive++
}
return iAlive
}
// Get Playing -returns number of users playing-
fnGetPlaying()
{
static iPlaying, id
iPlaying = 0 // our counter
for (id = 1; id <= g_maxplayers; id++)
{
if (is_user_connected(id))
{
if (fm_get_user_team(id) != CS_TEAM_SPECTATOR && fm_get_user_team(id) != CS_TEAM_UNASSIGNED)
iPlaying++
}
}
return iPlaying
}
// Get Random Alive -returns index of alive player number n -
fnGetRandomAlive(n)
{
static iAlive, id
iAlive = 0 // our counter
for (id = 1; id <= g_maxplayers; id++)
{
if (is_user_alive(id))
iAlive++
if (iAlive == n)
return id
}
return -1;
}
// Last Zombie Check -check for last zombie and set its flag-
public fnCheckLastZombie()
{
static id
for (id = 1; id <= g_maxplayers; id++)
{
if (is_user_alive(id) && g_zombie[id] && fnGetZombies() == 1) // last zombie
g_lastzombie[id] = true
else
g_lastzombie[id] = false
if (is_user_alive(id) && !g_zombie[id] && !g_survivor[id] && fnGetHumans() == 1) // last human
{
if (!g_lasthuman[id]) 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 into the database
save_stats(id)
{
static name[64]
get_user_name(id, name, sizeof name - 1) // get his name
// check whether there is another record already in that slot
if (db_name[id][0] && !equal(name, db_name[id]))
{
if (db_slot_i >= sizeof db_name) // if DB size is exceeded
db_slot_i = g_maxplayers+1 // write over old records
// move previous record onto an additional save slot
copy(db_name[db_slot_i], 63, 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], 63, name) // store the name
db_ammopacks[id] = g_ammopacks[id] // store ammo packs
db_zombieclass[id] = g_zombieclassnext[id] // store zombie type
}
// Load player's stats from the database (if a record is found)
load_stats(id)
{
static name[64], i
get_user_name(id, name, sizeof name - 1) // get player name
for (i = 0; i < sizeof db_name; i++) // look for a matching record in the DB
{
if (equal(name, db_name[i]))
{
g_ammopacks[id] = db_ammopacks[i];
g_zombieclass[id] = db_zombieclass[i];
g_zombieclassnext[id] = db_zombieclass[i];
return;
}
}
}
// Checks if a player is allowed to be a zombie
allowed_zombie(id)
{
if (!is_user_alive(id) || g_zombie[id] || g_swarmround || g_nemround || g_survround || g_endround || task_exists(WELCOMEMSG_TASK) || (!g_zombie[id] && fnGetHumans() == 1))
return false
return true
}
// Checks if a player is allowed to be a human
allowed_human(id)
{
if (!is_user_alive(id) || !g_zombie[id] || g_swarmround || g_nemround || g_survround || g_endround || (g_zombie[id] && fnGetZombies() == 1))
return false
return true
}
// Checks if a player is allowed to be a survivor
allowed_survivor(id)
{
if (!is_user_alive(id) || !get_pcvar_num(cvar_surv) || g_endround || !g_newround || task_exists(WELCOMEMSG_TASK))
return false
return true
}
// Checks if a player is allowed to be a nemesis
allowed_nemesis(id)
{
if (!is_user_alive(id) || !get_pcvar_num(cvar_nem) || g_endround || !g_newround || task_exists(WELCOMEMSG_TASK))
return false
return true
}
// Checks if a player is allowed to respawn
allowed_respawn(id)
{
if (!is_user_connected(id) || is_user_alive(id) || g_endround || g_survround || g_swarmround || g_nemround)
return false
return true
}
// Checks if swarm mode is allowed
allowed_swarm()
{
if (!get_pcvar_num(cvar_swarm) || g_endround || !g_newround || task_exists(WELCOMEMSG_TASK))
return false
return true
}
// Checks if multi infection mode is allowed
allowed_multi()
{
if (!get_pcvar_num(cvar_multi) || g_endround || !g_newround || task_exists(WELCOMEMSG_TASK))
return false
return true
}
// Admin Command. zp_zombie
command_zombie(id, player)
{
static name1[32], name2[32]
get_user_name(id, name1, sizeof name1 - 1)
get_user_name(player, name2, sizeof name2 - 1)
switch (get_pcvar_num(cvar_showactivity)) // show activity?
{
case 1: client_print(0, print_chat, "ADMIN - %s %L", name2, LANG_PLAYER, "CMD_INFECT")
case 2: client_print(0, print_chat, "ADMIN %s - %s %L", name1, name2, LANG_PLAYER, "CMD_INFECT")
}
if (get_pcvar_num(cvar_logcommands)) // Log to Zombie Plague log file?
{
static logdata[100]
formatex(logdata, sizeof logdata - 1, "ADMIN %s - %s %L (Players: %d/%d)", name1, name2, LANG_SERVER, "CMD_INFECT", fnGetPlaying(), g_maxplayers)
log_to_file("zombieplague.log", logdata)
}
if (g_newround) // new round, set as first zombie
{
remove_task(MAKEZOMBIE_TASK)
make_a_zombie(player, 0, 0, 0, 0);
}
else
{
zombieme(player, 0, 0) // just infect
}
}
// Admin Command. zp_human
command_human(id, player)
{
static name1[32], name2[32]
get_user_name(id, name1, sizeof name1 - 1)
get_user_name(player, name2, sizeof name2 - 1)
switch (get_pcvar_num(cvar_showactivity)) // show activity?
{
case 1: client_print(0, print_chat, "ADMIN - %s %L", name2, LANG_PLAYER, "CMD_DISINFECT")
case 2: client_print(0, print_chat, "ADMIN %s - %s %L", name1, name2, LANG_PLAYER, "CMD_DISINFECT")
}
if (get_pcvar_num(cvar_logcommands)) // Log to Zombie Plague log file?
{
static logdata[100]
formatex(logdata, sizeof logdata - 1, "ADMIN %s - %s %L (Players: %d/%d)", name1, name2, LANG_SERVER,"CMD_DISINFECT", fnGetPlaying(), g_maxplayers)
log_to_file("zombieplague.log", logdata)
}
humanme(player) // turn back to human
}
// Admin Command. zp_survivor
command_survivor(id, player)
{
static name1[32], name2[32]
get_user_name(id, name1, sizeof name1 - 1)
get_user_name(player, name2, sizeof name2 - 1)
switch (get_pcvar_num(cvar_showactivity)) // show activity?
{
case 1: client_print(0, print_chat, "ADMIN - %s %L", name2, LANG_PLAYER, "CMD_SURVIVAL")
case 2: client_print(0, print_chat, "ADMIN %s - %s %L", name1, name2, LANG_PLAYER, "CMD_SURVIVAL")
}
if (get_pcvar_num(cvar_logcommands)) // Log to Zombie Plague log file?
{
static logdata[100]
formatex(logdata, sizeof logdata - 1, "ADMIN %s - %s %L (Players: %d/%d)", name1, name2, LANG_SERVER,"CMD_SURVIVAL", fnGetPlaying(), g_maxplayers)
log_to_file("zombieplague.log", logdata)
}
remove_task(MAKEZOMBIE_TASK)
make_a_zombie(player,0,1, 0, 0)
}
// Admin Command. zp_nemesis
command_nemesis(id, player)
{
static name1[32], name2[32]
get_user_name(id, name1, sizeof name1 - 1)
get_user_name(player, name2, sizeof name2 - 1)
switch (get_pcvar_num(cvar_showactivity)) // show activity?
{
case 1: client_print(0, print_chat, "ADMIN - %s %L", name2, LANG_PLAYER, "CMD_NEMESIS")
case 2: client_print(0, print_chat, "ADMIN %s - %s %L", name1, name2, LANG_PLAYER, "CMD_NEMESIS")
}
if (get_pcvar_num(cvar_logcommands)) // Log to Zombie Plague log file?
{
static logdata[100]
formatex(logdata, sizeof logdata - 1, "ADMIN %s - %s %L (Players: %d/%d)", name1, name2, LANG_SERVER,"CMD_NEMESIS", fnGetPlaying(), g_maxplayers)
log_to_file("zombieplague.log", logdata)
}
remove_task(MAKEZOMBIE_TASK)
make_a_zombie(player, 1, 0, 0, 0) // turn into a Nemesis zombie
}
// Admin Command. zp_swarm
command_swarm(id)
{
static name1[32]
get_user_name(id, name1, sizeof name1 - 1)
switch (get_pcvar_num(cvar_showactivity)) // show activity?
{
case 1: client_print(0, print_chat, "ADMIN - %L", LANG_PLAYER, "CMD_SWARM")
case 2: client_print(0, print_chat, "ADMIN %s - %L", name1, LANG_PLAYER, "CMD_SWARM")
}
if (get_pcvar_num(cvar_logcommands)) // Log to Zombie Plague log file?
{
static logdata[100]
formatex(logdata, sizeof logdata - 1, "ADMIN %s - %L (Players: %d/%d)", name1, LANG_SERVER, "CMD_SWARM", fnGetPlaying(), g_maxplayers)
log_to_file("zombieplague.log", logdata)
}
remove_task(MAKEZOMBIE_TASK)
make_a_zombie(0, 0, 0, 1, 0) // Call Swarm Mode
}
// Admin Command. zp_multi
command_multi(id)
{
static name1[32]
get_user_name(id, name1, sizeof name1 - 1)
switch (get_pcvar_num(cvar_showactivity)) // show activity?
{
case 1: client_print(0, print_chat, "ADMIN - %L", LANG_PLAYER, "CMD_MULTI")
case 2: client_print(0, print_chat, "ADMIN %s - %L", name1, LANG_PLAYER, "CMD_MULTI")
}
if (get_pcvar_num(cvar_logcommands)) // Log to Zombie Plague log file?
{
static logdata[100]
formatex(logdata, sizeof logdata - 1, "ADMIN %s - %L (Players: %d/%d)", name1, LANG_SERVER,"CMD_MULTI", fnGetPlaying(), g_maxplayers)
log_to_file("zombieplague.log", logdata)
}
remove_task(MAKEZOMBIE_TASK)
make_a_zombie(0, 0, 0, 0, 1) // Call Multi Infection
}
// Admin Command. zp_respawn
command_respawn(id, player)
{
static name1[32], name2[32]
get_user_name(id, name1, sizeof name1 - 1)
get_user_name(player, name2, sizeof name2 - 1)
switch (get_pcvar_num(cvar_showactivity)) // show activity?
{
case 1: client_print(0, print_chat, "ADMIN - %s %L", name2, LANG_PLAYER, "CMD_RESPAWN")
case 2: client_print(0, print_chat, "ADMIN %s - %s %L", name1, name2, LANG_PLAYER, "CMD_RESPAWN")
}
if (get_pcvar_num(cvar_logcommands)) // Log to Zombie Plague log file?
{
static logdata[100]
formatex(logdata, sizeof logdata - 1, "ADMIN %s - %s %L (Players: %d/%d)", name1, name2, LANG_SERVER, "CMD_RESPAWN", fnGetPlaying(), g_maxplayers)
log_to_file("zombieplague.log", logdata)
}
respawn_player(player+SPAWN_TASK);
}
/*================================================================================
[Custom Messages]
=================================================================================*/
// Custom Night Vision
public set_user_nvision(taskid)
{
// Not meant to have nvision or not enabled
if (!g_nvision[ID_NVISION] || !g_nvisionenabled[ID_NVISION])
return;
// Get player origin
static origin[3], Float:originF[3]
pev(ID_NVISION, pev_origin, originF)
FVecIVec(originF, origin);
// Nightvision message
message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, _, ID_NVISION);
write_byte(TE_DLIGHT);
write_coord(origin[0]); //x
write_coord(origin[1]); //y
write_coord(origin[2]); //z
write_byte(get_pcvar_num(cvar_nvgsize)); //visible distance
write_byte((g_nemround || g_nodamage[ID_NVISION]) ? get_pcvar_num(cvar_nemnvgcolor[0]) : get_pcvar_num(cvar_nvgcolor[0])); //red
write_byte((g_nemround || g_nodamage[ID_NVISION]) ? get_pcvar_num(cvar_nemnvgcolor[1]) : get_pcvar_num(cvar_nvgcolor[1])); //green
write_byte((g_nemround || g_nodamage[ID_NVISION]) ? get_pcvar_num(cvar_nemnvgcolor[2]) : get_pcvar_num(cvar_nvgcolor[2])); //blue
write_byte(2); //life
write_byte(0); //decay rate
message_end();
// Keep calling back the task
set_task(0.1, "set_user_nvision", taskid)
}
// Game Nightvision
set_user_gnvision(id, toggle)
{
message_begin(MSG_ONE, g_msgNVGToggle, _, id)
write_byte(toggle) // 1 On - 0 Off
message_end()
}
// Custom Flashlight
public set_user_flashlight(id)
{
// Not meant to have flashlight or not enabled
if (!get_pcvar_num(cvar_cflash) || !is_user_connected(id) || !g_flashlight[id])
return;
// Disable flashlight if it shouldn't be available
if (!is_user_alive(id) || g_zombie[id] || g_survivor[id])
{
// Turn it off
g_flashlight[id] = 0;
g_flashbattery[id] = 0;
// Update flashlight HUD
message_begin(MSG_ONE, g_msgFlashlight, _, id);
write_byte(g_flashlight[id]);
write_byte(g_flashbattery[id]);
message_end();
return;
}
// Get player and aiming origins
static origin[3], Float:originF[3], destorigin[3], Float:destoriginF[3]
pev(id, pev_origin, originF)
FVecIVec(originF, origin)
fm_get_aim_origin(id, destoriginF)
FVecIVec(destoriginF, destorigin)
// Make sure it doesn't exceed the max distance
if (get_distance(origin, destorigin) < get_pcvar_num(cvar_flashdist))
{
// Flashlight message
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_DLIGHT);
write_coord(destorigin[0]); // X
write_coord(destorigin[1]); // Y
write_coord(destorigin[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();
}
// Keep calling back the task
set_task(0.1, "set_user_flashlight", id)
}
// Screen Fade Effect on infection
fadeFX(id)
{
message_begin(MSG_ONE_UNRELIABLE, g_msgScreenFade, _, id)
write_short(4096) // Duration
write_short(0) // Hold time
write_short(0x0000) // Fade type
write_byte(g_nemesis[id] ? get_pcvar_num(cvar_nemnvgcolor[0]) : get_pcvar_num(cvar_nvgcolor[0])); // Red
write_byte(g_nemesis[id] ? get_pcvar_num(cvar_nemnvgcolor[1]) : get_pcvar_num(cvar_nvgcolor[1])); // Green
write_byte(g_nemesis[id] ? get_pcvar_num(cvar_nemnvgcolor[2]) : get_pcvar_num(cvar_nvgcolor[2])); // Blue
write_byte (255) // Alpha
message_end()
}
// Infection special effects
public infectionFX(id)
{
if (!is_user_alive(id)) // not alive
return;
// get player origin
static origin[3], Float:originF[3]
pev(id, pev_origin, originF)
FVecIVec(originF, origin)
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_DLIGHT);
write_coord(origin[0]); //x
write_coord(origin[1]); //y
write_coord(origin[2]); //z
write_byte(20); //visible distance
write_byte((g_nemesis[id] || g_nodamage[id]) ? get_pcvar_num(cvar_nemnvgcolor[0]) : get_pcvar_num(cvar_nvgcolor[0])); //red
write_byte((g_nemesis[id] || g_nodamage[id]) ? get_pcvar_num(cvar_nemnvgcolor[1]) : get_pcvar_num(cvar_nvgcolor[1])); //green
write_byte((g_nemesis[id] || g_nodamage[id]) ? get_pcvar_num(cvar_nemnvgcolor[2]) : get_pcvar_num(cvar_nvgcolor[2])); //blue
write_byte(2); //life
write_byte(0); //decay rate
message_end();
if (!g_nemesis[id] && !g_nodamage[id]) // skip for nemesis or zombie madness
{
message_begin(MSG_BROADCAST, SVC_TEMPENTITY); // tracers
write_byte(TE_IMPLOSION);
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();
message_begin(MSG_BROADCAST, SVC_TEMPENTITY); // particles
write_byte(TE_PARTICLEBURST);
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();
}
else // keep sending for nemesis/madness aura
set_task(0.1, "infectionFX", id)
}
// Flare Lightning
public flare_lightning(args[5])
{
// args[0] = entity id
// args[1] = duration
// args[2] = r
// args[3] = g
// args[4] = b
static ent
ent = args[0]
// invalid entity
if (!pev_valid(ent)) return;
if (args[1] <= 0) // flare depleted -clean up the mess-
{
engfunc(EngFunc_RemoveEntity, ent)
return;
}
// get origin
static origin[3], Float:originF[3]
pev(ent, pev_origin, originF)
FVecIVec(originF, origin)
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_DLIGHT);
write_coord(origin[0]); //x
write_coord(origin[1]); //y
write_coord(origin[2]); //z
write_byte(get_pcvar_num(cvar_flaresize)); //visible distance
write_byte(args[2]); //red
write_byte(args[3]); //green
write_byte(args[4]); //blue
write_byte(51); //life
write_byte(args[1] < 2 ? 3 : 0); //decay rate
message_end();
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_SPARKS);
write_coord(origin[0]); // x
write_coord(origin[1]); // y
write_coord(origin[2]); // z
message_end();
// decrease task cycle count
args[1]--
// prevent smokegrenade from exploding
set_pev(ent, pev_nextthink, get_gametime()+10.0);
// keep sending flare messaegs
set_task(5.0, "flare_lightning", NADES_TASK, args, sizeof args)
}
// Burning Flames
public burning_flame(args[2])
{
// args[0] = player id
// args[1] = cycles left (duration)
static id
id = args[0]
// not alive - madness mode - in water - burning stopped
if (!is_user_alive(id) || g_nodamage[id] || pev(id, pev_flags) & FL_INWATER || args[1] < 1)
return;
if (!random_num(0, 20) && !g_nemesis[id]) // randomly play burning zombie scream sounds
engfunc(EngFunc_EmitSound, id, CHAN_VOICE, grenade_fire_player[random_num(0, sizeof grenade_fire_player - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM)
// take damage from the fire
if (pev(id, pev_health) > get_pcvar_num(cvar_firedamage))
fm_set_user_health(id, pev(id, pev_health) - get_pcvar_num(cvar_firedamage))
// get player origin
static origin[3], Float:originF[3]
pev(id, pev_origin, originF)
FVecIVec(originF, origin)
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_SPRITE);
write_coord(-5+origin[0]+random_num(0, 10)) // x
write_coord(-5+origin[1]+random_num(0, 10)) // y
write_coord(-10+origin[2]+random_num(0, 20)) // z
write_short(g_flameSpr) // sprite name
write_byte(random_num(5,10)) // scale
write_byte(200) // brightness
message_end()
// decrease task cycle count
args[1]--;
// keep sending flame messaegs
set_task(0.2, "burning_flame", id+BLOOD_TASK, args, sizeof args)
}
// Infection Grenade: Green Blast
create_blast(const origin[3])
{
// smallest ring
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BEAMCYLINDER);
write_coord(origin[0]); // start X
write_coord(origin[1]); // start Y
write_coord(origin[2]); // start Z
write_coord(origin[0]); // something X
write_coord(origin[1]); // something Y
write_coord(origin[2] + 385); // something Z
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
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BEAMCYLINDER);
write_coord(origin[0]); // start X
write_coord(origin[1]); // start Y
write_coord(origin[2]); // start Z
write_coord(origin[0]); // something X
write_coord(origin[1]); // something Y
write_coord(origin[2] + 470); // something Z
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
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BEAMCYLINDER);
write_coord(origin[0]); // start X
write_coord(origin[1]); // start Y
write_coord(origin[2]); // start Z
write_coord(origin[0]); // something X
write_coord(origin[1]); // something Y
write_coord(origin[2] + 555); // something Z
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 origin[3])
{
// smallest ring
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BEAMCYLINDER);
write_coord(origin[0]); // start X
write_coord(origin[1]); // start Y
write_coord(origin[2]); // start Z
write_coord(origin[0]); // something X
write_coord(origin[1]); // something Y
write_coord(origin[2] + 385); // something Z
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
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BEAMCYLINDER);
write_coord(origin[0]); // start X
write_coord(origin[1]); // start Y
write_coord(origin[2]); // start Z
write_coord(origin[0]); // something X
write_coord(origin[1]); // something Y
write_coord(origin[2] + 470); // something Z
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
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BEAMCYLINDER);
write_coord(origin[0]); // start X
write_coord(origin[1]); // start Y
write_coord(origin[2]); // start Z
write_coord(origin[0]); // something X
write_coord(origin[1]); // something Y
write_coord(origin[2] + 555); // something Z
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 origin[3])
{
// smallest ring
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BEAMCYLINDER);
write_coord(origin[0]); // start X
write_coord(origin[1]); // start Y
write_coord(origin[2]); // start Z
write_coord(origin[0]); // something X
write_coord(origin[1]); // something Y
write_coord(origin[2] + 385); // something Z
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
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BEAMCYLINDER);
write_coord(origin[0]); // start X
write_coord(origin[1]); // start Y
write_coord(origin[2]); // start Z
write_coord(origin[0]); // something X
write_coord(origin[1]); // something Y
write_coord(origin[2] + 470); // something Z
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
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BEAMCYLINDER);
write_coord(origin[0]); // start X
write_coord(origin[1]); // start Y
write_coord(origin[2]); // start Z
write_coord(origin[0]); // something X
write_coord(origin[1]); // something Y
write_coord(origin[2] + 555); // something Z
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) // send message to everyone
write_byte(id) // target
write_byte(0) // 0 nothing - (1<<0) dead
message_end()
}
// Send Death Message for Zombies
SendDeathMsg(attacker, victim)
{
message_begin(MSG_BROADCAST, g_msgDeathMsg)
write_byte(attacker) // killer (0 - world)
write_byte(victim) // victim
write_byte(1) // headshot flag
write_string("infection") // killer's weapon
message_end()
}
// Update Player Frags
UpdateFrags(attacker, victim)
{
// set attacker frags
set_pev(attacker, pev_frags, float(pev(attacker, pev_frags) + 1))
// Update scoreboard with attacker info
message_begin(MSG_BROADCAST, g_msgScoreInfo)
write_byte(attacker)
write_short(pev(attacker, pev_frags))
write_short(fm_get_user_deaths(attacker))
write_short(0)
write_short(fm_get_user_team(attacker))
message_end()
// set victim deaths
fm_set_user_deaths(victim, fm_get_user_deaths(victim) + 1)
// Update scoreboard with victim info
message_begin(MSG_BROADCAST, g_msgScoreInfo)
write_byte(victim)
write_short(pev(victim, pev_frags))
write_short(fm_get_user_deaths(victim))
write_short(0)
write_short(fm_get_user_team(victim))
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_set_user_deaths(victim, fm_get_user_deaths(victim) - 1)
}
// Play a sound on clients
PlaySound(const sound[])
{
message_begin(MSG_BROADCAST, g_msgSendAudio)
write_byte(0) // sender id
write_string(sound) // sound string
write_short(100) // pitch
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) {}
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 spawn points from entity origins
stock collect_spawns(const classname[])
{
static ent
ent = -1;
while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", classname)) != 0)
{
// get origin
static 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;
}
}
// Drop primary/secondary weapons
stock drop_weapons(id, dropwhat)
{
static weapons[32], num, i
num = 0 // reset passed weapons count (bugfix)
get_user_weapons(id, weapons, num)
for (i = 0; i < num; i++)
{
if ((dropwhat == 1 && ((1<<weapons[i]) & PRIMARY_WEAPONS_BIT_SUM)) || (dropwhat == 2 && ((1<<weapons[i]) & SECONDARY_WEAPONS_BIT_SUM)))
{
static wname[32], weapon_ent
get_weaponname(weapons[i], wname, sizeof wname - 1)
weapon_ent = fm_find_ent_by_owner(-1, wname, id); // get weapon entity
// hack: store weapon bpammo on pev_iuser1
set_pev(weapon_ent, pev_iuser1, fm_get_user_bpammo(id, weapons[i]))
engclient_cmd(id, "drop", wname) // player drops it
fm_set_user_bpammo(id, weapons[i], 0); // and looses his bpammo
}
}
}
// Stock by (probably) Twilight Suzuka -counts number of chars in a string
stock str_count(const str[], searchchar)
{
static count, i
count = 0
for (i = 0; i <= strlen(str); i++)
{
if(str[i] == 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;
}
// Get User BP Ammo
stock fm_get_user_bpammo(id, weapon)
{
static offset
switch(weapon)
{
case CSW_AWP: offset = OFFSET_AWM_AMMO;
case CSW_SCOUT,CSW_AK47,CSW_G3SG1: offset = OFFSET_SCOUT_AMMO;
case CSW_M249: offset = OFFSET_PARA_AMMO;
case CSW_M4A1,CSW_FAMAS,CSW_AUG,CSW_SG550,CSW_GALI,CSW_SG552: offset = OFFSET_FAMAS_AMMO;
case CSW_M3,CSW_XM1014: offset = OFFSET_M3_AMMO;
case CSW_USP,CSW_UMP45,CSW_MAC10: offset = OFFSET_USP_AMMO;
case CSW_FIVESEVEN,CSW_P90: offset = OFFSET_FIVESEVEN_AMMO;
case CSW_DEAGLE: offset = OFFSET_DEAGLE_AMMO;
case CSW_P228: offset = OFFSET_P228_AMMO;
case CSW_GLOCK18,CSW_MP5NAVY,CSW_TMP,CSW_ELITE: offset = OFFSET_GLOCK_AMMO;
case CSW_FLASHBANG: offset = OFFSET_FLASH_AMMO;
case CSW_HEGRENADE: offset = OFFSET_HE_AMMO;
case CSW_SMOKEGRENADE: offset = OFFSET_SMOKE_AMMO;
case CSW_C4: offset = OFFSET_C4_AMMO;
default: return -1;
}
return get_pdata_int(id, offset, OFFSET_LINUX);
}
// Set User BP Ammo
stock fm_set_user_bpammo(id, weapon, amount)
{
static offset
switch(weapon)
{
case CSW_AWP: offset = OFFSET_AWM_AMMO;
case CSW_SCOUT,CSW_AK47,CSW_G3SG1: offset = OFFSET_SCOUT_AMMO;
case CSW_M249: offset = OFFSET_PARA_AMMO;
case CSW_M4A1,CSW_FAMAS,CSW_AUG,CSW_SG550,CSW_GALI,CSW_SG552: offset = OFFSET_FAMAS_AMMO;
case CSW_M3,CSW_XM1014: offset = OFFSET_M3_AMMO;
case CSW_USP,CSW_UMP45,CSW_MAC10: offset = OFFSET_USP_AMMO;
case CSW_FIVESEVEN,CSW_P90: offset = OFFSET_FIVESEVEN_AMMO;
case CSW_DEAGLE: offset = OFFSET_DEAGLE_AMMO;
case CSW_P228: offset = OFFSET_P228_AMMO;
case CSW_GLOCK18,CSW_MP5NAVY,CSW_TMP,CSW_ELITE: offset = OFFSET_GLOCK_AMMO;
case CSW_FLASHBANG: offset = OFFSET_FLASH_AMMO;
case CSW_HEGRENADE: offset = OFFSET_HE_AMMO;
case CSW_SMOKEGRENADE: offset = OFFSET_SMOKE_AMMO;
case CSW_C4: offset = OFFSET_C4_AMMO;
default: return;
}
set_pdata_int(id, offset, amount, OFFSET_LINUX);
}
// Set Weapon Clip Ammo
stock fm_set_weapon_ammo(entity, amount)
{
set_pdata_int(entity, OFFSET_CLIPAMMO, amount, OFFSET_LINUX_WEAPONS);
}
// Get Weapon Clip Ammo
stock fm_get_weapon_ammo(entity)
{
return get_pdata_int(entity, OFFSET_CLIPAMMO, OFFSET_LINUX_WEAPONS);
}
// Set User Zoom
stock fm_remove_user_zoom(id)
{
set_pdata_int(id, OFFSET_ZOOMTYPE, CS_NO_ZOOM, OFFSET_LINUX);
}
// Get User Deaths
stock fm_get_user_deaths(id)
{
return get_pdata_int(id, OFFSET_CSDEATHS, OFFSET_LINUX);
}
// Set User Deaths
stock fm_set_user_deaths(id, value)
{
set_pdata_int(id, OFFSET_CSDEATHS, value, OFFSET_LINUX);
}
// Set Bots NVG
stock fm_set_bot_nvg(id, value)
{
g_nvision[id] = true;
set_pdata_int(id, OFFSET_NVGOGGLES, value, OFFSET_LINUX);
/*
// Seems this isn't really needed either
emessage_begin(MSG_ONE, g_msgNVGToggle, _, id)
ewrite_byte(value) // 1 On - 0 Off
emessage_end()
*/
}
// Get User Team
stock fm_get_user_team(id)
{
return get_pdata_int(id, OFFSET_CSTEAMS, OFFSET_LINUX);
}
// Set a Player's Team
stock fm_set_user_team(id, team)
{
set_pdata_int(id, OFFSET_CSTEAMS, team, OFFSET_LINUX);
}
// Send User Team Message
public fm_set_user_team_msg(taskid)
{
// Beware: this message can now be picked up by other metamod
// plugins (yeah, that includes AMXX plugins as well)
// Set the switching team flag
g_switchingteam[ID_TEAM] = true;
// Tell everyone my new team
emessage_begin(MSG_ALL, g_msgTeamInfo)
ewrite_byte(ID_TEAM)
switch (fm_get_user_team(ID_TEAM))
{
case CS_TEAM_UNASSIGNED: ewrite_string("UNASSIGNED");
case CS_TEAM_T: ewrite_string("TERRORIST");
case CS_TEAM_CT: ewrite_string("CT");
case CS_TEAM_SPECTATOR: ewrite_string("SPECTATOR");
}
emessage_end()
// Done switching team
g_switchingteam[ID_TEAM] = false;
}
#if defined HANDLE_MODELS_ON_SEPARATE_ENT
// Set User Model on Entity
stock fm_set_user_model_ent(id)
{
static model[100], ent
// format model string
formatex(model, sizeof model - 1, "models/player/%s/%s.mdl", g_playermodel[id], g_playermodel[id])
ent = fm_find_ent_by_owner(-1, "player_model", id) // get player_model entity
if (!ent) // doesn't exist, make a new one
{
ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
set_pev(ent, pev_classname, "player_model")
set_pev(ent, pev_movetype, MOVETYPE_FOLLOW)
engfunc(EngFunc_SetModel, ent, model)
set_pev(ent, pev_aiment, id)
set_pev(ent, pev_owner, id)
}
else
{
engfunc(EngFunc_SetModel, ent, model)
}
}
// Set Weapon Model on Entity
stock fm_set_weapon_model_ent(id, const model[])
{
static ent
ent = fm_find_ent_by_owner(-1, "weapon_model", id) // get weapon_model entity
if (!ent) // doesn't exist, make a new one
{
ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
set_pev(ent, pev_classname, "weapon_model")
set_pev(ent, pev_movetype, MOVETYPE_FOLLOW)
engfunc(EngFunc_SetModel, ent, model)
set_pev(ent, pev_aiment, id)
set_pev(ent, pev_owner, id)
}
else
{
engfunc(EngFunc_SetModel, ent, model)
}
}
#else
// Set User Model by ClientKeyValue
public fm_set_user_model(taskid)
{
engfunc(EngFunc_SetClientKeyValue, ID_MODEL, engfunc(EngFunc_GetInfoKeyBuffer, ID_MODEL), "model", g_playermodel[ID_MODEL])
}
// Get User Model -model passed byref-
stock fm_get_user_model(player, model[], len)
{
engfunc(EngFunc_InfoKeyValue, engfunc(EngFunc_GetInfoKeyBuffer, player), "model", model, len)
}
#endif
/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang3082\\ f0\\ fs16 \n\\ par }
*/