Guest User

Untitled

a guest
Nov 8th, 2018
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 344.01 KB | None | 0 0
  1. /*================================================================================
  2. *****************************************************
  3. ************** [Zombie Plague Mod 4.3] **************
  4. *****************************************************
  5. =================================================================================*/
  6.  
  7. /*================================================================================
  8. [Plugin Customization]
  9. =================================================================================*/
  10.  
  11. // All customization settings have been moved
  12. // to external files to allow easier editing
  13. new const ZP_CUSTOMIZATION_FILE[] = "zombieplague.ini"
  14. new const ZP_EXTRAITEMS_FILE[] = "zp_extraitems.ini"
  15. new const ZP_ZOMBIECLASSES_FILE[] = "zp_zombieclasses.ini"
  16.  
  17. // Limiters for stuff not worth making dynamic arrays out of (increase if needed)
  18. const MAX_CSDM_SPAWNS = 128
  19. const MAX_STATS_SAVED = 64
  20.  
  21. /*================================================================================
  22. Customization ends here! Yes, that's it. Editing anything beyond
  23. here is not officially supported. Proceed at your own risk...
  24. =================================================================================*/
  25.  
  26. #include <amxmodx>
  27. #include <amxmisc>
  28. #include <cstrike>
  29. #include <fakemeta>
  30. #include <hamsandwich>
  31. #include <xs>
  32. #include <dhudmessage>
  33. #include <csx>
  34.  
  35.  
  36. /*================================================================================
  37. [Constants, Offsets, Macros]
  38. =================================================================================*/
  39.  
  40. // Plugin Version
  41. new const PLUGIN_VERSION[] = "4.3 Fix6a"
  42.  
  43. // Customization file sections
  44. enum
  45. {
  46. SECTION_NONE = 0,
  47. SECTION_ACCESS_FLAGS,
  48. SECTION_PLAYER_MODELS,
  49. SECTION_WEAPON_MODELS,
  50. SECTION_GRENADE_SPRITES,
  51. SECTION_SOUNDS,
  52. SECTION_AMBIENCE_SOUNDS,
  53. SECTION_BUY_MENU_WEAPONS,
  54. SECTION_EXTRA_ITEMS_WEAPONS,
  55. SECTION_HARD_CODED_ITEMS_COSTS,
  56. SECTION_WEATHER_EFFECTS,
  57. SECTION_SKY,
  58. SECTION_LIGHTNING,
  59. SECTION_ZOMBIE_DECALS,
  60. SECTION_KNOCKBACK,
  61. SECTION_OBJECTIVE_ENTS,
  62. SECTION_SVC_BAD
  63. }
  64.  
  65. // Access flags
  66. enum
  67. {
  68. ACCESS_ENABLE_MOD = 0,
  69. ACCESS_ADMIN_MENU,
  70. ACCESS_MODE_INFECTION,
  71. ACCESS_MODE_NEMESIS,
  72. ACCESS_MODE_SURVIVOR,
  73. ACCESS_MODE_SWARM,
  74. ACCESS_MODE_MULTI,
  75. ACCESS_MODE_PLAGUE,
  76. ACCESS_MAKE_ZOMBIE,
  77. ACCESS_MAKE_HUMAN,
  78. ACCESS_MAKE_NEMESIS,
  79. ACCESS_MAKE_SURVIVOR,
  80. ACCESS_RESPAWN_PLAYERS,
  81. ACCESS_ADMIN_MODELS,
  82. MAX_ACCESS_FLAGS
  83. }
  84.  
  85. // Task offsets
  86. enum (+= 100)
  87. {
  88. TASK_MODEL = 2000,
  89. TASK_TEAM,
  90. TASK_SPAWN,
  91. TASK_BLOOD,
  92. TASK_AURA,
  93. TASK_BURN,
  94. TASK_NVISION,
  95. TASK_FLASH,
  96. TASK_CHARGE,
  97. TASK_SHOWHUD,
  98. TASK_MAKEZOMBIE,
  99. TASK_WELCOMEMSG,
  100. TASK_THUNDER_PRE,
  101. TASK_THUNDER,
  102. TASK_AMBIENCESOUNDS
  103. }
  104.  
  105. // IDs inside tasks
  106. #define ID_MODEL (taskid - TASK_MODEL)
  107. #define ID_TEAM (taskid - TASK_TEAM)
  108. #define ID_SPAWN (taskid - TASK_SPAWN)
  109. #define ID_BLOOD (taskid - TASK_BLOOD)
  110. #define ID_AURA (taskid - TASK_AURA)
  111. #define ID_BURN (taskid - TASK_BURN)
  112. #define ID_NVISION (taskid - TASK_NVISION)
  113. #define ID_FLASH (taskid - TASK_FLASH)
  114. #define ID_CHARGE (taskid - TASK_CHARGE)
  115. #define ID_SHOWHUD (taskid - TASK_SHOWHUD)
  116.  
  117. // BP Ammo Refill task
  118. #define REFILL_WEAPONID args[0]
  119.  
  120. // For weapon buy menu handlers
  121. #define WPN_STARTID g_menu_data[id][1]
  122. #define WPN_MAXIDS ArraySize(g_primary_items)
  123. #define WPN_SELECTION (g_menu_data[id][1]+key)
  124. #define WPN_AUTO_ON g_menu_data[id][2]
  125. #define WPN_AUTO_PRI g_menu_data[id][3]
  126. #define WPN_AUTO_SEC g_menu_data[id][4]
  127.  
  128. // For player list menu handlers
  129. #define PL_ACTION g_menu_data[id][0]
  130.  
  131. // For remembering menu pages
  132. #define MENU_PAGE_ZCLASS g_menu_data[id][5]
  133. #define MENU_PAGE_EXTRAS g_menu_data[id][6]
  134. #define MENU_PAGE_PLAYERS g_menu_data[id][7]
  135.  
  136. // For extra items menu handlers
  137. #define EXTRAS_CUSTOM_STARTID (EXTRA_WEAPONS_STARTID + ArraySize(g_extraweapon_names))
  138.  
  139. // Menu selections
  140. const MENU_KEY_AUTOSELECT = 7
  141. const MENU_KEY_BACK = 7
  142. const MENU_KEY_NEXT = 8
  143. const MENU_KEY_EXIT = 9
  144.  
  145. // Hard coded extra items
  146. enum
  147. {
  148. EXTRA_NVISION = 0,
  149. EXTRA_ANTIDOTE,
  150. EXTRA_MADNESS,
  151. EXTRA_INFBOMB,
  152. EXTRA_WEAPONS_STARTID
  153. }
  154.  
  155. // Game modes
  156. enum
  157. {
  158. MODE_NONE = 0,
  159. MODE_INFECTION,
  160. MODE_NEMESIS,
  161. MODE_SURVIVOR,
  162. MODE_SWARM,
  163. MODE_MULTI,
  164. MODE_PLAGUE
  165. }
  166.  
  167. // ZP Teams
  168. const ZP_TEAM_NO_ONE = 0
  169. const ZP_TEAM_ANY = 0
  170. const ZP_TEAM_ZOMBIE = (1<<0)
  171. const ZP_TEAM_HUMAN = (1<<1)
  172. const ZP_TEAM_NEMESIS = (1<<2)
  173. const ZP_TEAM_SURVIVOR = (1<<3)
  174. new const ZP_TEAM_NAMES[][] = { "ZOMBIE , HUMAN", "ZOMBIE", "HUMAN", "ZOMBIE , HUMAN", "NEMESIS",
  175. "ZOMBIE , NEMESIS", "HUMAN , NEMESIS", "ZOMBIE , HUMAN , NEMESIS",
  176. "SURVIVOR", "ZOMBIE , SURVIVOR", "HUMAN , SURVIVOR", "ZOMBIE , HUMAN , SURVIVOR",
  177. "NEMESIS , SURVIVOR", "ZOMBIE , NEMESIS , SURVIVOR", "HUMAN, NEMESIS, SURVIVOR",
  178. "ZOMBIE , HUMAN , NEMESIS , SURVIVOR" }
  179.  
  180. // Zombie classes
  181. const ZCLASS_NONE = -1
  182.  
  183. // HUD messages
  184. const Float:HUD_EVENT_X = -1.0
  185. const Float:HUD_EVENT_Y = 0.17
  186. const Float:HUD_INFECT_X = 0.05
  187. const Float:HUD_INFECT_Y = 0.45
  188. const Float:HUD_SPECT_X = 0.6
  189. const Float:HUD_SPECT_Y = 0.8
  190. const Float:HUD_STATS_X = 0.02
  191. const Float:HUD_STATS_Y = 0.9
  192.  
  193. // Hack to be able to use Ham_Player_ResetMaxSpeed (by joaquimandrade)
  194. new Ham:Ham_Player_ResetMaxSpeed = Ham_Item_PreFrame
  195.  
  196. // CS Player PData Offsets (win32)
  197. const PDATA_SAFE = 2
  198. const OFFSET_PAINSHOCK = 108 // ConnorMcLeod
  199. const OFFSET_CSTEAMS = 114
  200. const OFFSET_CSMONEY = 115
  201. const OFFSET_CSMENUCODE = 205
  202. const OFFSET_FLASHLIGHT_BATTERY = 244
  203. const OFFSET_CSDEATHS = 444
  204. const OFFSET_MODELINDEX = 491 // Orangutanz
  205.  
  206. // CS Player CBase Offsets (win32)
  207. const OFFSET_ACTIVE_ITEM = 373
  208.  
  209. // CS Weapon CBase Offsets (win32)
  210. const OFFSET_WEAPONOWNER = 41
  211.  
  212. // Linux diff's
  213. const OFFSET_LINUX = 5 // offsets 5 higher in Linux builds
  214. const OFFSET_LINUX_WEAPONS = 4 // weapon offsets are only 4 steps higher on Linux
  215.  
  216. // CS Teams
  217. enum
  218. {
  219. FM_CS_TEAM_UNASSIGNED = 0,
  220. FM_CS_TEAM_T,
  221. FM_CS_TEAM_CT,
  222. FM_CS_TEAM_SPECTATOR
  223. }
  224. new const CS_TEAM_NAMES[][] = { "UNASSIGNED", "TERRORIST", "CT", "SPECTATOR" }
  225.  
  226. // Some constants
  227. const HIDE_MONEY = (1<<5)
  228. const UNIT_SECOND = (1<<12)
  229. const DMG_HEGRENADE = (1<<24)
  230. const IMPULSE_FLASHLIGHT = 100
  231. const USE_USING = 2
  232. const USE_STOPPED = 0
  233. const STEPTIME_SILENT = 999
  234. const BREAK_GLASS = 0x01
  235. const FFADE_IN = 0x0000
  236. const FFADE_STAYOUT = 0x0004
  237. const PEV_SPEC_TARGET = pev_iuser2
  238.  
  239. // Max BP ammo for weapons
  240. new const MAXBPAMMO[] = { -1, 52, -1, 90, 1, 32, 1, 100, 90, 1, 120, 100, 100, 90, 90, 90, 100, 120,
  241. 30, 120, 200, 32, 90, 120, 90, 2, 35, 90, 90, -1, 100 }
  242.  
  243. // Max Clip for weapons
  244. new const MAXCLIP[] = { -1, 13, -1, 10, -1, 7, -1, 30, 30, -1, 30, 20, 25, 30, 35, 25, 12, 20,
  245. 10, 30, 100, 8, 30, 30, 20, -1, 7, 30, 30, -1, 50 }
  246.  
  247. // Amount of ammo to give when buying additional clips for weapons
  248. new const BUYAMMO[] = { -1, 13, -1, 30, -1, 8, -1, 12, 30, -1, 30, 50, 12, 30, 30, 30, 12, 30,
  249. 10, 30, 30, 8, 30, 30, 30, -1, 7, 30, 30, -1, 50 }
  250.  
  251. // Ammo IDs for weapons
  252. new const AMMOID[] = { -1, 9, -1, 2, 12, 5, 14, 6, 4, 13, 10, 7, 6, 4, 4, 4, 6, 10,
  253. 1, 10, 3, 5, 4, 10, 2, 11, 8, 4, 2, -1, 7 }
  254.  
  255. // Ammo Type Names for weapons
  256. new const AMMOTYPE[][] = { "", "357sig", "", "762nato", "", "buckshot", "", "45acp", "556nato", "", "9mm", "57mm", "45acp",
  257. "556nato", "556nato", "556nato", "45acp", "9mm", "338magnum", "9mm", "556natobox", "buckshot",
  258. "556nato", "9mm", "762nato", "", "50ae", "556nato", "762nato", "", "57mm" }
  259.  
  260. // Weapon IDs for ammo types
  261. new const AMMOWEAPON[] = { 0, CSW_AWP, CSW_SCOUT, CSW_M249, CSW_AUG, CSW_XM1014, CSW_MAC10, CSW_FIVESEVEN, CSW_DEAGLE,
  262. CSW_P228, CSW_ELITE, CSW_FLASHBANG, CSW_HEGRENADE, CSW_SMOKEGRENADE, CSW_C4 }
  263.  
  264. // Primary and Secondary Weapon Names
  265. new const WEAPONNAMES[][] = { "", "P228", "", "Scout", "", "XM1014", "", "MAC-10", "AUG",
  266. "", "Dual Elite", "FiveseveN", "UMP 45", "SG-550", "Galil", "Famas",
  267. "USP", "Glock", "AWP", "MP5", "M249",
  268. "M3", "M4A1", "TMP", "G3SG1", "", "Deagle",
  269. "SG-552", "AK-47", "", "P90" }
  270.  
  271. // Weapon entity names
  272. new const WEAPONENTNAMES[][] = { "", "weapon_p228", "", "weapon_scout", "weapon_hegrenade", "weapon_xm1014", "weapon_c4", "weapon_mac10",
  273. "weapon_aug", "weapon_smokegrenade", "weapon_elite", "weapon_fiveseven", "weapon_ump45", "weapon_sg550",
  274. "weapon_galil", "weapon_famas", "weapon_usp", "weapon_glock18", "weapon_awp", "weapon_mp5navy", "weapon_m249",
  275. "weapon_m3", "weapon_m4a1", "weapon_tmp", "weapon_g3sg1", "weapon_flashbang", "weapon_deagle", "weapon_sg552",
  276. "weapon_ak47", "weapon_knife", "weapon_p90" }
  277.  
  278. // CS sounds
  279. new const sound_flashlight[] = "items/flashlight1.wav"
  280. new const sound_buyammo[] = "items/9mmclip1.wav"
  281. new const sound_armorhit[] = "player/bhit_helmet-1.wav"
  282.  
  283. // Explosion radius for custom grenades
  284. const Float:NADE_EXPLOSION_RADIUS = 240.0
  285.  
  286. // HACK: pev_ field used to store additional ammo on weapons
  287. const PEV_ADDITIONAL_AMMO = pev_iuser1
  288.  
  289. // HACK: pev_ field used to store custom nade types and their values
  290. const PEV_NADE_TYPE = pev_flTimeStepSound
  291. const NADE_TYPE_INFECTION = 1111
  292. const NADE_TYPE_NAPALM = 2222
  293. const NADE_TYPE_FROST = 3333
  294. const NADE_TYPE_FLARE = 4444
  295. const PEV_FLARE_COLOR = pev_punchangle
  296. const PEV_FLARE_DURATION = pev_flSwimTime
  297.  
  298. // Weapon bitsums
  299. 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)
  300. const SECONDARY_WEAPONS_BIT_SUM = (1<<CSW_P228)|(1<<CSW_ELITE)|(1<<CSW_FIVESEVEN)|(1<<CSW_USP)|(1<<CSW_GLOCK18)|(1<<CSW_DEAGLE)
  301.  
  302. // Allowed weapons for zombies (added grenades/bomb for sub-plugin support, since they shouldn't be getting them anyway)
  303. const ZOMBIE_ALLOWED_WEAPONS_BITSUM = (1<<CSW_KNIFE)|(1<<CSW_HEGRENADE)|(1<<CSW_FLASHBANG)|(1<<CSW_SMOKEGRENADE)|(1<<CSW_C4)
  304.  
  305. // Classnames for separate model entities
  306. new const MODEL_ENT_CLASSNAME[] = "player_model"
  307. new const WEAPON_ENT_CLASSNAME[] = "weapon_model"
  308.  
  309. // Menu keys
  310. const KEYSMENU = MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4|MENU_KEY_5|MENU_KEY_6|MENU_KEY_7|MENU_KEY_8|MENU_KEY_9|MENU_KEY_0
  311.  
  312. // Ambience Sounds
  313. enum
  314. {
  315. AMBIENCE_SOUNDS_INFECTION = 0,
  316. AMBIENCE_SOUNDS_NEMESIS,
  317. AMBIENCE_SOUNDS_SURVIVOR,
  318. AMBIENCE_SOUNDS_SWARM,
  319. AMBIENCE_SOUNDS_PLAGUE,
  320. MAX_AMBIENCE_SOUNDS
  321. }
  322.  
  323. // Admin menu actions
  324. enum
  325. {
  326. ACTION_ZOMBIEFY_HUMANIZE = 0,
  327. ACTION_MAKE_NEMESIS,
  328. ACTION_MAKE_SURVIVOR,
  329. ACTION_RESPAWN_PLAYER,
  330. ACTION_MODE_SWARM,
  331. ACTION_MODE_MULTI,
  332. ACTION_MODE_PLAGUE
  333. }
  334.  
  335. // Custom forward return values
  336. const ZP_PLUGIN_HANDLED = 97
  337.  
  338. /*================================================================================
  339. [Global Variables]
  340. =================================================================================*/
  341.  
  342. // Player vars
  343. new g_zombie[33] // is zombie
  344. new g_nemesis[33] // is nemesis
  345. new g_survivor[33] // is survivor
  346. new g_firstzombie[33] // is first zombie
  347. new g_lastzombie[33] // is last zombie
  348. new g_lasthuman[33] // is last human
  349. new g_frozen[33] // is frozen (can't move)
  350. new Float:g_frozen_gravity[33] // store previous gravity when frozen
  351. new g_nodamage[33] // has spawn protection/zombie madness
  352. new g_respawn_as_zombie[33] // should respawn as zombie
  353. new g_nvision[33] // has night vision
  354. new g_nvisionenabled[33] // has night vision turned on
  355. new g_zombieclass[33] // zombie class
  356. new g_zombieclassnext[33] // zombie class for next infection
  357. new g_flashlight[33] // has custom flashlight turned on
  358. new g_flashbattery[33] = { 100, ... } // custom flashlight battery
  359. new g_canbuy[33] // is allowed to buy a new weapon through the menu
  360. new g_ammopacks[33] // ammo pack count
  361. new g_damagedealt_human[33] // damage dealt as human (used to calculate ammo packs reward)
  362. new g_damagedealt_zombie[33] // damage dealt as zombie (used to calculate ammo packs reward)
  363. new Float:g_lastleaptime[33] // time leap was last used
  364. new Float:g_lastflashtime[33] // time flashlight was last toggled
  365. new g_playermodel[33][32] // current model's short name [player][model]
  366. new g_menu_data[33][8] // data for some menu handlers
  367. new g_ent_playermodel[33] // player model entity
  368. new g_ent_weaponmodel[33] // weapon model entity
  369. new g_burning_duration[33] // burning task duration
  370. new Float:g_buytime[33] // used to calculate custom buytime
  371.  
  372. // Game vars
  373. new g_pluginenabled // ZP enabled
  374. new g_newround // new round starting
  375. new g_endround // round ended
  376. new g_nemround // nemesis round
  377. new g_survround // survivor round
  378. new g_swarmround // swarm round
  379. new g_plagueround // plague round
  380. new g_modestarted // mode fully started
  381. new g_lastmode // last played mode
  382. new g_scorezombies, g_scorehumans, g_gamecommencing // team scores
  383. new g_spawnCount, g_spawnCount2 // available spawn points counter
  384. new Float:g_spawns[MAX_CSDM_SPAWNS][3], Float:g_spawns2[MAX_CSDM_SPAWNS][3] // spawn points data
  385. new g_lights_i // lightning current lights counter
  386. new g_lights_cycle[32] // current lightning cycle
  387. new g_lights_cycle_len // lightning cycle length
  388. new Float:g_models_targettime // for adding delays between Model Change messages
  389. new Float:g_teams_targettime // for adding delays between Team Change messages
  390. new g_MsgSync, g_MsgSync2 // message sync objects
  391. new g_trailSpr, g_exploSpr, g_flameSpr, g_smokeSpr, g_glassSpr // grenade sprites
  392. new g_fire_explode, g_frost_explode, g_fire_gib, g_frost_gib, g_fire_trail, g_frost_trail, g_flare_trail //new effects
  393. new g_modname[32] // for formatting the mod name
  394. new g_freezetime // whether CS's freeze time is on
  395. new g_maxplayers // max players counter
  396. new g_czero // whether we are running on a CZ server
  397. new g_hamczbots // whether ham forwards are registered for CZ bots
  398. new g_fwSpawn, g_fwPrecacheSound // spawn and precache sound forward handles
  399. new g_infbombcounter, g_antidotecounter, g_madnesscounter // to limit buying some items
  400. new g_arrays_created // to prevent stuff from being registered before initializing arrays
  401. new g_lastplayerleaving // flag for whenever a player leaves and another takes his place
  402. new g_switchingteam // flag for whenever a player's team change emessage is sent
  403. new g_buyzone_ent // custom buyzone entity
  404.  
  405. // Message IDs vars
  406. new g_msgScoreInfo, g_msgNVGToggle, g_msgScoreAttrib, g_msgAmmoPickup, g_msgScreenFade,
  407. g_msgDeathMsg, g_msgSetFOV, g_msgFlashlight, g_msgFlashBat, g_msgTeamInfo, g_msgDamage,
  408. g_msgHideWeapon, g_msgCrosshair, g_msgSayText, g_msgScreenShake, g_msgCurWeapon
  409.  
  410. // Some forward handlers
  411. new g_fwRoundStart, g_fwRoundEnd, g_fwUserInfected_pre, g_fwUserInfected_post,
  412. g_fwUserHumanized_pre, g_fwUserHumanized_post, g_fwUserInfect_attempt,
  413. g_fwUserHumanize_attempt, g_fwExtraItemSelected, g_fwUserUnfrozen,
  414. g_fwUserLastZombie, g_fwUserLastHuman, g_fwDummyResult
  415.  
  416. // Temporary Database vars (used to restore players stats in case they get disconnected)
  417. new db_name[MAX_STATS_SAVED][32] // player name
  418. new db_ammopacks[MAX_STATS_SAVED] // ammo pack count
  419. new db_zombieclass[MAX_STATS_SAVED] // zombie class
  420. new db_slot_i // additional saved slots counter (should start on maxplayers+1)
  421.  
  422. // Extra Items vars
  423. new Array:g_extraitem_name // caption
  424. new Array:g_extraitem_cost // cost
  425. new Array:g_extraitem_team // team
  426. new g_extraitem_i // loaded extra items counter
  427.  
  428. // For extra items file parsing
  429. new Array:g_extraitem2_realname, Array:g_extraitem2_name, Array:g_extraitem2_cost,
  430. Array:g_extraitem2_team, Array:g_extraitem_new
  431.  
  432. // Zombie Classes vars
  433. new Array:g_zclass_name // caption
  434. new Array:g_zclass_info // description
  435. new Array:g_zclass_modelsstart // start position in models array
  436. new Array:g_zclass_modelsend // end position in models array
  437. new Array:g_zclass_playermodel // player models array
  438. new Array:g_zclass_modelindex // model indices array
  439. new Array:g_zclass_clawmodel // claw model
  440. new Array:g_zclass_hp // health
  441. new Array:g_zclass_spd // speed
  442. new Array:g_zclass_grav // gravity
  443. new Array:g_zclass_kb // knockback
  444. new g_zclass_i // loaded zombie classes counter
  445.  
  446. // For zombie classes file parsing
  447. new Array:g_zclass2_realname, Array:g_zclass2_name, Array:g_zclass2_info,
  448. Array:g_zclass2_modelsstart, Array:g_zclass2_modelsend, Array:g_zclass2_playermodel,
  449. Array:g_zclass2_modelindex, Array:g_zclass2_clawmodel, Array:g_zclass2_hp,
  450. Array:g_zclass2_spd, Array:g_zclass2_grav, Array:g_zclass2_kb, Array:g_zclass_new
  451.  
  452. // Customization vars
  453. new g_access_flag[MAX_ACCESS_FLAGS], Array:model_nemesis, Array:model_survivor, Array:model_human,
  454. Array:model_admin_zombie, Array:model_admin_human, Array:g_modelindex_human,
  455. Array:g_modelindex_nemesis, Array:g_modelindex_survivor, g_same_models_for_all,
  456. Array:g_modelindex_admin_zombie, Array:g_modelindex_admin_human, model_vknife_human[64],
  457. model_vknife_nemesis[64], model_vweapon_survivor[64], model_grenade_infect[64],
  458. model_grenade_fire[64], model_grenade_frost[64], model_grenade_flare[64],
  459. model_vknife_admin_human[64], model_vknife_admin_zombie[64],
  460. sprite_grenade_trail[64], sprite_grenade_ring[64], sprite_grenade_fire[64],
  461. sprite_grenade_smoke[64], sprite_grenade_glass[64], Array:sound_win_zombies,
  462. Array:sound_win_humans, Array:sound_win_no_one, Array:sound_win_zombies_ismp3,
  463. Array:sound_win_humans_ismp3, Array:sound_win_no_one_ismp3, Array:zombie_infect,
  464. Array:zombie_idle, Array:zombie_pain, Array:nemesis_pain, Array:zombie_die, Array:zombie_fall,
  465. Array:zombie_miss_wall, Array:zombie_hit_normal, Array:zombie_hit_stab, g_ambience_rain,
  466. Array:zombie_idle_last, Array:zombie_madness, Array:sound_nemesis, Array:sound_survivor,
  467. Array:sound_swarm, Array:sound_multi, Array:sound_plague, Array:grenade_infect,
  468. Array:grenade_infect_player, Array:grenade_fire, Array:grenade_fire_player,
  469. Array:grenade_frost, Array:grenade_frost_player, Array:grenade_frost_break,
  470. Array:grenade_flare, Array:sound_antidote, Array:sound_thunder, g_ambience_sounds[MAX_AMBIENCE_SOUNDS],
  471. Array:sound_ambience1, Array:sound_ambience2, Array:sound_ambience3, Array:sound_ambience4,
  472. Array:sound_ambience5, Array:sound_ambience1_duration, Array:sound_ambience2_duration,
  473. Array:sound_ambience3_duration, Array:sound_ambience4_duration,
  474. Array:sound_ambience5_duration, Array:sound_ambience1_ismp3, Array:sound_ambience2_ismp3,
  475. Array:sound_ambience3_ismp3, Array:sound_ambience4_ismp3, Array:sound_ambience5_ismp3,
  476. Array:g_primary_items, Array:g_secondary_items, Array:g_additional_items,
  477. Array:g_primary_weaponids, Array:g_secondary_weaponids, Array:g_extraweapon_names,
  478. Array:g_extraweapon_items, Array:g_extraweapon_costs, g_extra_costs2[EXTRA_WEAPONS_STARTID],
  479. g_ambience_snow, g_ambience_fog, g_fog_density[10], g_fog_color[12], g_sky_enable,
  480. Array:g_sky_names, Array:lights_thunder, Array:zombie_decals, Array:g_objective_ents,
  481. Float:g_modelchange_delay, g_set_modelindex_offset, g_handle_models_on_separate_ent,
  482. Float:kb_weapon_power[31] = { -1.0, ... }, Array:zombie_miss_slash, g_force_consistency
  483.  
  484. // CVAR pointers
  485. new cvar_lighting, cvar_zombiefov, cvar_plague, cvar_plaguechance, cvar_zombiefirsthp,
  486. cvar_removemoney, cvar_thunder, cvar_zombiebonushp, cvar_nemhp, cvar_nem, cvar_surv,
  487. cvar_nemchance, cvar_deathmatch, cvar_nemglow, cvar_customnvg, cvar_hitzones, cvar_humanhp,
  488. cvar_nemgravity, cvar_flashsize, cvar_ammodamage_human, cvar_ammodamage_zombie,
  489. cvar_zombiearmor, cvar_survpainfree, cvar_nempainfree, cvar_nemspd, cvar_survchance,
  490. cvar_survhp, cvar_survspd, cvar_humanspd, cvar_swarmchance, cvar_flashdrain,
  491. cvar_zombiebleeding, cvar_removedoors, cvar_customflash, cvar_randspawn, cvar_multi,
  492. cvar_multichance, cvar_infammo, cvar_swarm, cvar_ammoinfect, cvar_toggle,
  493. cvar_knockbackpower, cvar_freezeduration, cvar_triggered, cvar_flashcharge,
  494. cvar_firegrenades, cvar_frostgrenades, cvar_survgravity, cvar_logcommands, cvar_survglow,
  495. cvar_humangravity, cvar_spawnprotection, cvar_nvgsize, cvar_flareduration, cvar_zclasses,
  496. cvar_extraitems, cvar_showactivity, cvar_humanlasthp, cvar_nemignorefrags, cvar_warmup,
  497. cvar_flashdist, cvar_flarecolor, cvar_survignorefrags, cvar_fireduration, cvar_firedamage,
  498. cvar_flaregrenades, cvar_knockbackducking, cvar_knockbackdamage, cvar_knockbackzvel,
  499. cvar_multiratio, cvar_flaresize, cvar_spawndelay, cvar_extraantidote, cvar_extramadness,
  500. cvar_extraweapons, cvar_extranvision, cvar_nvggive, cvar_preventconsecutive, cvar_botquota,
  501. cvar_buycustom, cvar_zombiepainfree, cvar_fireslowdown, cvar_survbasehp, cvar_survaura,
  502. cvar_nemignoreammo, cvar_survignoreammo, cvar_nemaura, cvar_extrainfbomb, cvar_knockback,
  503. cvar_fragsinfect, cvar_fragskill, cvar_humanarmor, cvar_zombiesilent, cvar_removedropped,
  504. cvar_plagueratio, cvar_blocksuicide, cvar_knockbackdist, cvar_nemdamage, cvar_leapzombies,
  505. cvar_leapzombiesforce, cvar_leapzombiesheight, cvar_leapzombiescooldown, cvar_leapnemesis,
  506. cvar_leapnemesisforce, cvar_leapnemesisheight, cvar_leapnemesiscooldown, cvar_leapsurvivor,
  507. cvar_leapsurvivorforce, cvar_leapsurvivorheight, cvar_nemminplayers, cvar_survminplayers,
  508. cvar_respawnonsuicide, cvar_respawnafterlast, cvar_leapsurvivorcooldown, cvar_statssave,
  509. cvar_swarmminplayers, cvar_multiminplayers, cvar_plagueminplayers, cvar_adminmodelshuman,
  510. cvar_adminmodelszombie, cvar_nembasehp, cvar_blockpushables, cvar_respawnworldspawnkill,
  511. cvar_madnessduration, cvar_plaguenemnum, cvar_plaguenemhpmulti, cvar_plaguesurvhpmulti,
  512. cvar_survweapon, cvar_plaguesurvnum, cvar_infectionscreenfade, cvar_infectionscreenshake,
  513. cvar_infectionsparkle, cvar_infectiontracers, cvar_infectionparticles, cvar_infbomblimit,
  514. cvar_allowrespawnsurv, cvar_flashshowall, cvar_allowrespawninfection, cvar_allowrespawnnem,
  515. cvar_allowrespawnswarm, cvar_allowrespawnplague, cvar_survinfammo, cvar_nemknockback,
  516. cvar_nvgcolor[3], cvar_nemnvgcolor[3], cvar_humnvgcolor[3], cvar_flashcolor[3],
  517. cvar_hudicons, cvar_respawnzomb, cvar_respawnhum, cvar_respawnnem, cvar_respawnsurv,
  518. cvar_startammopacks, cvar_randweapons, cvar_antidotelimit, cvar_madnesslimit,
  519. cvar_adminknifemodelshuman, cvar_adminknifemodelszombie, cvar_keephealthondisconnect,
  520. cvar_buyzonetime, cvar_huddisplay
  521.  
  522. // Cached stuff for players
  523. new g_isconnected[33] // whether player is connected
  524. new g_isalive[33] // whether player is alive
  525. new g_isbot[33] // whether player is a bot
  526. new g_currentweapon[33] // player's current weapon id
  527. new g_playername[33][32] // player's name
  528. new Float:g_zombie_spd[33] // zombie class speed
  529. new Float:g_zombie_knockback[33] // zombie class knockback
  530. new g_zombie_classname[33][32] // zombie class name
  531. #define is_user_valid_connected(%1) (1 <= %1 <= g_maxplayers && g_isconnected[%1])
  532. #define is_user_valid_alive(%1) (1 <= %1 <= g_maxplayers && g_isalive[%1])
  533. #define is_user_valid(%1) (1 <= %1 <= g_maxplayers)
  534.  
  535. // Cached CVARs
  536. new g_cached_customflash, g_cached_zombiesilent, g_cached_leapzombies, g_cached_leapnemesis,
  537. g_cached_leapsurvivor, Float:g_cached_leapzombiescooldown, Float:g_cached_leapnemesiscooldown,
  538. Float:g_cached_leapsurvivorcooldown, Float:g_cached_buytime
  539.  
  540. /*================================================================================
  541. [Natives, Precache and Init]
  542. =================================================================================*/
  543.  
  544. public plugin_natives()
  545. {
  546. // Player specific natives
  547. register_native("zp_get_user_zombie", "native_get_user_zombie", 1)
  548. register_native("zp_get_user_nemesis", "native_get_user_nemesis", 1)
  549. register_native("zp_get_user_survivor", "native_get_user_survivor", 1)
  550. register_native("zp_get_user_first_zombie", "native_get_user_first_zombie", 1)
  551. register_native("zp_get_user_last_zombie", "native_get_user_last_zombie", 1)
  552. register_native("zp_get_user_last_human", "native_get_user_last_human", 1)
  553. register_native("zp_get_user_zombie_class", "native_get_user_zombie_class", 1)
  554. register_native("zp_get_user_next_class", "native_get_user_next_class", 1)
  555. register_native("zp_set_user_zombie_class", "native_set_user_zombie_class", 1)
  556. register_native("zp_get_user_ammo_packs", "native_get_user_ammo_packs", 1)
  557. register_native("zp_set_user_ammo_packs", "native_set_user_ammo_packs", 1)
  558. register_native("zp_get_zombie_maxhealth", "native_get_zombie_maxhealth", 1)
  559. register_native("zp_get_user_batteries", "native_get_user_batteries", 1)
  560. register_native("zp_set_user_batteries", "native_set_user_batteries", 1)
  561. register_native("zp_get_user_nightvision", "native_get_user_nightvision", 1)
  562. register_native("zp_set_user_nightvision", "native_set_user_nightvision", 1)
  563. register_native("zp_infect_user", "native_infect_user", 1)
  564. register_native("zp_disinfect_user", "native_disinfect_user", 1)
  565. register_native("zp_make_user_nemesis", "native_make_user_nemesis", 1)
  566. register_native("zp_make_user_survivor", "native_make_user_survivor", 1)
  567. register_native("zp_respawn_user", "native_respawn_user", 1)
  568. register_native("zp_force_buy_extra_item", "native_force_buy_extra_item", 1)
  569. register_native("zp_override_user_model", "native_override_user_model", 1)
  570.  
  571. // Round natives
  572. register_native("zp_has_round_started", "native_has_round_started", 1)
  573. register_native("zp_is_nemesis_round", "native_is_nemesis_round", 1)
  574. register_native("zp_is_survivor_round", "native_is_survivor_round", 1)
  575. register_native("zp_is_swarm_round", "native_is_swarm_round", 1)
  576. register_native("zp_is_plague_round", "native_is_plague_round", 1)
  577. register_native("zp_get_zombie_count", "native_get_zombie_count", 1)
  578. register_native("zp_get_human_count", "native_get_human_count", 1)
  579. register_native("zp_get_nemesis_count", "native_get_nemesis_count", 1)
  580. register_native("zp_get_survivor_count", "native_get_survivor_count", 1)
  581.  
  582. // External additions natives
  583. register_native("zp_register_extra_item", "native_register_extra_item", 1)
  584. register_native("zp_register_zombie_class", "native_register_zombie_class", 1)
  585. register_native("zp_get_extra_item_id", "native_get_extra_item_id", 1)
  586. register_native("zp_get_zombie_class_id", "native_get_zombie_class_id", 1)
  587. register_native("zp_get_zombie_class_info", "native_get_zombie_class_info", 1)
  588. }
  589.  
  590. public plugin_precache()
  591. {
  592. // Register earlier to show up in plugins list properly after plugin disable/error at loading
  593. register_plugin("Zombie Plague", PLUGIN_VERSION, "MeRcyLeZZ")
  594.  
  595. // To switch plugin on/off
  596. register_concmd("zp_toggle", "cmd_toggle", _, "<1/0> - Enable/Disable Zombie Plague (will restart the current map)", 0)
  597. cvar_toggle = register_cvar("zp_on", "1")
  598.  
  599. // Plugin disabled?
  600. if (!get_pcvar_num(cvar_toggle)) return;
  601. g_pluginenabled = true
  602.  
  603. // Initialize a few dynamically sized arrays (alright, maybe more than just a few...)
  604. model_human = ArrayCreate(32, 1)
  605. model_nemesis = ArrayCreate(32, 1)
  606. model_survivor = ArrayCreate(32, 1)
  607. model_admin_human = ArrayCreate(32, 1)
  608. model_admin_zombie = ArrayCreate(32, 1)
  609. g_modelindex_human = ArrayCreate(1, 1)
  610. g_modelindex_nemesis = ArrayCreate(1, 1)
  611. g_modelindex_survivor = ArrayCreate(1, 1)
  612. g_modelindex_admin_human = ArrayCreate(1, 1)
  613. g_modelindex_admin_zombie = ArrayCreate(1, 1)
  614. sound_win_zombies = ArrayCreate(64, 1)
  615. sound_win_zombies_ismp3 = ArrayCreate(1, 1)
  616. sound_win_humans = ArrayCreate(64, 1)
  617. sound_win_humans_ismp3 = ArrayCreate(1, 1)
  618. sound_win_no_one = ArrayCreate(64, 1)
  619. sound_win_no_one_ismp3 = ArrayCreate(1, 1)
  620. zombie_infect = ArrayCreate(64, 1)
  621. zombie_pain = ArrayCreate(64, 1)
  622. nemesis_pain = ArrayCreate(64, 1)
  623. zombie_die = ArrayCreate(64, 1)
  624. zombie_fall = ArrayCreate(64, 1)
  625. zombie_miss_slash = ArrayCreate(64, 1)
  626. zombie_miss_wall = ArrayCreate(64, 1)
  627. zombie_hit_normal = ArrayCreate(64, 1)
  628. zombie_hit_stab = ArrayCreate(64, 1)
  629. zombie_idle = ArrayCreate(64, 1)
  630. zombie_idle_last = ArrayCreate(64, 1)
  631. zombie_madness = ArrayCreate(64, 1)
  632. sound_nemesis = ArrayCreate(64, 1)
  633. sound_survivor = ArrayCreate(64, 1)
  634. sound_swarm = ArrayCreate(64, 1)
  635. sound_multi = ArrayCreate(64, 1)
  636. sound_plague = ArrayCreate(64, 1)
  637. grenade_infect = ArrayCreate(64, 1)
  638. grenade_infect_player = ArrayCreate(64, 1)
  639. grenade_fire = ArrayCreate(64, 1)
  640. grenade_fire_player = ArrayCreate(64, 1)
  641. grenade_frost = ArrayCreate(64, 1)
  642. grenade_frost_player = ArrayCreate(64, 1)
  643. grenade_frost_break = ArrayCreate(64, 1)
  644. grenade_flare = ArrayCreate(64, 1)
  645. sound_antidote = ArrayCreate(64, 1)
  646. sound_thunder = ArrayCreate(64, 1)
  647. sound_ambience1 = ArrayCreate(64, 1)
  648. sound_ambience2 = ArrayCreate(64, 1)
  649. sound_ambience3 = ArrayCreate(64, 1)
  650. sound_ambience4 = ArrayCreate(64, 1)
  651. sound_ambience5 = ArrayCreate(64, 1)
  652. sound_ambience1_duration = ArrayCreate(1, 1)
  653. sound_ambience2_duration = ArrayCreate(1, 1)
  654. sound_ambience3_duration = ArrayCreate(1, 1)
  655. sound_ambience4_duration = ArrayCreate(1, 1)
  656. sound_ambience5_duration = ArrayCreate(1, 1)
  657. sound_ambience1_ismp3 = ArrayCreate(1, 1)
  658. sound_ambience2_ismp3 = ArrayCreate(1, 1)
  659. sound_ambience3_ismp3 = ArrayCreate(1, 1)
  660. sound_ambience4_ismp3 = ArrayCreate(1, 1)
  661. sound_ambience5_ismp3 = ArrayCreate(1, 1)
  662. g_primary_items = ArrayCreate(32, 1)
  663. g_secondary_items = ArrayCreate(32, 1)
  664. g_additional_items = ArrayCreate(32, 1)
  665. g_primary_weaponids = ArrayCreate(1, 1)
  666. g_secondary_weaponids = ArrayCreate(1, 1)
  667. g_extraweapon_names = ArrayCreate(32, 1)
  668. g_extraweapon_items = ArrayCreate(32, 1)
  669. g_extraweapon_costs = ArrayCreate(1, 1)
  670. g_sky_names = ArrayCreate(32, 1)
  671. lights_thunder = ArrayCreate(32, 1)
  672. zombie_decals = ArrayCreate(1, 1)
  673. g_objective_ents = ArrayCreate(32, 1)
  674. g_extraitem_name = ArrayCreate(32, 1)
  675. g_extraitem_cost = ArrayCreate(1, 1)
  676. g_extraitem_team = ArrayCreate(1, 1)
  677. g_extraitem2_realname = ArrayCreate(32, 1)
  678. g_extraitem2_name = ArrayCreate(32, 1)
  679. g_extraitem2_cost = ArrayCreate(1, 1)
  680. g_extraitem2_team = ArrayCreate(1, 1)
  681. g_extraitem_new = ArrayCreate(1, 1)
  682. g_zclass_name = ArrayCreate(32, 1)
  683. g_zclass_info = ArrayCreate(32, 1)
  684. g_zclass_modelsstart = ArrayCreate(1, 1)
  685. g_zclass_modelsend = ArrayCreate(1, 1)
  686. g_zclass_playermodel = ArrayCreate(32, 1)
  687. g_zclass_modelindex = ArrayCreate(1, 1)
  688. g_zclass_clawmodel = ArrayCreate(32, 1)
  689. g_zclass_hp = ArrayCreate(1, 1)
  690. g_zclass_spd = ArrayCreate(1, 1)
  691. g_zclass_grav = ArrayCreate(1, 1)
  692. g_zclass_kb = ArrayCreate(1, 1)
  693. g_zclass2_realname = ArrayCreate(32, 1)
  694. g_zclass2_name = ArrayCreate(32, 1)
  695. g_zclass2_info = ArrayCreate(32, 1)
  696. g_zclass2_modelsstart = ArrayCreate(1, 1)
  697. g_zclass2_modelsend = ArrayCreate(1, 1)
  698. g_zclass2_playermodel = ArrayCreate(32, 1)
  699. g_zclass2_modelindex = ArrayCreate(1, 1)
  700. g_zclass2_clawmodel = ArrayCreate(32, 1)
  701. g_zclass2_hp = ArrayCreate(1, 1)
  702. g_zclass2_spd = ArrayCreate(1, 1)
  703. g_zclass2_grav = ArrayCreate(1, 1)
  704. g_zclass2_kb = ArrayCreate(1, 1)
  705. g_zclass_new = ArrayCreate(1, 1)
  706.  
  707. // Allow registering stuff now
  708. g_arrays_created = true
  709.  
  710. // Load customization data
  711. load_customization_from_files()
  712.  
  713. new i, buffer[100]
  714.  
  715. // Load up the hard coded extra items
  716. native_register_extra_item2("NightVision", g_extra_costs2[EXTRA_NVISION], ZP_TEAM_HUMAN)
  717. native_register_extra_item2("T-Virus Antidote", g_extra_costs2[EXTRA_ANTIDOTE], ZP_TEAM_ZOMBIE)
  718. native_register_extra_item2("Zombie Madness", g_extra_costs2[EXTRA_MADNESS], ZP_TEAM_ZOMBIE)
  719. native_register_extra_item2("Infection Bomb", g_extra_costs2[EXTRA_INFBOMB], ZP_TEAM_ZOMBIE)
  720.  
  721. // Extra weapons
  722. for (i = 0; i < ArraySize(g_extraweapon_names); i++)
  723. {
  724. ArrayGetString(g_extraweapon_names, i, buffer, charsmax(buffer))
  725. native_register_extra_item2(buffer, ArrayGetCell(g_extraweapon_costs, i), ZP_TEAM_HUMAN)
  726. }
  727.  
  728. // Custom player models
  729. for (i = 0; i < ArraySize(model_human); i++)
  730. {
  731. ArrayGetString(model_human, i, buffer, charsmax(buffer))
  732. format(buffer, charsmax(buffer), "models/player/%s/%s.mdl", buffer, buffer)
  733. ArrayPushCell(g_modelindex_human, engfunc(EngFunc_PrecacheModel, buffer))
  734. if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, buffer)
  735. if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, buffer)
  736. // Precache modelT.mdl files too
  737. copy(buffer[strlen(buffer)-4], charsmax(buffer) - (strlen(buffer)-4), "T.mdl")
  738. if (file_exists(buffer)) engfunc(EngFunc_PrecacheModel, buffer)
  739. }
  740. for (i = 0; i < ArraySize(model_nemesis); i++)
  741. {
  742. ArrayGetString(model_nemesis, i, buffer, charsmax(buffer))
  743. format(buffer, charsmax(buffer), "models/player/%s/%s.mdl", buffer, buffer)
  744. ArrayPushCell(g_modelindex_nemesis, engfunc(EngFunc_PrecacheModel, buffer))
  745. if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, buffer)
  746. if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, buffer)
  747. // Precache modelT.mdl files too
  748. copy(buffer[strlen(buffer)-4], charsmax(buffer) - (strlen(buffer)-4), "T.mdl")
  749. if (file_exists(buffer)) engfunc(EngFunc_PrecacheModel, buffer)
  750. }
  751. for (i = 0; i < ArraySize(model_survivor); i++)
  752. {
  753. ArrayGetString(model_survivor, i, buffer, charsmax(buffer))
  754. format(buffer, charsmax(buffer), "models/player/%s/%s.mdl", buffer, buffer)
  755. ArrayPushCell(g_modelindex_survivor, engfunc(EngFunc_PrecacheModel, buffer))
  756. if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, buffer)
  757. if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, buffer)
  758. // Precache modelT.mdl files too
  759. copy(buffer[strlen(buffer)-4], charsmax(buffer) - (strlen(buffer)-4), "T.mdl")
  760. if (file_exists(buffer)) engfunc(EngFunc_PrecacheModel, buffer)
  761. }
  762. for (i = 0; i < ArraySize(model_admin_zombie); i++)
  763. {
  764. ArrayGetString(model_admin_zombie, i, buffer, charsmax(buffer))
  765. format(buffer, charsmax(buffer), "models/player/%s/%s.mdl", buffer, buffer)
  766. ArrayPushCell(g_modelindex_admin_zombie, engfunc(EngFunc_PrecacheModel, buffer))
  767. if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, buffer)
  768. if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, buffer)
  769. // Precache modelT.mdl files too
  770. copy(buffer[strlen(buffer)-4], charsmax(buffer) - (strlen(buffer)-4), "T.mdl")
  771. if (file_exists(buffer)) engfunc(EngFunc_PrecacheModel, buffer)
  772. }
  773. for (i = 0; i < ArraySize(model_admin_human); i++)
  774. {
  775. ArrayGetString(model_admin_human, i, buffer, charsmax(buffer))
  776. format(buffer, charsmax(buffer), "models/player/%s/%s.mdl", buffer, buffer)
  777. ArrayPushCell(g_modelindex_admin_human, engfunc(EngFunc_PrecacheModel, buffer))
  778. if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, buffer)
  779. if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, buffer)
  780. // Precache modelT.mdl files too
  781. copy(buffer[strlen(buffer)-4], charsmax(buffer) - (strlen(buffer)-4), "T.mdl")
  782. if (file_exists(buffer)) engfunc(EngFunc_PrecacheModel, buffer)
  783. }
  784.  
  785. // Custom weapon models
  786. engfunc(EngFunc_PrecacheModel, model_vknife_human)
  787. engfunc(EngFunc_PrecacheModel, model_vknife_nemesis)
  788. engfunc(EngFunc_PrecacheModel, model_vweapon_survivor)
  789. engfunc(EngFunc_PrecacheModel, model_grenade_infect)
  790. engfunc(EngFunc_PrecacheModel, model_grenade_fire)
  791. engfunc(EngFunc_PrecacheModel, model_grenade_frost)
  792. engfunc(EngFunc_PrecacheModel, model_grenade_flare)
  793. engfunc(EngFunc_PrecacheModel, model_vknife_admin_human)
  794. engfunc(EngFunc_PrecacheModel, model_vknife_admin_zombie)
  795.  
  796. // Custom sprites for grenades
  797. g_trailSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_trail)
  798. g_exploSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_ring)
  799. g_flameSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_fire)
  800. g_smokeSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_smoke)
  801. g_glassSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_glass)
  802. g_fire_explode = precache_model ("sprites/ZP/fire_explode.spr")
  803. g_frost_explode = precache_model ("sprites/ZP/frost_explode.spr")
  804. g_fire_gib = precache_model ("sprites/ZP/fire_gib.spr")
  805. g_frost_gib = precache_model ("sprites/ZP/frost_gib.spr")
  806. g_fire_trail = precache_model ("sprites/ZP/fire_trail.spr")
  807. g_frost_trail = precache_model ("sprites/ZP/frost_trail.spr")
  808. g_flare_trail = precache_model ("sprites/ZP/flare_trail.spr")
  809.  
  810. // Custom sounds
  811. for (i = 0; i < ArraySize(sound_win_zombies); i++)
  812. {
  813. ArrayGetString(sound_win_zombies, i, buffer, charsmax(buffer))
  814. if (ArrayGetCell(sound_win_zombies_ismp3, i))
  815. {
  816. format(buffer, charsmax(buffer), "sound/%s", buffer)
  817. engfunc(EngFunc_PrecacheGeneric, buffer)
  818. }
  819. else
  820. {
  821. engfunc(EngFunc_PrecacheSound, buffer)
  822. }
  823. }
  824. for (i = 0; i < ArraySize(sound_win_humans); i++)
  825. {
  826. ArrayGetString(sound_win_humans, i, buffer, charsmax(buffer))
  827. if (ArrayGetCell(sound_win_humans_ismp3, i))
  828. {
  829. format(buffer, charsmax(buffer), "sound/%s", buffer)
  830. engfunc(EngFunc_PrecacheGeneric, buffer)
  831. }
  832. else
  833. {
  834. engfunc(EngFunc_PrecacheSound, buffer)
  835. }
  836. }
  837. for (i = 0; i < ArraySize(sound_win_no_one); i++)
  838. {
  839. ArrayGetString(sound_win_no_one, i, buffer, charsmax(buffer))
  840. if (ArrayGetCell(sound_win_no_one_ismp3, i))
  841. {
  842. format(buffer, charsmax(buffer), "sound/%s", buffer)
  843. engfunc(EngFunc_PrecacheGeneric, buffer)
  844. }
  845. else
  846. {
  847. engfunc(EngFunc_PrecacheSound, buffer)
  848. }
  849. }
  850. for (i = 0; i < ArraySize(zombie_infect); i++)
  851. {
  852. ArrayGetString(zombie_infect, i, buffer, charsmax(buffer))
  853. engfunc(EngFunc_PrecacheSound, buffer)
  854. }
  855. for (i = 0; i < ArraySize(zombie_pain); i++)
  856. {
  857. ArrayGetString(zombie_pain, i, buffer, charsmax(buffer))
  858. engfunc(EngFunc_PrecacheSound, buffer)
  859. }
  860. for (i = 0; i < ArraySize(nemesis_pain); i++)
  861. {
  862. ArrayGetString(nemesis_pain, i, buffer, charsmax(buffer))
  863. engfunc(EngFunc_PrecacheSound, buffer)
  864. }
  865. for (i = 0; i < ArraySize(zombie_die); i++)
  866. {
  867. ArrayGetString(zombie_die, i, buffer, charsmax(buffer))
  868. engfunc(EngFunc_PrecacheSound, buffer)
  869. }
  870. for (i = 0; i < ArraySize(zombie_fall); i++)
  871. {
  872. ArrayGetString(zombie_fall, i, buffer, charsmax(buffer))
  873. engfunc(EngFunc_PrecacheSound, buffer)
  874. }
  875. for (i = 0; i < ArraySize(zombie_miss_slash); i++)
  876. {
  877. ArrayGetString(zombie_miss_slash, i, buffer, charsmax(buffer))
  878. engfunc(EngFunc_PrecacheSound, buffer)
  879. }
  880. for (i = 0; i < ArraySize(zombie_miss_wall); i++)
  881. {
  882. ArrayGetString(zombie_miss_wall, i, buffer, charsmax(buffer))
  883. engfunc(EngFunc_PrecacheSound, buffer)
  884. }
  885. for (i = 0; i < ArraySize(zombie_hit_normal); i++)
  886. {
  887. ArrayGetString(zombie_hit_normal, i, buffer, charsmax(buffer))
  888. engfunc(EngFunc_PrecacheSound, buffer)
  889. }
  890. for (i = 0; i < ArraySize(zombie_hit_stab); i++)
  891. {
  892. ArrayGetString(zombie_hit_stab, i, buffer, charsmax(buffer))
  893. engfunc(EngFunc_PrecacheSound, buffer)
  894. }
  895. for (i = 0; i < ArraySize(zombie_idle); i++)
  896. {
  897. ArrayGetString(zombie_idle, i, buffer, charsmax(buffer))
  898. engfunc(EngFunc_PrecacheSound, buffer)
  899. }
  900. for (i = 0; i < ArraySize(zombie_idle_last); i++)
  901. {
  902. ArrayGetString(zombie_idle_last, i, buffer, charsmax(buffer))
  903. engfunc(EngFunc_PrecacheSound, buffer)
  904. }
  905. for (i = 0; i < ArraySize(zombie_madness); i++)
  906. {
  907. ArrayGetString(zombie_madness, i, buffer, charsmax(buffer))
  908. engfunc(EngFunc_PrecacheSound, buffer)
  909. }
  910. for (i = 0; i < ArraySize(sound_nemesis); i++)
  911. {
  912. ArrayGetString(sound_nemesis, i, buffer, charsmax(buffer))
  913. engfunc(EngFunc_PrecacheSound, buffer)
  914. }
  915. for (i = 0; i < ArraySize(sound_survivor); i++)
  916. {
  917. ArrayGetString(sound_survivor, i, buffer, charsmax(buffer))
  918. engfunc(EngFunc_PrecacheSound, buffer)
  919. }
  920. for (i = 0; i < ArraySize(sound_swarm); i++)
  921. {
  922. ArrayGetString(sound_swarm, i, buffer, charsmax(buffer))
  923. engfunc(EngFunc_PrecacheSound, buffer)
  924. }
  925. for (i = 0; i < ArraySize(sound_multi); i++)
  926. {
  927. ArrayGetString(sound_multi, i, buffer, charsmax(buffer))
  928. engfunc(EngFunc_PrecacheSound, buffer)
  929. }
  930. for (i = 0; i < ArraySize(sound_plague); i++)
  931. {
  932. ArrayGetString(sound_plague, i, buffer, charsmax(buffer))
  933. engfunc(EngFunc_PrecacheSound, buffer)
  934. }
  935. for (i = 0; i < ArraySize(grenade_infect); i++)
  936. {
  937. ArrayGetString(grenade_infect, i, buffer, charsmax(buffer))
  938. engfunc(EngFunc_PrecacheSound, buffer)
  939. }
  940. for (i = 0; i < ArraySize(grenade_infect_player); i++)
  941. {
  942. ArrayGetString(grenade_infect_player, i, buffer, charsmax(buffer))
  943. engfunc(EngFunc_PrecacheSound, buffer)
  944. }
  945. for (i = 0; i < ArraySize(grenade_fire); i++)
  946. {
  947. ArrayGetString(grenade_fire, i, buffer, charsmax(buffer))
  948. engfunc(EngFunc_PrecacheSound, buffer)
  949. }
  950. for (i = 0; i < ArraySize(grenade_fire_player); i++)
  951. {
  952. ArrayGetString(grenade_fire_player, i, buffer, charsmax(buffer))
  953. engfunc(EngFunc_PrecacheSound, buffer)
  954. }
  955. for (i = 0; i < ArraySize(grenade_frost); i++)
  956. {
  957. ArrayGetString(grenade_frost, i, buffer, charsmax(buffer))
  958. engfunc(EngFunc_PrecacheSound, buffer)
  959. }
  960. for (i = 0; i < ArraySize(grenade_frost_player); i++)
  961. {
  962. ArrayGetString(grenade_frost_player, i, buffer, charsmax(buffer))
  963. engfunc(EngFunc_PrecacheSound, buffer)
  964. }
  965. for (i = 0; i < ArraySize(grenade_frost_break); i++)
  966. {
  967. ArrayGetString(grenade_frost_break, i, buffer, charsmax(buffer))
  968. engfunc(EngFunc_PrecacheSound, buffer)
  969. }
  970. for (i = 0; i < ArraySize(grenade_flare); i++)
  971. {
  972. ArrayGetString(grenade_flare, i, buffer, charsmax(buffer))
  973. engfunc(EngFunc_PrecacheSound, buffer)
  974. }
  975. for (i = 0; i < ArraySize(sound_antidote); i++)
  976. {
  977. ArrayGetString(sound_antidote, i, buffer, charsmax(buffer))
  978. engfunc(EngFunc_PrecacheSound, buffer)
  979. }
  980. for (i = 0; i < ArraySize(sound_thunder); i++)
  981. {
  982. ArrayGetString(sound_thunder, i, buffer, charsmax(buffer))
  983. engfunc(EngFunc_PrecacheSound, buffer)
  984. }
  985.  
  986. // Ambience Sounds
  987. if (g_ambience_sounds[AMBIENCE_SOUNDS_INFECTION])
  988. {
  989. for (i = 0; i < ArraySize(sound_ambience1); i++)
  990. {
  991. ArrayGetString(sound_ambience1, i, buffer, charsmax(buffer))
  992.  
  993. if (ArrayGetCell(sound_ambience1_ismp3, i))
  994. {
  995. format(buffer, charsmax(buffer), "sound/%s", buffer)
  996. engfunc(EngFunc_PrecacheGeneric, buffer)
  997. }
  998. else
  999. {
  1000. engfunc(EngFunc_PrecacheSound, buffer)
  1001. }
  1002. }
  1003. }
  1004. if (g_ambience_sounds[AMBIENCE_SOUNDS_NEMESIS])
  1005. {
  1006. for (i = 0; i < ArraySize(sound_ambience2); i++)
  1007. {
  1008. ArrayGetString(sound_ambience2, i, buffer, charsmax(buffer))
  1009.  
  1010. if (ArrayGetCell(sound_ambience2_ismp3, i))
  1011. {
  1012. format(buffer, charsmax(buffer), "sound/%s", buffer)
  1013. engfunc(EngFunc_PrecacheGeneric, buffer)
  1014. }
  1015. else
  1016. {
  1017. engfunc(EngFunc_PrecacheSound, buffer)
  1018. }
  1019. }
  1020. }
  1021. if (g_ambience_sounds[AMBIENCE_SOUNDS_SURVIVOR])
  1022. {
  1023. for (i = 0; i < ArraySize(sound_ambience3); i++)
  1024. {
  1025. ArrayGetString(sound_ambience3, i, buffer, charsmax(buffer))
  1026.  
  1027. if (ArrayGetCell(sound_ambience3_ismp3, i))
  1028. {
  1029. format(buffer, charsmax(buffer), "sound/%s", buffer)
  1030. engfunc(EngFunc_PrecacheGeneric, buffer)
  1031. }
  1032. else
  1033. {
  1034. engfunc(EngFunc_PrecacheSound, buffer)
  1035. }
  1036. }
  1037. }
  1038. if (g_ambience_sounds[AMBIENCE_SOUNDS_SWARM])
  1039. {
  1040. for (i = 0; i < ArraySize(sound_ambience4); i++)
  1041. {
  1042. ArrayGetString(sound_ambience4, i, buffer, charsmax(buffer))
  1043.  
  1044. if (ArrayGetCell(sound_ambience4_ismp3, i))
  1045. {
  1046. format(buffer, charsmax(buffer), "sound/%s", buffer)
  1047. engfunc(EngFunc_PrecacheGeneric, buffer)
  1048. }
  1049. else
  1050. {
  1051. engfunc(EngFunc_PrecacheSound, buffer)
  1052. }
  1053. }
  1054. }
  1055. if (g_ambience_sounds[AMBIENCE_SOUNDS_PLAGUE])
  1056. {
  1057. for (i = 0; i < ArraySize(sound_ambience5); i++)
  1058. {
  1059. ArrayGetString(sound_ambience5, i, buffer, charsmax(buffer))
  1060.  
  1061. if (ArrayGetCell(sound_ambience5_ismp3, i))
  1062. {
  1063. format(buffer, charsmax(buffer), "sound/%s", buffer)
  1064. engfunc(EngFunc_PrecacheGeneric, buffer)
  1065. }
  1066. else
  1067. {
  1068. engfunc(EngFunc_PrecacheSound, buffer)
  1069. }
  1070. }
  1071. }
  1072.  
  1073. // CS sounds (just in case)
  1074. engfunc(EngFunc_PrecacheSound, sound_flashlight)
  1075. engfunc(EngFunc_PrecacheSound, sound_buyammo)
  1076. engfunc(EngFunc_PrecacheSound, sound_armorhit)
  1077.  
  1078. new ent
  1079.  
  1080. // Fake Hostage (to force round ending)
  1081. ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "hostage_entity"))
  1082. if (pev_valid(ent))
  1083. {
  1084. engfunc(EngFunc_SetOrigin, ent, Float:{8192.0,8192.0,8192.0})
  1085. dllfunc(DLLFunc_Spawn, ent)
  1086. }
  1087.  
  1088. // Weather/ambience effects
  1089. if (g_ambience_fog)
  1090. {
  1091. ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "env_fog"))
  1092. if (pev_valid(ent))
  1093. {
  1094. fm_set_kvd(ent, "density", g_fog_density, "env_fog")
  1095. fm_set_kvd(ent, "rendercolor", g_fog_color, "env_fog")
  1096. }
  1097. }
  1098. if (g_ambience_rain) engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "env_rain"))
  1099. if (g_ambience_snow) engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "env_snow"))
  1100.  
  1101. // Custom buyzone for all players
  1102. g_buyzone_ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "func_buyzone"))
  1103. if (pev_valid(g_buyzone_ent))
  1104. {
  1105. dllfunc(DLLFunc_Spawn, g_buyzone_ent)
  1106. set_pev(g_buyzone_ent, pev_solid, SOLID_NOT)
  1107. }
  1108.  
  1109. // Prevent some entities from spawning
  1110. g_fwSpawn = register_forward(FM_Spawn, "fw_Spawn")
  1111.  
  1112. // Prevent hostage sounds from being precached
  1113. g_fwPrecacheSound = register_forward(FM_PrecacheSound, "fw_PrecacheSound")
  1114. }
  1115.  
  1116. public plugin_init()
  1117. {
  1118. // Plugin disabled?
  1119. if (!g_pluginenabled) return;
  1120.  
  1121. // No zombie classes?
  1122. if (!g_zclass_i) set_fail_state("No zombie classes loaded!")
  1123.  
  1124. // Language files
  1125. register_dictionary("zombie_plague.txt")
  1126.  
  1127. // Events
  1128. register_event("HLTV", "event_round_start", "a", "1=0", "2=0")
  1129. register_logevent("logevent_round_start",2, "1=Round_Start")
  1130. register_logevent("logevent_round_end", 2, "1=Round_End")
  1131. register_event("AmmoX", "event_ammo_x", "be")
  1132. if (g_ambience_sounds[AMBIENCE_SOUNDS_INFECTION] || g_ambience_sounds[AMBIENCE_SOUNDS_NEMESIS] || g_ambience_sounds[AMBIENCE_SOUNDS_SURVIVOR] || g_ambience_sounds[AMBIENCE_SOUNDS_SWARM] || g_ambience_sounds[AMBIENCE_SOUNDS_PLAGUE])
  1133. register_event("30", "event_intermission", "a")
  1134.  
  1135. // HAM Forwards
  1136. RegisterHam(Ham_Spawn, "player", "fw_PlayerSpawn_Post", 1)
  1137. RegisterHam(Ham_Killed, "player", "fw_PlayerKilled")
  1138. RegisterHam(Ham_Killed, "player", "fw_PlayerKilled_Post", 1)
  1139. RegisterHam(Ham_TakeDamage, "player", "fw_TakeDamage")
  1140. RegisterHam(Ham_TakeDamage, "player", "fw_TakeDamage_Post", 1)
  1141. RegisterHam(Ham_TraceAttack, "player", "fw_TraceAttack")
  1142. RegisterHam(Ham_Player_ResetMaxSpeed, "player", "fw_ResetMaxSpeed_Post", 1)
  1143. RegisterHam(Ham_Use, "func_tank", "fw_UseStationary")
  1144. RegisterHam(Ham_Use, "func_tankmortar", "fw_UseStationary")
  1145. RegisterHam(Ham_Use, "func_tankrocket", "fw_UseStationary")
  1146. RegisterHam(Ham_Use, "func_tanklaser", "fw_UseStationary")
  1147. RegisterHam(Ham_Use, "func_tank", "fw_UseStationary_Post", 1)
  1148. RegisterHam(Ham_Use, "func_tankmortar", "fw_UseStationary_Post", 1)
  1149. RegisterHam(Ham_Use, "func_tankrocket", "fw_UseStationary_Post", 1)
  1150. RegisterHam(Ham_Use, "func_tanklaser", "fw_UseStationary_Post", 1)
  1151. RegisterHam(Ham_Use, "func_pushable", "fw_UsePushable")
  1152. RegisterHam(Ham_Touch, "weaponbox", "fw_TouchWeapon")
  1153. RegisterHam(Ham_Touch, "armoury_entity", "fw_TouchWeapon")
  1154. RegisterHam(Ham_Touch, "weapon_shield", "fw_TouchWeapon")
  1155. RegisterHam(Ham_AddPlayerItem, "player", "fw_AddPlayerItem")
  1156. for (new i = 1; i < sizeof WEAPONENTNAMES; i++)
  1157. if (WEAPONENTNAMES[i][0]) RegisterHam(Ham_Item_Deploy, WEAPONENTNAMES[i], "fw_Item_Deploy_Post", 1)
  1158.  
  1159. // FM Forwards
  1160. register_forward(FM_ClientDisconnect, "fw_ClientDisconnect")
  1161. register_forward(FM_ClientDisconnect, "fw_ClientDisconnect_Post", 1)
  1162. register_forward(FM_ClientKill, "fw_ClientKill")
  1163. register_forward(FM_EmitSound, "fw_EmitSound")
  1164. if (!g_handle_models_on_separate_ent) register_forward(FM_SetClientKeyValue, "fw_SetClientKeyValue")
  1165. register_forward(FM_ClientUserInfoChanged, "fw_ClientUserInfoChanged")
  1166. register_forward(FM_GetGameDescription, "fw_GetGameDescription")
  1167. register_forward(FM_SetModel, "fw_SetModel")
  1168. RegisterHam(Ham_Think, "grenade", "fw_ThinkGrenade")
  1169. register_forward(FM_CmdStart, "fw_CmdStart")
  1170. register_forward(FM_PlayerPreThink, "fw_PlayerPreThink")
  1171. unregister_forward(FM_Spawn, g_fwSpawn)
  1172. unregister_forward(FM_PrecacheSound, g_fwPrecacheSound)
  1173.  
  1174. // Client commands
  1175. register_clcmd("say zpmenu", "clcmd_saymenu")
  1176. register_clcmd("say /zpmenu", "clcmd_saymenu")
  1177. register_clcmd("say unstuck", "clcmd_sayunstuck")
  1178. register_clcmd("say /unstuck", "clcmd_sayunstuck")
  1179. register_clcmd("nightvision", "clcmd_nightvision")
  1180. register_clcmd("drop", "clcmd_drop")
  1181. register_clcmd("buyammo1", "clcmd_buyammo")
  1182. register_clcmd("buyammo2", "clcmd_buyammo")
  1183. register_clcmd("chooseteam", "clcmd_changeteam")
  1184. register_clcmd("jointeam", "clcmd_changeteam")
  1185.  
  1186. // Menus
  1187. register_menu("Game Menu", KEYSMENU, "menu_game")
  1188. register_menu("Buy Menu 1", KEYSMENU, "menu_buy1")
  1189. register_menu("Buy Menu 2", KEYSMENU, "menu_buy2")
  1190. register_menu("Mod Info", KEYSMENU, "menu_info")
  1191. register_menu("Admin Menu", KEYSMENU, "menu_admin")
  1192.  
  1193. // CS Buy Menus (to prevent zombies/survivor from buying)
  1194. register_menucmd(register_menuid("#Buy", 1), 511, "menu_cs_buy")
  1195. register_menucmd(register_menuid("BuyPistol", 1), 511, "menu_cs_buy")
  1196. register_menucmd(register_menuid("BuyShotgun", 1), 511, "menu_cs_buy")
  1197. register_menucmd(register_menuid("BuySub", 1), 511, "menu_cs_buy")
  1198. register_menucmd(register_menuid("BuyRifle", 1), 511, "menu_cs_buy")
  1199. register_menucmd(register_menuid("BuyMachine", 1), 511, "menu_cs_buy")
  1200. register_menucmd(register_menuid("BuyItem", 1), 511, "menu_cs_buy")
  1201. register_menucmd(-28, 511, "menu_cs_buy")
  1202. register_menucmd(-29, 511, "menu_cs_buy")
  1203. register_menucmd(-30, 511, "menu_cs_buy")
  1204. register_menucmd(-32, 511, "menu_cs_buy")
  1205. register_menucmd(-31, 511, "menu_cs_buy")
  1206. register_menucmd(-33, 511, "menu_cs_buy")
  1207. register_menucmd(-34, 511, "menu_cs_buy")
  1208.  
  1209. // Admin commands
  1210. register_concmd("zp_zombie", "cmd_zombie", _, "<target> - Turn someone into a Zombie", 0)
  1211. register_concmd("zp_human", "cmd_human", _, "<target> - Turn someone back to Human", 0)
  1212. register_concmd("zp_nemesis", "cmd_nemesis", _, "<target> - Turn someone into a Nemesis", 0)
  1213. register_concmd("zp_survivor", "cmd_survivor", _, "<target> - Turn someone into a Survivor", 0)
  1214. register_concmd("zp_respawn", "cmd_respawn", _, "<target> - Respawn someone", 0)
  1215. register_concmd("zp_swarm", "cmd_swarm", _, " - Start Swarm Mode", 0)
  1216. register_concmd("zp_multi", "cmd_multi", _, " - Start Multi Infection", 0)
  1217. register_concmd("zp_plague", "cmd_plague", _, " - Start Plague Mode", 0)
  1218.  
  1219. // Message IDs
  1220. g_msgScoreInfo = get_user_msgid("ScoreInfo")
  1221. g_msgTeamInfo = get_user_msgid("TeamInfo")
  1222. g_msgDeathMsg = get_user_msgid("DeathMsg")
  1223. g_msgScoreAttrib = get_user_msgid("ScoreAttrib")
  1224. g_msgSetFOV = get_user_msgid("SetFOV")
  1225. g_msgScreenFade = get_user_msgid("ScreenFade")
  1226. g_msgScreenShake = get_user_msgid("ScreenShake")
  1227. g_msgNVGToggle = get_user_msgid("NVGToggle")
  1228. g_msgFlashlight = get_user_msgid("Flashlight")
  1229. g_msgFlashBat = get_user_msgid("FlashBat")
  1230. g_msgAmmoPickup = get_user_msgid("AmmoPickup")
  1231. g_msgDamage = get_user_msgid("Damage")
  1232. g_msgHideWeapon = get_user_msgid("HideWeapon")
  1233. g_msgCrosshair = get_user_msgid("Crosshair")
  1234. g_msgSayText = get_user_msgid("SayText")
  1235. g_msgCurWeapon = get_user_msgid("CurWeapon")
  1236.  
  1237. // Message hooks
  1238. register_message(g_msgCurWeapon, "message_cur_weapon")
  1239. register_message(get_user_msgid("Money"), "message_money")
  1240. register_message(get_user_msgid("Health"), "message_health")
  1241. register_message(g_msgFlashBat, "message_flashbat")
  1242. register_message(g_msgScreenFade, "message_screenfade")
  1243. register_message(g_msgNVGToggle, "message_nvgtoggle")
  1244. if (g_handle_models_on_separate_ent) register_message(get_user_msgid("ClCorpse"), "message_clcorpse")
  1245. register_message(get_user_msgid("WeapPickup"), "message_weappickup")
  1246. register_message(g_msgAmmoPickup, "message_ammopickup")
  1247. register_message(get_user_msgid("Scenario"), "message_scenario")
  1248. register_message(get_user_msgid("HostagePos"), "message_hostagepos")
  1249. register_message(get_user_msgid("TextMsg"), "message_textmsg")
  1250. register_message(get_user_msgid("SendAudio"), "message_sendaudio")
  1251. register_message(get_user_msgid("TeamScore"), "message_teamscore")
  1252. register_message(g_msgTeamInfo, "message_teaminfo")
  1253.  
  1254. // CVARS - General Purpose
  1255. cvar_warmup = register_cvar("zp_delay", "10")
  1256. cvar_lighting = register_cvar("zp_lighting", "a")
  1257. cvar_thunder = register_cvar("zp_thunderclap", "90")
  1258. cvar_triggered = register_cvar("zp_triggered_lights", "1")
  1259. cvar_removedoors = register_cvar("zp_remove_doors", "0")
  1260. cvar_blockpushables = register_cvar("zp_blockuse_pushables", "1")
  1261. cvar_blocksuicide = register_cvar("zp_block_suicide", "1")
  1262. cvar_randspawn = register_cvar("zp_random_spawn", "1")
  1263. cvar_respawnworldspawnkill = register_cvar("zp_respawn_on_worldspawn_kill", "1")
  1264. cvar_removedropped = register_cvar("zp_remove_dropped", "0")
  1265. cvar_removemoney = register_cvar("zp_remove_money", "1")
  1266. cvar_buycustom = register_cvar("zp_buy_custom", "1")
  1267. cvar_buyzonetime = register_cvar("zp_buyzone_time", "0.0")
  1268. cvar_randweapons = register_cvar("zp_random_weapons", "0")
  1269. cvar_adminmodelshuman = register_cvar("zp_admin_models_human", "1")
  1270. cvar_adminknifemodelshuman = register_cvar("zp_admin_knife_models_human", "0")
  1271. cvar_adminmodelszombie = register_cvar("zp_admin_models_zombie", "1")
  1272. cvar_adminknifemodelszombie = register_cvar("zp_admin_knife_models_zombie", "0")
  1273. cvar_zclasses = register_cvar("zp_zombie_classes", "1")
  1274. cvar_statssave = register_cvar("zp_stats_save", "1")
  1275. cvar_startammopacks = register_cvar("zp_starting_ammo_packs", "5")
  1276. cvar_preventconsecutive = register_cvar("zp_prevent_consecutive_modes", "1")
  1277. cvar_keephealthondisconnect = register_cvar("zp_keep_health_on_disconnect", "1")
  1278. cvar_huddisplay = register_cvar("zp_hud_display", "1")
  1279.  
  1280. // CVARS - Deathmatch
  1281. cvar_deathmatch = register_cvar("zp_deathmatch", "0")
  1282. cvar_spawndelay = register_cvar("zp_spawn_delay", "5")
  1283. cvar_spawnprotection = register_cvar("zp_spawn_protection", "5")
  1284. cvar_respawnonsuicide = register_cvar("zp_respawn_on_suicide", "0")
  1285. cvar_respawnafterlast = register_cvar("zp_respawn_after_last_human", "1")
  1286. cvar_allowrespawninfection = register_cvar("zp_infection_allow_respawn", "1")
  1287. cvar_allowrespawnnem = register_cvar("zp_nem_allow_respawn", "0")
  1288. cvar_allowrespawnsurv = register_cvar("zp_surv_allow_respawn", "0")
  1289. cvar_allowrespawnswarm = register_cvar("zp_swarm_allow_respawn", "0")
  1290. cvar_allowrespawnplague = register_cvar("zp_plague_allow_respawn", "0")
  1291. cvar_respawnzomb = register_cvar("zp_respawn_zombies", "1")
  1292. cvar_respawnhum = register_cvar("zp_respawn_humans", "1")
  1293. cvar_respawnnem = register_cvar("zp_respawn_nemesis", "1")
  1294. cvar_respawnsurv = register_cvar("zp_respawn_survivors", "1")
  1295.  
  1296. // CVARS - Extra Items
  1297. cvar_extraitems = register_cvar("zp_extra_items", "1")
  1298. cvar_extraweapons = register_cvar("zp_extra_weapons", "1")
  1299. cvar_extranvision = register_cvar("zp_extra_nvision", "1")
  1300. cvar_extraantidote = register_cvar("zp_extra_antidote", "1")
  1301. cvar_antidotelimit = register_cvar("zp_extra_antidote_limit", "999")
  1302. cvar_extramadness = register_cvar("zp_extra_madness", "1")
  1303. cvar_madnesslimit = register_cvar("zp_extra_madness_limit", "999")
  1304. cvar_madnessduration = register_cvar("zp_extra_madness_duration", "5.0")
  1305. cvar_extrainfbomb = register_cvar("zp_extra_infbomb", "1")
  1306. cvar_infbomblimit = register_cvar("zp_extra_infbomb_limit", "999")
  1307.  
  1308. // CVARS - Flashlight and Nightvision
  1309. cvar_nvggive = register_cvar("zp_nvg_give", "1")
  1310. cvar_customnvg = register_cvar("zp_nvg_custom", "1")
  1311. cvar_nvgsize = register_cvar("zp_nvg_size", "80")
  1312. cvar_nvgcolor[0] = register_cvar("zp_nvg_color_R", "0")
  1313. cvar_nvgcolor[1] = register_cvar("zp_nvg_color_G", "150")
  1314. cvar_nvgcolor[2] = register_cvar("zp_nvg_color_B", "0")
  1315. cvar_humnvgcolor[0] = register_cvar("zp_nvg_hum_color_R", "0")
  1316. cvar_humnvgcolor[1] = register_cvar("zp_nvg_hum_color_G", "150")
  1317. cvar_humnvgcolor[2] = register_cvar("zp_nvg_hum_color_B", "0")
  1318. cvar_nemnvgcolor[0] = register_cvar("zp_nvg_nem_color_R", "150")
  1319. cvar_nemnvgcolor[1] = register_cvar("zp_nvg_nem_color_G", "0")
  1320. cvar_nemnvgcolor[2] = register_cvar("zp_nvg_nem_color_B", "0")
  1321. cvar_customflash = register_cvar("zp_flash_custom", "0")
  1322. cvar_flashsize = register_cvar("zp_flash_size", "10")
  1323. cvar_flashdrain = register_cvar("zp_flash_drain", "1")
  1324. cvar_flashcharge = register_cvar("zp_flash_charge", "5")
  1325. cvar_flashdist = register_cvar("zp_flash_distance", "1000")
  1326. cvar_flashcolor[0] = register_cvar("zp_flash_color_R", "100")
  1327. cvar_flashcolor[1] = register_cvar("zp_flash_color_G", "100")
  1328. cvar_flashcolor[2] = register_cvar("zp_flash_color_B", "100")
  1329. cvar_flashshowall = register_cvar("zp_flash_show_all", "1")
  1330.  
  1331. // CVARS - Knockback
  1332. cvar_knockback = register_cvar("zp_knockback", "0")
  1333. cvar_knockbackdamage = register_cvar("zp_knockback_damage", "1")
  1334. cvar_knockbackpower = register_cvar("zp_knockback_power", "1")
  1335. cvar_knockbackzvel = register_cvar("zp_knockback_zvel", "0")
  1336. cvar_knockbackducking = register_cvar("zp_knockback_ducking", "0.25")
  1337. cvar_knockbackdist = register_cvar("zp_knockback_distance", "500")
  1338. cvar_nemknockback = register_cvar("zp_knockback_nemesis", "0.25")
  1339.  
  1340. // CVARS - Leap
  1341. cvar_leapzombies = register_cvar("zp_leap_zombies", "0")
  1342. cvar_leapzombiesforce = register_cvar("zp_leap_zombies_force", "500")
  1343. cvar_leapzombiesheight = register_cvar("zp_leap_zombies_height", "300")
  1344. cvar_leapzombiescooldown = register_cvar("zp_leap_zombies_cooldown", "5.0")
  1345. cvar_leapnemesis = register_cvar("zp_leap_nemesis", "1")
  1346. cvar_leapnemesisforce = register_cvar("zp_leap_nemesis_force", "500")
  1347. cvar_leapnemesisheight = register_cvar("zp_leap_nemesis_height", "300")
  1348. cvar_leapnemesiscooldown = register_cvar("zp_leap_nemesis_cooldown", "5.0")
  1349. cvar_leapsurvivor = register_cvar("zp_leap_survivor", "0")
  1350. cvar_leapsurvivorforce = register_cvar("zp_leap_survivor_force", "500")
  1351. cvar_leapsurvivorheight = register_cvar("zp_leap_survivor_height", "300")
  1352. cvar_leapsurvivorcooldown = register_cvar("zp_leap_survivor_cooldown", "5.0")
  1353.  
  1354. // CVARS - Humans
  1355. cvar_humanhp = register_cvar("zp_human_health", "100")
  1356. cvar_humanlasthp = register_cvar("zp_human_last_extrahp", "0")
  1357. cvar_humanspd = register_cvar("zp_human_speed", "240")
  1358. cvar_humangravity = register_cvar("zp_human_gravity", "1.0")
  1359. cvar_humanarmor = register_cvar("zp_human_armor_protect", "1")
  1360. cvar_infammo = register_cvar("zp_human_unlimited_ammo", "0")
  1361. cvar_ammodamage_human = register_cvar("zp_human_damage_reward", "500")
  1362. cvar_fragskill = register_cvar("zp_human_frags_for_kill", "1")
  1363.  
  1364. // CVARS - Custom Grenades
  1365. cvar_firegrenades = register_cvar("zp_fire_grenades", "1")
  1366. cvar_fireduration = register_cvar("zp_fire_duration", "10")
  1367. cvar_firedamage = register_cvar("zp_fire_damage", "5")
  1368. cvar_fireslowdown = register_cvar("zp_fire_slowdown", "0.5")
  1369. cvar_frostgrenades = register_cvar("zp_frost_grenades", "1")
  1370. cvar_freezeduration = register_cvar("zp_frost_duration", "3")
  1371. cvar_flaregrenades = register_cvar("zp_flare_grenades","1")
  1372. cvar_flareduration = register_cvar("zp_flare_duration", "60")
  1373. cvar_flaresize = register_cvar("zp_flare_size", "25")
  1374. cvar_flarecolor = register_cvar("zp_flare_color", "0")
  1375.  
  1376. // CVARS - Zombies
  1377. cvar_zombiefirsthp = register_cvar("zp_zombie_first_hp", "2.0")
  1378. cvar_zombiearmor = register_cvar("zp_zombie_armor", "0.75")
  1379. cvar_hitzones = register_cvar("zp_zombie_hitzones", "0")
  1380. cvar_zombiebonushp = register_cvar("zp_zombie_infect_health", "100")
  1381. cvar_zombiefov = register_cvar("zp_zombie_fov", "110")
  1382. cvar_zombiesilent = register_cvar("zp_zombie_silent", "1")
  1383. cvar_zombiepainfree = register_cvar("zp_zombie_painfree", "2")
  1384. cvar_zombiebleeding = register_cvar("zp_zombie_bleeding", "1")
  1385. cvar_ammoinfect = register_cvar("zp_zombie_infect_reward", "1")
  1386. cvar_ammodamage_zombie = register_cvar("zp_zombie_damage_reward", "0")
  1387. cvar_fragsinfect = register_cvar("zp_zombie_frags_for_infect", "1")
  1388.  
  1389. // CVARS - Special Effects
  1390. cvar_infectionscreenfade = register_cvar("zp_infection_screenfade", "1")
  1391. cvar_infectionscreenshake = register_cvar("zp_infection_screenshake", "1")
  1392. cvar_infectionsparkle = register_cvar("zp_infection_sparkle", "1")
  1393. cvar_infectiontracers = register_cvar("zp_infection_tracers", "1")
  1394. cvar_infectionparticles = register_cvar("zp_infection_particles", "1")
  1395. cvar_hudicons = register_cvar("zp_hud_icons", "1")
  1396.  
  1397. // CVARS - Nemesis
  1398. cvar_nem = register_cvar("zp_nem_enabled", "1")
  1399. cvar_nemchance = register_cvar("zp_nem_chance", "20")
  1400. cvar_nemminplayers = register_cvar("zp_nem_min_players", "0")
  1401. cvar_nemhp = register_cvar("zp_nem_health", "0")
  1402. cvar_nembasehp = register_cvar("zp_nem_base_health", "0")
  1403. cvar_nemspd = register_cvar("zp_nem_speed", "250")
  1404. cvar_nemgravity = register_cvar("zp_nem_gravity", "0.5")
  1405. cvar_nemdamage = register_cvar("zp_nem_damage", "250")
  1406. cvar_nemglow = register_cvar("zp_nem_glow", "1")
  1407. cvar_nemaura = register_cvar("zp_nem_aura", "1")
  1408. cvar_nempainfree = register_cvar("zp_nem_painfree", "0")
  1409. cvar_nemignorefrags = register_cvar("zp_nem_ignore_frags", "1")
  1410. cvar_nemignoreammo = register_cvar("zp_nem_ignore_rewards", "1")
  1411.  
  1412. // CVARS - Survivor
  1413. cvar_surv = register_cvar("zp_surv_enabled", "1")
  1414. cvar_survchance = register_cvar("zp_surv_chance", "20")
  1415. cvar_survminplayers = register_cvar("zp_surv_min_players", "0")
  1416. cvar_survhp = register_cvar("zp_surv_health", "0")
  1417. cvar_survbasehp = register_cvar("zp_surv_base_health", "0")
  1418. cvar_survspd = register_cvar("zp_surv_speed", "230")
  1419. cvar_survgravity = register_cvar("zp_surv_gravity", "1.25")
  1420. cvar_survglow = register_cvar("zp_surv_glow", "1")
  1421. cvar_survaura = register_cvar("zp_surv_aura", "1")
  1422. cvar_survpainfree = register_cvar("zp_surv_painfree", "1")
  1423. cvar_survignorefrags = register_cvar("zp_surv_ignore_frags", "1")
  1424. cvar_survignoreammo = register_cvar("zp_surv_ignore_rewards", "1")
  1425. cvar_survweapon = register_cvar("zp_surv_weapon", "weapon_m249")
  1426. cvar_survinfammo = register_cvar("zp_surv_unlimited_ammo", "2")
  1427.  
  1428. // CVARS - Swarm Mode
  1429. cvar_swarm = register_cvar("zp_swarm_enabled", "1")
  1430. cvar_swarmchance = register_cvar("zp_swarm_chance", "20")
  1431. cvar_swarmminplayers = register_cvar("zp_swarm_min_players", "0")
  1432.  
  1433. // CVARS - Multi Infection
  1434. cvar_multi = register_cvar("zp_multi_enabled", "1")
  1435. cvar_multichance = register_cvar("zp_multi_chance", "20")
  1436. cvar_multiminplayers = register_cvar("zp_multi_min_players", "0")
  1437. cvar_multiratio = register_cvar("zp_multi_ratio", "0.15")
  1438.  
  1439. // CVARS - Plague Mode
  1440. cvar_plague = register_cvar("zp_plague_enabled", "1")
  1441. cvar_plaguechance = register_cvar("zp_plague_chance", "30")
  1442. cvar_plagueminplayers = register_cvar("zp_plague_min_players", "0")
  1443. cvar_plagueratio = register_cvar("zp_plague_ratio", "0.5")
  1444. cvar_plaguenemnum = register_cvar("zp_plague_nem_number", "1")
  1445. cvar_plaguenemhpmulti = register_cvar("zp_plague_nem_hp_multi", "0.5")
  1446. cvar_plaguesurvnum = register_cvar("zp_plague_surv_number", "1")
  1447. cvar_plaguesurvhpmulti = register_cvar("zp_plague_surv_hp_multi", "0.5")
  1448.  
  1449. // CVARS - Others
  1450. cvar_logcommands = register_cvar("zp_logcommands", "1")
  1451. cvar_showactivity = get_cvar_pointer("amx_show_activity")
  1452. cvar_botquota = get_cvar_pointer("bot_quota")
  1453. register_cvar("zp_version", PLUGIN_VERSION, FCVAR_SERVER|FCVAR_SPONLY)
  1454. set_cvar_string("zp_version", PLUGIN_VERSION)
  1455.  
  1456. // Custom Forwards
  1457. g_fwRoundStart = CreateMultiForward("zp_round_started", ET_IGNORE, FP_CELL, FP_CELL)
  1458. g_fwRoundEnd = CreateMultiForward("zp_round_ended", ET_IGNORE, FP_CELL)
  1459. g_fwUserInfected_pre = CreateMultiForward("zp_user_infected_pre", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL)
  1460. g_fwUserInfected_post = CreateMultiForward("zp_user_infected_post", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL)
  1461. g_fwUserHumanized_pre = CreateMultiForward("zp_user_humanized_pre", ET_IGNORE, FP_CELL, FP_CELL)
  1462. g_fwUserHumanized_post = CreateMultiForward("zp_user_humanized_post", ET_IGNORE, FP_CELL, FP_CELL)
  1463. g_fwUserInfect_attempt = CreateMultiForward("zp_user_infect_attempt", ET_CONTINUE, FP_CELL, FP_CELL, FP_CELL)
  1464. g_fwUserHumanize_attempt = CreateMultiForward("zp_user_humanize_attempt", ET_CONTINUE, FP_CELL, FP_CELL)
  1465. g_fwExtraItemSelected = CreateMultiForward("zp_extra_item_selected", ET_CONTINUE, FP_CELL, FP_CELL)
  1466. g_fwUserUnfrozen = CreateMultiForward("zp_user_unfrozen", ET_IGNORE, FP_CELL)
  1467. g_fwUserLastZombie = CreateMultiForward("zp_user_last_zombie", ET_IGNORE, FP_CELL)
  1468. g_fwUserLastHuman = CreateMultiForward("zp_user_last_human", ET_IGNORE, FP_CELL)
  1469.  
  1470. // Collect random spawn points
  1471. load_spawns()
  1472.  
  1473. // Set a random skybox?
  1474. if (g_sky_enable)
  1475. {
  1476. new sky[32]
  1477. ArrayGetString(g_sky_names, random_num(0, ArraySize(g_sky_names) - 1), sky, charsmax(sky))
  1478. set_cvar_string("sv_skyname", sky)
  1479. }
  1480.  
  1481. // Disable sky lighting so it doesn't mess with our custom lighting
  1482. set_cvar_num("sv_skycolor_r", 0)
  1483. set_cvar_num("sv_skycolor_g", 0)
  1484. set_cvar_num("sv_skycolor_b", 0)
  1485.  
  1486. // Create the HUD Sync Objects
  1487. g_MsgSync = CreateHudSyncObj()
  1488. g_MsgSync2 = CreateHudSyncObj()
  1489.  
  1490. // Format mod name
  1491. formatex(g_modname, charsmax(g_modname), "Zombie Plague %s", PLUGIN_VERSION)
  1492.  
  1493. // Get Max Players
  1494. g_maxplayers = get_maxplayers()
  1495.  
  1496. // Reserved saving slots starts on maxplayers+1
  1497. db_slot_i = g_maxplayers+1
  1498.  
  1499. // Check if it's a CZ server
  1500. new mymod[6]
  1501. get_modname(mymod, charsmax(mymod))
  1502. if (equal(mymod, "czero")) g_czero = 1
  1503. }
  1504.  
  1505. public plugin_cfg()
  1506. {
  1507. // Plugin disabled?
  1508. if (!g_pluginenabled) return;
  1509.  
  1510. // Get configs dir
  1511. new cfgdir[32]
  1512. get_configsdir(cfgdir, charsmax(cfgdir))
  1513.  
  1514. // Execute config file (zombieplague.cfg)
  1515. server_cmd("exec %s/zombieplague.cfg", cfgdir)
  1516.  
  1517. // Prevent any more stuff from registering
  1518. g_arrays_created = false
  1519.  
  1520. // Save customization data
  1521. save_customization()
  1522.  
  1523. // Lighting task
  1524. set_task(5.0, "lighting_effects", _, _, _, "b")
  1525.  
  1526. // Cache CVARs after configs are loaded / call roundstart manually
  1527. set_task(0.5, "cache_cvars")
  1528. set_task(0.5, "event_round_start")
  1529. set_task(0.5, "logevent_round_start")
  1530. }
  1531.  
  1532. /*================================================================================
  1533. [Main Events]
  1534. =================================================================================*/
  1535.  
  1536. // Event Round Start
  1537. public event_round_start()
  1538. {
  1539. // Remove doors/lights?
  1540. set_task(0.1, "remove_stuff")
  1541.  
  1542. // New round starting
  1543. g_newround = true
  1544. g_endround = false
  1545. g_survround = false
  1546. g_nemround = false
  1547. g_swarmround = false
  1548. g_plagueround = false
  1549. g_modestarted = false
  1550.  
  1551. // Reset bought infection bombs counter
  1552. g_infbombcounter = 0
  1553. g_antidotecounter = 0
  1554. g_madnesscounter = 0
  1555.  
  1556. // Freezetime begins
  1557. g_freezetime = true
  1558.  
  1559. // Show welcome message and T-Virus notice
  1560. remove_task(TASK_WELCOMEMSG)
  1561. set_task(2.0, "welcome_msg", TASK_WELCOMEMSG)
  1562.  
  1563. // Set a new "Make Zombie Task"
  1564. remove_task(TASK_MAKEZOMBIE)
  1565. set_task(2.0 + get_pcvar_float(cvar_warmup), "make_zombie_task", TASK_MAKEZOMBIE)
  1566. }
  1567.  
  1568. // Log Event Round Start
  1569. public logevent_round_start()
  1570. {
  1571. // Freezetime ends
  1572. g_freezetime = false
  1573. }
  1574.  
  1575. // Log Event Round End
  1576. public logevent_round_end()
  1577. {
  1578. // Prevent this from getting called twice when restarting (bugfix)
  1579. static Float:lastendtime, Float:current_time
  1580. current_time = get_gametime()
  1581. if (current_time - lastendtime < 0.5) return;
  1582. lastendtime = current_time
  1583.  
  1584. // Temporarily save player stats?
  1585. if (get_pcvar_num(cvar_statssave))
  1586. {
  1587. static id, team
  1588. for (id = 1; id <= g_maxplayers; id++)
  1589. {
  1590. // Not connected
  1591. if (!g_isconnected[id])
  1592. continue;
  1593.  
  1594. team = fm_cs_get_user_team(id)
  1595.  
  1596. // Not playing
  1597. if (team == FM_CS_TEAM_SPECTATOR || team == FM_CS_TEAM_UNASSIGNED)
  1598. continue;
  1599.  
  1600. save_stats(id)
  1601. }
  1602. }
  1603.  
  1604. // Round ended
  1605. g_endround = true
  1606.  
  1607. // Stop old tasks (if any)
  1608. remove_task(TASK_WELCOMEMSG)
  1609. remove_task(TASK_MAKEZOMBIE)
  1610.  
  1611. // Stop ambience sounds
  1612. if ((g_ambience_sounds[AMBIENCE_SOUNDS_NEMESIS] && g_nemround) || (g_ambience_sounds[AMBIENCE_SOUNDS_SURVIVOR] && g_survround) || (g_ambience_sounds[AMBIENCE_SOUNDS_SWARM] && g_swarmround) || (g_ambience_sounds[AMBIENCE_SOUNDS_PLAGUE] && g_plagueround) || (g_ambience_sounds[AMBIENCE_SOUNDS_INFECTION] && !g_nemround && !g_survround && !g_swarmround && !g_plagueround))
  1613. {
  1614. remove_task(TASK_AMBIENCESOUNDS)
  1615. ambience_sound_stop()
  1616. }
  1617.  
  1618. // Show HUD notice, play win sound, update team scores...
  1619. static sound[64]
  1620. if (!fnGetZombies())
  1621. {
  1622. // Human team wins
  1623. set_dhudmessage(0, 155, 200, HUD_EVENT_X, HUD_EVENT_Y, 0, 0.0, 3.0, 2.0, 1.0)
  1624. show_dhudmessage(0, "%L", LANG_PLAYER, "WIN_HUMAN")
  1625.  
  1626. // Play win sound and increase score, unless game commencing
  1627. ArrayGetString(sound_win_humans, random_num(0, ArraySize(sound_win_humans) - 1), sound, charsmax(sound))
  1628. PlaySound(sound)
  1629. if (!g_gamecommencing) g_scorehumans++
  1630.  
  1631. // Round end forward
  1632. ExecuteForward(g_fwRoundEnd, g_fwDummyResult, ZP_TEAM_HUMAN);
  1633. }
  1634. else if (!fnGetHumans())
  1635. {
  1636. // Zombie team wins
  1637. set_dhudmessage(255, 0, 0, HUD_EVENT_X, HUD_EVENT_Y, 0, 0.0, 3.0, 2.0, 1.0)
  1638. show_dhudmessage(0, "%L", LANG_PLAYER, "WIN_ZOMBIE")
  1639.  
  1640. // Play win sound and increase score, unless game commencing
  1641. ArrayGetString(sound_win_zombies, random_num(0, ArraySize(sound_win_zombies) - 1), sound, charsmax(sound))
  1642. PlaySound(sound)
  1643. if (!g_gamecommencing) g_scorezombies++
  1644.  
  1645. // Round end forward
  1646. ExecuteForward(g_fwRoundEnd, g_fwDummyResult, ZP_TEAM_ZOMBIE);
  1647. }
  1648. else
  1649. {
  1650. // No one wins
  1651. set_dhudmessage(155, 255, 0, HUD_EVENT_X, HUD_EVENT_Y, 0, 0.0, 3.0, 2.0, 1.0)
  1652. show_dhudmessage(0, "%L", LANG_PLAYER, "WIN_NO_ONE")
  1653.  
  1654. // Play win sound
  1655. ArrayGetString(sound_win_no_one, random_num(0, ArraySize(sound_win_no_one) - 1), sound, charsmax(sound))
  1656. PlaySound(sound)
  1657.  
  1658. // Round end forward
  1659. ExecuteForward(g_fwRoundEnd, g_fwDummyResult, ZP_TEAM_NO_ONE);
  1660. }
  1661.  
  1662. // Game commencing triggers round end
  1663. g_gamecommencing = false
  1664.  
  1665. // Balance the teams
  1666. balance_teams()
  1667. }
  1668.  
  1669. // Event Map Ended
  1670. public event_intermission()
  1671. {
  1672. // Remove ambience sounds task
  1673. remove_task(TASK_AMBIENCESOUNDS)
  1674. }
  1675.  
  1676. // BP Ammo update
  1677. public event_ammo_x(id)
  1678. {
  1679. // Humans only
  1680. if (g_zombie[id])
  1681. return;
  1682.  
  1683. // Get ammo type
  1684. static type
  1685. type = read_data(1)
  1686.  
  1687. // Unknown ammo type
  1688. if (type >= sizeof AMMOWEAPON)
  1689. return;
  1690.  
  1691. // Get weapon's id
  1692. static weapon
  1693. weapon = AMMOWEAPON[type]
  1694.  
  1695. // Primary and secondary only
  1696. if (MAXBPAMMO[weapon] <= 2)
  1697. return;
  1698.  
  1699. // Get ammo amount
  1700. static amount
  1701. amount = read_data(2)
  1702.  
  1703. // Unlimited BP Ammo?
  1704. if (g_survivor[id] ? get_pcvar_num(cvar_survinfammo) : get_pcvar_num(cvar_infammo))
  1705. {
  1706. if (amount < MAXBPAMMO[weapon])
  1707. {
  1708. // The BP Ammo refill code causes the engine to send a message, but we
  1709. // can't have that in this forward or we risk getting some recursion bugs.
  1710. // For more info see: https://bugs.alliedmods.net/show_bug.cgi?id=3664
  1711. static args[1]
  1712. args[0] = weapon
  1713. set_task(0.1, "refill_bpammo", id, args, sizeof args)
  1714. }
  1715. }
  1716. // Bots automatically buy ammo when needed
  1717. else if (g_isbot[id] && amount <= BUYAMMO[weapon])
  1718. {
  1719. // Task needed for the same reason as above
  1720. set_task(0.1, "clcmd_buyammo", id)
  1721. }
  1722. }
  1723.  
  1724. /*================================================================================
  1725. [Main Forwards]
  1726. =================================================================================*/
  1727.  
  1728. // Entity Spawn Forward
  1729. public fw_Spawn(entity)
  1730. {
  1731. // Invalid entity
  1732. if (!pev_valid(entity)) return FMRES_IGNORED;
  1733.  
  1734. // Get classname
  1735. new classname[32], objective[32], size = ArraySize(g_objective_ents)
  1736. pev(entity, pev_classname, classname, charsmax(classname))
  1737.  
  1738. // Check whether it needs to be removed
  1739. for (new i = 0; i < size; i++)
  1740. {
  1741. ArrayGetString(g_objective_ents, i, objective, charsmax(objective))
  1742.  
  1743. if (equal(classname, objective))
  1744. {
  1745. engfunc(EngFunc_RemoveEntity, entity)
  1746. return FMRES_SUPERCEDE;
  1747. }
  1748. }
  1749.  
  1750. return FMRES_IGNORED;
  1751. }
  1752.  
  1753. // Sound Precache Forward
  1754. public fw_PrecacheSound(const sound[])
  1755. {
  1756. // Block all those unneeeded hostage sounds
  1757. if (equal(sound, "hostage", 7))
  1758. return FMRES_SUPERCEDE;
  1759.  
  1760. return FMRES_IGNORED;
  1761. }
  1762.  
  1763. // Ham Player Spawn Post Forward
  1764. public fw_PlayerSpawn_Post(id)
  1765. {
  1766. // Not alive or didn't join a team yet
  1767. if (!is_user_alive(id) || !fm_cs_get_user_team(id))
  1768. return;
  1769.  
  1770. // Player spawned
  1771. g_isalive[id] = true
  1772.  
  1773. // Remove previous tasks
  1774. remove_task(id+TASK_SPAWN)
  1775. remove_task(id+TASK_MODEL)
  1776. remove_task(id+TASK_BLOOD)
  1777. remove_task(id+TASK_AURA)
  1778. remove_task(id+TASK_BURN)
  1779. remove_task(id+TASK_CHARGE)
  1780. remove_task(id+TASK_FLASH)
  1781. remove_task(id+TASK_NVISION)
  1782.  
  1783. // Spawn at a random location?
  1784. if (get_pcvar_num(cvar_randspawn)) do_random_spawn(id)
  1785.  
  1786. // Hide money?
  1787. if (get_pcvar_num(cvar_removemoney))
  1788. set_task(0.4, "task_hide_money", id+TASK_SPAWN)
  1789.  
  1790. // Respawn player if he dies because of a worldspawn kill?
  1791. if (get_pcvar_num(cvar_respawnworldspawnkill))
  1792. set_task(2.0, "respawn_player_check_task", id+TASK_SPAWN)
  1793.  
  1794. // Spawn as zombie?
  1795. if (g_respawn_as_zombie[id] && !g_newround)
  1796. {
  1797. reset_vars(id, 0) // reset player vars
  1798. zombieme(id, 0, 0, 0, 0) // make him zombie right away
  1799. return;
  1800. }
  1801.  
  1802. // Reset player vars
  1803. reset_vars(id, 0)
  1804. g_buytime[id] = get_gametime()
  1805.  
  1806. // Show custom buy menu?
  1807. if (get_pcvar_num(cvar_buycustom))
  1808. set_task(0.2, "show_menu_buy1", id+TASK_SPAWN)
  1809.  
  1810. // Set health and gravity
  1811. fm_set_user_health(id, get_pcvar_num(cvar_humanhp))
  1812. set_pev(id, pev_gravity, get_pcvar_float(cvar_humangravity))
  1813.  
  1814. // Set human maxspeed
  1815. ExecuteHamB(Ham_Player_ResetMaxSpeed, id)
  1816.  
  1817. // Switch to CT if spawning mid-round
  1818. if (!g_newround && fm_cs_get_user_team(id) != FM_CS_TEAM_CT) // need to change team?
  1819. {
  1820. remove_task(id+TASK_TEAM)
  1821. fm_cs_set_user_team(id, FM_CS_TEAM_CT)
  1822. fm_user_team_update(id)
  1823. }
  1824.  
  1825. // Custom models stuff
  1826. static currentmodel[32], tempmodel[32], already_has_model, i, iRand, size
  1827. already_has_model = false
  1828.  
  1829. if (g_handle_models_on_separate_ent)
  1830. {
  1831. // Set the right model
  1832. if (get_pcvar_num(cvar_adminmodelshuman) && (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS]))
  1833. {
  1834. iRand = random_num(0, ArraySize(model_admin_human) - 1)
  1835. ArrayGetString(model_admin_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  1836. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_admin_human, iRand))
  1837. }
  1838. else
  1839. {
  1840. iRand = random_num(0, ArraySize(model_human) - 1)
  1841. ArrayGetString(model_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  1842. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_human, iRand))
  1843. }
  1844.  
  1845. // Set model on player model entity
  1846. fm_set_playermodel_ent(id)
  1847.  
  1848. // Remove glow on player model entity
  1849. fm_set_rendering(g_ent_playermodel[id])
  1850. }
  1851. else
  1852. {
  1853. // Get current model for comparing it with the current one
  1854. fm_cs_get_user_model(id, currentmodel, charsmax(currentmodel))
  1855.  
  1856. // Set the right model, after checking that we don't already have it
  1857. if (get_pcvar_num(cvar_adminmodelshuman) && (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS]))
  1858. {
  1859. size = ArraySize(model_admin_human)
  1860. for (i = 0; i < size; i++)
  1861. {
  1862. ArrayGetString(model_admin_human, i, tempmodel, charsmax(tempmodel))
  1863. if (equal(currentmodel, tempmodel)) already_has_model = true
  1864. }
  1865.  
  1866. if (!already_has_model)
  1867. {
  1868. iRand = random_num(0, size - 1)
  1869. ArrayGetString(model_admin_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  1870. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_admin_human, iRand))
  1871. }
  1872. }
  1873. else
  1874. {
  1875. size = ArraySize(model_human)
  1876. for (i = 0; i < size; i++)
  1877. {
  1878. ArrayGetString(model_human, i, tempmodel, charsmax(tempmodel))
  1879. if (equal(currentmodel, tempmodel)) already_has_model = true
  1880. }
  1881.  
  1882. if (!already_has_model)
  1883. {
  1884. iRand = random_num(0, size - 1)
  1885. ArrayGetString(model_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  1886. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_human, iRand))
  1887. }
  1888. }
  1889.  
  1890. // Need to change the model?
  1891. if (!already_has_model)
  1892. {
  1893. // An additional delay is offset at round start
  1894. // since SVC_BAD is more likely to be triggered there
  1895. if (g_newround)
  1896. set_task(5.0 * g_modelchange_delay, "fm_user_model_update", id+TASK_MODEL)
  1897. else
  1898. fm_user_model_update(id+TASK_MODEL)
  1899. }
  1900.  
  1901. // Remove glow
  1902. fm_set_rendering(id)
  1903. }
  1904.  
  1905. // Bots stuff
  1906. if (g_isbot[id])
  1907. {
  1908. // Turn off NVG for bots
  1909. cs_set_user_nvg(id, 0)
  1910.  
  1911. // Automatically buy extra items/weapons after first zombie is chosen
  1912. if (get_pcvar_num(cvar_extraitems))
  1913. {
  1914. if (g_newround) set_task(10.0 + get_pcvar_float(cvar_warmup), "bot_buy_extras", id+TASK_SPAWN)
  1915. else set_task(10.0, "bot_buy_extras", id+TASK_SPAWN)
  1916. }
  1917. }
  1918.  
  1919. // Enable spawn protection for humans spawning mid-round
  1920. if (!g_newround && get_pcvar_float(cvar_spawnprotection) > 0.0)
  1921. {
  1922. // Do not take damage
  1923. g_nodamage[id] = true
  1924.  
  1925. // Make temporarily invisible
  1926. set_pev(id, pev_effects, pev(id, pev_effects) | EF_NODRAW)
  1927.  
  1928. // Set task to remove it
  1929. set_task(get_pcvar_float(cvar_spawnprotection), "remove_spawn_protection", id+TASK_SPAWN)
  1930. }
  1931.  
  1932. // Turn off his flashlight (prevents double flashlight bug/exploit)
  1933. turn_off_flashlight(id)
  1934.  
  1935. // Set the flashlight charge task to update battery status
  1936. if (g_cached_customflash)
  1937. set_task(1.0, "flashlight_charge", id+TASK_CHARGE, _, _, "b")
  1938.  
  1939. // Replace weapon models (bugfix)
  1940. static weapon_ent
  1941. weapon_ent = fm_cs_get_current_weapon_ent(id)
  1942. if (pev_valid(weapon_ent)) replace_weapon_models(id, cs_get_weapon_id(weapon_ent))
  1943.  
  1944. // Last Zombie Check
  1945. fnCheckLastZombie()
  1946. }
  1947.  
  1948. // Ham Player Killed Forward
  1949. public fw_PlayerKilled(victim, attacker, shouldgib)
  1950. {
  1951. // Player killed
  1952. g_isalive[victim] = false
  1953. // Disable nodamage mode after we die to prevent spectator nightvision using zombie madness colors bug
  1954. g_nodamage[victim] = false
  1955.  
  1956. // Enable dead players nightvision
  1957. set_task(0.1, "spec_nvision", victim)
  1958.  
  1959. // Disable nightvision when killed (bugfix)
  1960. if (get_pcvar_num(cvar_nvggive) == 0 && g_nvision[victim])
  1961. {
  1962. if (get_pcvar_num(cvar_customnvg)) remove_task(victim+TASK_NVISION)
  1963. else if (g_nvisionenabled[victim]) set_user_gnvision(victim, 0)
  1964. g_nvision[victim] = false
  1965. g_nvisionenabled[victim] = false
  1966. }
  1967.  
  1968. // Turn off nightvision when killed (bugfix)
  1969. if (get_pcvar_num(cvar_nvggive) == 2 && g_nvision[victim] && g_nvisionenabled[victim])
  1970. {
  1971. if (get_pcvar_num(cvar_customnvg)) remove_task(victim+TASK_NVISION)
  1972. else set_user_gnvision(victim, 0)
  1973. g_nvisionenabled[victim] = false
  1974. }
  1975.  
  1976. // Turn off custom flashlight when killed
  1977. if (g_cached_customflash)
  1978. {
  1979. // Turn it off
  1980. g_flashlight[victim] = false
  1981. g_flashbattery[victim] = 100
  1982.  
  1983. // Remove previous tasks
  1984. remove_task(victim+TASK_CHARGE)
  1985. remove_task(victim+TASK_FLASH)
  1986. }
  1987.  
  1988. // Stop bleeding/burning/aura when killed
  1989. if (g_zombie[victim])
  1990. {
  1991. remove_task(victim+TASK_BLOOD)
  1992. remove_task(victim+TASK_AURA)
  1993. remove_task(victim+TASK_BURN)
  1994. }
  1995.  
  1996. // Nemesis explodes!
  1997. if (g_nemesis[victim])
  1998. SetHamParamInteger(3, 2)
  1999.  
  2000. // Determine whether the player killed himself
  2001. static selfkill
  2002. selfkill = (victim == attacker || !is_user_valid_connected(attacker)) ? true : false
  2003.  
  2004. // Killed by a non-player entity or self killed
  2005. if (selfkill) return;
  2006.  
  2007. // Ignore Nemesis/Survivor Frags?
  2008. if ((g_nemesis[attacker] && get_pcvar_num(cvar_nemignorefrags)) || (g_survivor[attacker] && get_pcvar_num(cvar_survignorefrags)))
  2009. RemoveFrags(attacker, victim)
  2010.  
  2011. // Zombie/nemesis killed human, reward ammo packs
  2012. if (g_zombie[attacker] && (!g_nemesis[attacker] || !get_pcvar_num(cvar_nemignoreammo)))
  2013. g_ammopacks[attacker] += get_pcvar_num(cvar_ammoinfect)
  2014.  
  2015. // Human killed zombie, add up the extra frags for kill
  2016. if (!g_zombie[attacker] && get_pcvar_num(cvar_fragskill) > 1)
  2017. UpdateFrags(attacker, victim, get_pcvar_num(cvar_fragskill) - 1, 0, 0)
  2018.  
  2019. // Zombie killed human, add up the extra frags for kill
  2020. if (g_zombie[attacker] && get_pcvar_num(cvar_fragsinfect) > 1)
  2021. UpdateFrags(attacker, victim, get_pcvar_num(cvar_fragsinfect) - 1, 0, 0)
  2022. }
  2023.  
  2024. // Ham Player Killed Post Forward
  2025. public fw_PlayerKilled_Post(victim, attacker, shouldgib)
  2026. {
  2027. // Last Zombie Check
  2028. fnCheckLastZombie()
  2029.  
  2030. // Determine whether the player killed himself
  2031. static selfkill
  2032. selfkill = (victim == attacker || !is_user_valid_connected(attacker)) ? true : false
  2033.  
  2034. // Respawn if deathmatch is enabled
  2035. if (get_pcvar_num(cvar_deathmatch))
  2036. {
  2037. // Respawn on suicide?
  2038. if (selfkill && !get_pcvar_num(cvar_respawnonsuicide))
  2039. return;
  2040.  
  2041. // Respawn if human/zombie/nemesis/survivor?
  2042. if ((g_zombie[victim] && !g_nemesis[victim] && !get_pcvar_num(cvar_respawnzomb)) || (!g_zombie[victim] && !g_survivor[victim] && !get_pcvar_num(cvar_respawnhum)) || (g_nemesis[victim] && !get_pcvar_num(cvar_respawnnem)) || (g_survivor[victim] && !get_pcvar_num(cvar_respawnsurv)))
  2043. return;
  2044.  
  2045. // Set the respawn task
  2046. set_task(get_pcvar_float(cvar_spawndelay), "respawn_player_task", victim+TASK_SPAWN)
  2047. }
  2048. }
  2049.  
  2050. // Ham Take Damage Forward
  2051. public fw_TakeDamage(victim, inflictor, attacker, Float:damage, damage_type)
  2052. {
  2053. // Non-player damage or self damage
  2054. if (victim == attacker || !is_user_valid_connected(attacker))
  2055. return HAM_IGNORED;
  2056.  
  2057. // New round starting or round ended
  2058. if (g_newround || g_endround)
  2059. return HAM_SUPERCEDE;
  2060.  
  2061. // Victim shouldn't take damage or victim is frozen
  2062. if (g_nodamage[victim] || g_frozen[victim])
  2063. return HAM_SUPERCEDE;
  2064.  
  2065. // Prevent friendly fire
  2066. if (g_zombie[attacker] == g_zombie[victim])
  2067. return HAM_SUPERCEDE;
  2068.  
  2069. // Attacker is human...
  2070. if (!g_zombie[attacker])
  2071. {
  2072. // Armor multiplier for the final damage on normal zombies
  2073. if (!g_nemesis[victim])
  2074. {
  2075. damage *= get_pcvar_float(cvar_zombiearmor)
  2076. SetHamParamFloat(4, damage)
  2077. }
  2078.  
  2079. // Reward ammo packs to humans for damaging zombies?
  2080. if ((get_pcvar_num(cvar_ammodamage_human) > 0) && (!g_survivor[attacker] || !get_pcvar_num(cvar_survignoreammo)))
  2081. {
  2082. // Store damage dealt
  2083. g_damagedealt_human[attacker] += floatround(damage)
  2084.  
  2085. // Reward ammo packs for every [ammo damage] dealt
  2086. while (g_damagedealt_human[attacker] > get_pcvar_num(cvar_ammodamage_human))
  2087. {
  2088. g_ammopacks[attacker]++
  2089. g_damagedealt_human[attacker] -= get_pcvar_num(cvar_ammodamage_human)
  2090. }
  2091. }
  2092.  
  2093. return HAM_IGNORED;
  2094. }
  2095.  
  2096. // Attacker is zombie...
  2097.  
  2098. // Prevent infection/damage by HE grenade (bugfix)
  2099. if (damage_type & DMG_HEGRENADE)
  2100. return HAM_SUPERCEDE;
  2101.  
  2102. // Nemesis?
  2103. if (g_nemesis[attacker])
  2104. {
  2105. // Ignore nemesis damage override if damage comes from a 3rd party entity
  2106. // (to prevent this from affecting a sub-plugin's rockets e.g.)
  2107. if (inflictor == attacker)
  2108. {
  2109. // Set nemesis damage
  2110. SetHamParamFloat(4, get_pcvar_float(cvar_nemdamage))
  2111. }
  2112.  
  2113. return HAM_IGNORED;
  2114. }
  2115.  
  2116. // Reward ammo packs to zombies for damaging humans?
  2117. if (get_pcvar_num(cvar_ammodamage_zombie) > 0)
  2118. {
  2119. // Store damage dealt
  2120. g_damagedealt_zombie[attacker] += floatround(damage)
  2121.  
  2122. // Reward ammo packs for every [ammo damage] dealt
  2123. while (g_damagedealt_zombie[attacker] > get_pcvar_num(cvar_ammodamage_zombie))
  2124. {
  2125. g_ammopacks[attacker]++
  2126. g_damagedealt_zombie[attacker] -= get_pcvar_num(cvar_ammodamage_zombie)
  2127. }
  2128. }
  2129.  
  2130. // Last human or not an infection round
  2131. if (g_survround || g_nemround || g_swarmround || g_plagueround || fnGetHumans() == 1)
  2132. return HAM_IGNORED; // human is killed
  2133.  
  2134. // Does human armor need to be reduced before infecting?
  2135. if (get_pcvar_num(cvar_humanarmor))
  2136. {
  2137. // Get victim armor
  2138. static Float:armor
  2139. pev(victim, pev_armorvalue, armor)
  2140.  
  2141. // If he has some, block the infection and reduce armor instead
  2142. if (armor > 0.0)
  2143. {
  2144. emit_sound(victim, CHAN_BODY, sound_armorhit, 1.0, ATTN_NORM, 0, PITCH_NORM)
  2145. if (armor - damage > 0.0)
  2146. set_pev(victim, pev_armorvalue, armor - damage)
  2147. else
  2148. cs_set_user_armor(victim, 0, CS_ARMOR_NONE)
  2149. return HAM_SUPERCEDE;
  2150. }
  2151. }
  2152.  
  2153. // Infection allowed
  2154. zombieme(victim, attacker, 0, 0, 1) // turn into zombie
  2155. return HAM_SUPERCEDE;
  2156. }
  2157.  
  2158. // Ham Take Damage Post Forward
  2159. public fw_TakeDamage_Post(victim)
  2160. {
  2161. // --- Check if victim should be Pain Shock Free ---
  2162.  
  2163. // Check if proper CVARs are enabled
  2164. if (g_zombie[victim])
  2165. {
  2166. if (g_nemesis[victim])
  2167. {
  2168. if (!get_pcvar_num(cvar_nempainfree)) return;
  2169. }
  2170. else
  2171. {
  2172. switch (get_pcvar_num(cvar_zombiepainfree))
  2173. {
  2174. case 0: return;
  2175. case 2: if (!g_lastzombie[victim]) return;
  2176. case 3: if (!g_firstzombie[victim]) return;
  2177. }
  2178. }
  2179. }
  2180. else
  2181. {
  2182. if (g_survivor[victim])
  2183. {
  2184. if (!get_pcvar_num(cvar_survpainfree)) return;
  2185. }
  2186. else return;
  2187. }
  2188.  
  2189. // Prevent server crash if entity's private data not initalized
  2190. if (pev_valid(victim) != PDATA_SAFE)
  2191. return;
  2192.  
  2193. // Set pain shock free offset
  2194. set_pdata_float(victim, OFFSET_PAINSHOCK, 1.0, OFFSET_LINUX)
  2195. }
  2196.  
  2197. // Ham Trace Attack Forward
  2198. public fw_TraceAttack(victim, attacker, Float:damage, Float:direction[3], tracehandle, damage_type)
  2199. {
  2200. // Non-player damage or self damage
  2201. if (victim == attacker || !is_user_valid_connected(attacker))
  2202. return HAM_IGNORED;
  2203.  
  2204. // New round starting or round ended
  2205. if (g_newround || g_endround)
  2206. return HAM_SUPERCEDE;
  2207.  
  2208. // Victim shouldn't take damage or victim is frozen
  2209. if (g_nodamage[victim] || g_frozen[victim])
  2210. return HAM_SUPERCEDE;
  2211.  
  2212. // Prevent friendly fire
  2213. if (g_zombie[attacker] == g_zombie[victim])
  2214. return HAM_SUPERCEDE;
  2215.  
  2216. // Victim isn't a zombie or not bullet damage, nothing else to do here
  2217. if (!g_zombie[victim] || !(damage_type & DMG_BULLET))
  2218. return HAM_IGNORED;
  2219.  
  2220. // If zombie hitzones are enabled, check whether we hit an allowed one
  2221. if (get_pcvar_num(cvar_hitzones) && !g_nemesis[victim] && !(get_pcvar_num(cvar_hitzones) & (1<<get_tr2(tracehandle, TR_iHitgroup))))
  2222. return HAM_SUPERCEDE;
  2223.  
  2224. // Knockback disabled, nothing else to do here
  2225. if (!get_pcvar_num(cvar_knockback))
  2226. return HAM_IGNORED;
  2227.  
  2228. // Nemesis knockback disabled, nothing else to do here
  2229. if (g_nemesis[victim] && get_pcvar_float(cvar_nemknockback) == 0.0)
  2230. return HAM_IGNORED;
  2231.  
  2232. // Get whether the victim is in a crouch state
  2233. static ducking
  2234. ducking = pev(victim, pev_flags) & (FL_DUCKING | FL_ONGROUND) == (FL_DUCKING | FL_ONGROUND)
  2235.  
  2236. // Zombie knockback when ducking disabled
  2237. if (ducking && get_pcvar_float(cvar_knockbackducking) == 0.0)
  2238. return HAM_IGNORED;
  2239.  
  2240. // Get distance between players
  2241. static origin1[3], origin2[3]
  2242. get_user_origin(victim, origin1)
  2243. get_user_origin(attacker, origin2)
  2244.  
  2245. // Max distance exceeded
  2246. if (get_distance(origin1, origin2) > get_pcvar_num(cvar_knockbackdist))
  2247. return HAM_IGNORED;
  2248.  
  2249. // Get victim's velocity
  2250. static Float:velocity[3]
  2251. pev(victim, pev_velocity, velocity)
  2252.  
  2253. // Use damage on knockback calculation
  2254. if (get_pcvar_num(cvar_knockbackdamage))
  2255. xs_vec_mul_scalar(direction, damage, direction)
  2256.  
  2257. // Use weapon power on knockback calculation
  2258. if (get_pcvar_num(cvar_knockbackpower) && kb_weapon_power[g_currentweapon[attacker]] > 0.0)
  2259. xs_vec_mul_scalar(direction, kb_weapon_power[g_currentweapon[attacker]], direction)
  2260.  
  2261. // Apply ducking knockback multiplier
  2262. if (ducking)
  2263. xs_vec_mul_scalar(direction, get_pcvar_float(cvar_knockbackducking), direction)
  2264.  
  2265. // Apply zombie class/nemesis knockback multiplier
  2266. if (g_nemesis[victim])
  2267. xs_vec_mul_scalar(direction, get_pcvar_float(cvar_nemknockback), direction)
  2268. else
  2269. xs_vec_mul_scalar(direction, g_zombie_knockback[victim], direction)
  2270.  
  2271. // Add up the new vector
  2272. xs_vec_add(velocity, direction, direction)
  2273.  
  2274. // Should knockback also affect vertical velocity?
  2275. if (!get_pcvar_num(cvar_knockbackzvel))
  2276. direction[2] = velocity[2]
  2277.  
  2278. // Set the knockback'd victim's velocity
  2279. set_pev(victim, pev_velocity, direction)
  2280.  
  2281. return HAM_IGNORED;
  2282. }
  2283.  
  2284. // Ham Reset MaxSpeed Post Forward
  2285. public fw_ResetMaxSpeed_Post(id)
  2286. {
  2287. // Freezetime active or player not alive
  2288. if (g_freezetime || !g_isalive[id])
  2289. return;
  2290.  
  2291. set_player_maxspeed(id)
  2292. }
  2293.  
  2294. // Ham Use Stationary Gun Forward
  2295. public fw_UseStationary(entity, caller, activator, use_type)
  2296. {
  2297. // Prevent zombies from using stationary guns
  2298. if (use_type == USE_USING && is_user_valid_connected(caller) && g_zombie[caller])
  2299. return HAM_SUPERCEDE;
  2300.  
  2301. return HAM_IGNORED;
  2302. }
  2303.  
  2304. // Ham Use Stationary Gun Post Forward
  2305. public fw_UseStationary_Post(entity, caller, activator, use_type)
  2306. {
  2307. // Someone stopped using a stationary gun
  2308. if (use_type == USE_STOPPED && is_user_valid_connected(caller))
  2309. replace_weapon_models(caller, g_currentweapon[caller]) // replace weapon models (bugfix)
  2310. }
  2311.  
  2312. // Ham Use Pushable Forward
  2313. public fw_UsePushable()
  2314. {
  2315. // Prevent speed bug with pushables?
  2316. if (get_pcvar_num(cvar_blockpushables))
  2317. return HAM_SUPERCEDE;
  2318.  
  2319. return HAM_IGNORED;
  2320. }
  2321.  
  2322. // Ham Weapon Touch Forward
  2323. public fw_TouchWeapon(weapon, id)
  2324. {
  2325. // Not a player
  2326. if (!is_user_valid_connected(id))
  2327. return HAM_IGNORED;
  2328.  
  2329. // Dont pickup weapons if zombie or survivor (+PODBot MM fix)
  2330. if (g_zombie[id] || (g_survivor[id] && !g_isbot[id]))
  2331. return HAM_SUPERCEDE;
  2332.  
  2333. return HAM_IGNORED;
  2334. }
  2335.  
  2336. // Ham Weapon Pickup Forward
  2337. public fw_AddPlayerItem(id, weapon_ent)
  2338. {
  2339. // HACK: Retrieve our custom extra ammo from the weapon
  2340. static extra_ammo
  2341. extra_ammo = pev(weapon_ent, PEV_ADDITIONAL_AMMO)
  2342.  
  2343. // If present
  2344. if (extra_ammo)
  2345. {
  2346. // Get weapon's id
  2347. static weaponid
  2348. weaponid = cs_get_weapon_id(weapon_ent)
  2349.  
  2350. // Add to player's bpammo
  2351. ExecuteHamB(Ham_GiveAmmo, id, extra_ammo, AMMOTYPE[weaponid], MAXBPAMMO[weaponid])
  2352. set_pev(weapon_ent, PEV_ADDITIONAL_AMMO, 0)
  2353. }
  2354. }
  2355.  
  2356. // Ham Weapon Deploy Forward
  2357. public fw_Item_Deploy_Post(weapon_ent)
  2358. {
  2359. // Get weapon's owner
  2360. static owner
  2361. owner = fm_cs_get_weapon_ent_owner(weapon_ent)
  2362.  
  2363. // Valid owner?
  2364. if (!pev_valid(owner))
  2365. return;
  2366.  
  2367. // Get weapon's id
  2368. static weaponid
  2369. weaponid = cs_get_weapon_id(weapon_ent)
  2370.  
  2371. // Store current weapon's id for reference
  2372. g_currentweapon[owner] = weaponid
  2373.  
  2374. // Replace weapon models with custom ones
  2375. replace_weapon_models(owner, weaponid)
  2376.  
  2377. // Zombie not holding an allowed weapon for some reason
  2378. if (g_zombie[owner] && !((1<<weaponid) & ZOMBIE_ALLOWED_WEAPONS_BITSUM))
  2379. {
  2380. // Switch to knife
  2381. g_currentweapon[owner] = CSW_KNIFE
  2382. engclient_cmd(owner, "weapon_knife")
  2383. }
  2384. }
  2385.  
  2386. // WeaponMod bugfix
  2387. //forward wpn_gi_reset_weapon(id);
  2388. public wpn_gi_reset_weapon(id)
  2389. {
  2390. // Replace knife model
  2391. replace_weapon_models(id, CSW_KNIFE)
  2392. }
  2393.  
  2394. // Client joins the game
  2395. public client_putinserver(id)
  2396. {
  2397. // Plugin disabled?
  2398. if (!g_pluginenabled) return;
  2399.  
  2400. // Player joined
  2401. g_isconnected[id] = true
  2402.  
  2403. // Cache player's name
  2404. get_user_name(id, g_playername[id], charsmax(g_playername[]))
  2405.  
  2406. // Initialize player vars
  2407. reset_vars(id, 1)
  2408.  
  2409. // Load player stats?
  2410. if (get_pcvar_num(cvar_statssave)) load_stats(id)
  2411.  
  2412. // Set some tasks for humans only
  2413. if (!is_user_bot(id))
  2414. {
  2415. // Set the custom HUD display task if enabled
  2416. if (get_pcvar_num(cvar_huddisplay))
  2417. set_task(1.0, "ShowHUD", id+TASK_SHOWHUD, _, _, "b")
  2418.  
  2419. // Disable minmodels for clients to see zombies properly
  2420. set_task(5.0, "disable_minmodels", id)
  2421. }
  2422. else
  2423. {
  2424. // Set bot flag
  2425. g_isbot[id] = true
  2426.  
  2427. // CZ bots seem to use a different "classtype" for player entities
  2428. // (or something like that) which needs to be hooked separately
  2429. if (!g_hamczbots && cvar_botquota)
  2430. {
  2431. // Set a task to let the private data initialize
  2432. set_task(0.1, "register_ham_czbots", id)
  2433. }
  2434. }
  2435. }
  2436.  
  2437. // Client leaving
  2438. public fw_ClientDisconnect(id)
  2439. {
  2440. // Check that we still have both humans and zombies to keep the round going
  2441. if (g_isalive[id]) check_round(id)
  2442.  
  2443. // Temporarily save player stats?
  2444. if (get_pcvar_num(cvar_statssave)) save_stats(id)
  2445.  
  2446. // Remove previous tasks
  2447. remove_task(id+TASK_TEAM)
  2448. remove_task(id+TASK_MODEL)
  2449. remove_task(id+TASK_FLASH)
  2450. remove_task(id+TASK_CHARGE)
  2451. remove_task(id+TASK_SPAWN)
  2452. remove_task(id+TASK_BLOOD)
  2453. remove_task(id+TASK_AURA)
  2454. remove_task(id+TASK_BURN)
  2455. remove_task(id+TASK_NVISION)
  2456. remove_task(id+TASK_SHOWHUD)
  2457.  
  2458. if (g_handle_models_on_separate_ent)
  2459. {
  2460. // Remove custom model entities
  2461. fm_remove_model_ents(id)
  2462. }
  2463.  
  2464. // Player left, clear cached flags
  2465. g_isconnected[id] = false
  2466. g_isbot[id] = false
  2467. g_isalive[id] = false
  2468. }
  2469.  
  2470. // Client left
  2471. public fw_ClientDisconnect_Post()
  2472. {
  2473. // Last Zombie Check
  2474. fnCheckLastZombie()
  2475. }
  2476.  
  2477. // Client Kill Forward
  2478. public fw_ClientKill()
  2479. {
  2480. // Prevent players from killing themselves?
  2481. if (get_pcvar_num(cvar_blocksuicide))
  2482. return FMRES_SUPERCEDE;
  2483.  
  2484. return FMRES_IGNORED;
  2485. }
  2486.  
  2487. // Emit Sound Forward
  2488. public fw_EmitSound(id, channel, const sample[], Float:volume, Float:attn, flags, pitch)
  2489. {
  2490. // Block all those unneeeded hostage sounds
  2491. if (sample[0] == 'h' && sample[1] == 'o' && sample[2] == 's' && sample[3] == 't' && sample[4] == 'a' && sample[5] == 'g' && sample[6] == 'e')
  2492. return FMRES_SUPERCEDE;
  2493.  
  2494. // Replace these next sounds for zombies only
  2495. if (!is_user_valid_connected(id) || !g_zombie[id])
  2496. return FMRES_IGNORED;
  2497.  
  2498. static sound[64]
  2499.  
  2500. // Zombie being hit
  2501. if (sample[7] == 'b' && sample[8] == 'h' && sample[9] == 'i' && sample[10] == 't')
  2502. {
  2503. if (g_nemesis[id])
  2504. {
  2505. ArrayGetString(nemesis_pain, random_num(0, ArraySize(nemesis_pain) - 1), sound, charsmax(sound))
  2506. emit_sound(id, channel, sound, volume, attn, flags, pitch)
  2507. }
  2508. else
  2509. {
  2510. ArrayGetString(zombie_pain, random_num(0, ArraySize(zombie_pain) - 1), sound, charsmax(sound))
  2511. emit_sound(id, channel, sound, volume, attn, flags, pitch)
  2512. }
  2513. return FMRES_SUPERCEDE;
  2514. }
  2515.  
  2516. // Zombie attacks with knife
  2517. if (sample[8] == 'k' && sample[9] == 'n' && sample[10] == 'i')
  2518. {
  2519. if (sample[14] == 's' && sample[15] == 'l' && sample[16] == 'a') // slash
  2520. {
  2521. ArrayGetString(zombie_miss_slash, random_num(0, ArraySize(zombie_miss_slash) - 1), sound, charsmax(sound))
  2522. emit_sound(id, channel, sound, volume, attn, flags, pitch)
  2523. return FMRES_SUPERCEDE;
  2524. }
  2525. if (sample[14] == 'h' && sample[15] == 'i' && sample[16] == 't') // hit
  2526. {
  2527. if (sample[17] == 'w') // wall
  2528. {
  2529. ArrayGetString(zombie_miss_wall, random_num(0, ArraySize(zombie_miss_wall) - 1), sound, charsmax(sound))
  2530. emit_sound(id, channel, sound, volume, attn, flags, pitch)
  2531. return FMRES_SUPERCEDE;
  2532. }
  2533. else
  2534. {
  2535. ArrayGetString(zombie_hit_normal, random_num(0, ArraySize(zombie_hit_normal) - 1), sound, charsmax(sound))
  2536. emit_sound(id, channel, sound, volume, attn, flags, pitch)
  2537. return FMRES_SUPERCEDE;
  2538. }
  2539. }
  2540. if (sample[14] == 's' && sample[15] == 't' && sample[16] == 'a') // stab
  2541. {
  2542. ArrayGetString(zombie_hit_stab, random_num(0, ArraySize(zombie_hit_stab) - 1), sound, charsmax(sound))
  2543. emit_sound(id, channel, sound, volume, attn, flags, pitch)
  2544. return FMRES_SUPERCEDE;
  2545. }
  2546. }
  2547.  
  2548. // Zombie dies
  2549. if (sample[7] == 'd' && ((sample[8] == 'i' && sample[9] == 'e') || (sample[8] == 'e' && sample[9] == 'a')))
  2550. {
  2551. ArrayGetString(zombie_die, random_num(0, ArraySize(zombie_die) - 1), sound, charsmax(sound))
  2552. emit_sound(id, channel, sound, volume, attn, flags, pitch)
  2553. return FMRES_SUPERCEDE;
  2554. }
  2555.  
  2556. // Zombie falls off
  2557. if (sample[10] == 'f' && sample[11] == 'a' && sample[12] == 'l' && sample[13] == 'l')
  2558. {
  2559. ArrayGetString(zombie_fall, random_num(0, ArraySize(zombie_fall) - 1), sound, charsmax(sound))
  2560. emit_sound(id, channel, sound, volume, attn, flags, pitch)
  2561. return FMRES_SUPERCEDE;
  2562. }
  2563.  
  2564. return FMRES_IGNORED;
  2565. }
  2566.  
  2567. // Forward Set ClientKey Value -prevent CS from changing player models-
  2568. public fw_SetClientKeyValue(id, const infobuffer[], const key[])
  2569. {
  2570. // Block CS model changes
  2571. if (key[0] == 'm' && key[1] == 'o' && key[2] == 'd' && key[3] == 'e' && key[4] == 'l')
  2572. return FMRES_SUPERCEDE;
  2573.  
  2574. return FMRES_IGNORED;
  2575. }
  2576.  
  2577. // Forward Client User Info Changed -prevent players from changing models-
  2578. public fw_ClientUserInfoChanged(id)
  2579. {
  2580. // Cache player's name
  2581. get_user_name(id, g_playername[id], charsmax(g_playername[]))
  2582.  
  2583. if (!g_handle_models_on_separate_ent)
  2584. {
  2585. // Get current model
  2586. static currentmodel[32]
  2587. fm_cs_get_user_model(id, currentmodel, charsmax(currentmodel))
  2588.  
  2589. // If they're different, set model again
  2590. if (!equal(currentmodel, g_playermodel[id]) && !task_exists(id+TASK_MODEL))
  2591. fm_cs_set_user_model(id+TASK_MODEL)
  2592. }
  2593. }
  2594.  
  2595. // Forward Get Game Description
  2596. public fw_GetGameDescription()
  2597. {
  2598. // Return the mod name so it can be easily identified
  2599. forward_return(FMV_STRING, g_modname)
  2600.  
  2601. return FMRES_SUPERCEDE;
  2602. }
  2603.  
  2604. // Forward Set Model
  2605. public fw_SetModel(entity, const model[])
  2606. {
  2607. // We don't care
  2608. if (strlen(model) < 8)
  2609. return;
  2610.  
  2611. // Remove weapons?
  2612. if (get_pcvar_float(cvar_removedropped) > 0.0)
  2613. {
  2614. // Get entity's classname
  2615. static classname[10]
  2616. pev(entity, pev_classname, classname, charsmax(classname))
  2617.  
  2618. // Check if it's a weapon box
  2619. if (equal(classname, "weaponbox"))
  2620. {
  2621. // They get automatically removed when thinking
  2622. set_pev(entity, pev_nextthink, get_gametime() + get_pcvar_float(cvar_removedropped))
  2623. return;
  2624. }
  2625. }
  2626.  
  2627. // Narrow down our matches a bit
  2628. if (model[7] != 'w' || model[8] != '_')
  2629. return;
  2630.  
  2631. // Get damage time of grenade
  2632. static Float:dmgtime
  2633. pev(entity, pev_dmgtime, dmgtime)
  2634.  
  2635. // Grenade not yet thrown
  2636. if (dmgtime == 0.0)
  2637. return;
  2638.  
  2639. // Get whether grenade's owner is a zombie
  2640. if (g_zombie[pev(entity, pev_owner)])
  2641. {
  2642. if (model[9] == 'h' && model[10] == 'e' && get_pcvar_num(cvar_extrainfbomb)) // Infection Bomb
  2643. {
  2644. // Give it a glow
  2645. fm_set_rendering(entity, kRenderFxGlowShell, 0, 200, 0, kRenderNormal, 16);
  2646.  
  2647. // And a colored trail
  2648. message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
  2649. write_byte(TE_BEAMFOLLOW) // TE id
  2650. write_short(entity) // entity
  2651. write_short(g_trailSpr) // sprite
  2652. write_byte(10) // life
  2653. write_byte(10) // width
  2654. write_byte(0) // r
  2655. write_byte(200) // g
  2656. write_byte(0) // b
  2657. write_byte(200) // brightness
  2658. message_end()
  2659.  
  2660. // Set grenade type on the thrown grenade entity
  2661. set_pev(entity, PEV_NADE_TYPE, NADE_TYPE_INFECTION)
  2662. }
  2663. }
  2664. else if (model[9] == 'h' && model[10] == 'e' && get_pcvar_num(cvar_firegrenades)) // Napalm Grenade
  2665. {
  2666. // Give it a glow
  2667. fm_set_rendering(entity, kRenderFxGlowShell, 200, 0, 0, kRenderNormal, 16);
  2668.  
  2669. // And a colored trail
  2670. message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
  2671. write_byte(TE_BEAMFOLLOW) // TE id
  2672. write_short(entity) // entity
  2673. write_short(g_fire_trail) // sprite
  2674. write_byte(10) // life
  2675. write_byte(10) // width
  2676. write_byte(200) // r
  2677. write_byte(0) // g
  2678. write_byte(0) // b
  2679. write_byte(200) // brightness
  2680. message_end()
  2681.  
  2682. // Set grenade type on the thrown grenade entity
  2683. set_pev(entity, PEV_NADE_TYPE, NADE_TYPE_NAPALM)
  2684. }
  2685. else if (model[9] == 'f' && model[10] == 'l' && get_pcvar_num(cvar_frostgrenades)) // Frost Grenade
  2686. {
  2687. // Give it a glow
  2688. fm_set_rendering(entity, kRenderFxGlowShell, 0, 100, 200, kRenderNormal, 16);
  2689.  
  2690. // And a colored trail
  2691. message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
  2692. write_byte(TE_BEAMFOLLOW) // TE id
  2693. write_short(entity) // entity
  2694. write_short(g_frost_trail) // sprite
  2695. write_byte(10) // life
  2696. write_byte(10) // width
  2697. write_byte(0) // r
  2698. write_byte(100) // g
  2699. write_byte(200) // b
  2700. write_byte(200) // brightness
  2701. message_end()
  2702.  
  2703.  
  2704. // Set grenade type on the thrown grenade entity
  2705. set_pev(entity, PEV_NADE_TYPE, NADE_TYPE_FROST)
  2706. }
  2707. else if (model[9] == 's' && model[10] == 'm' && get_pcvar_num(cvar_flaregrenades)) // Flare
  2708. {
  2709. // Build flare's color
  2710. static rgb[3]
  2711. switch (get_pcvar_num(cvar_flarecolor))
  2712. {
  2713. case 0: // white
  2714. {
  2715. rgb[0] = 255 // r
  2716. rgb[1] = 255 // g
  2717. rgb[2] = 255 // b
  2718. }
  2719. case 1: // red
  2720. {
  2721. rgb[0] = random_num(50,255) // r
  2722. rgb[1] = 0 // g
  2723. rgb[2] = 0 // b
  2724. }
  2725. case 2: // green
  2726. {
  2727. rgb[0] = 0 // r
  2728. rgb[1] = random_num(50,255) // g
  2729. rgb[2] = 0 // b
  2730. }
  2731. case 3: // blue
  2732. {
  2733. rgb[0] = 0 // r
  2734. rgb[1] = 0 // g
  2735. rgb[2] = random_num(50,255) // b
  2736. }
  2737. case 4: // random (all colors)
  2738. {
  2739. rgb[0] = random_num(50,200) // r
  2740. rgb[1] = random_num(50,200) // g
  2741. rgb[2] = random_num(50,200) // b
  2742. }
  2743. case 5: // random (r,g,b)
  2744. {
  2745. switch (random_num(1, 3))
  2746. {
  2747. case 1: // red
  2748. {
  2749. rgb[0] = random_num(50,255) // r
  2750. rgb[1] = 0 // g
  2751. rgb[2] = 0 // b
  2752. }
  2753. case 2: // green
  2754. {
  2755. rgb[0] = 0 // r
  2756. rgb[1] = random_num(50,255) // g
  2757. rgb[2] = 0 // b
  2758. }
  2759. case 3: // blue
  2760. {
  2761. rgb[0] = 0 // r
  2762. rgb[1] = 0 // g
  2763. rgb[2] = random_num(50,255) // b
  2764. }
  2765. }
  2766. }
  2767. }
  2768.  
  2769. // Give it a glow
  2770. fm_set_rendering(entity, kRenderFxGlowShell, rgb[0], rgb[1], rgb[2], kRenderNormal, 16);
  2771.  
  2772. // And a colored trail
  2773. message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
  2774. write_byte(TE_BEAMFOLLOW) // TE id
  2775. write_short(entity) // entity
  2776. write_short(g_flare_trail) // sprite
  2777. write_byte(10) // life
  2778. write_byte(10) // width
  2779. write_byte(rgb[0]) // r
  2780. write_byte(rgb[1]) // g
  2781. write_byte(rgb[2]) // b
  2782. write_byte(200) // brightness
  2783. message_end()
  2784.  
  2785. // Set grenade type on the thrown grenade entity
  2786. set_pev(entity, PEV_NADE_TYPE, NADE_TYPE_FLARE)
  2787.  
  2788. // Set flare color on the thrown grenade entity
  2789. set_pev(entity, PEV_FLARE_COLOR, rgb)
  2790. }
  2791. }
  2792.  
  2793. // Ham Grenade Think Forward
  2794. public fw_ThinkGrenade(entity)
  2795. {
  2796. // Invalid entity
  2797. if (!pev_valid(entity)) return HAM_IGNORED;
  2798.  
  2799. // Get damage time of grenade
  2800. static Float:dmgtime, Float:current_time
  2801. pev(entity, pev_dmgtime, dmgtime)
  2802. current_time = get_gametime()
  2803.  
  2804. // Check if it's time to go off
  2805. if (dmgtime > current_time)
  2806. return HAM_IGNORED;
  2807.  
  2808. // Check if it's one of our custom nades
  2809. switch (pev(entity, PEV_NADE_TYPE))
  2810. {
  2811. case NADE_TYPE_INFECTION: // Infection Bomb
  2812. {
  2813. infection_explode(entity)
  2814. return HAM_SUPERCEDE;
  2815. }
  2816. case NADE_TYPE_NAPALM: // Napalm Grenade
  2817. {
  2818. fire_explode(entity)
  2819. return HAM_SUPERCEDE;
  2820. }
  2821. case NADE_TYPE_FROST: // Frost Grenade
  2822. {
  2823. frost_explode(entity)
  2824. return HAM_SUPERCEDE;
  2825. }
  2826. case NADE_TYPE_FLARE: // Flare
  2827. {
  2828. // Get its duration
  2829. static duration
  2830. duration = pev(entity, PEV_FLARE_DURATION)
  2831.  
  2832. // Already went off, do lighting loop for the duration of PEV_FLARE_DURATION
  2833. if (duration > 0)
  2834. {
  2835. // Check whether this is the last loop
  2836. if (duration == 1)
  2837. {
  2838. // Get rid of the flare entity
  2839. engfunc(EngFunc_RemoveEntity, entity)
  2840. return HAM_SUPERCEDE;
  2841. }
  2842.  
  2843. // Light it up!
  2844. flare_lighting(entity, duration)
  2845.  
  2846. // Set time for next loop
  2847. set_pev(entity, PEV_FLARE_DURATION, --duration)
  2848. set_pev(entity, pev_dmgtime, current_time + 2.0)
  2849. }
  2850. // Light up when it's stopped on ground
  2851. else if ((pev(entity, pev_flags) & FL_ONGROUND) && fm_get_speed(entity) < 10)
  2852. {
  2853. // Flare sound
  2854. static sound[64]
  2855. ArrayGetString(grenade_flare, random_num(0, ArraySize(grenade_flare) - 1), sound, charsmax(sound))
  2856. emit_sound(entity, CHAN_WEAPON, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  2857.  
  2858. // Set duration and start lightning loop on next think
  2859. set_pev(entity, PEV_FLARE_DURATION, 1 + get_pcvar_num(cvar_flareduration)/2)
  2860. set_pev(entity, pev_dmgtime, current_time + 0.1)
  2861. }
  2862. else
  2863. {
  2864. // Delay explosion until we hit ground
  2865. set_pev(entity, pev_dmgtime, current_time + 0.5)
  2866. }
  2867. }
  2868. }
  2869.  
  2870. return HAM_IGNORED;
  2871. }
  2872.  
  2873. // Forward CmdStart
  2874. public fw_CmdStart(id, handle)
  2875. {
  2876. // Not alive
  2877. if (!g_isalive[id])
  2878. return;
  2879.  
  2880. // This logic looks kinda weird, but it should work in theory...
  2881. // p = g_zombie[id], q = g_survivor[id], r = g_cached_customflash
  2882. // ¬(p v q v (¬p ^ r)) <==> ¬p ^ ¬q ^ (p v ¬r)
  2883. if (!g_zombie[id] && !g_survivor[id] && (g_zombie[id] || !g_cached_customflash))
  2884. return;
  2885.  
  2886. // Check if it's a flashlight impulse
  2887. if (get_uc(handle, UC_Impulse) != IMPULSE_FLASHLIGHT)
  2888. return;
  2889.  
  2890. // Block it I say!
  2891. set_uc(handle, UC_Impulse, 0)
  2892.  
  2893. // Should human's custom flashlight be turned on?
  2894. if (!g_zombie[id] && !g_survivor[id] && g_flashbattery[id] > 2 && get_gametime() - g_lastflashtime[id] > 1.2)
  2895. {
  2896. // Prevent calling flashlight too quickly (bugfix)
  2897. g_lastflashtime[id] = get_gametime()
  2898.  
  2899. // Toggle custom flashlight
  2900. g_flashlight[id] = !(g_flashlight[id])
  2901.  
  2902. // Play flashlight toggle sound
  2903. emit_sound(id, CHAN_ITEM, sound_flashlight, 1.0, ATTN_NORM, 0, PITCH_NORM)
  2904.  
  2905. // Update flashlight status on the HUD
  2906. message_begin(MSG_ONE, g_msgFlashlight, _, id)
  2907. write_byte(g_flashlight[id]) // toggle
  2908. write_byte(g_flashbattery[id]) // battery
  2909. message_end()
  2910.  
  2911. // Remove previous tasks
  2912. remove_task(id+TASK_CHARGE)
  2913. remove_task(id+TASK_FLASH)
  2914.  
  2915. // Set the flashlight charge task
  2916. set_task(1.0, "flashlight_charge", id+TASK_CHARGE, _, _, "b")
  2917.  
  2918. // Call our custom flashlight task if enabled
  2919. if (g_flashlight[id]) set_task(0.1, "set_user_flashlight", id+TASK_FLASH, _, _, "b")
  2920. }
  2921. }
  2922.  
  2923. // Forward Player PreThink
  2924. public fw_PlayerPreThink(id)
  2925. {
  2926. // Not alive
  2927. if (!g_isalive[id])
  2928. return;
  2929.  
  2930. // Enable custom buyzone for player during buytime, unless zombie or survivor or time expired
  2931. if (g_cached_buytime > 0.0 && !g_zombie[id] && !g_survivor[id] && (get_gametime() < g_buytime[id] + g_cached_buytime))
  2932. {
  2933. if (pev_valid(g_buyzone_ent))
  2934. dllfunc(DLLFunc_Touch, g_buyzone_ent, id)
  2935. }
  2936.  
  2937. // Silent footsteps for zombies?
  2938. if (g_cached_zombiesilent && g_zombie[id] && !g_nemesis[id])
  2939. set_pev(id, pev_flTimeStepSound, STEPTIME_SILENT)
  2940.  
  2941. // Player frozen?
  2942. if (g_frozen[id])
  2943. {
  2944. set_pev(id, pev_velocity, Float:{0.0,0.0,0.0}) // stop motion
  2945. return; // shouldn't leap while frozen
  2946. }
  2947.  
  2948. // --- Check if player should leap ---
  2949.  
  2950. // Don't allow leap during freezetime
  2951. if (g_freezetime)
  2952. return;
  2953.  
  2954. // Check if proper CVARs are enabled and retrieve leap settings
  2955. static Float:cooldown, Float:current_time
  2956. if (g_zombie[id])
  2957. {
  2958. if (g_nemesis[id])
  2959. {
  2960. if (!g_cached_leapnemesis) return;
  2961. cooldown = g_cached_leapnemesiscooldown
  2962. }
  2963. else
  2964. {
  2965. switch (g_cached_leapzombies)
  2966. {
  2967. case 0: return;
  2968. case 2: if (!g_firstzombie[id]) return;
  2969. case 3: if (!g_lastzombie[id]) return;
  2970. }
  2971. cooldown = g_cached_leapzombiescooldown
  2972. }
  2973. }
  2974. else
  2975. {
  2976. if (g_survivor[id])
  2977. {
  2978. if (!g_cached_leapsurvivor) return;
  2979. cooldown = g_cached_leapsurvivorcooldown
  2980. }
  2981. else return;
  2982. }
  2983.  
  2984. current_time = get_gametime()
  2985.  
  2986. // Cooldown not over yet
  2987. if (current_time - g_lastleaptime[id] < cooldown)
  2988. return;
  2989.  
  2990. // Not doing a longjump (don't perform check for bots, they leap automatically)
  2991. if (!g_isbot[id] && !(pev(id, pev_button) & (IN_JUMP | IN_DUCK) == (IN_JUMP | IN_DUCK)))
  2992. return;
  2993.  
  2994. // Not on ground or not enough speed
  2995. if (!(pev(id, pev_flags) & FL_ONGROUND) || fm_get_speed(id) < 80)
  2996. return;
  2997.  
  2998. static Float:velocity[3]
  2999.  
  3000. // Make velocity vector
  3001. velocity_by_aim(id, g_survivor[id] ? get_pcvar_num(cvar_leapsurvivorforce) : g_nemesis[id] ? get_pcvar_num(cvar_leapnemesisforce) : get_pcvar_num(cvar_leapzombiesforce), velocity)
  3002.  
  3003. // Set custom height
  3004. velocity[2] = g_survivor[id] ? get_pcvar_float(cvar_leapsurvivorheight) : g_nemesis[id] ? get_pcvar_float(cvar_leapnemesisheight) : get_pcvar_float(cvar_leapzombiesheight)
  3005.  
  3006. // Apply the new velocity
  3007. set_pev(id, pev_velocity, velocity)
  3008.  
  3009. // Update last leap time
  3010. g_lastleaptime[id] = current_time
  3011. }
  3012.  
  3013. /*================================================================================
  3014. [Client Commands]
  3015. =================================================================================*/
  3016.  
  3017. // Say "/zpmenu"
  3018. public clcmd_saymenu(id)
  3019. {
  3020. show_menu_game(id) // show game menu
  3021. }
  3022.  
  3023. // Say "/unstuck"
  3024. public clcmd_sayunstuck(id)
  3025. {
  3026. menu_game(id, 3) // try to get unstuck
  3027. }
  3028.  
  3029. // Nightvision toggle
  3030. public clcmd_nightvision(id)
  3031. {
  3032. // Nightvision available to player?
  3033. if (g_nvision[id] || (g_isalive[id] && cs_get_user_nvg(id)))
  3034. {
  3035. // Enable-disable
  3036. g_nvisionenabled[id] = !(g_nvisionenabled[id])
  3037.  
  3038. // Custom nvg?
  3039. if (get_pcvar_num(cvar_customnvg))
  3040. {
  3041. remove_task(id+TASK_NVISION)
  3042. if (g_nvisionenabled[id]) set_task(0.1, "set_user_nvision", id+TASK_NVISION, _, _, "b")
  3043. }
  3044. else
  3045. set_user_gnvision(id, g_nvisionenabled[id])
  3046. }
  3047.  
  3048. return PLUGIN_HANDLED;
  3049. }
  3050.  
  3051. // Weapon Drop
  3052. public clcmd_drop(id)
  3053. {
  3054. // Survivor should stick with its weapon
  3055. if (g_survivor[id])
  3056. return PLUGIN_HANDLED;
  3057.  
  3058. return PLUGIN_CONTINUE;
  3059. }
  3060.  
  3061. // Buy BP Ammo
  3062. public clcmd_buyammo(id)
  3063. {
  3064. // Not alive or infinite ammo setting enabled
  3065. if (!g_isalive[id] || get_pcvar_num(cvar_infammo))
  3066. return PLUGIN_HANDLED;
  3067.  
  3068. // Not human
  3069. if (g_zombie[id])
  3070. {
  3071. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_HUMAN_ONLY")
  3072. return PLUGIN_HANDLED;
  3073. }
  3074.  
  3075. // Custom buytime enabled and human player standing in buyzone, allow buying weapon's ammo normally instead
  3076. if (g_cached_buytime > 0.0 && !g_survivor[id] && (get_gametime() < g_buytime[id] + g_cached_buytime) && cs_get_user_buyzone(id))
  3077. return PLUGIN_CONTINUE;
  3078.  
  3079. // Not enough ammo packs
  3080. if (g_ammopacks[id] < 1)
  3081. {
  3082. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "NOT_ENOUGH_AMMO")
  3083. return PLUGIN_HANDLED;
  3084. }
  3085.  
  3086. // Get user weapons
  3087. static weapons[32], num, i, currentammo, weaponid, refilled
  3088. num = 0 // reset passed weapons count (bugfix)
  3089. refilled = false
  3090. get_user_weapons(id, weapons, num)
  3091.  
  3092. // Loop through them and give the right ammo type
  3093. for (i = 0; i < num; i++)
  3094. {
  3095. // Prevents re-indexing the array
  3096. weaponid = weapons[i]
  3097.  
  3098. // Primary and secondary only
  3099. if (MAXBPAMMO[weaponid] > 2)
  3100. {
  3101. // Get current ammo of the weapon
  3102. currentammo = cs_get_user_bpammo(id, weaponid)
  3103.  
  3104. // Give additional ammo
  3105. ExecuteHamB(Ham_GiveAmmo, id, BUYAMMO[weaponid], AMMOTYPE[weaponid], MAXBPAMMO[weaponid])
  3106.  
  3107. // Check whether we actually refilled the weapon's ammo
  3108. if (cs_get_user_bpammo(id, weaponid) - currentammo > 0) refilled = true
  3109. }
  3110. }
  3111.  
  3112. // Weapons already have full ammo
  3113. if (!refilled) return PLUGIN_HANDLED;
  3114.  
  3115. // Deduce ammo packs, play clip purchase sound, and notify player
  3116. g_ammopacks[id]--
  3117. emit_sound(id, CHAN_ITEM, sound_buyammo, 1.0, ATTN_NORM, 0, PITCH_NORM)
  3118. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "AMMO_BOUGHT")
  3119.  
  3120. return PLUGIN_HANDLED;
  3121. }
  3122.  
  3123. // Block Team Change
  3124. public clcmd_changeteam(id)
  3125. {
  3126. static team
  3127. team = fm_cs_get_user_team(id)
  3128.  
  3129. // Unless it's a spectator joining the game
  3130. if (team == FM_CS_TEAM_SPECTATOR || team == FM_CS_TEAM_UNASSIGNED)
  3131. return PLUGIN_CONTINUE;
  3132.  
  3133. // Pressing 'M' (chooseteam) ingame should show the main menu instead
  3134. show_menu_game(id)
  3135. return PLUGIN_HANDLED;
  3136. }
  3137.  
  3138. /*================================================================================
  3139. [Menus]
  3140. =================================================================================*/
  3141.  
  3142. // Game Menu
  3143. show_menu_game(id)
  3144. {
  3145. // Player disconnected?
  3146. if (!g_isconnected[id])
  3147. return;
  3148.  
  3149. static menu[250], len, userflags
  3150. len = 0
  3151. userflags = get_user_flags(id)
  3152.  
  3153. // Title
  3154. len += formatex(menu[len], charsmax(menu) - len, "\y%s^n^n", g_modname)
  3155.  
  3156. // 1. Buy weapons
  3157. if (get_pcvar_num(cvar_buycustom))
  3158. len += formatex(menu[len], charsmax(menu) - len, "\r1.\w %L^n", id, "MENU_BUY")
  3159. else
  3160. len += formatex(menu[len], charsmax(menu) - len, "\d1. %L^n", id, "MENU_BUY")
  3161.  
  3162. // 2. Extra items
  3163. if (get_pcvar_num(cvar_extraitems) && g_isalive[id])
  3164. len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L^n", id, "MENU_EXTRABUY")
  3165. else
  3166. len += formatex(menu[len], charsmax(menu) - len, "\d2. %L^n", id, "MENU_EXTRABUY")
  3167.  
  3168. // 3. Zombie class
  3169. if (get_pcvar_num(cvar_zclasses))
  3170. len += formatex(menu[len], charsmax(menu) - len, "\r3.\w %L^n", id,"MENU_ZCLASS")
  3171. else
  3172. len += formatex(menu[len], charsmax(menu) - len, "\d3. %L^n", id,"MENU_ZCLASS")
  3173.  
  3174. // 4. Unstuck
  3175. if (g_isalive[id])
  3176. len += formatex(menu[len], charsmax(menu) - len, "\r4.\w %L^n", id, "MENU_UNSTUCK")
  3177. else
  3178. len += formatex(menu[len], charsmax(menu) - len, "\d4. %L^n", id, "MENU_UNSTUCK")
  3179.  
  3180. // 5. Help
  3181. len += formatex(menu[len], charsmax(menu) - len, "\r5.\w %L^n^n", id, "MENU_INFO")
  3182.  
  3183. // 6. Join spec
  3184. if (!g_isalive[id] || !get_pcvar_num(cvar_blocksuicide) || (userflags & g_access_flag[ACCESS_ADMIN_MENU]))
  3185. len += formatex(menu[len], charsmax(menu) - len, "\r6.\w %L^n^n", id, "MENU_SPECTATOR")
  3186. else
  3187. len += formatex(menu[len], charsmax(menu) - len, "\d6. %L^n^n", id, "MENU_SPECTATOR")
  3188.  
  3189. // 9. Admin menu
  3190. if (userflags & g_access_flag[ACCESS_ADMIN_MENU])
  3191. len += formatex(menu[len], charsmax(menu) - len, "\r9.\w %L", id, "MENU_ADMIN")
  3192. else
  3193. len += formatex(menu[len], charsmax(menu) - len, "\d9. %L", id, "MENU_ADMIN")
  3194.  
  3195. // 0. Exit
  3196. len += formatex(menu[len], charsmax(menu) - len, "^n^n\r0.\w %L", id, "MENU_EXIT")
  3197.  
  3198. // Fix for AMXX custom menus
  3199. if (pev_valid(id) == PDATA_SAFE)
  3200. set_pdata_int(id, OFFSET_CSMENUCODE, 0, OFFSET_LINUX)
  3201.  
  3202. show_menu(id, KEYSMENU, menu, -1, "Game Menu")
  3203. }
  3204.  
  3205. // Buy Menu 1
  3206. public show_menu_buy1(taskid)
  3207. {
  3208. // Get player's id
  3209. static id
  3210. (taskid > g_maxplayers) ? (id = ID_SPAWN) : (id = taskid);
  3211.  
  3212. // Player dead?
  3213. if (!g_isalive[id])
  3214. return;
  3215.  
  3216. // Zombies or survivors get no guns
  3217. if (g_zombie[id] || g_survivor[id])
  3218. return;
  3219.  
  3220. // Bots pick their weapons randomly / Random weapons setting enabled
  3221. if (get_pcvar_num(cvar_randweapons) || g_isbot[id])
  3222. {
  3223. buy_primary_weapon(id, random_num(0, ArraySize(g_primary_items) - 1))
  3224. menu_buy2(id, random_num(0, ArraySize(g_secondary_items) - 1))
  3225. return;
  3226. }
  3227.  
  3228. // Automatic selection enabled for player and menu called on spawn event
  3229. if (WPN_AUTO_ON && taskid > g_maxplayers)
  3230. {
  3231. buy_primary_weapon(id, WPN_AUTO_PRI)
  3232. menu_buy2(id, WPN_AUTO_SEC)
  3233. return;
  3234. }
  3235.  
  3236. static menu[300], len, weap, maxloops
  3237. len = 0
  3238. maxloops = min(WPN_STARTID+7, WPN_MAXIDS)
  3239.  
  3240. // Title
  3241. len += formatex(menu[len], charsmax(menu) - len, "\y%L \r[%d-%d]^n^n", id, "MENU_BUY1_TITLE", WPN_STARTID+1, min(WPN_STARTID+7, WPN_MAXIDS))
  3242.  
  3243. // 1-7. Weapon List
  3244. for (weap = WPN_STARTID; weap < maxloops; weap++)
  3245. len += formatex(menu[len], charsmax(menu) - len, "\r%d.\w %s^n", weap-WPN_STARTID+1, WEAPONNAMES[ArrayGetCell(g_primary_weaponids, weap)])
  3246.  
  3247. // 8. Auto Select
  3248. len += formatex(menu[len], charsmax(menu) - len, "^n\r8.\w %L \y[%L]", id, "MENU_AUTOSELECT", id, (WPN_AUTO_ON) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  3249.  
  3250. // 9. Next/Back - 0. Exit
  3251. len += formatex(menu[len], charsmax(menu) - len, "^n^n\r9.\w %L/%L^n^n\r0.\w %L", id, "MENU_NEXT", id, "MENU_BACK", id, "MENU_EXIT")
  3252.  
  3253. // Fix for AMXX custom menus
  3254. if (pev_valid(id) == PDATA_SAFE)
  3255. set_pdata_int(id, OFFSET_CSMENUCODE, 0, OFFSET_LINUX)
  3256.  
  3257. show_menu(id, KEYSMENU, menu, -1, "Buy Menu 1")
  3258. }
  3259.  
  3260. // Buy Menu 2
  3261. show_menu_buy2(id)
  3262. {
  3263. // Player dead?
  3264. if (!g_isalive[id])
  3265. return;
  3266.  
  3267. static menu[250], len, weap, maxloops
  3268. len = 0
  3269. maxloops = ArraySize(g_secondary_items)
  3270.  
  3271. // Title
  3272. len += formatex(menu[len], charsmax(menu) - len, "\y%L^n", id, "MENU_BUY2_TITLE")
  3273.  
  3274. // 1-6. Weapon List
  3275. for (weap = 0; weap < maxloops; weap++)
  3276. len += formatex(menu[len], charsmax(menu) - len, "^n\r%d.\w %s", weap+1, WEAPONNAMES[ArrayGetCell(g_secondary_weaponids, weap)])
  3277.  
  3278. // 8. Auto Select
  3279. len += formatex(menu[len], charsmax(menu) - len, "^n^n\r8.\w %L \y[%L]", id, "MENU_AUTOSELECT", id, (WPN_AUTO_ON) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  3280.  
  3281. // 0. Exit
  3282. len += formatex(menu[len], charsmax(menu) - len, "^n^n\r0.\w %L", id, "MENU_EXIT")
  3283.  
  3284. // Fix for AMXX custom menus
  3285. if (pev_valid(id) == PDATA_SAFE)
  3286. set_pdata_int(id, OFFSET_CSMENUCODE, 0, OFFSET_LINUX)
  3287.  
  3288. show_menu(id, KEYSMENU, menu, -1, "Buy Menu 2")
  3289. }
  3290.  
  3291. // Extra Items Menu
  3292. show_menu_extras(id)
  3293. {
  3294. // Player dead?
  3295. if (!g_isalive[id])
  3296. return;
  3297.  
  3298. static menuid, menu[128], item, team, buffer[32]
  3299.  
  3300. // Title
  3301. formatex(menu, charsmax(menu), "%L [%L]\r", id, "MENU_EXTRA_TITLE", id, g_zombie[id] ? g_nemesis[id] ? "CLASS_NEMESIS" : "CLASS_ZOMBIE" : g_survivor[id] ? "CLASS_SURVIVOR" : "CLASS_HUMAN")
  3302. menuid = menu_create(menu, "menu_extras")
  3303.  
  3304. // Item List
  3305. for (item = 0; item < g_extraitem_i; item++)
  3306. {
  3307. // Retrieve item's team
  3308. team = ArrayGetCell(g_extraitem_team, item)
  3309.  
  3310. // Item not available to player's team/class
  3311. if ((g_zombie[id] && !g_nemesis[id] && !(team & ZP_TEAM_ZOMBIE)) || (!g_zombie[id] && !g_survivor[id] && !(team & ZP_TEAM_HUMAN)) || (g_nemesis[id] && !(team & ZP_TEAM_NEMESIS)) || (g_survivor[id] && !(team & ZP_TEAM_SURVIVOR)))
  3312. continue;
  3313.  
  3314. // Check if it's one of the hardcoded items, check availability, set translated caption
  3315. switch (item)
  3316. {
  3317. case EXTRA_NVISION:
  3318. {
  3319. if (!get_pcvar_num(cvar_extranvision)) continue;
  3320. formatex(buffer, charsmax(buffer), "%L", id, "MENU_EXTRA1")
  3321. }
  3322. case EXTRA_ANTIDOTE:
  3323. {
  3324. if (!get_pcvar_num(cvar_extraantidote) || g_antidotecounter >= get_pcvar_num(cvar_antidotelimit)) continue;
  3325. formatex(buffer, charsmax(buffer), "%L", id, "MENU_EXTRA2")
  3326. }
  3327. case EXTRA_MADNESS:
  3328. {
  3329. if (!get_pcvar_num(cvar_extramadness) || g_madnesscounter >= get_pcvar_num(cvar_madnesslimit)) continue;
  3330. formatex(buffer, charsmax(buffer), "%L", id, "MENU_EXTRA3")
  3331. }
  3332. case EXTRA_INFBOMB:
  3333. {
  3334. if (!get_pcvar_num(cvar_extrainfbomb) || g_infbombcounter >= get_pcvar_num(cvar_infbomblimit)) continue;
  3335. formatex(buffer, charsmax(buffer), "%L", id, "MENU_EXTRA4")
  3336. }
  3337. default:
  3338. {
  3339. if (item >= EXTRA_WEAPONS_STARTID && item <= EXTRAS_CUSTOM_STARTID-1 && !get_pcvar_num(cvar_extraweapons)) continue;
  3340. ArrayGetString(g_extraitem_name, item, buffer, charsmax(buffer))
  3341. }
  3342. }
  3343.  
  3344. // Add Item Name and Cost
  3345. formatex(menu, charsmax(menu), "%s \y%d %L", buffer, ArrayGetCell(g_extraitem_cost, item), id, "AMMO_PACKS2")
  3346. buffer[0] = item
  3347. buffer[1] = 0
  3348. menu_additem(menuid, menu, buffer)
  3349. }
  3350.  
  3351. // No items to display?
  3352. if (menu_items(menuid) <= 0)
  3353. {
  3354. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id ,"CMD_NOT_EXTRAS")
  3355. menu_destroy(menuid)
  3356. return;
  3357. }
  3358.  
  3359. // Back - Next - Exit
  3360. formatex(menu, charsmax(menu), "%L", id, "MENU_BACK")
  3361. menu_setprop(menuid, MPROP_BACKNAME, menu)
  3362. formatex(menu, charsmax(menu), "%L", id, "MENU_NEXT")
  3363. menu_setprop(menuid, MPROP_NEXTNAME, menu)
  3364. formatex(menu, charsmax(menu), "%L", id, "MENU_EXIT")
  3365. menu_setprop(menuid, MPROP_EXITNAME, menu)
  3366.  
  3367. // If remembered page is greater than number of pages, clamp down the value
  3368. MENU_PAGE_EXTRAS = min(MENU_PAGE_EXTRAS, menu_pages(menuid)-1)
  3369.  
  3370. // Fix for AMXX custom menus
  3371. if (pev_valid(id) == PDATA_SAFE)
  3372. set_pdata_int(id, OFFSET_CSMENUCODE, 0, OFFSET_LINUX)
  3373.  
  3374. menu_display(id, menuid, MENU_PAGE_EXTRAS)
  3375. }
  3376.  
  3377. // Zombie Class Menu
  3378. public show_menu_zclass(id)
  3379. {
  3380. // Player disconnected
  3381. if (!g_isconnected[id])
  3382. return;
  3383.  
  3384. // Bots pick their zombie class randomly
  3385. if (g_isbot[id])
  3386. {
  3387. g_zombieclassnext[id] = random_num(0, g_zclass_i - 1)
  3388. return;
  3389. }
  3390.  
  3391. static menuid, menu[128], class, buffer[32], buffer2[32]
  3392.  
  3393. // Title
  3394. formatex(menu, charsmax(menu), "%L\r", id, "MENU_ZCLASS_TITLE")
  3395. menuid = menu_create(menu, "menu_zclass")
  3396.  
  3397. // Class List
  3398. for (class = 0; class < g_zclass_i; class++)
  3399. {
  3400. // Retrieve name and info
  3401. ArrayGetString(g_zclass_name, class, buffer, charsmax(buffer))
  3402. ArrayGetString(g_zclass_info, class, buffer2, charsmax(buffer2))
  3403.  
  3404. // Add to menu
  3405. if (class == g_zombieclassnext[id])
  3406. formatex(menu, charsmax(menu), "\d%s %s", buffer, buffer2)
  3407. else
  3408. formatex(menu, charsmax(menu), "%s \y%s", buffer, buffer2)
  3409.  
  3410. buffer[0] = class
  3411. buffer[1] = 0
  3412. menu_additem(menuid, menu, buffer)
  3413. }
  3414.  
  3415. // Back - Next - Exit
  3416. formatex(menu, charsmax(menu), "%L", id, "MENU_BACK")
  3417. menu_setprop(menuid, MPROP_BACKNAME, menu)
  3418. formatex(menu, charsmax(menu), "%L", id, "MENU_NEXT")
  3419. menu_setprop(menuid, MPROP_NEXTNAME, menu)
  3420. formatex(menu, charsmax(menu), "%L", id, "MENU_EXIT")
  3421. menu_setprop(menuid, MPROP_EXITNAME, menu)
  3422.  
  3423. // If remembered page is greater than number of pages, clamp down the value
  3424. MENU_PAGE_ZCLASS = min(MENU_PAGE_ZCLASS, menu_pages(menuid)-1)
  3425.  
  3426. // Fix for AMXX custom menus
  3427. if (pev_valid(id) == PDATA_SAFE)
  3428. set_pdata_int(id, OFFSET_CSMENUCODE, 0, OFFSET_LINUX)
  3429.  
  3430. menu_display(id, menuid, MENU_PAGE_ZCLASS)
  3431. }
  3432.  
  3433. // Help Menu
  3434. show_menu_info(id)
  3435. {
  3436. // Player disconnected?
  3437. if (!g_isconnected[id])
  3438. return;
  3439.  
  3440. static menu[150]
  3441.  
  3442. formatex(menu, charsmax(menu), "\y%L^n^n\r1.\w %L^n\r2.\w %L^n\r3.\w %L^n\r4.\w %L^n^n\r0.\w %L", id, "MENU_INFO_TITLE", id, "MENU_INFO1", id,"MENU_INFO2", id,"MENU_INFO3", id,"MENU_INFO4", id, "MENU_EXIT")
  3443.  
  3444. // Fix for AMXX custom menus
  3445. if (pev_valid(id) == PDATA_SAFE)
  3446. set_pdata_int(id, OFFSET_CSMENUCODE, 0, OFFSET_LINUX)
  3447.  
  3448. show_menu(id, KEYSMENU, menu, -1, "Mod Info")
  3449. }
  3450.  
  3451. // Admin Menu
  3452. show_menu_admin(id)
  3453. {
  3454. // Player disconnected?
  3455. if (!g_isconnected[id])
  3456. return;
  3457.  
  3458. static menu[250], len, userflags
  3459. len = 0
  3460. userflags = get_user_flags(id)
  3461.  
  3462. // Title
  3463. len += formatex(menu[len], charsmax(menu) - len, "\y%L^n^n", id, "MENU_ADMIN_TITLE")
  3464.  
  3465. // 1. Zombiefy/Humanize command
  3466. if (userflags & (g_access_flag[ACCESS_MODE_INFECTION] | g_access_flag[ACCESS_MAKE_ZOMBIE] | g_access_flag[ACCESS_MAKE_HUMAN]))
  3467. len += formatex(menu[len], charsmax(menu) - len, "\r1.\w %L^n", id, "MENU_ADMIN1")
  3468. else
  3469. len += formatex(menu[len], charsmax(menu) - len, "\d1. %L^n", id, "MENU_ADMIN1")
  3470.  
  3471. // 2. Nemesis command
  3472. if (userflags & (g_access_flag[ACCESS_MODE_NEMESIS] | g_access_flag[ACCESS_MAKE_NEMESIS]))
  3473. len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L^n", id, "MENU_ADMIN2")
  3474. else
  3475. len += formatex(menu[len], charsmax(menu) - len, "\d2. %L^n", id, "MENU_ADMIN2")
  3476.  
  3477. // 3. Survivor command
  3478. if (userflags & (g_access_flag[ACCESS_MODE_SURVIVOR] | g_access_flag[ACCESS_MAKE_SURVIVOR]))
  3479. len += formatex(menu[len], charsmax(menu) - len, "\r3.\w %L^n", id, "MENU_ADMIN3")
  3480. else
  3481. len += formatex(menu[len], charsmax(menu) - len, "\d3. %L^n", id, "MENU_ADMIN3")
  3482.  
  3483. // 4. Respawn command
  3484. if (userflags & g_access_flag[ACCESS_RESPAWN_PLAYERS])
  3485. len += formatex(menu[len], charsmax(menu) - len, "\r4.\w %L^n", id, "MENU_ADMIN4")
  3486. else
  3487. len += formatex(menu[len], charsmax(menu) - len, "\d4. %L^n", id, "MENU_ADMIN4")
  3488.  
  3489. // 5. Swarm mode command
  3490. if ((userflags & g_access_flag[ACCESS_MODE_SWARM]) && allowed_swarm())
  3491. len += formatex(menu[len], charsmax(menu) - len, "\r5.\w %L^n", id, "MENU_ADMIN5")
  3492. else
  3493. len += formatex(menu[len], charsmax(menu) - len, "\d5. %L^n", id, "MENU_ADMIN5")
  3494.  
  3495. // 6. Multi infection command
  3496. if ((userflags & g_access_flag[ACCESS_MODE_MULTI]) && allowed_multi())
  3497. len += formatex(menu[len], charsmax(menu) - len, "\r6.\w %L^n", id, "MENU_ADMIN6")
  3498. else
  3499. len += formatex(menu[len], charsmax(menu) - len, "\d6. %L^n", id, "MENU_ADMIN6")
  3500.  
  3501. // 7. Plague mode command
  3502. if ((userflags & g_access_flag[ACCESS_MODE_PLAGUE]) && allowed_plague())
  3503. len += formatex(menu[len], charsmax(menu) - len, "\r7.\w %L^n", id, "MENU_ADMIN7")
  3504. else
  3505. len += formatex(menu[len], charsmax(menu) - len, "\d7. %L^n", id, "MENU_ADMIN7")
  3506.  
  3507. // 0. Exit
  3508. len += formatex(menu[len], charsmax(menu) - len, "^n\r0.\w %L", id, "MENU_EXIT")
  3509.  
  3510. // Fix for AMXX custom menus
  3511. if (pev_valid(id) == PDATA_SAFE)
  3512. set_pdata_int(id, OFFSET_CSMENUCODE, 0, OFFSET_LINUX)
  3513.  
  3514. show_menu(id, KEYSMENU, menu, -1, "Admin Menu")
  3515. }
  3516.  
  3517. // Player List Menu
  3518. show_menu_player_list(id)
  3519. {
  3520. // Player disconnected?
  3521. if (!g_isconnected[id])
  3522. return;
  3523.  
  3524. static menuid, menu[128], player, userflags, buffer[2]
  3525. userflags = get_user_flags(id)
  3526.  
  3527. // Title
  3528. switch (PL_ACTION)
  3529. {
  3530. case ACTION_ZOMBIEFY_HUMANIZE: formatex(menu, charsmax(menu), "%L\r", id, "MENU_ADMIN1")
  3531. case ACTION_MAKE_NEMESIS: formatex(menu, charsmax(menu), "%L\r", id, "MENU_ADMIN2")
  3532. case ACTION_MAKE_SURVIVOR: formatex(menu, charsmax(menu), "%L\r", id, "MENU_ADMIN3")
  3533. case ACTION_RESPAWN_PLAYER: formatex(menu, charsmax(menu), "%L\r", id, "MENU_ADMIN4")
  3534. }
  3535. menuid = menu_create(menu, "menu_player_list")
  3536.  
  3537. // Player List
  3538. for (player = 0; player <= g_maxplayers; player++)
  3539. {
  3540. // Skip if not connected
  3541. if (!g_isconnected[player])
  3542. continue;
  3543.  
  3544. // Format text depending on the action to take
  3545. switch (PL_ACTION)
  3546. {
  3547. case ACTION_ZOMBIEFY_HUMANIZE: // Zombiefy/Humanize command
  3548. {
  3549. if (g_zombie[player])
  3550. {
  3551. if (allowed_human(player) && (userflags & g_access_flag[ACCESS_MAKE_HUMAN]))
  3552. formatex(menu, charsmax(menu), "%s \r[%L]", g_playername[player], id, g_nemesis[player] ? "CLASS_NEMESIS" : "CLASS_ZOMBIE")
  3553. else
  3554. formatex(menu, charsmax(menu), "\d%s [%L]", g_playername[player], id, g_nemesis[player] ? "CLASS_NEMESIS" : "CLASS_ZOMBIE")
  3555. }
  3556. else
  3557. {
  3558. if (allowed_zombie(player) && (g_newround ? (userflags & g_access_flag[ACCESS_MODE_INFECTION]) : (userflags & g_access_flag[ACCESS_MAKE_ZOMBIE])))
  3559. formatex(menu, charsmax(menu), "%s \y[%L]", g_playername[player], id, g_survivor[player] ? "CLASS_SURVIVOR" : "CLASS_HUMAN")
  3560. else
  3561. formatex(menu, charsmax(menu), "\d%s [%L]", g_playername[player], id, g_survivor[player] ? "CLASS_SURVIVOR" : "CLASS_HUMAN")
  3562. }
  3563. }
  3564. case ACTION_MAKE_NEMESIS: // Nemesis command
  3565. {
  3566. if (allowed_nemesis(player) && (g_newround ? (userflags & g_access_flag[ACCESS_MODE_NEMESIS]) : (userflags & g_access_flag[ACCESS_MAKE_NEMESIS])))
  3567. {
  3568. if (g_zombie[player])
  3569. formatex(menu, charsmax(menu), "%s \r[%L]", g_playername[player], id, g_nemesis[player] ? "CLASS_NEMESIS" : "CLASS_ZOMBIE")
  3570. else
  3571. formatex(menu, charsmax(menu), "%s \y[%L]", g_playername[player], id, g_survivor[player] ? "CLASS_SURVIVOR" : "CLASS_HUMAN")
  3572. }
  3573. else
  3574. formatex(menu, charsmax(menu), "\d%s [%L]", g_playername[player], id, g_zombie[player] ? g_nemesis[player] ? "CLASS_NEMESIS" : "CLASS_ZOMBIE" : g_survivor[player] ? "CLASS_SURVIVOR" : "CLASS_HUMAN")
  3575. }
  3576. case ACTION_MAKE_SURVIVOR: // Survivor command
  3577. {
  3578. if (allowed_survivor(player) && (g_newround ? (userflags & g_access_flag[ACCESS_MODE_SURVIVOR]) : (userflags & g_access_flag[ACCESS_MAKE_SURVIVOR])))
  3579. {
  3580. if (g_zombie[player])
  3581. formatex(menu, charsmax(menu), "%s \r[%L]", g_playername[player], id, g_nemesis[player] ? "CLASS_NEMESIS" : "CLASS_ZOMBIE")
  3582. else
  3583. formatex(menu, charsmax(menu), "%s \y[%L]", g_playername[player], id, g_survivor[player] ? "CLASS_SURVIVOR" : "CLASS_HUMAN")
  3584. }
  3585. else
  3586. formatex(menu, charsmax(menu), "\d%s [%L]", g_playername[player], id, g_zombie[player] ? g_nemesis[player] ? "CLASS_NEMESIS" : "CLASS_ZOMBIE" : g_survivor[player] ? "CLASS_SURVIVOR" : "CLASS_HUMAN")
  3587. }
  3588. case ACTION_RESPAWN_PLAYER: // Respawn command
  3589. {
  3590. if (allowed_respawn(player) && (userflags & g_access_flag[ACCESS_RESPAWN_PLAYERS]))
  3591. formatex(menu, charsmax(menu), "%s", g_playername[player])
  3592. else
  3593. formatex(menu, charsmax(menu), "\d%s", g_playername[player])
  3594. }
  3595. }
  3596.  
  3597. // Add player
  3598. buffer[0] = player
  3599. buffer[1] = 0
  3600. menu_additem(menuid, menu, buffer)
  3601. }
  3602.  
  3603. // Back - Next - Exit
  3604. formatex(menu, charsmax(menu), "%L", id, "MENU_BACK")
  3605. menu_setprop(menuid, MPROP_BACKNAME, menu)
  3606. formatex(menu, charsmax(menu), "%L", id, "MENU_NEXT")
  3607. menu_setprop(menuid, MPROP_NEXTNAME, menu)
  3608. formatex(menu, charsmax(menu), "%L", id, "MENU_EXIT")
  3609. menu_setprop(menuid, MPROP_EXITNAME, menu)
  3610.  
  3611. // If remembered page is greater than number of pages, clamp down the value
  3612. MENU_PAGE_PLAYERS = min(MENU_PAGE_PLAYERS, menu_pages(menuid)-1)
  3613.  
  3614. // Fix for AMXX custom menus
  3615. if (pev_valid(id) == PDATA_SAFE)
  3616. set_pdata_int(id, OFFSET_CSMENUCODE, 0, OFFSET_LINUX)
  3617.  
  3618. menu_display(id, menuid, MENU_PAGE_PLAYERS)
  3619. }
  3620.  
  3621. /*================================================================================
  3622. [Menu Handlers]
  3623. =================================================================================*/
  3624.  
  3625. // Game Menu
  3626. public menu_game(id, key)
  3627. {
  3628. // Player disconnected?
  3629. if (!g_isconnected[id])
  3630. return PLUGIN_HANDLED;
  3631.  
  3632. switch (key)
  3633. {
  3634. case 0: // Buy Weapons
  3635. {
  3636. // Custom buy menus enabled?
  3637. if (get_pcvar_num(cvar_buycustom))
  3638. {
  3639. // Disable the remember selection setting
  3640. WPN_AUTO_ON = 0
  3641. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "BUY_ENABLED")
  3642.  
  3643. // Show menu if player hasn't yet bought anything
  3644. if (g_canbuy[id]) show_menu_buy1(id)
  3645. }
  3646. else
  3647. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT")
  3648. }
  3649. case 1: // Extra Items
  3650. {
  3651. // Extra items enabled?
  3652. if (get_pcvar_num(cvar_extraitems))
  3653. {
  3654. // Check whether the player is able to buy anything
  3655. if (g_isalive[id])
  3656. show_menu_extras(id)
  3657. else
  3658. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT")
  3659. }
  3660. else
  3661. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT_EXTRAS")
  3662. }
  3663. case 2: // Zombie Classes
  3664. {
  3665. // Zombie classes enabled?
  3666. if (get_pcvar_num(cvar_zclasses))
  3667. show_menu_zclass(id)
  3668. else
  3669. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT_ZCLASSES")
  3670. }
  3671. case 3: // Unstuck
  3672. {
  3673. // Check if player is stuck
  3674. if (g_isalive[id])
  3675. {
  3676. if (is_player_stuck(id))
  3677. {
  3678. // Move to an initial spawn
  3679. if (get_pcvar_num(cvar_randspawn))
  3680. do_random_spawn(id) // random spawn (including CSDM)
  3681. else
  3682. do_random_spawn(id, 1) // regular spawn
  3683. }
  3684. else
  3685. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT_STUCK")
  3686. }
  3687. else
  3688. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT")
  3689. }
  3690. case 4: // Help Menu
  3691. {
  3692. show_menu_info(id)
  3693. }
  3694. case 5: // Join Spectator
  3695. {
  3696. // Player alive?
  3697. if (g_isalive[id])
  3698. {
  3699. // Prevent abuse by non-admins if block suicide setting is enabled
  3700. if (get_pcvar_num(cvar_blocksuicide) && !(get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MENU]))
  3701. {
  3702. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT")
  3703. return PLUGIN_HANDLED;
  3704. }
  3705.  
  3706. // Check that we still have both humans and zombies to keep the round going
  3707. check_round(id)
  3708.  
  3709. // Kill him before he switches team
  3710. dllfunc(DLLFunc_ClientKill, id)
  3711. }
  3712.  
  3713. // Temporarily save player stats?
  3714. if (get_pcvar_num(cvar_statssave)) save_stats(id)
  3715.  
  3716. // Remove previous tasks
  3717. remove_task(id+TASK_TEAM)
  3718. remove_task(id+TASK_MODEL)
  3719. remove_task(id+TASK_FLASH)
  3720. remove_task(id+TASK_CHARGE)
  3721. remove_task(id+TASK_SPAWN)
  3722. remove_task(id+TASK_BLOOD)
  3723. remove_task(id+TASK_AURA)
  3724. remove_task(id+TASK_BURN)
  3725.  
  3726. // Then move him to the spectator team
  3727. fm_cs_set_user_team(id, FM_CS_TEAM_SPECTATOR)
  3728. fm_user_team_update(id)
  3729. }
  3730. case 8: // Admin Menu
  3731. {
  3732. // Check if player has the required access
  3733. if (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MENU])
  3734. show_menu_admin(id)
  3735. else
  3736. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT_ACCESS")
  3737. }
  3738. }
  3739.  
  3740. return PLUGIN_HANDLED;
  3741. }
  3742.  
  3743. // Buy Menu 1
  3744. public menu_buy1(id, key)
  3745. {
  3746. // Player dead?
  3747. if (!g_isalive[id])
  3748. return PLUGIN_HANDLED;
  3749.  
  3750. // Zombies or survivors get no guns
  3751. if (g_zombie[id] || g_survivor[id])
  3752. return PLUGIN_HANDLED;
  3753.  
  3754. // Special keys / weapon list exceeded
  3755. if (key >= MENU_KEY_AUTOSELECT || WPN_SELECTION >= WPN_MAXIDS)
  3756. {
  3757. switch (key)
  3758. {
  3759. case MENU_KEY_AUTOSELECT: // toggle auto select
  3760. {
  3761. WPN_AUTO_ON = 1 - WPN_AUTO_ON
  3762. }
  3763. case MENU_KEY_NEXT: // next/back
  3764. {
  3765. if (WPN_STARTID+7 < WPN_MAXIDS)
  3766. WPN_STARTID += 7
  3767. else
  3768. WPN_STARTID = 0
  3769. }
  3770. case MENU_KEY_EXIT: // exit
  3771. {
  3772. return PLUGIN_HANDLED;
  3773. }
  3774. }
  3775.  
  3776. // Show buy menu again
  3777. show_menu_buy1(id)
  3778. return PLUGIN_HANDLED;
  3779. }
  3780.  
  3781. // Store selected weapon id
  3782. WPN_AUTO_PRI = WPN_SELECTION
  3783.  
  3784. // Buy primary weapon
  3785. buy_primary_weapon(id, WPN_AUTO_PRI)
  3786.  
  3787. // Show pistols menu
  3788. show_menu_buy2(id)
  3789.  
  3790. return PLUGIN_HANDLED;
  3791. }
  3792.  
  3793. // Buy Primary Weapon
  3794. buy_primary_weapon(id, selection)
  3795. {
  3796. // Drop previous weapons
  3797. drop_weapons(id, 1)
  3798. drop_weapons(id, 2)
  3799.  
  3800. // Strip off from weapons
  3801. fm_strip_user_weapons(id)
  3802. fm_give_item(id, "weapon_knife")
  3803.  
  3804. // Get weapon's id and name
  3805. static weaponid, wname[32]
  3806. weaponid = ArrayGetCell(g_primary_weaponids, selection)
  3807. ArrayGetString(g_primary_items, selection, wname, charsmax(wname))
  3808.  
  3809. // Give the new weapon and full ammo
  3810. fm_give_item(id, wname)
  3811. ExecuteHamB(Ham_GiveAmmo, id, MAXBPAMMO[weaponid], AMMOTYPE[weaponid], MAXBPAMMO[weaponid])
  3812.  
  3813. // Weapons bought
  3814. g_canbuy[id] = false
  3815.  
  3816. // Give additional items
  3817. static i
  3818. for (i = 0; i < ArraySize(g_additional_items); i++)
  3819. {
  3820. ArrayGetString(g_additional_items, i, wname, charsmax(wname))
  3821. fm_give_item(id, wname)
  3822. }
  3823. }
  3824.  
  3825. // Buy Menu 2
  3826. public menu_buy2(id, key)
  3827. {
  3828. // Player dead?
  3829. if (!g_isalive[id])
  3830. return PLUGIN_HANDLED;
  3831.  
  3832. // Zombies or survivors get no guns
  3833. if (g_zombie[id] || g_survivor[id])
  3834. return PLUGIN_HANDLED;
  3835.  
  3836. // Special keys / weapon list exceeded
  3837. if (key >= ArraySize(g_secondary_items))
  3838. {
  3839. // Toggle autoselect
  3840. if (key == MENU_KEY_AUTOSELECT)
  3841. WPN_AUTO_ON = 1 - WPN_AUTO_ON
  3842.  
  3843. // Reshow menu unless user exited
  3844. if (key != MENU_KEY_EXIT)
  3845. show_menu_buy2(id)
  3846.  
  3847. return PLUGIN_HANDLED;
  3848. }
  3849.  
  3850. // Store selected weapon
  3851. WPN_AUTO_SEC = key
  3852.  
  3853. // Drop secondary gun again, in case we picked another (bugfix)
  3854. drop_weapons(id, 2)
  3855.  
  3856. // Get weapon's id
  3857. static weaponid, wname[32]
  3858. weaponid = ArrayGetCell(g_secondary_weaponids, key)
  3859. ArrayGetString(g_secondary_items, key, wname, charsmax(wname))
  3860.  
  3861. // Give the new weapon and full ammo
  3862. fm_give_item(id, wname)
  3863. ExecuteHamB(Ham_GiveAmmo, id, MAXBPAMMO[weaponid], AMMOTYPE[weaponid], MAXBPAMMO[weaponid])
  3864.  
  3865. return PLUGIN_HANDLED;
  3866. }
  3867.  
  3868. // Extra Items Menu
  3869. public menu_extras(id, menuid, item)
  3870. {
  3871. // Player disconnected?
  3872. if (!is_user_connected(id))
  3873. {
  3874. menu_destroy(menuid)
  3875. return PLUGIN_HANDLED;
  3876. }
  3877.  
  3878. // Remember player's menu page
  3879. static menudummy
  3880. player_menu_info(id, menudummy, menudummy, MENU_PAGE_EXTRAS)
  3881.  
  3882. // Menu was closed
  3883. if (item == MENU_EXIT)
  3884. {
  3885. menu_destroy(menuid)
  3886. return PLUGIN_HANDLED;
  3887. }
  3888.  
  3889. // Dead players are not allowed to buy items
  3890. if (!g_isalive[id])
  3891. {
  3892. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT")
  3893. menu_destroy(menuid)
  3894. return PLUGIN_HANDLED;
  3895. }
  3896.  
  3897. // Retrieve extra item id
  3898. static buffer[2], dummy, itemid
  3899. menu_item_getinfo(menuid, item, dummy, buffer, charsmax(buffer), _, _, dummy)
  3900. itemid = buffer[0]
  3901.  
  3902. // Attempt to buy the item
  3903. buy_extra_item(id, itemid)
  3904. menu_destroy(menuid)
  3905. return PLUGIN_HANDLED;
  3906. }
  3907.  
  3908. // Buy Extra Item
  3909. buy_extra_item(id, itemid, ignorecost = 0)
  3910. {
  3911. // Retrieve item's team
  3912. static team
  3913. team = ArrayGetCell(g_extraitem_team, itemid)
  3914.  
  3915. // Check for team/class specific items
  3916. if ((g_zombie[id] && !g_nemesis[id] && !(team & ZP_TEAM_ZOMBIE)) || (!g_zombie[id] && !g_survivor[id] && !(team & ZP_TEAM_HUMAN)) || (g_nemesis[id] && !(team & ZP_TEAM_NEMESIS)) || (g_survivor[id] && !(team & ZP_TEAM_SURVIVOR)))
  3917. {
  3918. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT")
  3919. return;
  3920. }
  3921.  
  3922. // Check for unavailable items
  3923. if ((itemid == EXTRA_NVISION && !get_pcvar_num(cvar_extranvision))
  3924. || (itemid == EXTRA_ANTIDOTE && (!get_pcvar_num(cvar_extraantidote) || g_antidotecounter >= get_pcvar_num(cvar_antidotelimit)))
  3925. || (itemid == EXTRA_MADNESS && (!get_pcvar_num(cvar_extramadness) || g_madnesscounter >= get_pcvar_num(cvar_madnesslimit)))
  3926. || (itemid == EXTRA_INFBOMB && (!get_pcvar_num(cvar_extrainfbomb) || g_infbombcounter >= get_pcvar_num(cvar_infbomblimit)))
  3927. || (itemid >= EXTRA_WEAPONS_STARTID && itemid <= EXTRAS_CUSTOM_STARTID-1 && !get_pcvar_num(cvar_extraweapons)))
  3928. {
  3929. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT")
  3930. return;
  3931. }
  3932.  
  3933. // Check for hard coded items with special conditions
  3934. if ((itemid == EXTRA_ANTIDOTE && (g_endround || g_swarmround || g_nemround || g_survround || g_plagueround || fnGetZombies() <= 1 || (get_pcvar_num(cvar_deathmatch) && !get_pcvar_num(cvar_respawnafterlast) && fnGetHumans() == 1)))
  3935. || (itemid == EXTRA_MADNESS && g_nodamage[id]) || (itemid == EXTRA_INFBOMB && (g_endround || g_swarmround || g_nemround || g_survround || g_plagueround)))
  3936. {
  3937. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT_CANTUSE")
  3938. return;
  3939. }
  3940.  
  3941. // Ignore item's cost?
  3942. if (!ignorecost)
  3943. {
  3944. // Check that we have enough ammo packs
  3945. if (g_ammopacks[id] < ArrayGetCell(g_extraitem_cost, itemid))
  3946. {
  3947. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "NOT_ENOUGH_AMMO")
  3948. return;
  3949. }
  3950.  
  3951. // Deduce item cost
  3952. g_ammopacks[id] -= ArrayGetCell(g_extraitem_cost, itemid)
  3953. }
  3954.  
  3955. // Check which kind of item we're buying
  3956. switch (itemid)
  3957. {
  3958. case EXTRA_NVISION: // Night Vision
  3959. {
  3960. g_nvision[id] = true
  3961.  
  3962. if (!g_isbot[id])
  3963. {
  3964. g_nvisionenabled[id] = true
  3965.  
  3966. // Custom nvg?
  3967. if (get_pcvar_num(cvar_customnvg))
  3968. {
  3969. remove_task(id+TASK_NVISION)
  3970. set_task(0.1, "set_user_nvision", id+TASK_NVISION, _, _, "b")
  3971. }
  3972. else
  3973. set_user_gnvision(id, 1)
  3974. }
  3975. else
  3976. cs_set_user_nvg(id, 1)
  3977. }
  3978. case EXTRA_ANTIDOTE: // Antidote
  3979. {
  3980. // Increase antidote purchase count for this round
  3981. g_antidotecounter++
  3982.  
  3983. humanme(id, 0, 0)
  3984. }
  3985. case EXTRA_MADNESS: // Zombie Madness
  3986. {
  3987. // Increase madness purchase count for this round
  3988. g_madnesscounter++
  3989.  
  3990. g_nodamage[id] = true
  3991. set_task(0.1, "zombie_aura", id+TASK_AURA, _, _, "b")
  3992. set_task(get_pcvar_float(cvar_madnessduration), "madness_over", id+TASK_BLOOD)
  3993.  
  3994. static sound[64]
  3995. ArrayGetString(zombie_madness, random_num(0, ArraySize(zombie_madness) - 1), sound, charsmax(sound))
  3996. emit_sound(id, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  3997. }
  3998. case EXTRA_INFBOMB: // Infection Bomb
  3999. {
  4000. // Increase infection bomb purchase count for this round
  4001. g_infbombcounter++
  4002.  
  4003. // Already own one
  4004. if (user_has_weapon(id, CSW_HEGRENADE))
  4005. {
  4006. // Increase BP ammo on it instead
  4007. cs_set_user_bpammo(id, CSW_HEGRENADE, cs_get_user_bpammo(id, CSW_HEGRENADE) + 1)
  4008.  
  4009. // Flash ammo in hud
  4010. message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoPickup, _, id)
  4011. write_byte(AMMOID[CSW_HEGRENADE]) // ammo id
  4012. write_byte(1) // ammo amount
  4013. message_end()
  4014.  
  4015. // Play clip purchase sound
  4016. emit_sound(id, CHAN_ITEM, sound_buyammo, 1.0, ATTN_NORM, 0, PITCH_NORM)
  4017.  
  4018. return; // stop here
  4019. }
  4020.  
  4021. // Give weapon to the player
  4022. fm_give_item(id, "weapon_hegrenade")
  4023. }
  4024. default:
  4025. {
  4026. if (itemid >= EXTRA_WEAPONS_STARTID && itemid <= EXTRAS_CUSTOM_STARTID-1) // Weapons
  4027. {
  4028. // Get weapon's id and name
  4029. static weaponid, wname[32]
  4030. ArrayGetString(g_extraweapon_items, itemid - EXTRA_WEAPONS_STARTID, wname, charsmax(wname))
  4031. weaponid = cs_weapon_name_to_id(wname)
  4032.  
  4033. // If we are giving a primary/secondary weapon
  4034. if (MAXBPAMMO[weaponid] > 2)
  4035. {
  4036. // Make user drop the previous one
  4037. if ((1<<weaponid) & PRIMARY_WEAPONS_BIT_SUM)
  4038. drop_weapons(id, 1)
  4039. else
  4040. drop_weapons(id, 2)
  4041.  
  4042. // Give full BP ammo for the new one
  4043. ExecuteHamB(Ham_GiveAmmo, id, MAXBPAMMO[weaponid], AMMOTYPE[weaponid], MAXBPAMMO[weaponid])
  4044. }
  4045. // If we are giving a grenade which the user already owns
  4046. else if (user_has_weapon(id, weaponid))
  4047. {
  4048. // Increase BP ammo on it instead
  4049. cs_set_user_bpammo(id, weaponid, cs_get_user_bpammo(id, weaponid) + 1)
  4050.  
  4051. // Flash ammo in hud
  4052. message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoPickup, _, id)
  4053. write_byte(AMMOID[weaponid]) // ammo id
  4054. write_byte(1) // ammo amount
  4055. message_end()
  4056.  
  4057. // Play clip purchase sound
  4058. emit_sound(id, CHAN_ITEM, sound_buyammo, 1.0, ATTN_NORM, 0, PITCH_NORM)
  4059.  
  4060. return; // stop here
  4061. }
  4062.  
  4063. // Give weapon to the player
  4064. fm_give_item(id, wname)
  4065. }
  4066. else // Custom additions
  4067. {
  4068. // Item selected forward
  4069. ExecuteForward(g_fwExtraItemSelected, g_fwDummyResult, id, itemid);
  4070.  
  4071. // Item purchase blocked, restore buyer's ammo packs
  4072. if (g_fwDummyResult >= ZP_PLUGIN_HANDLED && !ignorecost)
  4073. g_ammopacks[id] += ArrayGetCell(g_extraitem_cost, itemid)
  4074. }
  4075. }
  4076. }
  4077. }
  4078.  
  4079. // Zombie Class Menu
  4080. public menu_zclass(id, menuid, item)
  4081. {
  4082. // Player disconnected?
  4083. if (!is_user_connected(id))
  4084. {
  4085. menu_destroy(menuid)
  4086. return PLUGIN_HANDLED;
  4087. }
  4088.  
  4089. // Remember player's menu page
  4090. static menudummy
  4091. player_menu_info(id, menudummy, menudummy, MENU_PAGE_ZCLASS)
  4092.  
  4093. // Menu was closed
  4094. if (item == MENU_EXIT)
  4095. {
  4096. menu_destroy(menuid)
  4097. return PLUGIN_HANDLED;
  4098. }
  4099.  
  4100. // Retrieve zombie class id
  4101. static buffer[2], dummy, classid
  4102. menu_item_getinfo(menuid, item, dummy, buffer, charsmax(buffer), _, _, dummy)
  4103. classid = buffer[0]
  4104.  
  4105. // Store selection for the next infection
  4106. g_zombieclassnext[id] = classid
  4107.  
  4108. static name[32]
  4109. ArrayGetString(g_zclass_name, g_zombieclassnext[id], name, charsmax(name))
  4110.  
  4111. // Show selected zombie class info and stats
  4112. zp_colored_print(id, "^x04[ZP-New]^x01 %L: %s", id, "ZOMBIE_SELECT", name)
  4113. zp_colored_print(id, "^x04[ZP-New]^x01 %L: %d %L: %d %L: %d %L: %d%%", id, "ZOMBIE_ATTRIB1", ArrayGetCell(g_zclass_hp, g_zombieclassnext[id]), id, "ZOMBIE_ATTRIB2", ArrayGetCell(g_zclass_spd, g_zombieclassnext[id]),
  4114. id, "ZOMBIE_ATTRIB3", floatround(Float:ArrayGetCell(g_zclass_grav, g_zombieclassnext[id]) * 800.0), id, "ZOMBIE_ATTRIB4", floatround(Float:ArrayGetCell(g_zclass_kb, g_zombieclassnext[id]) * 100.0))
  4115.  
  4116. menu_destroy(menuid)
  4117. return PLUGIN_HANDLED;
  4118. }
  4119.  
  4120. // Info Menu
  4121. public menu_info(id, key)
  4122. {
  4123. // Player disconnected?
  4124. if (!g_isconnected[id])
  4125. return PLUGIN_HANDLED;
  4126.  
  4127. static motd[1500], len
  4128. len = 0
  4129.  
  4130. switch (key)
  4131. {
  4132. case 0: // General
  4133. {
  4134. static weather, lighting[2]
  4135. weather = 0
  4136. get_pcvar_string(cvar_lighting, lighting, charsmax(lighting))
  4137. strtolower(lighting)
  4138.  
  4139. len += formatex(motd[len], charsmax(motd) - len, "%L ", id, "MOTD_INFO11", "Zombie Plague", PLUGIN_VERSION, "MeRcyLeZZ")
  4140. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO12")
  4141. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_A")
  4142.  
  4143. if (g_ambience_fog)
  4144. {
  4145. len += formatex(motd[len], charsmax(motd) - len, (weather < 1) ? " %L" : ". %L", id, "MOTD_FOG")
  4146. weather++
  4147. }
  4148. if (g_ambience_rain)
  4149. {
  4150. len += formatex(motd[len], charsmax(motd) - len, (weather < 1) ? " %L" : ". %L", id, "MOTD_RAIN")
  4151. weather++
  4152. }
  4153. if (g_ambience_snow)
  4154. {
  4155. len += formatex(motd[len], charsmax(motd) - len, (weather < 1) ? " %L" : ". %L", id, "MOTD_SNOW")
  4156. weather++
  4157. }
  4158. if (weather < 1) len += formatex(motd[len], charsmax(motd) - len, " %L", id, "MOTD_DISABLED")
  4159.  
  4160. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_B", lighting)
  4161. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_C", id, get_pcvar_num(cvar_triggered) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4162. if (lighting[0] >= 'a' && lighting[0] <= 'd' && get_pcvar_float(cvar_thunder) > 0.0) len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_D", floatround(get_pcvar_float(cvar_thunder)))
  4163. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_E", id, get_pcvar_num(cvar_removedoors) > 0 ? get_pcvar_num(cvar_removedoors) > 1 ? "MOTD_DOORS" : "MOTD_ROTATING" : "MOTD_ENABLED")
  4164. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_F", id, get_pcvar_num(cvar_deathmatch) > 0 ? get_pcvar_num(cvar_deathmatch) > 1 ? get_pcvar_num(cvar_deathmatch) > 2 ? "MOTD_ENABLED" : "MOTD_DM_ZOMBIE" : "MOTD_DM_HUMAN" : "MOTD_DISABLED")
  4165. if (get_pcvar_num(cvar_deathmatch)) len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_G", floatround(get_pcvar_float(cvar_spawnprotection)))
  4166. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_H", id, get_pcvar_num(cvar_randspawn) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4167. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_I", id, get_pcvar_num(cvar_extraitems) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4168. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_J", id, get_pcvar_num(cvar_zclasses) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4169. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_K", id, get_pcvar_num(cvar_customnvg) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4170. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO1_L", id, g_cached_customflash ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4171.  
  4172. show_motd(id, motd)
  4173. }
  4174. case 1: // Humans
  4175. {
  4176. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2")
  4177. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_A", get_pcvar_num(cvar_humanhp))
  4178. if (get_pcvar_num(cvar_humanlasthp) > 0) len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_B", get_pcvar_num(cvar_humanlasthp))
  4179. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_C", get_pcvar_num(cvar_humanspd))
  4180. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_D", floatround(get_pcvar_float(cvar_humangravity) * 800.0))
  4181. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_E", id, get_pcvar_num(cvar_infammo) > 0 ? get_pcvar_num(cvar_infammo) > 1 ? "MOTD_AMMO_CLIP" : "MOTD_AMMO_BP" : "MOTD_LIMITED")
  4182. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_F", get_pcvar_num(cvar_ammodamage_human))
  4183. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_G", id, get_pcvar_num(cvar_firegrenades) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4184. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_H", id, get_pcvar_num(cvar_frostgrenades) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4185. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_I", id, get_pcvar_num(cvar_flaregrenades) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4186. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO2_J", id, get_pcvar_num(cvar_knockback) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4187.  
  4188. show_motd(id, motd)
  4189. }
  4190. case 2: // Zombies
  4191. {
  4192. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3")
  4193. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_A", ArrayGetCell(g_zclass_hp, 0))
  4194. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_B", floatround(float(ArrayGetCell(g_zclass_hp, 0)) * get_pcvar_float(cvar_zombiefirsthp)))
  4195. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_C", floatround(get_pcvar_float(cvar_zombiearmor) * 100.0))
  4196. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_D", ArrayGetCell(g_zclass_spd, 0))
  4197. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_E", floatround(Float:ArrayGetCell(g_zclass_grav, 0) * 800.0))
  4198. if (get_pcvar_num(cvar_zombiebonushp)) len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_F", get_pcvar_num(cvar_zombiebonushp))
  4199. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_G", id, get_pcvar_num(cvar_zombiepainfree) > 0 ? get_pcvar_num(cvar_zombiepainfree) > 1 ? "MOTD_LASTZOMBIE" : "MOTD_ENABLED" : "MOTD_DISABLED")
  4200. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_H", id, get_pcvar_num(cvar_zombiebleeding) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4201. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO3_I", get_pcvar_num(cvar_ammoinfect))
  4202.  
  4203. show_motd(id, motd)
  4204. }
  4205. case 3: // Gameplay Modes
  4206. {
  4207. static nemhp[5], survhp[5]
  4208.  
  4209. // Get nemesis and survivor health
  4210. num_to_str(get_pcvar_num(cvar_nemhp), nemhp, charsmax(nemhp))
  4211. num_to_str(get_pcvar_num(cvar_survhp), survhp, charsmax(survhp))
  4212.  
  4213. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4")
  4214. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_A", id, get_pcvar_num(cvar_nem) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4215. if (get_pcvar_num(cvar_nem))
  4216. {
  4217. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_B", get_pcvar_num(cvar_nemchance))
  4218. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_C", get_pcvar_num(cvar_nemhp) > 0 ? nemhp : "[Auto]")
  4219. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_D", get_pcvar_num(cvar_nemspd))
  4220. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_E", floatround(get_pcvar_float(cvar_nemgravity) * 800.0))
  4221. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_F", id, g_cached_leapnemesis ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4222. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_G", id, get_pcvar_num(cvar_nempainfree) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4223. }
  4224. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_H", id, get_pcvar_num(cvar_surv) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4225. if (get_pcvar_num(cvar_surv))
  4226. {
  4227. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_I", get_pcvar_num(cvar_survchance))
  4228. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_J", get_pcvar_num(cvar_survhp) > 0 ? survhp : "[Auto]")
  4229. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_K", get_pcvar_num(cvar_survspd))
  4230. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_L", floatround(get_pcvar_float(cvar_survgravity) * 800.0))
  4231. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_M", id, g_cached_leapsurvivor ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4232. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_N", id, get_pcvar_num(cvar_survpainfree) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4233. }
  4234. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_O", id, get_pcvar_num(cvar_swarm) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4235. if (get_pcvar_num(cvar_swarm)) len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_P", get_pcvar_num(cvar_swarmchance))
  4236. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_Q", id, get_pcvar_num(cvar_multi) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4237. if (get_pcvar_num(cvar_multi))
  4238. {
  4239. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_R", get_pcvar_num(cvar_multichance))
  4240. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_S", floatround(get_pcvar_float(cvar_multiratio) * 100.0))
  4241. }
  4242. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_T", id, get_pcvar_num(cvar_plague) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4243. if (get_pcvar_num(cvar_plague))
  4244. {
  4245. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_U", get_pcvar_num(cvar_plaguechance))
  4246. len += formatex(motd[len], charsmax(motd) - len, "%L", id, "MOTD_INFO4_V", floatround(get_pcvar_float(cvar_plagueratio) * 100.0))
  4247. }
  4248.  
  4249. show_motd(id, motd)
  4250. }
  4251. default: return PLUGIN_HANDLED;
  4252. }
  4253.  
  4254. // Show help menu again if user wishes to read another topic
  4255. show_menu_info(id)
  4256.  
  4257. return PLUGIN_HANDLED;
  4258. }
  4259.  
  4260. // Admin Menu
  4261. public menu_admin(id, key)
  4262. {
  4263. // Player disconnected?
  4264. if (!g_isconnected[id])
  4265. return PLUGIN_HANDLED;
  4266.  
  4267. static userflags
  4268. userflags = get_user_flags(id)
  4269.  
  4270. switch (key)
  4271. {
  4272. case ACTION_ZOMBIEFY_HUMANIZE: // Zombiefy/Humanize command
  4273. {
  4274. if (userflags & (g_access_flag[ACCESS_MODE_INFECTION] | g_access_flag[ACCESS_MAKE_ZOMBIE] | g_access_flag[ACCESS_MAKE_HUMAN]))
  4275. {
  4276. // Show player list for admin to pick a target
  4277. PL_ACTION = ACTION_ZOMBIEFY_HUMANIZE
  4278. show_menu_player_list(id)
  4279. }
  4280. else
  4281. {
  4282. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT_ACCESS")
  4283. show_menu_admin(id)
  4284. }
  4285. }
  4286. case ACTION_MAKE_NEMESIS: // Nemesis command
  4287. {
  4288. if (userflags & (g_access_flag[ACCESS_MODE_NEMESIS] | g_access_flag[ACCESS_MAKE_NEMESIS]))
  4289. {
  4290. // Show player list for admin to pick a target
  4291. PL_ACTION = ACTION_MAKE_NEMESIS
  4292. show_menu_player_list(id)
  4293. }
  4294. else
  4295. {
  4296. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT_ACCESS")
  4297. show_menu_admin(id)
  4298. }
  4299. }
  4300. case ACTION_MAKE_SURVIVOR: // Survivor command
  4301. {
  4302. if (userflags & (g_access_flag[ACCESS_MODE_SURVIVOR] | g_access_flag[ACCESS_MAKE_SURVIVOR]))
  4303. {
  4304. // Show player list for admin to pick a target
  4305. PL_ACTION = ACTION_MAKE_SURVIVOR
  4306. show_menu_player_list(id)
  4307. }
  4308. else
  4309. {
  4310. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT_ACCESS")
  4311. show_menu_admin(id)
  4312. }
  4313. }
  4314. case ACTION_RESPAWN_PLAYER: // Respawn command
  4315. {
  4316. if (userflags & g_access_flag[ACCESS_RESPAWN_PLAYERS])
  4317. {
  4318. // Show player list for admin to pick a target
  4319. PL_ACTION = ACTION_RESPAWN_PLAYER
  4320. show_menu_player_list(id)
  4321. }
  4322. else
  4323. {
  4324. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT_ACCESS")
  4325. show_menu_admin(id)
  4326. }
  4327. }
  4328. case ACTION_MODE_SWARM: // Swarm Mode command
  4329. {
  4330. if (userflags & g_access_flag[ACCESS_MODE_SWARM])
  4331. {
  4332. if (allowed_swarm())
  4333. command_swarm(id)
  4334. else
  4335. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT")
  4336. }
  4337. else
  4338. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT_ACCESS")
  4339.  
  4340. show_menu_admin(id)
  4341. }
  4342. case ACTION_MODE_MULTI: // Multiple Infection command
  4343. {
  4344. if (userflags & g_access_flag[ACCESS_MODE_MULTI])
  4345. {
  4346. if (allowed_multi())
  4347. command_multi(id)
  4348. else
  4349. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT")
  4350. }
  4351. else
  4352. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT_ACCESS")
  4353.  
  4354. show_menu_admin(id)
  4355. }
  4356. case ACTION_MODE_PLAGUE: // Plague Mode command
  4357. {
  4358. if (userflags & g_access_flag[ACCESS_MODE_PLAGUE])
  4359. {
  4360. if (allowed_plague())
  4361. command_plague(id)
  4362. else
  4363. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT")
  4364. }
  4365. else
  4366. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT_ACCESS")
  4367.  
  4368. show_menu_admin(id)
  4369. }
  4370. }
  4371.  
  4372. return PLUGIN_HANDLED;
  4373. }
  4374.  
  4375. // Player List Menu
  4376. public menu_player_list(id, menuid, item)
  4377. {
  4378. // Player disconnected?
  4379. if (!is_user_connected(id))
  4380. {
  4381. menu_destroy(menuid)
  4382. return PLUGIN_HANDLED;
  4383. }
  4384.  
  4385. // Remember player's menu page
  4386. static menudummy
  4387. player_menu_info(id, menudummy, menudummy, MENU_PAGE_PLAYERS)
  4388.  
  4389. // Menu was closed
  4390. if (item == MENU_EXIT)
  4391. {
  4392. menu_destroy(menuid)
  4393. show_menu_admin(id)
  4394. return PLUGIN_HANDLED;
  4395. }
  4396.  
  4397. // Retrieve player id
  4398. static buffer[2], dummy, playerid
  4399. menu_item_getinfo(menuid, item, dummy, buffer, charsmax(buffer), _, _, dummy)
  4400. playerid = buffer[0]
  4401.  
  4402. // Perform action on player
  4403.  
  4404. // Get admin flags
  4405. static userflags
  4406. userflags = get_user_flags(id)
  4407.  
  4408. // Make sure it's still connected
  4409. if (g_isconnected[playerid])
  4410. {
  4411. // Perform the right action if allowed
  4412. switch (PL_ACTION)
  4413. {
  4414. case ACTION_ZOMBIEFY_HUMANIZE: // Zombiefy/Humanize command
  4415. {
  4416. if (g_zombie[playerid])
  4417. {
  4418. if (userflags & g_access_flag[ACCESS_MAKE_HUMAN])
  4419. {
  4420. if (allowed_human(playerid))
  4421. command_human(id, playerid)
  4422. else
  4423. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT")
  4424. }
  4425. else
  4426. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT_ACCESS")
  4427. }
  4428. else
  4429. {
  4430. if (g_newround ? (userflags & g_access_flag[ACCESS_MODE_INFECTION]) : (userflags & g_access_flag[ACCESS_MAKE_ZOMBIE]))
  4431. {
  4432. if (allowed_zombie(playerid))
  4433. command_zombie(id, playerid)
  4434. else
  4435. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT")
  4436. }
  4437. else
  4438. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT_ACCESS")
  4439. }
  4440. }
  4441. case ACTION_MAKE_NEMESIS: // Nemesis command
  4442. {
  4443. if (g_newround ? (userflags & g_access_flag[ACCESS_MODE_NEMESIS]) : (userflags & g_access_flag[ACCESS_MAKE_NEMESIS]))
  4444. {
  4445. if (allowed_nemesis(playerid))
  4446. command_nemesis(id, playerid)
  4447. else
  4448. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT")
  4449. }
  4450. else
  4451. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT_ACCESS")
  4452. }
  4453. case ACTION_MAKE_SURVIVOR: // Survivor command
  4454. {
  4455. if (g_newround ? (userflags & g_access_flag[ACCESS_MODE_SURVIVOR]) : (userflags & g_access_flag[ACCESS_MAKE_SURVIVOR]))
  4456. {
  4457. if (allowed_survivor(playerid))
  4458. command_survivor(id, playerid)
  4459. else
  4460. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT")
  4461. }
  4462. else
  4463. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT_ACCESS")
  4464. }
  4465. case ACTION_RESPAWN_PLAYER: // Respawn command
  4466. {
  4467. if (userflags & g_access_flag[ACCESS_RESPAWN_PLAYERS])
  4468. {
  4469. if (allowed_respawn(playerid))
  4470. command_respawn(id, playerid)
  4471. else
  4472. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT")
  4473. }
  4474. else
  4475. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT_ACCESS")
  4476. }
  4477. }
  4478. }
  4479. else
  4480. zp_colored_print(id, "^x04[ZP-New]^x01 %L", id, "CMD_NOT")
  4481.  
  4482. menu_destroy(menuid)
  4483. show_menu_player_list(id)
  4484. return PLUGIN_HANDLED;
  4485. }
  4486.  
  4487. // CS Buy Menus
  4488. public menu_cs_buy(id, key)
  4489. {
  4490. // Prevent buying if zombie/survivor (bugfix)
  4491. if (g_zombie[id] || g_survivor[id])
  4492. return PLUGIN_HANDLED;
  4493.  
  4494. return PLUGIN_CONTINUE;
  4495. }
  4496.  
  4497. /*================================================================================
  4498. [Admin Commands]
  4499. =================================================================================*/
  4500.  
  4501. // zp_toggle [1/0]
  4502. public cmd_toggle(id, level, cid)
  4503. {
  4504. // Check for access flag - Enable/Disable Mod
  4505. if (!cmd_access(id, g_access_flag[ACCESS_ENABLE_MOD], cid, 2))
  4506. return PLUGIN_HANDLED;
  4507.  
  4508. // Retrieve arguments
  4509. new arg[2]
  4510. read_argv(1, arg, charsmax(arg))
  4511.  
  4512. // Mod already enabled/disabled
  4513. if (str_to_num(arg) == g_pluginenabled)
  4514. return PLUGIN_HANDLED;
  4515.  
  4516. // Set toggle cvar
  4517. set_pcvar_num(cvar_toggle, str_to_num(arg))
  4518. client_print(id, print_console, "Zombie Plague %L.", id, str_to_num(arg) ? "MOTD_ENABLED" : "MOTD_DISABLED")
  4519.  
  4520. // Retrieve map name
  4521. new mapname[32]
  4522. get_mapname(mapname, charsmax(mapname))
  4523.  
  4524. // Restart current map
  4525. server_cmd("changelevel %s", mapname)
  4526.  
  4527. return PLUGIN_HANDLED;
  4528. }
  4529.  
  4530. // zp_zombie [target]
  4531. public cmd_zombie(id, level, cid)
  4532. {
  4533. // Check for access flag depending on the resulting action
  4534. if (g_newround)
  4535. {
  4536. // Start Mode Infection
  4537. if (!cmd_access(id, g_access_flag[ACCESS_MODE_INFECTION], cid, 2))
  4538. return PLUGIN_HANDLED;
  4539. }
  4540. else
  4541. {
  4542. // Make Zombie
  4543. if (!cmd_access(id, g_access_flag[ACCESS_MAKE_ZOMBIE], cid, 2))
  4544. return PLUGIN_HANDLED;
  4545. }
  4546.  
  4547. // Retrieve arguments
  4548. static arg[32], player
  4549. read_argv(1, arg, charsmax(arg))
  4550. player = cmd_target(id, arg, (CMDTARGET_ONLY_ALIVE | CMDTARGET_ALLOW_SELF))
  4551.  
  4552. // Invalid target
  4553. if (!player) return PLUGIN_HANDLED;
  4554.  
  4555. // Target not allowed to be zombie
  4556. if (!allowed_zombie(player))
  4557. {
  4558. client_print(id, print_console, "[ZP-New] %L", id, "CMD_NOT")
  4559. return PLUGIN_HANDLED
  4560. }
  4561.  
  4562. command_zombie(id, player)
  4563.  
  4564. return PLUGIN_HANDLED;
  4565. }
  4566.  
  4567. // zp_human [target]
  4568. public cmd_human(id, level, cid)
  4569. {
  4570. // Check for access flag - Make Human
  4571. if (!cmd_access(id, g_access_flag[ACCESS_MAKE_HUMAN], cid, 2))
  4572. return PLUGIN_HANDLED;
  4573.  
  4574. // Retrieve arguments
  4575. static arg[32], player
  4576. read_argv(1, arg, charsmax(arg))
  4577. player = cmd_target(id, arg, (CMDTARGET_ONLY_ALIVE | CMDTARGET_ALLOW_SELF))
  4578.  
  4579. // Invalid target
  4580. if (!player) return PLUGIN_HANDLED;
  4581.  
  4582. // Target not allowed to be human
  4583. if (!allowed_human(player))
  4584. {
  4585. client_print(id, print_console, "[ZP-New] %L", id, "CMD_NOT")
  4586. return PLUGIN_HANDLED;
  4587. }
  4588.  
  4589. command_human(id, player)
  4590.  
  4591. return PLUGIN_HANDLED;
  4592. }
  4593.  
  4594. // zp_survivor [target]
  4595. public cmd_survivor(id, level, cid)
  4596. {
  4597. // Check for access flag depending on the resulting action
  4598. if (g_newround)
  4599. {
  4600. // Start Mode Survivor
  4601. if (!cmd_access(id, g_access_flag[ACCESS_MODE_SURVIVOR], cid, 2))
  4602. return PLUGIN_HANDLED;
  4603. }
  4604. else
  4605. {
  4606. // Make Survivor
  4607. if (!cmd_access(id, g_access_flag[ACCESS_MAKE_SURVIVOR], cid, 2))
  4608. return PLUGIN_HANDLED;
  4609. }
  4610.  
  4611. // Retrieve arguments
  4612. static arg[32], player
  4613. read_argv(1, arg, charsmax(arg))
  4614. player = cmd_target(id, arg, (CMDTARGET_ONLY_ALIVE | CMDTARGET_ALLOW_SELF))
  4615.  
  4616. // Invalid target
  4617. if (!player) return PLUGIN_HANDLED;
  4618.  
  4619. // Target not allowed to be survivor
  4620. if (!allowed_survivor(player))
  4621. {
  4622. client_print(id, print_console, "[ZP-New] %L", id, "CMD_NOT")
  4623. return PLUGIN_HANDLED;
  4624. }
  4625.  
  4626. command_survivor(id, player)
  4627.  
  4628. return PLUGIN_HANDLED;
  4629. }
  4630.  
  4631. // zp_nemesis [target]
  4632. public cmd_nemesis(id, level, cid)
  4633. {
  4634. // Check for access flag depending on the resulting action
  4635. if (g_newround)
  4636. {
  4637. // Start Mode Nemesis
  4638. if (!cmd_access(id, g_access_flag[ACCESS_MODE_NEMESIS], cid, 2))
  4639. return PLUGIN_HANDLED;
  4640. }
  4641. else
  4642. {
  4643. // Make Nemesis
  4644. if (!cmd_access(id, g_access_flag[ACCESS_MAKE_NEMESIS], cid, 2))
  4645. return PLUGIN_HANDLED;
  4646. }
  4647.  
  4648. // Retrieve arguments
  4649. static arg[32], player
  4650. read_argv(1, arg, charsmax(arg))
  4651. player = cmd_target(id, arg, (CMDTARGET_ONLY_ALIVE | CMDTARGET_ALLOW_SELF))
  4652.  
  4653. // Invalid target
  4654. if (!player) return PLUGIN_HANDLED;
  4655.  
  4656. // Target not allowed to be nemesis
  4657. if (!allowed_nemesis(player))
  4658. {
  4659. client_print(id, print_console, "[ZP-New] %L", id, "CMD_NOT")
  4660. return PLUGIN_HANDLED;
  4661. }
  4662.  
  4663. command_nemesis(id, player)
  4664.  
  4665. return PLUGIN_HANDLED;
  4666. }
  4667.  
  4668. // zp_respawn [target]
  4669. public cmd_respawn(id, level, cid)
  4670. {
  4671. // Check for access flag - Respawn
  4672. if (!cmd_access(id, g_access_flag[ACCESS_RESPAWN_PLAYERS], cid, 2))
  4673. return PLUGIN_HANDLED;
  4674.  
  4675. // Retrieve arguments
  4676. static arg[32], player
  4677. read_argv(1, arg, charsmax(arg))
  4678. player = cmd_target(id, arg, CMDTARGET_ALLOW_SELF)
  4679.  
  4680. // Invalid target
  4681. if (!player) return PLUGIN_HANDLED;
  4682.  
  4683. // Target not allowed to be respawned
  4684. if (!allowed_respawn(player))
  4685. {
  4686. client_print(id, print_console, "[ZP-New] %L", id, "CMD_NOT")
  4687. return PLUGIN_HANDLED;
  4688. }
  4689.  
  4690. command_respawn(id, player)
  4691.  
  4692. return PLUGIN_HANDLED;
  4693. }
  4694.  
  4695. // zp_swarm
  4696. public cmd_swarm(id, level, cid)
  4697. {
  4698. // Check for access flag - Mode Swarm
  4699. if (!cmd_access(id, g_access_flag[ACCESS_MODE_SWARM], cid, 1))
  4700. return PLUGIN_HANDLED;
  4701.  
  4702. // Swarm mode not allowed
  4703. if (!allowed_swarm())
  4704. {
  4705. client_print(id, print_console, "[ZP-New] %L", id, "CMD_NOT")
  4706. return PLUGIN_HANDLED;
  4707. }
  4708.  
  4709. command_swarm(id)
  4710.  
  4711. return PLUGIN_HANDLED;
  4712. }
  4713.  
  4714. // zp_multi
  4715. public cmd_multi(id, level, cid)
  4716. {
  4717. // Check for access flag - Mode Multi
  4718. if (!cmd_access(id, g_access_flag[ACCESS_MODE_MULTI], cid, 1))
  4719. return PLUGIN_HANDLED;
  4720.  
  4721. // Multi infection mode not allowed
  4722. if (!allowed_multi())
  4723. {
  4724. client_print(id, print_console, "[ZP-New] %L", id, "CMD_NOT")
  4725. return PLUGIN_HANDLED;
  4726. }
  4727.  
  4728. command_multi(id)
  4729.  
  4730. return PLUGIN_HANDLED;
  4731. }
  4732.  
  4733. // zp_plague
  4734. public cmd_plague(id, level, cid)
  4735. {
  4736. // Check for access flag - Mode Plague
  4737. if (!cmd_access(id, g_access_flag[ACCESS_MODE_PLAGUE], cid, 1))
  4738. return PLUGIN_HANDLED;
  4739.  
  4740. // Plague mode not allowed
  4741. if (!allowed_plague())
  4742. {
  4743. client_print(id, print_console, "[ZP-New] %L", id, "CMD_NOT")
  4744. return PLUGIN_HANDLED;
  4745. }
  4746.  
  4747. command_plague(id)
  4748.  
  4749. return PLUGIN_HANDLED;
  4750. }
  4751.  
  4752. /*================================================================================
  4753. [Message Hooks]
  4754. =================================================================================*/
  4755.  
  4756. // Current Weapon info
  4757. public message_cur_weapon(msg_id, msg_dest, msg_entity)
  4758. {
  4759. // Not alive or zombie
  4760. if (!g_isalive[msg_entity] || g_zombie[msg_entity])
  4761. return;
  4762.  
  4763. // Not an active weapon
  4764. if (get_msg_arg_int(1) != 1)
  4765. return;
  4766.  
  4767. // Unlimited clip disabled for class
  4768. if (g_survivor[msg_entity] ? get_pcvar_num(cvar_survinfammo) <= 1 : get_pcvar_num(cvar_infammo) <= 1)
  4769. return;
  4770.  
  4771. // Get weapon's id
  4772. static weapon
  4773. weapon = get_msg_arg_int(2)
  4774.  
  4775. // Unlimited Clip Ammo for this weapon?
  4776. if (MAXBPAMMO[weapon] > 2)
  4777. {
  4778. // Max out clip ammo
  4779. static weapon_ent
  4780. weapon_ent = fm_cs_get_current_weapon_ent(msg_entity)
  4781. if (pev_valid(weapon_ent)) cs_set_weapon_ammo(weapon_ent, MAXCLIP[weapon])
  4782.  
  4783. // HUD should show full clip all the time
  4784. set_msg_arg_int(3, get_msg_argtype(3), MAXCLIP[weapon])
  4785. }
  4786. }
  4787.  
  4788. // Take off player's money
  4789. public message_money(msg_id, msg_dest, msg_entity)
  4790. {
  4791. // Remove money setting enabled?
  4792. if (!get_pcvar_num(cvar_removemoney))
  4793. return PLUGIN_CONTINUE;
  4794.  
  4795. fm_cs_set_user_money(msg_entity, 0)
  4796. return PLUGIN_HANDLED;
  4797. }
  4798.  
  4799. // Fix for the HL engine bug when HP is multiples of 256
  4800. public message_health(msg_id, msg_dest, msg_entity)
  4801. {
  4802. // Get player's health
  4803. static health
  4804. health = get_msg_arg_int(1)
  4805.  
  4806. // Don't bother
  4807. if (health < 256) return;
  4808.  
  4809. // Check if we need to fix it
  4810. if (health % 256 == 0)
  4811. fm_set_user_health(msg_entity, pev(msg_entity, pev_health) + 1)
  4812.  
  4813. // HUD can only show as much as 255 hp
  4814. set_msg_arg_int(1, get_msg_argtype(1), 255)
  4815. }
  4816.  
  4817. // Block flashlight battery messages if custom flashlight is enabled instead
  4818. public message_flashbat()
  4819. {
  4820. if (g_cached_customflash)
  4821. return PLUGIN_HANDLED;
  4822.  
  4823. return PLUGIN_CONTINUE;
  4824. }
  4825.  
  4826. // Flashbangs should only affect zombies
  4827. public message_screenfade(msg_id, msg_dest, msg_entity)
  4828. {
  4829. 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)
  4830. return PLUGIN_CONTINUE;
  4831.  
  4832. // Nemesis shouldn't be FBed
  4833. if (g_zombie[msg_entity] && !g_nemesis[msg_entity])
  4834. {
  4835. // Set flash color to nighvision's
  4836. set_msg_arg_int(4, get_msg_argtype(4), get_pcvar_num(cvar_nvgcolor[0]))
  4837. set_msg_arg_int(5, get_msg_argtype(5), get_pcvar_num(cvar_nvgcolor[1]))
  4838. set_msg_arg_int(6, get_msg_argtype(6), get_pcvar_num(cvar_nvgcolor[2]))
  4839. return PLUGIN_CONTINUE;
  4840. }
  4841.  
  4842. return PLUGIN_HANDLED;
  4843. }
  4844.  
  4845. // Prevent spectators' nightvision from being turned off when switching targets, etc.
  4846. public message_nvgtoggle()
  4847. {
  4848. return PLUGIN_HANDLED;
  4849. }
  4850.  
  4851. // Set correct model on player corpses
  4852. public message_clcorpse()
  4853. {
  4854. set_msg_arg_string(1, g_playermodel[get_msg_arg_int(12)])
  4855. }
  4856.  
  4857. // Prevent zombies from seeing any weapon pickup icon
  4858. public message_weappickup(msg_id, msg_dest, msg_entity)
  4859. {
  4860. if (g_zombie[msg_entity])
  4861. return PLUGIN_HANDLED;
  4862.  
  4863. return PLUGIN_CONTINUE;
  4864. }
  4865.  
  4866. // Prevent zombies from seeing any ammo pickup icon
  4867. public message_ammopickup(msg_id, msg_dest, msg_entity)
  4868. {
  4869. if (g_zombie[msg_entity])
  4870. return PLUGIN_HANDLED;
  4871.  
  4872. return PLUGIN_CONTINUE;
  4873. }
  4874.  
  4875. // Block hostage HUD display
  4876. public message_scenario()
  4877. {
  4878. if (get_msg_args() > 1)
  4879. {
  4880. static sprite[8]
  4881. get_msg_arg_string(2, sprite, charsmax(sprite))
  4882.  
  4883. if (equal(sprite, "hostage"))
  4884. return PLUGIN_HANDLED;
  4885. }
  4886.  
  4887. return PLUGIN_CONTINUE;
  4888. }
  4889.  
  4890. // Block hostages from appearing on radar
  4891. public message_hostagepos()
  4892. {
  4893. return PLUGIN_HANDLED;
  4894. }
  4895.  
  4896. // Block some text messages
  4897. public message_textmsg()
  4898. {
  4899. static textmsg[22]
  4900. get_msg_arg_string(2, textmsg, charsmax(textmsg))
  4901.  
  4902. // Game restarting, reset scores and call round end to balance the teams
  4903. if (equal(textmsg, "#Game_will_restart_in"))
  4904. {
  4905. logevent_round_end()
  4906. g_scorehumans = 0
  4907. g_scorezombies = 0
  4908. }
  4909. // Game commencing, reset scores only (round end is automatically triggered)
  4910. else if (equal(textmsg, "#Game_Commencing"))
  4911. {
  4912. g_gamecommencing = true
  4913. g_scorehumans = 0
  4914. g_scorezombies = 0
  4915. }
  4916. // Block round end related messages
  4917. else if (equal(textmsg, "#Hostages_Not_Rescued") || equal(textmsg, "#Round_Draw") || equal(textmsg, "#Terrorists_Win") || equal(textmsg, "#CTs_Win"))
  4918. {
  4919. return PLUGIN_HANDLED;
  4920. }
  4921.  
  4922. return PLUGIN_CONTINUE;
  4923. }
  4924.  
  4925. // Block CS round win audio messages, since we're playing our own instead
  4926. public message_sendaudio()
  4927. {
  4928. static audio[17]
  4929. get_msg_arg_string(2, audio, charsmax(audio))
  4930.  
  4931. if(equal(audio[7], "terwin") || equal(audio[7], "ctwin") || equal(audio[7], "rounddraw"))
  4932. return PLUGIN_HANDLED;
  4933.  
  4934. return PLUGIN_CONTINUE;
  4935. }
  4936.  
  4937. // Send actual team scores (T = zombies // CT = humans)
  4938. public message_teamscore()
  4939. {
  4940. static team[2]
  4941. get_msg_arg_string(1, team, charsmax(team))
  4942.  
  4943. switch (team[0])
  4944. {
  4945. // CT
  4946. case 'C': set_msg_arg_int(2, get_msg_argtype(2), g_scorehumans)
  4947. // Terrorist
  4948. case 'T': set_msg_arg_int(2, get_msg_argtype(2), g_scorezombies)
  4949. }
  4950. }
  4951.  
  4952. // Team Switch (or player joining a team for first time)
  4953. public message_teaminfo(msg_id, msg_dest)
  4954. {
  4955. // Only hook global messages
  4956. if (msg_dest != MSG_ALL && msg_dest != MSG_BROADCAST) return;
  4957.  
  4958. // Don't pick up our own TeamInfo messages for this player (bugfix)
  4959. if (g_switchingteam) return;
  4960.  
  4961. // Get player's id
  4962. static id
  4963. id = get_msg_arg_int(1)
  4964.  
  4965. // Invalid player id? (bugfix)
  4966. if (!(1 <= id <= g_maxplayers)) return;
  4967.  
  4968. // Enable spectators' nightvision if not spawning right away
  4969. set_task(0.2, "spec_nvision", id)
  4970.  
  4971. // Round didn't start yet, nothing to worry about
  4972. if (g_newround) return;
  4973.  
  4974. // Get his new team
  4975. static team[2]
  4976. get_msg_arg_string(2, team, charsmax(team))
  4977.  
  4978. // Perform some checks to see if they should join a different team instead
  4979. switch (team[0])
  4980. {
  4981. case 'C': // CT
  4982. {
  4983. if (g_survround && fnGetHumans()) // survivor alive --> switch to T and spawn as zombie
  4984. {
  4985. g_respawn_as_zombie[id] = true;
  4986. remove_task(id+TASK_TEAM)
  4987. fm_cs_set_user_team(id, FM_CS_TEAM_T)
  4988. set_msg_arg_string(2, "TERRORIST")
  4989. }
  4990. else if (!fnGetZombies()) // no zombies alive --> switch to T and spawn as zombie
  4991. {
  4992. g_respawn_as_zombie[id] = true;
  4993. remove_task(id+TASK_TEAM)
  4994. fm_cs_set_user_team(id, FM_CS_TEAM_T)
  4995. set_msg_arg_string(2, "TERRORIST")
  4996. }
  4997. }
  4998. case 'T': // Terrorist
  4999. {
  5000. if ((g_swarmround || g_survround) && fnGetHumans()) // survivor alive or swarm round w/ humans --> spawn as zombie
  5001. {
  5002. g_respawn_as_zombie[id] = true;
  5003. }
  5004. else if (fnGetZombies()) // zombies alive --> switch to CT
  5005. {
  5006. remove_task(id+TASK_TEAM)
  5007. fm_cs_set_user_team(id, FM_CS_TEAM_CT)
  5008. set_msg_arg_string(2, "CT")
  5009. }
  5010. }
  5011. }
  5012. }
  5013.  
  5014. /*================================================================================
  5015. [Main Functions]
  5016. =================================================================================*/
  5017.  
  5018. // Make Zombie Task
  5019. public make_zombie_task()
  5020. {
  5021. // Call make a zombie with no specific mode
  5022. make_a_zombie(MODE_NONE, 0)
  5023. }
  5024.  
  5025. // Make a Zombie Function
  5026. make_a_zombie(mode, id)
  5027. {
  5028. // Get alive players count
  5029. static iPlayersnum
  5030. iPlayersnum = fnGetAlive()
  5031.  
  5032. // Not enough players, come back later!
  5033. if (iPlayersnum < 1)
  5034. {
  5035. set_task(2.0, "make_zombie_task", TASK_MAKEZOMBIE)
  5036. return;
  5037. }
  5038.  
  5039. // Round started!
  5040. g_newround = false
  5041.  
  5042. // Set up some common vars
  5043. static forward_id, sound[64], iZombies, iMaxZombies
  5044.  
  5045. if ((mode == MODE_NONE && (!get_pcvar_num(cvar_preventconsecutive) || g_lastmode != MODE_SURVIVOR) && random_num(1, get_pcvar_num(cvar_survchance)) == get_pcvar_num(cvar_surv) && iPlayersnum >= get_pcvar_num(cvar_survminplayers)) || mode == MODE_SURVIVOR)
  5046. {
  5047. // Survivor Mode
  5048. g_survround = true
  5049. g_lastmode = MODE_SURVIVOR
  5050.  
  5051. // Choose player randomly?
  5052. if (mode == MODE_NONE)
  5053. id = fnGetRandomAlive(random_num(1, iPlayersnum))
  5054.  
  5055. // Remember id for calling our forward later
  5056. forward_id = id
  5057.  
  5058. // Turn player into a survivor
  5059. humanme(id, 1, 0)
  5060.  
  5061. // Turn the remaining players into zombies
  5062. for (id = 1; id <= g_maxplayers; id++)
  5063. {
  5064. // Not alive
  5065. if (!g_isalive[id])
  5066. continue;
  5067.  
  5068. // Survivor or already a zombie
  5069. if (g_survivor[id] || g_zombie[id])
  5070. continue;
  5071.  
  5072. // Turn into a zombie
  5073. zombieme(id, 0, 0, 1, 0)
  5074. }
  5075.  
  5076. // Play survivor sound
  5077. ArrayGetString(sound_survivor, random_num(0, ArraySize(sound_survivor) - 1), sound, charsmax(sound))
  5078. PlaySound(sound);
  5079.  
  5080. // Show Survivor HUD notice
  5081. set_dhudmessage(0, 155, 255, HUD_EVENT_X, HUD_EVENT_Y, 1, 0.0, 5.0, 1.0, 1.0)
  5082. show_dhudmessage(0, "%L", LANG_PLAYER, "NOTICE_SURVIVOR", g_playername[forward_id])
  5083.  
  5084. // Mode fully started!
  5085. g_modestarted = true
  5086.  
  5087. // Round start forward
  5088. ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_SURVIVOR, forward_id);
  5089. }
  5090. else if ((mode == MODE_NONE && (!get_pcvar_num(cvar_preventconsecutive) || g_lastmode != MODE_SWARM) && random_num(1, get_pcvar_num(cvar_swarmchance)) == get_pcvar_num(cvar_swarm) && iPlayersnum >= get_pcvar_num(cvar_swarmminplayers)) || mode == MODE_SWARM)
  5091. {
  5092. // Swarm Mode
  5093. g_swarmround = true
  5094. g_lastmode = MODE_SWARM
  5095.  
  5096. // Make sure there are alive players on both teams (BUGFIX)
  5097. if (!fnGetAliveTs())
  5098. {
  5099. // Move random player to T team
  5100. id = fnGetRandomAlive(random_num(1, iPlayersnum))
  5101. remove_task(id+TASK_TEAM)
  5102. fm_cs_set_user_team(id, FM_CS_TEAM_T)
  5103. fm_user_team_update(id)
  5104. }
  5105. else if (!fnGetAliveCTs())
  5106. {
  5107. // Move random player to CT team
  5108. id = fnGetRandomAlive(random_num(1, iPlayersnum))
  5109. remove_task(id+TASK_TEAM)
  5110. fm_cs_set_user_team(id, FM_CS_TEAM_CT)
  5111. fm_user_team_update(id)
  5112. }
  5113.  
  5114. // Turn every T into a zombie
  5115. for (id = 1; id <= g_maxplayers; id++)
  5116. {
  5117. // Not alive
  5118. if (!g_isalive[id])
  5119. continue;
  5120.  
  5121. // Not a Terrorist
  5122. if (fm_cs_get_user_team(id) != FM_CS_TEAM_T)
  5123. continue;
  5124.  
  5125. // Turn into a zombie
  5126. zombieme(id, 0, 0, 1, 0)
  5127. }
  5128.  
  5129. // Play swarm sound
  5130. ArrayGetString(sound_swarm, random_num(0, ArraySize(sound_swarm) - 1), sound, charsmax(sound))
  5131. PlaySound(sound);
  5132.  
  5133. // Show Swarm HUD notice
  5134. set_dhudmessage(0, 255, 0, HUD_EVENT_X, HUD_EVENT_Y, 1, 0.0, 5.0, 1.0, 1.0)
  5135. show_dhudmessage(0, "%L", LANG_PLAYER, "NOTICE_SWARM")
  5136.  
  5137. // Mode fully started!
  5138. g_modestarted = true
  5139.  
  5140. // Round start forward
  5141. ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_SWARM, 0);
  5142. }
  5143. else if ((mode == MODE_NONE && (!get_pcvar_num(cvar_preventconsecutive) || g_lastmode != MODE_MULTI) && random_num(1, get_pcvar_num(cvar_multichance)) == get_pcvar_num(cvar_multi) && floatround(iPlayersnum*get_pcvar_float(cvar_multiratio), floatround_ceil) >= 2 && floatround(iPlayersnum*get_pcvar_float(cvar_multiratio), floatround_ceil) < iPlayersnum && iPlayersnum >= get_pcvar_num(cvar_multiminplayers)) || mode == MODE_MULTI)
  5144. {
  5145. // Multi Infection Mode
  5146. g_lastmode = MODE_MULTI
  5147.  
  5148. // iMaxZombies is rounded up, in case there aren't enough players
  5149. iMaxZombies = floatround(iPlayersnum*get_pcvar_float(cvar_multiratio), floatround_ceil)
  5150. iZombies = 0
  5151.  
  5152. // Randomly turn iMaxZombies players into zombies
  5153. while (iZombies < iMaxZombies)
  5154. {
  5155. // Keep looping through all players
  5156. if (++id > g_maxplayers) id = 1
  5157.  
  5158. // Dead or already a zombie
  5159. if (!g_isalive[id] || g_zombie[id])
  5160. continue;
  5161.  
  5162. // Random chance
  5163. if (random_num(0, 1))
  5164. {
  5165. // Turn into a zombie
  5166. zombieme(id, 0, 0, 1, 0)
  5167. iZombies++
  5168. }
  5169. }
  5170.  
  5171. // Turn the remaining players into humans
  5172. for (id = 1; id <= g_maxplayers; id++)
  5173. {
  5174. // Only those of them who aren't zombies
  5175. if (!g_isalive[id] || g_zombie[id])
  5176. continue;
  5177.  
  5178. // Switch to CT
  5179. if (fm_cs_get_user_team(id) != FM_CS_TEAM_CT) // need to change team?
  5180. {
  5181. remove_task(id+TASK_TEAM)
  5182. fm_cs_set_user_team(id, FM_CS_TEAM_CT)
  5183. fm_user_team_update(id)
  5184. }
  5185. }
  5186.  
  5187. // Play multi infection sound
  5188. ArrayGetString(sound_multi, random_num(0, ArraySize(sound_multi) - 1), sound, charsmax(sound))
  5189. PlaySound(sound);
  5190.  
  5191. // Show Multi Infection HUD notice
  5192. set_dhudmessage(255, 155, 0, HUD_EVENT_X, HUD_EVENT_Y, 1, 0.0, 5.0, 1.0, 1.0)
  5193. show_dhudmessage(0, "%L", LANG_PLAYER, "NOTICE_MULTI")
  5194.  
  5195. // Mode fully started!
  5196. g_modestarted = true
  5197.  
  5198. // Round start forward
  5199. ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_MULTI, 0);
  5200. }
  5201. else if ((mode == MODE_NONE && (!get_pcvar_num(cvar_preventconsecutive) || g_lastmode != MODE_PLAGUE) && random_num(1, get_pcvar_num(cvar_plaguechance)) == get_pcvar_num(cvar_plague) && floatround((iPlayersnum-(get_pcvar_num(cvar_plaguenemnum)+get_pcvar_num(cvar_plaguesurvnum)))*get_pcvar_float(cvar_plagueratio), floatround_ceil) >= 1
  5202. && iPlayersnum-(get_pcvar_num(cvar_plaguesurvnum)+get_pcvar_num(cvar_plaguenemnum)+floatround((iPlayersnum-(get_pcvar_num(cvar_plaguenemnum)+get_pcvar_num(cvar_plaguesurvnum)))*get_pcvar_float(cvar_plagueratio), floatround_ceil)) >= 1 && iPlayersnum >= get_pcvar_num(cvar_plagueminplayers)) || mode == MODE_PLAGUE)
  5203. {
  5204. // Plague Mode
  5205. g_plagueround = true
  5206. g_lastmode = MODE_PLAGUE
  5207.  
  5208. // Turn specified amount of players into Survivors
  5209. static iSurvivors, iMaxSurvivors
  5210. iMaxSurvivors = get_pcvar_num(cvar_plaguesurvnum)
  5211. iSurvivors = 0
  5212.  
  5213. while (iSurvivors < iMaxSurvivors)
  5214. {
  5215. // Choose random guy
  5216. id = fnGetRandomAlive(random_num(1, iPlayersnum))
  5217.  
  5218. // Already a survivor?
  5219. if (g_survivor[id])
  5220. continue;
  5221.  
  5222. // If not, turn him into one
  5223. humanme(id, 1, 0)
  5224. iSurvivors++
  5225.  
  5226. // Apply survivor health multiplier
  5227. fm_set_user_health(id, floatround(float(pev(id, pev_health)) * get_pcvar_float(cvar_plaguesurvhpmulti)))
  5228. }
  5229.  
  5230. // Turn specified amount of players into Nemesis
  5231. static iNemesis, iMaxNemesis
  5232. iMaxNemesis = get_pcvar_num(cvar_plaguenemnum)
  5233. iNemesis = 0
  5234.  
  5235. while (iNemesis < iMaxNemesis)
  5236. {
  5237. // Choose random guy
  5238. id = fnGetRandomAlive(random_num(1, iPlayersnum))
  5239.  
  5240. // Already a survivor or nemesis?
  5241. if (g_survivor[id] || g_nemesis[id])
  5242. continue;
  5243.  
  5244. // If not, turn him into one
  5245. zombieme(id, 0, 1, 0, 0)
  5246. iNemesis++
  5247.  
  5248. // Apply nemesis health multiplier
  5249. fm_set_user_health(id, floatround(float(pev(id, pev_health)) * get_pcvar_float(cvar_plaguenemhpmulti)))
  5250. }
  5251.  
  5252. // iMaxZombies is rounded up, in case there aren't enough players
  5253. iMaxZombies = floatround((iPlayersnum-(get_pcvar_num(cvar_plaguenemnum)+get_pcvar_num(cvar_plaguesurvnum)))*get_pcvar_float(cvar_plagueratio), floatround_ceil)
  5254. iZombies = 0
  5255.  
  5256. // Randomly turn iMaxZombies players into zombies
  5257. while (iZombies < iMaxZombies)
  5258. {
  5259. // Keep looping through all players
  5260. if (++id > g_maxplayers) id = 1
  5261.  
  5262. // Dead or already a zombie or survivor
  5263. if (!g_isalive[id] || g_zombie[id] || g_survivor[id])
  5264. continue;
  5265.  
  5266. // Random chance
  5267. if (random_num(0, 1))
  5268. {
  5269. // Turn into a zombie
  5270. zombieme(id, 0, 0, 1, 0)
  5271. iZombies++
  5272. }
  5273. }
  5274.  
  5275. // Turn the remaining players into humans
  5276. for (id = 1; id <= g_maxplayers; id++)
  5277. {
  5278. // Only those of them who arent zombies or survivor
  5279. if (!g_isalive[id] || g_zombie[id] || g_survivor[id])
  5280. continue;
  5281.  
  5282. // Switch to CT
  5283. if (fm_cs_get_user_team(id) != FM_CS_TEAM_CT) // need to change team?
  5284. {
  5285. remove_task(id+TASK_TEAM)
  5286. fm_cs_set_user_team(id, FM_CS_TEAM_CT)
  5287. fm_user_team_update(id)
  5288. }
  5289. }
  5290.  
  5291. // Play plague sound
  5292. ArrayGetString(sound_plague, random_num(0, ArraySize(sound_plague) - 1), sound, charsmax(sound))
  5293. PlaySound(sound);
  5294.  
  5295. // Show Plague HUD notice
  5296. set_dhudmessage(0, 100, 255, HUD_EVENT_X, HUD_EVENT_Y, 1, 0.0, 5.0, 1.0, 1.0)
  5297. show_dhudmessage(0, "%L", LANG_PLAYER, "NOTICE_PLAGUE")
  5298.  
  5299. // Mode fully started!
  5300. g_modestarted = true
  5301.  
  5302. // Round start forward
  5303. ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_PLAGUE, 0);
  5304. }
  5305. else
  5306. {
  5307. // Single Infection Mode or Nemesis Mode
  5308.  
  5309. // Choose player randomly?
  5310. if (mode == MODE_NONE)
  5311. id = fnGetRandomAlive(random_num(1, iPlayersnum))
  5312.  
  5313. // Remember id for calling our forward later
  5314. forward_id = id
  5315.  
  5316. if ((mode == MODE_NONE && (!get_pcvar_num(cvar_preventconsecutive) || g_lastmode != MODE_NEMESIS) && random_num(1, get_pcvar_num(cvar_nemchance)) == get_pcvar_num(cvar_nem) && iPlayersnum >= get_pcvar_num(cvar_nemminplayers)) || mode == MODE_NEMESIS)
  5317. {
  5318. // Nemesis Mode
  5319. g_nemround = true
  5320. g_lastmode = MODE_NEMESIS
  5321.  
  5322. // Turn player into nemesis
  5323. zombieme(id, 0, 1, 0, 0)
  5324. }
  5325. else
  5326. {
  5327. // Single Infection Mode
  5328. g_lastmode = MODE_INFECTION
  5329.  
  5330. // Turn player into the first zombie
  5331. zombieme(id, 0, 0, 0, 0)
  5332. }
  5333.  
  5334. // Remaining players should be humans (CTs)
  5335. for (id = 1; id <= g_maxplayers; id++)
  5336. {
  5337. // Not alive
  5338. if (!g_isalive[id])
  5339. continue;
  5340.  
  5341. // First zombie/nemesis
  5342. if (g_zombie[id])
  5343. continue;
  5344.  
  5345. // Switch to CT
  5346. if (fm_cs_get_user_team(id) != FM_CS_TEAM_CT) // need to change team?
  5347. {
  5348. remove_task(id+TASK_TEAM)
  5349. fm_cs_set_user_team(id, FM_CS_TEAM_CT)
  5350. fm_user_team_update(id)
  5351. }
  5352. }
  5353.  
  5354. if (g_nemround)
  5355. {
  5356. // Play Nemesis sound
  5357. ArrayGetString(sound_nemesis, random_num(0, ArraySize(sound_nemesis) - 1), sound, charsmax(sound))
  5358. PlaySound(sound);
  5359.  
  5360. // Show Nemesis HUD notice
  5361. set_dhudmessage(255, 0, 0, HUD_EVENT_X, HUD_EVENT_Y, 1, 0.0, 5.0, 1.0, 1.0)
  5362. show_dhudmessage(0, "%L", LANG_PLAYER, "NOTICE_NEMESIS", g_playername[forward_id])
  5363.  
  5364. // Mode fully started!
  5365. g_modestarted = true
  5366.  
  5367. // Round start forward
  5368. ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_NEMESIS, forward_id);
  5369. }
  5370. else
  5371. {
  5372. // Show First Zombie HUD notice
  5373. set_dhudmessage(0, 255, 0, HUD_EVENT_X, HUD_EVENT_Y, 0, 0.0, 5.0, 1.0, 1.0)
  5374. show_dhudmessage(0, "%L",LANG_PLAYER, "NOTICE_FIRST", g_playername[forward_id])
  5375.  
  5376. // Mode fully started!
  5377. g_modestarted = true
  5378.  
  5379. // Round start forward
  5380. ExecuteForward(g_fwRoundStart, g_fwDummyResult, MODE_INFECTION, forward_id);
  5381. }
  5382. }
  5383.  
  5384. // Start ambience sounds after a mode begins
  5385. if ((g_ambience_sounds[AMBIENCE_SOUNDS_NEMESIS] && g_nemround) || (g_ambience_sounds[AMBIENCE_SOUNDS_SURVIVOR] && g_survround) || (g_ambience_sounds[AMBIENCE_SOUNDS_SWARM] && g_swarmround) || (g_ambience_sounds[AMBIENCE_SOUNDS_PLAGUE] && g_plagueround) || (g_ambience_sounds[AMBIENCE_SOUNDS_INFECTION] && !g_nemround && !g_survround && !g_swarmround && !g_plagueround))
  5386. {
  5387. remove_task(TASK_AMBIENCESOUNDS)
  5388. set_task(2.0, "ambience_sound_effects", TASK_AMBIENCESOUNDS)
  5389. }
  5390. }
  5391.  
  5392. // Zombie Me Function (player id, infector, turn into a nemesis, silent mode, deathmsg and rewards)
  5393. zombieme(id, infector, nemesis, silentmode, rewards)
  5394. {
  5395. // User infect attempt forward
  5396. ExecuteForward(g_fwUserInfect_attempt, g_fwDummyResult, id, infector, nemesis)
  5397.  
  5398. // One or more plugins blocked the infection. Only allow this after making sure it's
  5399. // not going to leave us with no zombies. Take into account a last player leaving case.
  5400. // BUGFIX: only allow after a mode has started, to prevent blocking first zombie e.g.
  5401. if (g_fwDummyResult >= ZP_PLUGIN_HANDLED && g_modestarted && fnGetZombies() > g_lastplayerleaving)
  5402. return;
  5403.  
  5404. // Pre user infect forward
  5405. ExecuteForward(g_fwUserInfected_pre, g_fwDummyResult, id, infector, nemesis)
  5406.  
  5407. // Show zombie class menu if they haven't chosen any (e.g. just connected)
  5408. if (g_zombieclassnext[id] == ZCLASS_NONE && get_pcvar_num(cvar_zclasses))
  5409. set_task(0.2, "show_menu_zclass", id)
  5410.  
  5411. // Set selected zombie class
  5412. g_zombieclass[id] = g_zombieclassnext[id]
  5413. // If no class selected yet, use the first (default) one
  5414. if (g_zombieclass[id] == ZCLASS_NONE) g_zombieclass[id] = 0
  5415.  
  5416. // Way to go...
  5417. g_zombie[id] = true
  5418. g_nemesis[id] = false
  5419. g_survivor[id] = false
  5420. g_firstzombie[id] = false
  5421.  
  5422. // Remove survivor's aura (bugfix)
  5423. set_pev(id, pev_effects, pev(id, pev_effects) &~ EF_BRIGHTLIGHT)
  5424.  
  5425. // Remove spawn protection (bugfix)
  5426. g_nodamage[id] = false
  5427. set_pev(id, pev_effects, pev(id, pev_effects) &~ EF_NODRAW)
  5428.  
  5429. // Reset burning duration counter (bugfix)
  5430. g_burning_duration[id] = 0
  5431.  
  5432. // Show deathmsg and reward infector?
  5433. if (rewards && infector)
  5434. {
  5435. // Send death notice and fix the "dead" attrib on scoreboard
  5436. SendDeathMsg(infector, id)
  5437. FixDeadAttrib(id)
  5438.  
  5439. // Reward frags, deaths, health, and ammo packs
  5440. UpdateFrags(infector, id, get_pcvar_num(cvar_fragsinfect), 1, 1)
  5441. g_ammopacks[infector] += get_pcvar_num(cvar_ammoinfect)
  5442. fm_set_user_health(infector, pev(infector, pev_health) + get_pcvar_num(cvar_zombiebonushp))
  5443. }
  5444.  
  5445. // Cache speed, knockback, and name for player's class
  5446. g_zombie_spd[id] = float(ArrayGetCell(g_zclass_spd, g_zombieclass[id]))
  5447. g_zombie_knockback[id] = Float:ArrayGetCell(g_zclass_kb, g_zombieclass[id])
  5448. ArrayGetString(g_zclass_name, g_zombieclass[id], g_zombie_classname[id], charsmax(g_zombie_classname[]))
  5449.  
  5450. // Set zombie attributes based on the mode
  5451. static sound[64]
  5452. if (!silentmode)
  5453. {
  5454. if (nemesis)
  5455. {
  5456. // Nemesis
  5457. g_nemesis[id] = true
  5458.  
  5459. // Set health [0 = auto]
  5460. if (get_pcvar_num(cvar_nemhp) == 0)
  5461. {
  5462. if (get_pcvar_num(cvar_nembasehp) == 0)
  5463. fm_set_user_health(id, ArrayGetCell(g_zclass_hp, 0) * fnGetAlive())
  5464. else
  5465. fm_set_user_health(id, get_pcvar_num(cvar_nembasehp) * fnGetAlive())
  5466. }
  5467. else
  5468. fm_set_user_health(id, get_pcvar_num(cvar_nemhp))
  5469.  
  5470. // Set gravity, if frozen set the restore gravity value instead
  5471. if (!g_frozen[id]) set_pev(id, pev_gravity, get_pcvar_float(cvar_nemgravity))
  5472. else g_frozen_gravity[id] = get_pcvar_float(cvar_nemgravity)
  5473.  
  5474. // Set nemesis maxspeed
  5475. ExecuteHamB(Ham_Player_ResetMaxSpeed, id)
  5476. }
  5477. else if (fnGetZombies() == 1)
  5478. {
  5479. // First zombie
  5480. g_firstzombie[id] = true
  5481.  
  5482. // Set health
  5483. fm_set_user_health(id, floatround(float(ArrayGetCell(g_zclass_hp, g_zombieclass[id])) * get_pcvar_float(cvar_zombiefirsthp)))
  5484.  
  5485. // Set gravity, if frozen set the restore gravity value instead
  5486. if (!g_frozen[id]) set_pev(id, pev_gravity, Float:ArrayGetCell(g_zclass_grav, g_zombieclass[id]))
  5487. else g_frozen_gravity[id] = Float:ArrayGetCell(g_zclass_grav, g_zombieclass[id])
  5488.  
  5489. // Set zombie maxspeed
  5490. ExecuteHamB(Ham_Player_ResetMaxSpeed, id)
  5491.  
  5492. // Infection sound
  5493. ArrayGetString(zombie_infect, random_num(0, ArraySize(zombie_infect) - 1), sound, charsmax(sound))
  5494. emit_sound(id, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  5495. }
  5496. else
  5497. {
  5498. // Infected by someone
  5499.  
  5500. // Set health
  5501. fm_set_user_health(id, ArrayGetCell(g_zclass_hp, g_zombieclass[id]))
  5502.  
  5503. // Set gravity, if frozen set the restore gravity value instead
  5504. if (!g_frozen[id]) set_pev(id, pev_gravity, Float:ArrayGetCell(g_zclass_grav, g_zombieclass[id]))
  5505. else g_frozen_gravity[id] = Float:ArrayGetCell(g_zclass_grav, g_zombieclass[id])
  5506.  
  5507. // Set zombie maxspeed
  5508. ExecuteHamB(Ham_Player_ResetMaxSpeed, id)
  5509.  
  5510. // Infection sound
  5511. ArrayGetString(zombie_infect, random_num(0, ArraySize(zombie_infect) - 1), sound, charsmax(sound))
  5512. emit_sound(id, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  5513.  
  5514. // Show Infection HUD notice
  5515. set_hudmessage(255, 0, 0, HUD_INFECT_X, HUD_INFECT_Y, 0, 0.0, 5.0, 1.0, 1.0, -1)
  5516.  
  5517. if (infector) // infected by someone?
  5518. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_INFECT2", g_playername[id], g_playername[infector])
  5519. else
  5520. ShowSyncHudMsg(0, g_MsgSync, "%L", LANG_PLAYER, "NOTICE_INFECT", g_playername[id])
  5521. }
  5522. }
  5523. else
  5524. {
  5525. // Silent mode, no HUD messages, no infection sounds
  5526.  
  5527. // Set health
  5528. fm_set_user_health(id, ArrayGetCell(g_zclass_hp, g_zombieclass[id]))
  5529.  
  5530. // Set gravity, if frozen set the restore gravity value instead
  5531. if (!g_frozen[id]) set_pev(id, pev_gravity, Float:ArrayGetCell(g_zclass_grav, g_zombieclass[id]))
  5532. else g_frozen_gravity[id] = Float:ArrayGetCell(g_zclass_grav, g_zombieclass[id])
  5533.  
  5534. // Set zombie maxspeed
  5535. ExecuteHamB(Ham_Player_ResetMaxSpeed, id)
  5536. }
  5537.  
  5538. // Remove previous tasks
  5539. remove_task(id+TASK_MODEL)
  5540. remove_task(id+TASK_BLOOD)
  5541. remove_task(id+TASK_AURA)
  5542. remove_task(id+TASK_BURN)
  5543.  
  5544. // Switch to T
  5545. if (fm_cs_get_user_team(id) != FM_CS_TEAM_T) // need to change team?
  5546. {
  5547. remove_task(id+TASK_TEAM)
  5548. fm_cs_set_user_team(id, FM_CS_TEAM_T)
  5549. fm_user_team_update(id)
  5550. }
  5551.  
  5552. // Custom models stuff
  5553. static currentmodel[32], tempmodel[32], already_has_model, i, iRand, size
  5554. already_has_model = false
  5555.  
  5556. if (g_handle_models_on_separate_ent)
  5557. {
  5558. // Set the right model
  5559. if (g_nemesis[id])
  5560. {
  5561. iRand = random_num(0, ArraySize(model_nemesis) - 1)
  5562. ArrayGetString(model_nemesis, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  5563. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_nemesis, iRand))
  5564. }
  5565. else
  5566. {
  5567. if (get_pcvar_num(cvar_adminmodelszombie) && (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS]))
  5568. {
  5569. iRand = random_num(0, ArraySize(model_admin_zombie) - 1)
  5570. ArrayGetString(model_admin_zombie, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  5571. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_admin_zombie, iRand))
  5572. }
  5573. else
  5574. {
  5575. iRand = random_num(ArrayGetCell(g_zclass_modelsstart, g_zombieclass[id]), ArrayGetCell(g_zclass_modelsend, g_zombieclass[id]) - 1)
  5576. ArrayGetString(g_zclass_playermodel, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  5577. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_zclass_modelindex, iRand))
  5578. }
  5579. }
  5580.  
  5581. // Set model on player model entity
  5582. fm_set_playermodel_ent(id)
  5583.  
  5584. // Nemesis glow / remove glow on player model entity, unless frozen
  5585. if (!g_frozen[id])
  5586. {
  5587. if (g_nemesis[id] && get_pcvar_num(cvar_nemglow))
  5588. fm_set_rendering(g_ent_playermodel[id], kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 25)
  5589. else
  5590. fm_set_rendering(g_ent_playermodel[id])
  5591. }
  5592. }
  5593. else
  5594. {
  5595. // Get current model for comparing it with the current one
  5596. fm_cs_get_user_model(id, currentmodel, charsmax(currentmodel))
  5597.  
  5598. // Set the right model, after checking that we don't already have it
  5599. if (g_nemesis[id])
  5600. {
  5601. size = ArraySize(model_nemesis)
  5602. for (i = 0; i < size; i++)
  5603. {
  5604. ArrayGetString(model_nemesis, i, tempmodel, charsmax(tempmodel))
  5605. if (equal(currentmodel, tempmodel)) already_has_model = true
  5606. }
  5607.  
  5608. if (!already_has_model)
  5609. {
  5610. iRand = random_num(0, size - 1)
  5611. ArrayGetString(model_nemesis, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  5612. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_nemesis, iRand))
  5613. }
  5614. }
  5615. else
  5616. {
  5617. if (get_pcvar_num(cvar_adminmodelszombie) && (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS]))
  5618. {
  5619. size = ArraySize(model_admin_zombie)
  5620. for (i = 0; i < size; i++)
  5621. {
  5622. ArrayGetString(model_admin_zombie, i, tempmodel, charsmax(tempmodel))
  5623. if (equal(currentmodel, tempmodel)) already_has_model = true
  5624. }
  5625.  
  5626. if (!already_has_model)
  5627. {
  5628. iRand = random_num(0, size - 1)
  5629. ArrayGetString(model_admin_zombie, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  5630. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_admin_zombie, iRand))
  5631. }
  5632. }
  5633. else
  5634. {
  5635. for (i = ArrayGetCell(g_zclass_modelsstart, g_zombieclass[id]); i < ArrayGetCell(g_zclass_modelsend, g_zombieclass[id]); i++)
  5636. {
  5637. ArrayGetString(g_zclass_playermodel, i, tempmodel, charsmax(tempmodel))
  5638. if (equal(currentmodel, tempmodel)) already_has_model = true
  5639. }
  5640.  
  5641. if (!already_has_model)
  5642. {
  5643. iRand = random_num(ArrayGetCell(g_zclass_modelsstart, g_zombieclass[id]), ArrayGetCell(g_zclass_modelsend, g_zombieclass[id]) - 1)
  5644. ArrayGetString(g_zclass_playermodel, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  5645. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_zclass_modelindex, iRand))
  5646. }
  5647. }
  5648. }
  5649.  
  5650. // Need to change the model?
  5651. if (!already_has_model)
  5652. {
  5653. // An additional delay is offset at round start
  5654. // since SVC_BAD is more likely to be triggered there
  5655. if (g_newround)
  5656. set_task(5.0 * g_modelchange_delay, "fm_user_model_update", id+TASK_MODEL)
  5657. else
  5658. fm_user_model_update(id+TASK_MODEL)
  5659. }
  5660.  
  5661. // Nemesis glow / remove glow, unless frozen
  5662. if (!g_frozen[id])
  5663. {
  5664. if (g_nemesis[id] && get_pcvar_num(cvar_nemglow))
  5665. fm_set_rendering(id, kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 25)
  5666. else
  5667. fm_set_rendering(id)
  5668. }
  5669. }
  5670.  
  5671. // Remove any zoom (bugfix)
  5672. cs_set_user_zoom(id, CS_RESET_ZOOM, 1)
  5673.  
  5674. // Remove armor
  5675. cs_set_user_armor(id, 0, CS_ARMOR_NONE)
  5676.  
  5677. // Drop weapons when infected
  5678. drop_weapons(id, 1)
  5679. drop_weapons(id, 2)
  5680.  
  5681. // Strip zombies from guns and give them a knife
  5682. fm_strip_user_weapons(id)
  5683. fm_give_item(id, "weapon_knife")
  5684.  
  5685. // Fancy effects
  5686. infection_effects(id)
  5687.  
  5688. // Nemesis aura task
  5689. if (g_nemesis[id] && get_pcvar_num(cvar_nemaura))
  5690. set_task(0.1, "zombie_aura", id+TASK_AURA, _, _, "b")
  5691.  
  5692. // Remove CS nightvision if player owns one (bugfix)
  5693. if (cs_get_user_nvg(id))
  5694. {
  5695. cs_set_user_nvg(id, 0)
  5696. if (get_pcvar_num(cvar_customnvg)) remove_task(id+TASK_NVISION)
  5697. else if (g_nvisionenabled[id]) set_user_gnvision(id, 0)
  5698. }
  5699.  
  5700. // Give Zombies Night Vision?
  5701. if (get_pcvar_num(cvar_nvggive))
  5702. {
  5703. g_nvision[id] = true
  5704.  
  5705. if (!g_isbot[id])
  5706. {
  5707. // Turn on Night Vision automatically?
  5708. if (get_pcvar_num(cvar_nvggive) == 1)
  5709. {
  5710. g_nvisionenabled[id] = true
  5711.  
  5712. // Custom nvg?
  5713. if (get_pcvar_num(cvar_customnvg))
  5714. {
  5715. remove_task(id+TASK_NVISION)
  5716. set_task(0.1, "set_user_nvision", id+TASK_NVISION, _, _, "b")
  5717. }
  5718. else
  5719. set_user_gnvision(id, 1)
  5720. }
  5721. // Turn off nightvision when infected (bugfix)
  5722. else if (g_nvisionenabled[id])
  5723. {
  5724. if (get_pcvar_num(cvar_customnvg)) remove_task(id+TASK_NVISION)
  5725. else set_user_gnvision(id, 0)
  5726. g_nvisionenabled[id] = false
  5727. }
  5728. }
  5729. else
  5730. cs_set_user_nvg(id, 1); // turn on NVG for bots
  5731. }
  5732. // Disable nightvision when infected (bugfix)
  5733. else if (g_nvision[id])
  5734. {
  5735. if (get_pcvar_num(cvar_customnvg)) remove_task(id+TASK_NVISION)
  5736. else if (g_nvisionenabled[id]) set_user_gnvision(id, 0)
  5737. g_nvision[id] = false
  5738. g_nvisionenabled[id] = false
  5739. }
  5740.  
  5741. // Set custom FOV?
  5742. if (get_pcvar_num(cvar_zombiefov) != 90 && get_pcvar_num(cvar_zombiefov) != 0)
  5743. {
  5744. message_begin(MSG_ONE, g_msgSetFOV, _, id)
  5745. write_byte(get_pcvar_num(cvar_zombiefov)) // fov angle
  5746. message_end()
  5747. }
  5748.  
  5749. // Call the bloody task
  5750. if (!g_nemesis[id] && get_pcvar_num(cvar_zombiebleeding))
  5751. set_task(0.7, "make_blood", id+TASK_BLOOD, _, _, "b")
  5752.  
  5753. // Idle sounds task
  5754. if (!g_nemesis[id])
  5755. set_task(random_float(50.0, 70.0), "zombie_play_idle", id+TASK_BLOOD, _, _, "b")
  5756.  
  5757. // Turn off zombie's flashlight
  5758. turn_off_flashlight(id)
  5759.  
  5760. // Post user infect forward
  5761. ExecuteForward(g_fwUserInfected_post, g_fwDummyResult, id, infector, nemesis)
  5762.  
  5763. // Last Zombie Check
  5764. fnCheckLastZombie()
  5765. }
  5766.  
  5767. // Function Human Me (player id, turn into a survivor, silent mode)
  5768. humanme(id, survivor, silentmode)
  5769. {
  5770. // User humanize attempt forward
  5771. ExecuteForward(g_fwUserHumanize_attempt, g_fwDummyResult, id, survivor)
  5772.  
  5773. // One or more plugins blocked the "humanization". Only allow this after making sure it's
  5774. // not going to leave us with no humans. Take into account a last player leaving case.
  5775. // BUGFIX: only allow after a mode has started, to prevent blocking first survivor e.g.
  5776. if (g_fwDummyResult >= ZP_PLUGIN_HANDLED && g_modestarted && fnGetHumans() > g_lastplayerleaving)
  5777. return;
  5778.  
  5779. // Pre user humanize forward
  5780. ExecuteForward(g_fwUserHumanized_pre, g_fwDummyResult, id, survivor)
  5781.  
  5782. // Remove previous tasks
  5783. remove_task(id+TASK_MODEL)
  5784. remove_task(id+TASK_BLOOD)
  5785. remove_task(id+TASK_AURA)
  5786. remove_task(id+TASK_BURN)
  5787. remove_task(id+TASK_NVISION)
  5788.  
  5789. // Reset some vars
  5790. g_zombie[id] = false
  5791. g_nemesis[id] = false
  5792. g_survivor[id] = false
  5793. g_firstzombie[id] = false
  5794. g_canbuy[id] = true
  5795. g_buytime[id] = get_gametime()
  5796.  
  5797. // Remove survivor's aura (bugfix)
  5798. set_pev(id, pev_effects, pev(id, pev_effects) &~ EF_BRIGHTLIGHT)
  5799.  
  5800. // Remove spawn protection (bugfix)
  5801. g_nodamage[id] = false
  5802. set_pev(id, pev_effects, pev(id, pev_effects) &~ EF_NODRAW)
  5803.  
  5804. // Reset burning duration counter (bugfix)
  5805. g_burning_duration[id] = 0
  5806.  
  5807. // Remove CS nightvision if player owns one (bugfix)
  5808. if (cs_get_user_nvg(id))
  5809. {
  5810. cs_set_user_nvg(id, 0)
  5811. if (get_pcvar_num(cvar_customnvg)) remove_task(id+TASK_NVISION)
  5812. else if (g_nvisionenabled[id]) set_user_gnvision(id, 0)
  5813. }
  5814.  
  5815. // Drop previous weapons
  5816. drop_weapons(id, 1)
  5817. drop_weapons(id, 2)
  5818.  
  5819. // Strip off from weapons
  5820. fm_strip_user_weapons(id)
  5821. fm_give_item(id, "weapon_knife")
  5822.  
  5823. // Set human attributes based on the mode
  5824. if (survivor)
  5825. {
  5826. // Survivor
  5827. g_survivor[id] = true
  5828.  
  5829. // Set Health [0 = auto]
  5830. if (get_pcvar_num(cvar_survhp) == 0)
  5831. {
  5832. if (get_pcvar_num(cvar_survbasehp) == 0)
  5833. fm_set_user_health(id, get_pcvar_num(cvar_humanhp) * fnGetAlive())
  5834. else
  5835. fm_set_user_health(id, get_pcvar_num(cvar_survbasehp) * fnGetAlive())
  5836. }
  5837. else
  5838. fm_set_user_health(id, get_pcvar_num(cvar_survhp))
  5839.  
  5840. // Set gravity, if frozen set the restore gravity value instead
  5841. if (!g_frozen[id]) set_pev(id, pev_gravity, get_pcvar_float(cvar_survgravity))
  5842. else g_frozen_gravity[id] = get_pcvar_float(cvar_survgravity)
  5843.  
  5844. // Set survivor maxspeed
  5845. ExecuteHamB(Ham_Player_ResetMaxSpeed, id)
  5846.  
  5847. // Give survivor his own weapon
  5848. static survweapon[32]
  5849. get_pcvar_string(cvar_survweapon, survweapon, charsmax(survweapon))
  5850. fm_give_item(id, survweapon)
  5851. ExecuteHamB(Ham_GiveAmmo, id, MAXBPAMMO[cs_weapon_name_to_id(survweapon)], AMMOTYPE[cs_weapon_name_to_id(survweapon)], MAXBPAMMO[cs_weapon_name_to_id(survweapon)])
  5852.  
  5853. // Turn off his flashlight
  5854. turn_off_flashlight(id)
  5855.  
  5856. // Give the survivor a bright light
  5857. if (get_pcvar_num(cvar_survaura)) set_pev(id, pev_effects, pev(id, pev_effects) | EF_BRIGHTLIGHT)
  5858.  
  5859. // Survivor bots will also need nightvision to see in the dark
  5860. if (g_isbot[id])
  5861. {
  5862. g_nvision[id] = true
  5863. cs_set_user_nvg(id, 1)
  5864. }
  5865. }
  5866. else
  5867. {
  5868. // Human taking an antidote
  5869.  
  5870. // Set health
  5871. fm_set_user_health(id, get_pcvar_num(cvar_humanhp))
  5872.  
  5873. // Set gravity, if frozen set the restore gravity value instead
  5874. if (!g_frozen[id]) set_pev(id, pev_gravity, get_pcvar_float(cvar_humangravity))
  5875. else g_frozen_gravity[id] = get_pcvar_float(cvar_humangravity)
  5876.  
  5877. // Set human maxspeed
  5878. ExecuteHamB(Ham_Player_ResetMaxSpeed, id)
  5879.  
  5880. // Show custom buy menu?
  5881. if (get_pcvar_num(cvar_buycustom))
  5882. set_task(0.2, "show_menu_buy1", id+TASK_SPAWN)
  5883.  
  5884. // Silent mode = no HUD messages, no antidote sound
  5885. if (!silentmode)
  5886. {
  5887. // Antidote sound
  5888. static sound[64]
  5889. ArrayGetString(sound_antidote, random_num(0, ArraySize(sound_antidote) - 1), sound, charsmax(sound))
  5890. emit_sound(id, CHAN_ITEM, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  5891.  
  5892. // Show Antidote HUD notice
  5893. set_dhudmessage(0, 155, 255, HUD_INFECT_X, HUD_INFECT_Y, 0, 0.0, 5.0, 1.0, 1.0)
  5894. show_dhudmessage(0, "%L", LANG_PLAYER, "NOTICE_ANTIDOTE", g_playername[id])
  5895. }
  5896. }
  5897.  
  5898. // Switch to CT
  5899. if (fm_cs_get_user_team(id) != FM_CS_TEAM_CT) // need to change team?
  5900. {
  5901. remove_task(id+TASK_TEAM)
  5902. fm_cs_set_user_team(id, FM_CS_TEAM_CT)
  5903. fm_user_team_update(id)
  5904. }
  5905.  
  5906. // Custom models stuff
  5907. static currentmodel[32], tempmodel[32], already_has_model, i, iRand, size
  5908. already_has_model = false
  5909.  
  5910. if (g_handle_models_on_separate_ent)
  5911. {
  5912. // Set the right model
  5913. if (g_survivor[id])
  5914. {
  5915. iRand = random_num(0, ArraySize(model_survivor) - 1)
  5916. ArrayGetString(model_survivor, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  5917. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_survivor, iRand))
  5918. }
  5919. else
  5920. {
  5921. if (get_pcvar_num(cvar_adminmodelshuman) && (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS]))
  5922. {
  5923. iRand = random_num(0, ArraySize(model_admin_human) - 1)
  5924. ArrayGetString(model_admin_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  5925. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_admin_human, iRand))
  5926. }
  5927. else
  5928. {
  5929. iRand = random_num(0, ArraySize(model_human) - 1)
  5930. ArrayGetString(model_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  5931. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_human, iRand))
  5932. }
  5933. }
  5934.  
  5935. // Set model on player model entity
  5936. fm_set_playermodel_ent(id)
  5937.  
  5938. // Set survivor glow / remove glow on player model entity, unless frozen
  5939. if (!g_frozen[id])
  5940. {
  5941. if (g_survivor[id] && get_pcvar_num(cvar_survglow))
  5942. fm_set_rendering(g_ent_playermodel[id], kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 25)
  5943. else
  5944. fm_set_rendering(g_ent_playermodel[id])
  5945. }
  5946. }
  5947. else
  5948. {
  5949. // Get current model for comparing it with the current one
  5950. fm_cs_get_user_model(id, currentmodel, charsmax(currentmodel))
  5951.  
  5952. // Set the right model, after checking that we don't already have it
  5953. if (g_survivor[id])
  5954. {
  5955. size = ArraySize(model_survivor)
  5956. for (i = 0; i < size; i++)
  5957. {
  5958. ArrayGetString(model_survivor, i, tempmodel, charsmax(tempmodel))
  5959. if (equal(currentmodel, tempmodel)) already_has_model = true
  5960. }
  5961.  
  5962. if (!already_has_model)
  5963. {
  5964. iRand = random_num(0, size - 1)
  5965. ArrayGetString(model_survivor, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  5966. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_survivor, iRand))
  5967. }
  5968. }
  5969. else
  5970. {
  5971. if (get_pcvar_num(cvar_adminmodelshuman) && (get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS]))
  5972. {
  5973. size = ArraySize(model_admin_human)
  5974. for (i = 0; i < size; i++)
  5975. {
  5976. ArrayGetString(model_admin_human, i, tempmodel, charsmax(tempmodel))
  5977. if (equal(currentmodel, tempmodel)) already_has_model = true
  5978. }
  5979.  
  5980. if (!already_has_model)
  5981. {
  5982. iRand = random_num(0, size - 1)
  5983. ArrayGetString(model_admin_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  5984. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_admin_human, iRand))
  5985. }
  5986. }
  5987. else
  5988. {
  5989. size = ArraySize(model_human)
  5990. for (i = 0; i < size; i++)
  5991. {
  5992. ArrayGetString(model_human, i, tempmodel, charsmax(tempmodel))
  5993. if (equal(currentmodel, tempmodel)) already_has_model = true
  5994. }
  5995.  
  5996. if (!already_has_model)
  5997. {
  5998. iRand = random_num(0, size - 1)
  5999. ArrayGetString(model_human, iRand, g_playermodel[id], charsmax(g_playermodel[]))
  6000. if (g_set_modelindex_offset) fm_cs_set_user_model_index(id, ArrayGetCell(g_modelindex_human, iRand))
  6001. }
  6002. }
  6003. }
  6004.  
  6005. // Need to change the model?
  6006. if (!already_has_model)
  6007. {
  6008. // An additional delay is offset at round start
  6009. // since SVC_BAD is more likely to be triggered there
  6010. if (g_newround)
  6011. set_task(5.0 * g_modelchange_delay, "fm_user_model_update", id+TASK_MODEL)
  6012. else
  6013. fm_user_model_update(id+TASK_MODEL)
  6014. }
  6015.  
  6016. // Set survivor glow / remove glow, unless frozen
  6017. if (!g_frozen[id])
  6018. {
  6019. if (g_survivor[id] && get_pcvar_num(cvar_survglow))
  6020. fm_set_rendering(id, kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 25)
  6021. else
  6022. fm_set_rendering(id)
  6023. }
  6024. }
  6025.  
  6026. // Restore FOV?
  6027. if (get_pcvar_num(cvar_zombiefov) != 90 && get_pcvar_num(cvar_zombiefov) != 0)
  6028. {
  6029. message_begin(MSG_ONE, g_msgSetFOV, _, id)
  6030. write_byte(90) // angle
  6031. message_end()
  6032. }
  6033.  
  6034. // Disable nightvision when turning into human/survivor (bugfix)
  6035. if (g_nvision[id])
  6036. {
  6037. if (get_pcvar_num(cvar_customnvg)) remove_task(id+TASK_NVISION)
  6038. else if (g_nvisionenabled[id]) set_user_gnvision(id, 0)
  6039. g_nvision[id] = false
  6040. g_nvisionenabled[id] = false
  6041. }
  6042.  
  6043. // Post user humanize forward
  6044. ExecuteForward(g_fwUserHumanized_post, g_fwDummyResult, id, survivor)
  6045.  
  6046. // Last Zombie Check
  6047. fnCheckLastZombie()
  6048. }
  6049.  
  6050. /*================================================================================
  6051. [Other Functions and Tasks]
  6052. =================================================================================*/
  6053.  
  6054. public cache_cvars()
  6055. {
  6056. g_cached_zombiesilent = get_pcvar_num(cvar_zombiesilent)
  6057. g_cached_customflash = get_pcvar_num(cvar_customflash)
  6058. g_cached_leapzombies = get_pcvar_num(cvar_leapzombies)
  6059. g_cached_leapzombiescooldown = get_pcvar_float(cvar_leapzombiescooldown)
  6060. g_cached_leapnemesis = get_pcvar_num(cvar_leapnemesis)
  6061. g_cached_leapnemesiscooldown = get_pcvar_float(cvar_leapnemesiscooldown)
  6062. g_cached_leapsurvivor = get_pcvar_num(cvar_leapsurvivor)
  6063. g_cached_leapsurvivorcooldown = get_pcvar_float(cvar_leapsurvivorcooldown)
  6064. g_cached_buytime = get_pcvar_float(cvar_buyzonetime)
  6065. }
  6066.  
  6067. load_customization_from_files()
  6068. {
  6069. // Build customization file path
  6070. new path[64]
  6071. get_configsdir(path, charsmax(path))
  6072. format(path, charsmax(path), "%s/%s", path, ZP_CUSTOMIZATION_FILE)
  6073.  
  6074. // File not present
  6075. if (!file_exists(path))
  6076. {
  6077. new error[100]
  6078. formatex(error, charsmax(error), "Cannot load customization file %s!", path)
  6079. set_fail_state(error)
  6080. return;
  6081. }
  6082.  
  6083. // Set up some vars to hold parsing info
  6084. new linedata[1024], key[64], value[960], section, teams
  6085.  
  6086. // Open customization file for reading
  6087. new file = fopen(path, "rt")
  6088.  
  6089. while (file && !feof(file))
  6090. {
  6091. // Read one line at a time
  6092. fgets(file, linedata, charsmax(linedata))
  6093.  
  6094. // Replace newlines with a null character to prevent headaches
  6095. replace(linedata, charsmax(linedata), "^n", "")
  6096.  
  6097. // Blank line or comment
  6098. if (!linedata[0] || linedata[0] == ';') continue;
  6099.  
  6100. // New section starting
  6101. if (linedata[0] == '[')
  6102. {
  6103. section++
  6104. continue;
  6105. }
  6106.  
  6107. // Get key and value(s)
  6108. strtok(linedata, key, charsmax(key), value, charsmax(value), '=')
  6109.  
  6110. // Trim spaces
  6111. trim(key)
  6112. trim(value)
  6113.  
  6114. switch (section)
  6115. {
  6116. case SECTION_ACCESS_FLAGS:
  6117. {
  6118. if (equal(key, "ENABLE/DISABLE MOD"))
  6119. g_access_flag[ACCESS_ENABLE_MOD] = read_flags(value)
  6120. else if (equal(key, "ADMIN MENU"))
  6121. g_access_flag[ACCESS_ADMIN_MENU] = read_flags(value)
  6122. else if (equal(key, "START MODE INFECTION"))
  6123. g_access_flag[ACCESS_MODE_INFECTION] = read_flags(value)
  6124. else if (equal(key, "START MODE NEMESIS"))
  6125. g_access_flag[ACCESS_MODE_NEMESIS] = read_flags(value)
  6126. else if (equal(key, "START MODE SURVIVOR"))
  6127. g_access_flag[ACCESS_MODE_SURVIVOR] = read_flags(value)
  6128. else if (equal(key, "START MODE SWARM"))
  6129. g_access_flag[ACCESS_MODE_SWARM] = read_flags(value)
  6130. else if (equal(key, "START MODE MULTI"))
  6131. g_access_flag[ACCESS_MODE_MULTI] = read_flags(value)
  6132. else if (equal(key, "START MODE PLAGUE"))
  6133. g_access_flag[ACCESS_MODE_PLAGUE] = read_flags(value)
  6134. else if (equal(key, "MAKE ZOMBIE"))
  6135. g_access_flag[ACCESS_MAKE_ZOMBIE] = read_flags(value)
  6136. else if (equal(key, "MAKE HUMAN"))
  6137. g_access_flag[ACCESS_MAKE_HUMAN] = read_flags(value)
  6138. else if (equal(key, "MAKE NEMESIS"))
  6139. g_access_flag[ACCESS_MAKE_NEMESIS] = read_flags(value)
  6140. else if (equal(key, "MAKE SURVIVOR"))
  6141. g_access_flag[ACCESS_MAKE_SURVIVOR] = read_flags(value)
  6142. else if (equal(key, "RESPAWN PLAYERS"))
  6143. g_access_flag[ACCESS_RESPAWN_PLAYERS] = read_flags(value)
  6144. else if (equal(key, "ADMIN MODELS"))
  6145. g_access_flag[ACCESS_ADMIN_MODELS] = read_flags(value)
  6146. }
  6147. case SECTION_PLAYER_MODELS:
  6148. {
  6149. if (equal(key, "HUMAN"))
  6150. {
  6151. // Parse models
  6152. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6153. {
  6154. // Trim spaces
  6155. trim(key)
  6156. trim(value)
  6157.  
  6158. // Add to models array
  6159. ArrayPushString(model_human, key)
  6160. }
  6161. }
  6162. else if (equal(key, "NEMESIS"))
  6163. {
  6164. // Parse models
  6165. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6166. {
  6167. // Trim spaces
  6168. trim(key)
  6169. trim(value)
  6170.  
  6171. // Add to models array
  6172. ArrayPushString(model_nemesis, key)
  6173. }
  6174. }
  6175. else if (equal(key, "SURVIVOR"))
  6176. {
  6177. // Parse models
  6178. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6179. {
  6180. // Trim spaces
  6181. trim(key)
  6182. trim(value)
  6183.  
  6184. // Add to models array
  6185. ArrayPushString(model_survivor, key)
  6186. }
  6187. }
  6188. else if (equal(key, "ADMIN ZOMBIE"))
  6189. {
  6190. // Parse models
  6191. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6192. {
  6193. // Trim spaces
  6194. trim(key)
  6195. trim(value)
  6196.  
  6197. // Add to models array
  6198. ArrayPushString(model_admin_zombie, key)
  6199. }
  6200. }
  6201. else if (equal(key, "ADMIN HUMAN"))
  6202. {
  6203. // Parse models
  6204. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6205. {
  6206. // Trim spaces
  6207. trim(key)
  6208. trim(value)
  6209.  
  6210. // Add to models array
  6211. ArrayPushString(model_admin_human, key)
  6212. }
  6213. }
  6214. else if (equal(key, "FORCE CONSISTENCY"))
  6215. g_force_consistency = str_to_num(value)
  6216. else if (equal(key, "SAME MODELS FOR ALL"))
  6217. g_same_models_for_all = str_to_num(value)
  6218. else if (g_same_models_for_all && equal(key, "ZOMBIE"))
  6219. {
  6220. // Parse models
  6221. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6222. {
  6223. // Trim spaces
  6224. trim(key)
  6225. trim(value)
  6226.  
  6227. // Add to models array
  6228. ArrayPushString(g_zclass_playermodel, key)
  6229.  
  6230. // Precache model and retrieve its modelindex
  6231. formatex(linedata, charsmax(linedata), "models/player/%s/%s.mdl", key, key)
  6232. ArrayPushCell(g_zclass_modelindex, engfunc(EngFunc_PrecacheModel, linedata))
  6233. if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, linedata)
  6234. if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, linedata)
  6235. // Precache modelT.mdl files too
  6236. copy(linedata[strlen(linedata)-4], charsmax(linedata) - (strlen(linedata)-4), "T.mdl")
  6237. if (file_exists(linedata)) engfunc(EngFunc_PrecacheModel, linedata)
  6238. }
  6239. }
  6240. }
  6241. case SECTION_WEAPON_MODELS:
  6242. {
  6243. if (equal(key, "V_KNIFE HUMAN"))
  6244. copy(model_vknife_human, charsmax(model_vknife_human), value)
  6245. else if (equal(key, "V_KNIFE NEMESIS"))
  6246. copy(model_vknife_nemesis, charsmax(model_vknife_nemesis), value)
  6247. else if (equal(key, "V_M249 SURVIVOR")) // backwards compatibility with old configs
  6248. copy(model_vweapon_survivor, charsmax(model_vweapon_survivor), value)
  6249. else if (equal(key, "V_WEAPON SURVIVOR"))
  6250. copy(model_vweapon_survivor, charsmax(model_vweapon_survivor), value)
  6251. else if (equal(key, "GRENADE INFECT"))
  6252. copy(model_grenade_infect, charsmax(model_grenade_infect), value)
  6253. else if (equal(key, "GRENADE FIRE"))
  6254. copy(model_grenade_fire, charsmax(model_grenade_fire), value)
  6255. else if (equal(key, "GRENADE FROST"))
  6256. copy(model_grenade_frost, charsmax(model_grenade_frost), value)
  6257. else if (equal(key, "GRENADE FLARE"))
  6258. copy(model_grenade_flare, charsmax(model_grenade_flare), value)
  6259. else if (equal(key, "V_KNIFE ADMIN HUMAN"))
  6260. copy(model_vknife_admin_human, charsmax(model_vknife_admin_human), value)
  6261. else if (equal(key, "V_KNIFE ADMIN ZOMBIE"))
  6262. copy(model_vknife_admin_zombie, charsmax(model_vknife_admin_zombie), value)
  6263. }
  6264. case SECTION_GRENADE_SPRITES:
  6265. {
  6266. if (equal(key, "TRAIL"))
  6267. copy(sprite_grenade_trail, charsmax(sprite_grenade_trail), value)
  6268. else if (equal(key, "RING"))
  6269. copy(sprite_grenade_ring, charsmax(sprite_grenade_ring), value)
  6270. else if (equal(key, "FIRE"))
  6271. copy(sprite_grenade_fire, charsmax(sprite_grenade_fire), value)
  6272. else if (equal(key, "SMOKE"))
  6273. copy(sprite_grenade_smoke, charsmax(sprite_grenade_smoke), value)
  6274. else if (equal(key, "GLASS"))
  6275. copy(sprite_grenade_glass, charsmax(sprite_grenade_glass), value)
  6276. }
  6277. case SECTION_SOUNDS:
  6278. {
  6279. if (equal(key, "WIN ZOMBIES"))
  6280. {
  6281. // Parse sounds
  6282. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6283. {
  6284. // Trim spaces
  6285. trim(key)
  6286. trim(value)
  6287.  
  6288. // Add to sounds array
  6289. ArrayPushString(sound_win_zombies, key)
  6290. ArrayPushCell(sound_win_zombies_ismp3, equal(key[strlen(key)-4], ".mp3") ? 1 : 0)
  6291. }
  6292. }
  6293. else if (equal(key, "WIN HUMANS"))
  6294. {
  6295. // Parse sounds
  6296. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6297. {
  6298. // Trim spaces
  6299. trim(key)
  6300. trim(value)
  6301.  
  6302. // Add to sounds array
  6303. ArrayPushString(sound_win_humans, key)
  6304. ArrayPushCell(sound_win_humans_ismp3, equal(key[strlen(key)-4], ".mp3") ? 1 : 0)
  6305. }
  6306. }
  6307. else if (equal(key, "WIN NO ONE"))
  6308. {
  6309. // Parse sounds
  6310. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6311. {
  6312. // Trim spaces
  6313. trim(key)
  6314. trim(value)
  6315.  
  6316. // Add to sounds array
  6317. ArrayPushString(sound_win_no_one, key)
  6318. ArrayPushCell(sound_win_no_one_ismp3, equal(key[strlen(key)-4], ".mp3") ? 1 : 0)
  6319. }
  6320. }
  6321. else if (equal(key, "ZOMBIE INFECT"))
  6322. {
  6323. // Parse sounds
  6324. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6325. {
  6326. // Trim spaces
  6327. trim(key)
  6328. trim(value)
  6329.  
  6330. // Add to sounds array
  6331. ArrayPushString(zombie_infect, key)
  6332. }
  6333. }
  6334. else if (equal(key, "ZOMBIE PAIN"))
  6335. {
  6336. // Parse sounds
  6337. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6338. {
  6339. // Trim spaces
  6340. trim(key)
  6341. trim(value)
  6342.  
  6343. // Add to sounds array
  6344. ArrayPushString(zombie_pain, key)
  6345. }
  6346. }
  6347. else if (equal(key, "NEMESIS PAIN"))
  6348. {
  6349. // Parse sounds
  6350. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6351. {
  6352. // Trim spaces
  6353. trim(key)
  6354. trim(value)
  6355.  
  6356. // Add to sounds array
  6357. ArrayPushString(nemesis_pain, key)
  6358. }
  6359. }
  6360. else if (equal(key, "ZOMBIE DIE"))
  6361. {
  6362. // Parse sounds
  6363. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6364. {
  6365. // Trim spaces
  6366. trim(key)
  6367. trim(value)
  6368.  
  6369. // Add to sounds array
  6370. ArrayPushString(zombie_die, key)
  6371. }
  6372. }
  6373. else if (equal(key, "ZOMBIE FALL"))
  6374. {
  6375. // Parse sounds
  6376. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6377. {
  6378. // Trim spaces
  6379. trim(key)
  6380. trim(value)
  6381.  
  6382. // Add to sounds array
  6383. ArrayPushString(zombie_fall, key)
  6384. }
  6385. }
  6386. else if (equal(key, "ZOMBIE MISS SLASH"))
  6387. {
  6388. // Parse sounds
  6389. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6390. {
  6391. // Trim spaces
  6392. trim(key)
  6393. trim(value)
  6394.  
  6395. // Add to sounds array
  6396. ArrayPushString(zombie_miss_slash, key)
  6397. }
  6398. }
  6399. else if (equal(key, "ZOMBIE MISS WALL"))
  6400. {
  6401. // Parse sounds
  6402. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6403. {
  6404. // Trim spaces
  6405. trim(key)
  6406. trim(value)
  6407.  
  6408. // Add to sounds array
  6409. ArrayPushString(zombie_miss_wall, key)
  6410. }
  6411. }
  6412. else if (equal(key, "ZOMBIE HIT NORMAL"))
  6413. {
  6414. // Parse sounds
  6415. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6416. {
  6417. // Trim spaces
  6418. trim(key)
  6419. trim(value)
  6420.  
  6421. // Add to sounds array
  6422. ArrayPushString(zombie_hit_normal, key)
  6423. }
  6424. }
  6425. else if (equal(key, "ZOMBIE HIT STAB"))
  6426. {
  6427. // Parse sounds
  6428. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6429. {
  6430. // Trim spaces
  6431. trim(key)
  6432. trim(value)
  6433.  
  6434. // Add to sounds array
  6435. ArrayPushString(zombie_hit_stab, key)
  6436. }
  6437. }
  6438. else if (equal(key, "ZOMBIE IDLE"))
  6439. {
  6440. // Parse sounds
  6441. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6442. {
  6443. // Trim spaces
  6444. trim(key)
  6445. trim(value)
  6446.  
  6447. // Add to sounds array
  6448. ArrayPushString(zombie_idle, key)
  6449. }
  6450. }
  6451. else if (equal(key, "ZOMBIE IDLE LAST"))
  6452. {
  6453. // Parse sounds
  6454. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6455. {
  6456. // Trim spaces
  6457. trim(key)
  6458. trim(value)
  6459.  
  6460. // Add to sounds array
  6461. ArrayPushString(zombie_idle_last, key)
  6462. }
  6463. }
  6464. else if (equal(key, "ZOMBIE MADNESS"))
  6465. {
  6466. // Parse sounds
  6467. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6468. {
  6469. // Trim spaces
  6470. trim(key)
  6471. trim(value)
  6472.  
  6473. // Add to sounds array
  6474. ArrayPushString(zombie_madness, key)
  6475. }
  6476. }
  6477. else if (equal(key, "ROUND NEMESIS"))
  6478. {
  6479. // Parse sounds
  6480. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6481. {
  6482. // Trim spaces
  6483. trim(key)
  6484. trim(value)
  6485.  
  6486. // Add to sounds array
  6487. ArrayPushString(sound_nemesis, key)
  6488. }
  6489. }
  6490. else if (equal(key, "ROUND SURVIVOR"))
  6491. {
  6492. // Parse sounds
  6493. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6494. {
  6495. // Trim spaces
  6496. trim(key)
  6497. trim(value)
  6498.  
  6499. // Add to sounds array
  6500. ArrayPushString(sound_survivor, key)
  6501. }
  6502. }
  6503. else if (equal(key, "ROUND SWARM"))
  6504. {
  6505. // Parse sounds
  6506. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6507. {
  6508. // Trim spaces
  6509. trim(key)
  6510. trim(value)
  6511.  
  6512. // Add to sounds array
  6513. ArrayPushString(sound_swarm, key)
  6514. }
  6515. }
  6516. else if (equal(key, "ROUND MULTI"))
  6517. {
  6518. // Parse sounds
  6519. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6520. {
  6521. // Trim spaces
  6522. trim(key)
  6523. trim(value)
  6524.  
  6525. // Add to sounds array
  6526. ArrayPushString(sound_multi, key)
  6527. }
  6528. }
  6529. else if (equal(key, "ROUND PLAGUE"))
  6530. {
  6531. // Parse sounds
  6532. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6533. {
  6534. // Trim spaces
  6535. trim(key)
  6536. trim(value)
  6537.  
  6538. // Add to sounds array
  6539. ArrayPushString(sound_plague, key)
  6540. }
  6541. }
  6542. else if (equal(key, "GRENADE INFECT EXPLODE"))
  6543. {
  6544. // Parse sounds
  6545. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6546. {
  6547. // Trim spaces
  6548. trim(key)
  6549. trim(value)
  6550.  
  6551. // Add to sounds array
  6552. ArrayPushString(grenade_infect, key)
  6553. }
  6554. }
  6555. else if (equal(key, "GRENADE INFECT PLAYER"))
  6556. {
  6557. // Parse sounds
  6558. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6559. {
  6560. // Trim spaces
  6561. trim(key)
  6562. trim(value)
  6563.  
  6564. // Add to sounds array
  6565. ArrayPushString(grenade_infect_player, key)
  6566. }
  6567. }
  6568. else if (equal(key, "GRENADE FIRE EXPLODE"))
  6569. {
  6570. // Parse sounds
  6571. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6572. {
  6573. // Trim spaces
  6574. trim(key)
  6575. trim(value)
  6576.  
  6577. // Add to sounds array
  6578. ArrayPushString(grenade_fire, key)
  6579. }
  6580. }
  6581. else if (equal(key, "GRENADE FIRE PLAYER"))
  6582. {
  6583. // Parse sounds
  6584. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6585. {
  6586. // Trim spaces
  6587. trim(key)
  6588. trim(value)
  6589.  
  6590. // Add to sounds array
  6591. ArrayPushString(grenade_fire_player, key)
  6592. }
  6593. }
  6594. else if (equal(key, "GRENADE FROST EXPLODE"))
  6595. {
  6596. // Parse sounds
  6597. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6598. {
  6599. // Trim spaces
  6600. trim(key)
  6601. trim(value)
  6602.  
  6603. // Add to sounds array
  6604. ArrayPushString(grenade_frost, key)
  6605. }
  6606. }
  6607. else if (equal(key, "GRENADE FROST PLAYER"))
  6608. {
  6609. // Parse sounds
  6610. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6611. {
  6612. // Trim spaces
  6613. trim(key)
  6614. trim(value)
  6615.  
  6616. // Add to sounds array
  6617. ArrayPushString(grenade_frost_player, key)
  6618. }
  6619. }
  6620. else if (equal(key, "GRENADE FROST BREAK"))
  6621. {
  6622. // Parse sounds
  6623. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6624. {
  6625. // Trim spaces
  6626. trim(key)
  6627. trim(value)
  6628.  
  6629. // Add to sounds array
  6630. ArrayPushString(grenade_frost_break, key)
  6631. }
  6632. }
  6633. else if (equal(key, "GRENADE FLARE"))
  6634. {
  6635. // Parse sounds
  6636. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6637. {
  6638. // Trim spaces
  6639. trim(key)
  6640. trim(value)
  6641.  
  6642. // Add to sounds array
  6643. ArrayPushString(grenade_flare, key)
  6644. }
  6645. }
  6646. else if (equal(key, "ANTIDOTE"))
  6647. {
  6648. // Parse sounds
  6649. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6650. {
  6651. // Trim spaces
  6652. trim(key)
  6653. trim(value)
  6654.  
  6655. // Add to sounds array
  6656. ArrayPushString(sound_antidote, key)
  6657. }
  6658. }
  6659. else if (equal(key, "THUNDER"))
  6660. {
  6661. // Parse sounds
  6662. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6663. {
  6664. // Trim spaces
  6665. trim(key)
  6666. trim(value)
  6667.  
  6668. // Add to sounds array
  6669. ArrayPushString(sound_thunder, key)
  6670. }
  6671. }
  6672. }
  6673. case SECTION_AMBIENCE_SOUNDS:
  6674. {
  6675. if (equal(key, "INFECTION ENABLE"))
  6676. g_ambience_sounds[AMBIENCE_SOUNDS_INFECTION] = str_to_num(value)
  6677. else if (g_ambience_sounds[AMBIENCE_SOUNDS_INFECTION] && equal(key, "INFECTION SOUNDS"))
  6678. {
  6679. // Parse sounds
  6680. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6681. {
  6682. // Trim spaces
  6683. trim(key)
  6684. trim(value)
  6685.  
  6686. // Add to sounds array
  6687. ArrayPushString(sound_ambience1, key)
  6688. ArrayPushCell(sound_ambience1_ismp3, equal(key[strlen(key)-4], ".mp3") ? 1 : 0)
  6689. }
  6690. }
  6691. else if (g_ambience_sounds[AMBIENCE_SOUNDS_INFECTION] && equal(key, "INFECTION DURATIONS"))
  6692. {
  6693. // Parse sounds
  6694. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6695. {
  6696. // Trim spaces
  6697. trim(key)
  6698. trim(value)
  6699.  
  6700. // Add to sounds array
  6701. ArrayPushCell(sound_ambience1_duration, str_to_num(key))
  6702. }
  6703. }
  6704. else if (equal(key, "NEMESIS ENABLE"))
  6705. g_ambience_sounds[AMBIENCE_SOUNDS_NEMESIS] = str_to_num(value)
  6706. else if (g_ambience_sounds[AMBIENCE_SOUNDS_NEMESIS] && equal(key, "NEMESIS SOUNDS"))
  6707. {
  6708. // Parse sounds
  6709. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6710. {
  6711. // Trim spaces
  6712. trim(key)
  6713. trim(value)
  6714.  
  6715. // Add to sounds array
  6716. ArrayPushString(sound_ambience2, key)
  6717. ArrayPushCell(sound_ambience2_ismp3, equal(key[strlen(key)-4], ".mp3") ? 1 : 0)
  6718. }
  6719. }
  6720. else if (g_ambience_sounds[AMBIENCE_SOUNDS_NEMESIS] && equal(key, "NEMESIS DURATIONS"))
  6721. {
  6722. // Parse sounds
  6723. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6724. {
  6725. // Trim spaces
  6726. trim(key)
  6727. trim(value)
  6728.  
  6729. // Add to sounds array
  6730. ArrayPushCell(sound_ambience2_duration, str_to_num(key))
  6731. }
  6732. }
  6733. else if (equal(key, "SURVIVOR ENABLE"))
  6734. g_ambience_sounds[AMBIENCE_SOUNDS_SURVIVOR] = str_to_num(value)
  6735. else if (g_ambience_sounds[AMBIENCE_SOUNDS_SURVIVOR] && equal(key, "SURVIVOR SOUNDS"))
  6736. {
  6737. // Parse sounds
  6738. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6739. {
  6740. // Trim spaces
  6741. trim(key)
  6742. trim(value)
  6743.  
  6744. // Add to sounds array
  6745. ArrayPushString(sound_ambience3, key)
  6746. ArrayPushCell(sound_ambience3_ismp3, equal(key[strlen(key)-4], ".mp3") ? 1 : 0)
  6747. }
  6748. }
  6749. else if (g_ambience_sounds[AMBIENCE_SOUNDS_SURVIVOR] && equal(key, "SURVIVOR DURATIONS"))
  6750. {
  6751. // Parse sounds
  6752. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6753. {
  6754. // Trim spaces
  6755. trim(key)
  6756. trim(value)
  6757.  
  6758. // Add to sounds array
  6759. ArrayPushCell(sound_ambience3_duration, str_to_num(key))
  6760. }
  6761. }
  6762. else if (equal(key, "SWARM ENABLE"))
  6763. g_ambience_sounds[AMBIENCE_SOUNDS_SWARM] = str_to_num(value)
  6764. else if (g_ambience_sounds[AMBIENCE_SOUNDS_SWARM] && equal(key, "SWARM SOUNDS"))
  6765. {
  6766. // Parse sounds
  6767. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6768. {
  6769. // Trim spaces
  6770. trim(key)
  6771. trim(value)
  6772.  
  6773. // Add to sounds array
  6774. ArrayPushString(sound_ambience4, key)
  6775. ArrayPushCell(sound_ambience4_ismp3, equal(key[strlen(key)-4], ".mp3") ? 1 : 0)
  6776. }
  6777. }
  6778. else if (g_ambience_sounds[AMBIENCE_SOUNDS_SWARM] && equal(key, "SWARM DURATIONS"))
  6779. {
  6780. // Parse sounds
  6781. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6782. {
  6783. // Trim spaces
  6784. trim(key)
  6785. trim(value)
  6786.  
  6787. // Add to sounds array
  6788. ArrayPushCell(sound_ambience4_duration, str_to_num(key))
  6789. }
  6790. }
  6791. else if (equal(key, "PLAGUE ENABLE"))
  6792. g_ambience_sounds[AMBIENCE_SOUNDS_PLAGUE] = str_to_num(value)
  6793. else if (g_ambience_sounds[AMBIENCE_SOUNDS_PLAGUE] && equal(key, "PLAGUE SOUNDS"))
  6794. {
  6795. // Parse sounds
  6796. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6797. {
  6798. // Trim spaces
  6799. trim(key)
  6800. trim(value)
  6801.  
  6802. // Add to sounds array
  6803. ArrayPushString(sound_ambience5, key)
  6804. ArrayPushCell(sound_ambience5_ismp3, equal(key[strlen(key)-4], ".mp3") ? 1 : 0)
  6805. }
  6806. }
  6807. else if (g_ambience_sounds[AMBIENCE_SOUNDS_PLAGUE] && equal(key, "PLAGUE DURATIONS"))
  6808. {
  6809. // Parse sounds
  6810. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6811. {
  6812. // Trim spaces
  6813. trim(key)
  6814. trim(value)
  6815.  
  6816. // Add to sounds array
  6817. ArrayPushCell(sound_ambience5_duration, str_to_num(key))
  6818. }
  6819. }
  6820. }
  6821. case SECTION_BUY_MENU_WEAPONS:
  6822. {
  6823. if (equal(key, "PRIMARY"))
  6824. {
  6825. // Parse weapons
  6826. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6827. {
  6828. // Trim spaces
  6829. trim(key)
  6830. trim(value)
  6831.  
  6832. // Add to weapons array
  6833. ArrayPushString(g_primary_items, key)
  6834. ArrayPushCell(g_primary_weaponids, cs_weapon_name_to_id(key))
  6835. }
  6836. }
  6837. else if (equal(key, "SECONDARY"))
  6838. {
  6839. // Parse weapons
  6840. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6841. {
  6842. // Trim spaces
  6843. trim(key)
  6844. trim(value)
  6845.  
  6846. // Add to weapons array
  6847. ArrayPushString(g_secondary_items, key)
  6848. ArrayPushCell(g_secondary_weaponids, cs_weapon_name_to_id(key))
  6849. }
  6850. }
  6851. else if (equal(key, "ADDITIONAL ITEMS"))
  6852. {
  6853. // Parse weapons
  6854. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6855. {
  6856. // Trim spaces
  6857. trim(key)
  6858. trim(value)
  6859.  
  6860. // Add to weapons array
  6861. ArrayPushString(g_additional_items, key)
  6862. }
  6863. }
  6864. }
  6865. case SECTION_EXTRA_ITEMS_WEAPONS:
  6866. {
  6867. if (equal(key, "NAMES"))
  6868. {
  6869. // Parse weapon items
  6870. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6871. {
  6872. // Trim spaces
  6873. trim(key)
  6874. trim(value)
  6875.  
  6876. // Add to weapons array
  6877. ArrayPushString(g_extraweapon_names, key)
  6878. }
  6879. }
  6880. else if (equal(key, "ITEMS"))
  6881. {
  6882. // Parse weapon items
  6883. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6884. {
  6885. // Trim spaces
  6886. trim(key)
  6887. trim(value)
  6888.  
  6889. // Add to weapons array
  6890. ArrayPushString(g_extraweapon_items, key)
  6891. }
  6892. }
  6893. else if (equal(key, "COSTS"))
  6894. {
  6895. // Parse weapon items
  6896. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6897. {
  6898. // Trim spaces
  6899. trim(key)
  6900. trim(value)
  6901.  
  6902. // Add to weapons array
  6903. ArrayPushCell(g_extraweapon_costs, str_to_num(key))
  6904. }
  6905. }
  6906. }
  6907. case SECTION_HARD_CODED_ITEMS_COSTS:
  6908. {
  6909. if (equal(key, "NIGHT VISION"))
  6910. g_extra_costs2[EXTRA_NVISION] = str_to_num(value)
  6911. else if (equal(key, "ANTIDOTE"))
  6912. g_extra_costs2[EXTRA_ANTIDOTE] = str_to_num(value)
  6913. else if (equal(key, "ZOMBIE MADNESS"))
  6914. g_extra_costs2[EXTRA_MADNESS] = str_to_num(value)
  6915. else if (equal(key, "INFECTION BOMB"))
  6916. g_extra_costs2[EXTRA_INFBOMB] = str_to_num(value)
  6917. }
  6918. case SECTION_WEATHER_EFFECTS:
  6919. {
  6920. if (equal(key, "RAIN"))
  6921. g_ambience_rain = str_to_num(value)
  6922. else if (equal(key, "SNOW"))
  6923. g_ambience_snow = str_to_num(value)
  6924. else if (equal(key, "FOG"))
  6925. g_ambience_fog = str_to_num(value)
  6926. else if (equal(key, "FOG DENSITY"))
  6927. copy(g_fog_density, charsmax(g_fog_density), value)
  6928. else if (equal(key, "FOG COLOR"))
  6929. copy(g_fog_color, charsmax(g_fog_color), value)
  6930. }
  6931. case SECTION_SKY:
  6932. {
  6933. if (equal(key, "ENABLE"))
  6934. g_sky_enable = str_to_num(value)
  6935. else if (equal(key, "SKY NAMES"))
  6936. {
  6937. // Parse sky names
  6938. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6939. {
  6940. // Trim spaces
  6941. trim(key)
  6942. trim(value)
  6943.  
  6944. // Add to skies array
  6945. ArrayPushString(g_sky_names, key)
  6946.  
  6947. // Preache custom sky files
  6948. formatex(linedata, charsmax(linedata), "gfx/env/%sbk.tga", key)
  6949. engfunc(EngFunc_PrecacheGeneric, linedata)
  6950. formatex(linedata, charsmax(linedata), "gfx/env/%sdn.tga", key)
  6951. engfunc(EngFunc_PrecacheGeneric, linedata)
  6952. formatex(linedata, charsmax(linedata), "gfx/env/%sft.tga", key)
  6953. engfunc(EngFunc_PrecacheGeneric, linedata)
  6954. formatex(linedata, charsmax(linedata), "gfx/env/%slf.tga", key)
  6955. engfunc(EngFunc_PrecacheGeneric, linedata)
  6956. formatex(linedata, charsmax(linedata), "gfx/env/%srt.tga", key)
  6957. engfunc(EngFunc_PrecacheGeneric, linedata)
  6958. formatex(linedata, charsmax(linedata), "gfx/env/%sup.tga", key)
  6959. engfunc(EngFunc_PrecacheGeneric, linedata)
  6960. }
  6961. }
  6962. }
  6963. case SECTION_LIGHTNING:
  6964. {
  6965. if (equal(key, "LIGHTS"))
  6966. {
  6967. // Parse lights
  6968. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6969. {
  6970. // Trim spaces
  6971. trim(key)
  6972. trim(value)
  6973.  
  6974. // Add to lightning array
  6975. ArrayPushString(lights_thunder, key)
  6976. }
  6977. }
  6978. }
  6979. case SECTION_ZOMBIE_DECALS:
  6980. {
  6981. if (equal(key, "DECALS"))
  6982. {
  6983. // Parse decals
  6984. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  6985. {
  6986. // Trim spaces
  6987. trim(key)
  6988. trim(value)
  6989.  
  6990. // Add to zombie decals array
  6991. ArrayPushCell(zombie_decals, str_to_num(key))
  6992. }
  6993. }
  6994. }
  6995. case SECTION_KNOCKBACK:
  6996. {
  6997. // Format weapon entity name
  6998. strtolower(key)
  6999. format(key, charsmax(key), "weapon_%s", key)
  7000.  
  7001. // Add value to knockback power array
  7002. kb_weapon_power[cs_weapon_name_to_id(key)] = str_to_float(value)
  7003. }
  7004. case SECTION_OBJECTIVE_ENTS:
  7005. {
  7006. if (equal(key, "CLASSNAMES"))
  7007. {
  7008. // Parse classnames
  7009. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  7010. {
  7011. // Trim spaces
  7012. trim(key)
  7013. trim(value)
  7014.  
  7015. // Add to objective ents array
  7016. ArrayPushString(g_objective_ents, key)
  7017. }
  7018. }
  7019. }
  7020. case SECTION_SVC_BAD:
  7021. {
  7022. if (equal(key, "MODELCHANGE DELAY"))
  7023. g_modelchange_delay = str_to_float(value)
  7024. else if (equal(key, "HANDLE MODELS ON SEPARATE ENT"))
  7025. g_handle_models_on_separate_ent = str_to_num(value)
  7026. else if (equal(key, "SET MODELINDEX OFFSET"))
  7027. g_set_modelindex_offset = str_to_num(value)
  7028. }
  7029. }
  7030. }
  7031. if (file) fclose(file)
  7032.  
  7033. // Build zombie classes file path
  7034. get_configsdir(path, charsmax(path))
  7035. format(path, charsmax(path), "%s/%s", path, ZP_ZOMBIECLASSES_FILE)
  7036.  
  7037. // Parse if present
  7038. if (file_exists(path))
  7039. {
  7040. // Open zombie classes file for reading
  7041. file = fopen(path, "rt")
  7042.  
  7043. while (file && !feof(file))
  7044. {
  7045. // Read one line at a time
  7046. fgets(file, linedata, charsmax(linedata))
  7047.  
  7048. // Replace newlines with a null character to prevent headaches
  7049. replace(linedata, charsmax(linedata), "^n", "")
  7050.  
  7051. // Blank line or comment
  7052. if (!linedata[0] || linedata[0] == ';') continue;
  7053.  
  7054. // New class starting
  7055. if (linedata[0] == '[')
  7056. {
  7057. // Remove first and last characters (braces)
  7058. linedata[strlen(linedata) - 1] = 0
  7059. copy(linedata, charsmax(linedata), linedata[1])
  7060.  
  7061. // Store its real name for future reference
  7062. ArrayPushString(g_zclass2_realname, linedata)
  7063. continue;
  7064. }
  7065.  
  7066. // Get key and value(s)
  7067. strtok(linedata, key, charsmax(key), value, charsmax(value), '=')
  7068.  
  7069. // Trim spaces
  7070. trim(key)
  7071. trim(value)
  7072.  
  7073. if (equal(key, "NAME"))
  7074. ArrayPushString(g_zclass2_name, value)
  7075. else if (equal(key, "INFO"))
  7076. ArrayPushString(g_zclass2_info, value)
  7077. else if (equal(key, "MODELS"))
  7078. {
  7079. // Set models start index
  7080. ArrayPushCell(g_zclass2_modelsstart, ArraySize(g_zclass2_playermodel))
  7081.  
  7082. // Parse class models
  7083. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  7084. {
  7085. // Trim spaces
  7086. trim(key)
  7087. trim(value)
  7088.  
  7089. // Add to class models array
  7090. ArrayPushString(g_zclass2_playermodel, key)
  7091. ArrayPushCell(g_zclass2_modelindex, -1)
  7092. }
  7093.  
  7094. // Set models end index
  7095. ArrayPushCell(g_zclass2_modelsend, ArraySize(g_zclass2_playermodel))
  7096. }
  7097. else if (equal(key, "CLAWMODEL"))
  7098. ArrayPushString(g_zclass2_clawmodel, value)
  7099. else if (equal(key, "HEALTH"))
  7100. ArrayPushCell(g_zclass2_hp, str_to_num(value))
  7101. else if (equal(key, "SPEED"))
  7102. ArrayPushCell(g_zclass2_spd, str_to_num(value))
  7103. else if (equal(key, "GRAVITY"))
  7104. ArrayPushCell(g_zclass2_grav, str_to_float(value))
  7105. else if (equal(key, "KNOCKBACK"))
  7106. ArrayPushCell(g_zclass2_kb, str_to_float(value))
  7107. }
  7108. if (file) fclose(file)
  7109. }
  7110.  
  7111. // Build extra items file path
  7112. get_configsdir(path, charsmax(path))
  7113. format(path, charsmax(path), "%s/%s", path, ZP_EXTRAITEMS_FILE)
  7114.  
  7115. // Parse if present
  7116. if (file_exists(path))
  7117. {
  7118. // Open extra items file for reading
  7119. file = fopen(path, "rt")
  7120.  
  7121. while (file && !feof(file))
  7122. {
  7123. // Read one line at a time
  7124. fgets(file, linedata, charsmax(linedata))
  7125.  
  7126. // Replace newlines with a null character to prevent headaches
  7127. replace(linedata, charsmax(linedata), "^n", "")
  7128.  
  7129. // Blank line or comment
  7130. if (!linedata[0] || linedata[0] == ';') continue;
  7131.  
  7132. // New item starting
  7133. if (linedata[0] == '[')
  7134. {
  7135. // Remove first and last characters (braces)
  7136. linedata[strlen(linedata) - 1] = 0
  7137. copy(linedata, charsmax(linedata), linedata[1])
  7138.  
  7139. // Store its real name for future reference
  7140. ArrayPushString(g_extraitem2_realname, linedata)
  7141. continue;
  7142. }
  7143.  
  7144. // Get key and value(s)
  7145. strtok(linedata, key, charsmax(key), value, charsmax(value), '=')
  7146.  
  7147. // Trim spaces
  7148. trim(key)
  7149. trim(value)
  7150.  
  7151. if (equal(key, "NAME"))
  7152. ArrayPushString(g_extraitem2_name, value)
  7153. else if (equal(key, "COST"))
  7154. ArrayPushCell(g_extraitem2_cost, str_to_num(value))
  7155. else if (equal(key, "TEAMS"))
  7156. {
  7157. // Clear teams bitsum
  7158. teams = 0
  7159.  
  7160. // Parse teams
  7161. while (value[0] != 0 && strtok(value, key, charsmax(key), value, charsmax(value), ','))
  7162. {
  7163. // Trim spaces
  7164. trim(key)
  7165. trim(value)
  7166.  
  7167. if (equal(key, ZP_TEAM_NAMES[ZP_TEAM_ZOMBIE]))
  7168. teams |= ZP_TEAM_ZOMBIE
  7169. else if (equal(key, ZP_TEAM_NAMES[ZP_TEAM_HUMAN]))
  7170. teams |= ZP_TEAM_HUMAN
  7171. else if (equal(key, ZP_TEAM_NAMES[ZP_TEAM_NEMESIS]))
  7172. teams |= ZP_TEAM_NEMESIS
  7173. else if (equal(key, ZP_TEAM_NAMES[ZP_TEAM_SURVIVOR]))
  7174. teams |= ZP_TEAM_SURVIVOR
  7175. }
  7176.  
  7177. // Add to teams array
  7178. ArrayPushCell(g_extraitem2_team, teams)
  7179. }
  7180. }
  7181. if (file) fclose(file)
  7182. }
  7183. }
  7184.  
  7185. save_customization()
  7186. {
  7187. new i, k, buffer[512]
  7188.  
  7189. // Build zombie classes file path
  7190. new path[64]
  7191. get_configsdir(path, charsmax(path))
  7192. format(path, charsmax(path), "%s/%s", path, ZP_ZOMBIECLASSES_FILE)
  7193.  
  7194. // Open zombie classes file for appending data
  7195. new file = fopen(path, "at"), size = ArraySize(g_zclass_name)
  7196.  
  7197. // Add any new zombie classes data at the end if needed
  7198. for (i = 0; i < size; i++)
  7199. {
  7200. if (ArrayGetCell(g_zclass_new, i))
  7201. {
  7202. // Add real name
  7203. ArrayGetString(g_zclass_name, i, buffer, charsmax(buffer))
  7204. format(buffer, charsmax(buffer), "^n[%s]", buffer)
  7205. fputs(file, buffer)
  7206.  
  7207. // Add caption
  7208. ArrayGetString(g_zclass_name, i, buffer, charsmax(buffer))
  7209. format(buffer, charsmax(buffer), "^nNAME = %s", buffer)
  7210. fputs(file, buffer)
  7211.  
  7212. // Add info
  7213. ArrayGetString(g_zclass_info, i, buffer, charsmax(buffer))
  7214. format(buffer, charsmax(buffer), "^nINFO = %s", buffer)
  7215. fputs(file, buffer)
  7216.  
  7217. // Add models
  7218. for (k = ArrayGetCell(g_zclass_modelsstart, i); k < ArrayGetCell(g_zclass_modelsend, i); k++)
  7219. {
  7220. if (k == ArrayGetCell(g_zclass_modelsstart, i))
  7221. {
  7222. // First model, overwrite buffer
  7223. ArrayGetString(g_zclass_playermodel, k, buffer, charsmax(buffer))
  7224. }
  7225. else
  7226. {
  7227. // Successive models, append to buffer
  7228. ArrayGetString(g_zclass_playermodel, k, path, charsmax(path))
  7229. format(buffer, charsmax(buffer), "%s , %s", buffer, path)
  7230. }
  7231. }
  7232. format(buffer, charsmax(buffer), "^nMODELS = %s", buffer)
  7233. fputs(file, buffer)
  7234.  
  7235. // Add clawmodel
  7236. ArrayGetString(g_zclass_clawmodel, i, buffer, charsmax(buffer))
  7237. format(buffer, charsmax(buffer), "^nCLAWMODEL = %s", buffer)
  7238. fputs(file, buffer)
  7239.  
  7240. // Add health
  7241. formatex(buffer, charsmax(buffer), "^nHEALTH = %d", ArrayGetCell(g_zclass_hp, i))
  7242. fputs(file, buffer)
  7243.  
  7244. // Add speed
  7245. formatex(buffer, charsmax(buffer), "^nSPEED = %d", ArrayGetCell(g_zclass_spd, i))
  7246. fputs(file, buffer)
  7247.  
  7248. // Add gravity
  7249. formatex(buffer, charsmax(buffer), "^nGRAVITY = %.2f", Float:ArrayGetCell(g_zclass_grav, i))
  7250. fputs(file, buffer)
  7251.  
  7252. // Add knockback
  7253. formatex(buffer, charsmax(buffer), "^nKNOCKBACK = %.2f^n", Float:ArrayGetCell(g_zclass_kb, i))
  7254. fputs(file, buffer)
  7255. }
  7256. }
  7257. fclose(file)
  7258.  
  7259. // Build extra items file path
  7260. get_configsdir(path, charsmax(path))
  7261. format(path, charsmax(path), "%s/%s", path, ZP_EXTRAITEMS_FILE)
  7262.  
  7263. // Open extra items file for appending data
  7264. file = fopen(path, "at")
  7265. size = ArraySize(g_extraitem_name)
  7266.  
  7267. // Add any new extra items data at the end if needed
  7268. for (i = EXTRAS_CUSTOM_STARTID; i < size; i++)
  7269. {
  7270. if (ArrayGetCell(g_extraitem_new, i))
  7271. {
  7272. // Add real name
  7273. ArrayGetString(g_extraitem_name, i, buffer, charsmax(buffer))
  7274. format(buffer, charsmax(buffer), "^n[%s]", buffer)
  7275. fputs(file, buffer)
  7276.  
  7277. // Add caption
  7278. ArrayGetString(g_extraitem_name, i, buffer, charsmax(buffer))
  7279. format(buffer, charsmax(buffer), "^nNAME = %s", buffer)
  7280. fputs(file, buffer)
  7281.  
  7282. // Add cost
  7283. formatex(buffer, charsmax(buffer), "^nCOST = %d", ArrayGetCell(g_extraitem_cost, i))
  7284. fputs(file, buffer)
  7285.  
  7286. // Add team
  7287. formatex(buffer, charsmax(buffer), "^nTEAMS = %s^n", ZP_TEAM_NAMES[ArrayGetCell(g_extraitem_team, i)])
  7288. fputs(file, buffer)
  7289. }
  7290. }
  7291. fclose(file)
  7292.  
  7293. // Free arrays containing class/item overrides
  7294. ArrayDestroy(g_zclass2_realname)
  7295. ArrayDestroy(g_zclass2_name)
  7296. ArrayDestroy(g_zclass2_info)
  7297. ArrayDestroy(g_zclass2_modelsstart)
  7298. ArrayDestroy(g_zclass2_modelsend)
  7299. ArrayDestroy(g_zclass2_playermodel)
  7300. ArrayDestroy(g_zclass2_modelindex)
  7301. ArrayDestroy(g_zclass2_clawmodel)
  7302. ArrayDestroy(g_zclass2_hp)
  7303. ArrayDestroy(g_zclass2_spd)
  7304. ArrayDestroy(g_zclass2_grav)
  7305. ArrayDestroy(g_zclass2_kb)
  7306. ArrayDestroy(g_zclass_new)
  7307. ArrayDestroy(g_extraitem2_realname)
  7308. ArrayDestroy(g_extraitem2_name)
  7309. ArrayDestroy(g_extraitem2_cost)
  7310. ArrayDestroy(g_extraitem2_team)
  7311. ArrayDestroy(g_extraitem_new)
  7312. }
  7313.  
  7314. // Register Ham Forwards for CZ bots
  7315. public register_ham_czbots(id)
  7316. {
  7317. // Make sure it's a CZ bot and it's still connected
  7318. if (g_hamczbots || !g_isconnected[id] || !get_pcvar_num(cvar_botquota))
  7319. return;
  7320.  
  7321. RegisterHamFromEntity(Ham_Spawn, id, "fw_PlayerSpawn_Post", 1)
  7322. RegisterHamFromEntity(Ham_Killed, id, "fw_PlayerKilled")
  7323. RegisterHamFromEntity(Ham_Killed, id, "fw_PlayerKilled_Post", 1)
  7324. RegisterHamFromEntity(Ham_TakeDamage, id, "fw_TakeDamage")
  7325. RegisterHamFromEntity(Ham_TakeDamage, id, "fw_TakeDamage_Post", 1)
  7326. RegisterHamFromEntity(Ham_TraceAttack, id, "fw_TraceAttack")
  7327. RegisterHamFromEntity(Ham_Player_ResetMaxSpeed, id, "fw_ResetMaxSpeed_Post", 1)
  7328.  
  7329. // Ham forwards for CZ bots succesfully registered
  7330. g_hamczbots = true
  7331.  
  7332. // If the bot has already spawned, call the forward manually for him
  7333. if (is_user_alive(id)) fw_PlayerSpawn_Post(id)
  7334. }
  7335.  
  7336. // Disable minmodels task
  7337. public disable_minmodels(id)
  7338. {
  7339. if (!g_isconnected[id]) return;
  7340. client_cmd(id, "cl_minmodels 0")
  7341. }
  7342.  
  7343. // Bots automatically buy extra items
  7344. public bot_buy_extras(taskid)
  7345. {
  7346. // Nemesis or Survivor bots have nothing to buy by default
  7347. if (!g_isalive[ID_SPAWN] || g_survivor[ID_SPAWN] || g_nemesis[ID_SPAWN])
  7348. return;
  7349.  
  7350. if (!g_zombie[ID_SPAWN]) // human bots
  7351. {
  7352. // Attempt to buy Night Vision
  7353. buy_extra_item(ID_SPAWN, EXTRA_NVISION)
  7354.  
  7355. // Attempt to buy a weapon
  7356. buy_extra_item(ID_SPAWN, random_num(EXTRA_WEAPONS_STARTID, EXTRAS_CUSTOM_STARTID-1))
  7357. }
  7358. else // zombie bots
  7359. {
  7360. // Attempt to buy an Antidote
  7361. buy_extra_item(ID_SPAWN, EXTRA_ANTIDOTE)
  7362. }
  7363. }
  7364.  
  7365. // Refill BP Ammo Task
  7366. public refill_bpammo(const args[], id)
  7367. {
  7368. // Player died or turned into a zombie
  7369. if (!g_isalive[id] || g_zombie[id])
  7370. return;
  7371.  
  7372. set_msg_block(g_msgAmmoPickup, BLOCK_ONCE)
  7373. ExecuteHamB(Ham_GiveAmmo, id, MAXBPAMMO[REFILL_WEAPONID], AMMOTYPE[REFILL_WEAPONID], MAXBPAMMO[REFILL_WEAPONID])
  7374. }
  7375.  
  7376. // Balance Teams Task
  7377. balance_teams()
  7378. {
  7379. // Get amount of users playing
  7380. static iPlayersnum
  7381. iPlayersnum = fnGetPlaying()
  7382.  
  7383. // No players, don't bother
  7384. if (iPlayersnum < 1) return;
  7385.  
  7386. // Split players evenly
  7387. static iTerrors, iMaxTerrors, id, team[33]
  7388. iMaxTerrors = iPlayersnum/2
  7389. iTerrors = 0
  7390.  
  7391. // First, set everyone to CT
  7392. for (id = 1; id <= g_maxplayers; id++)
  7393. {
  7394. // Skip if not connected
  7395. if (!g_isconnected[id])
  7396. continue;
  7397.  
  7398. team[id] = fm_cs_get_user_team(id)
  7399.  
  7400. // Skip if not playing
  7401. if (team[id] == FM_CS_TEAM_SPECTATOR || team[id] == FM_CS_TEAM_UNASSIGNED)
  7402. continue;
  7403.  
  7404. // Set team
  7405. remove_task(id+TASK_TEAM)
  7406. fm_cs_set_user_team(id, FM_CS_TEAM_CT)
  7407. team[id] = FM_CS_TEAM_CT
  7408. }
  7409.  
  7410. // Then randomly set half of the players to Terrorists
  7411. while (iTerrors < iMaxTerrors)
  7412. {
  7413. // Keep looping through all players
  7414. if (++id > g_maxplayers) id = 1
  7415.  
  7416. // Skip if not connected
  7417. if (!g_isconnected[id])
  7418. continue;
  7419.  
  7420. // Skip if not playing or already a Terrorist
  7421. if (team[id] != FM_CS_TEAM_CT)
  7422. continue;
  7423.  
  7424. // Random chance
  7425. if (random_num(0, 1))
  7426. {
  7427. fm_cs_set_user_team(id, FM_CS_TEAM_T)
  7428. team[id] = FM_CS_TEAM_T
  7429. iTerrors++
  7430. }
  7431. }
  7432. }
  7433.  
  7434. // Welcome Message Task
  7435. public welcome_msg()
  7436. {
  7437. // Show mod info
  7438. zp_colored_print(0, "^x01**** ^x04%s^x01 ****", g_modname)
  7439. zp_colored_print(0, "^x04[ZP-New]^x01 %L", LANG_PLAYER, "NOTICE_INFO1")
  7440. if (!get_pcvar_num(cvar_infammo)) zp_colored_print(0, "^x04[ZP-New]^x01 %L", LANG_PLAYER, "NOTICE_INFO2")
  7441.  
  7442. // Show T-virus HUD notice
  7443. set_dhudmessage(0, 125, 200, HUD_EVENT_X, HUD_EVENT_Y, 0, 0.0, 3.0, 2.0, 1.0)
  7444. show_dhudmessage(0, "%L", LANG_PLAYER, "NOTICE_VIRUS_FREE")
  7445. }
  7446.  
  7447. // Respawn Player Task (deathmatch)
  7448. public respawn_player_task(taskid)
  7449. {
  7450. // Already alive or round ended
  7451. if (g_isalive[ID_SPAWN] || g_endround)
  7452. return;
  7453.  
  7454. // Get player's team
  7455. static team
  7456. team = fm_cs_get_user_team(ID_SPAWN)
  7457.  
  7458. // Player moved to spectators
  7459. if (team == FM_CS_TEAM_SPECTATOR || team == FM_CS_TEAM_UNASSIGNED)
  7460. return;
  7461.  
  7462. // Respawn player automatically if allowed on current round
  7463. if ((!g_survround || get_pcvar_num(cvar_allowrespawnsurv)) && (!g_swarmround || get_pcvar_num(cvar_allowrespawnswarm)) && (!g_nemround || get_pcvar_num(cvar_allowrespawnnem)) && (!g_plagueround || get_pcvar_num(cvar_allowrespawnplague)))
  7464. {
  7465. // Infection rounds = none of the above
  7466. if (!get_pcvar_num(cvar_allowrespawninfection) && !g_survround && !g_nemround && !g_swarmround && !g_plagueround)
  7467. return;
  7468.  
  7469. // Respawn if only the last human is left? (ignore this setting on survivor rounds)
  7470. if (!g_survround && !get_pcvar_num(cvar_respawnafterlast) && fnGetHumans() <= 1)
  7471. return;
  7472.  
  7473. // Respawn as zombie?
  7474. if (get_pcvar_num(cvar_deathmatch) == 2 || (get_pcvar_num(cvar_deathmatch) == 3 && random_num(0, 1)) || (get_pcvar_num(cvar_deathmatch) == 4 && fnGetZombies() < fnGetAlive()/2))
  7475. g_respawn_as_zombie[ID_SPAWN] = true
  7476.  
  7477. // Override respawn as zombie setting on nemesis and survivor rounds
  7478. if (g_survround) g_respawn_as_zombie[ID_SPAWN] = true
  7479. else if (g_nemround) g_respawn_as_zombie[ID_SPAWN] = false
  7480.  
  7481. respawn_player_manually(ID_SPAWN)
  7482. }
  7483. }
  7484.  
  7485. // Respawn Player Check Task (if killed by worldspawn)
  7486. public respawn_player_check_task(taskid)
  7487. {
  7488. // Successfully spawned or round ended
  7489. if (g_isalive[ID_SPAWN] || g_endround)
  7490. return;
  7491.  
  7492. // Get player's team
  7493. static team
  7494. team = fm_cs_get_user_team(ID_SPAWN)
  7495.  
  7496. // Player moved to spectators
  7497. if (team == FM_CS_TEAM_SPECTATOR || team == FM_CS_TEAM_UNASSIGNED)
  7498. return;
  7499.  
  7500. // If player was being spawned as a zombie, set the flag again
  7501. if (g_zombie[ID_SPAWN]) g_respawn_as_zombie[ID_SPAWN] = true
  7502. else g_respawn_as_zombie[ID_SPAWN] = false
  7503.  
  7504. respawn_player_manually(ID_SPAWN)
  7505. }
  7506.  
  7507. // Respawn Player Manually (called after respawn checks are done)
  7508. respawn_player_manually(id)
  7509. {
  7510. // Set proper team before respawning, so that the TeamInfo message that's sent doesn't confuse PODBots
  7511. if (g_respawn_as_zombie[id])
  7512. fm_cs_set_user_team(id, FM_CS_TEAM_T)
  7513. else
  7514. fm_cs_set_user_team(id, FM_CS_TEAM_CT)
  7515.  
  7516. // Respawning a player has never been so easy
  7517. ExecuteHamB(Ham_CS_RoundRespawn, id)
  7518. }
  7519.  
  7520. // Check Round Task -check that we still have both zombies and humans on a round-
  7521. check_round(leaving_player)
  7522. {
  7523. // Round ended or make_a_zombie task still active
  7524. if (g_endround || task_exists(TASK_MAKEZOMBIE))
  7525. return;
  7526.  
  7527. // Get alive players count
  7528. static iPlayersnum, id
  7529. iPlayersnum = fnGetAlive()
  7530.  
  7531. // Last alive player, don't bother
  7532. if (iPlayersnum < 2)
  7533. return;
  7534.  
  7535. // Last zombie disconnecting
  7536. if (g_zombie[leaving_player] && fnGetZombies() == 1)
  7537. {
  7538. // Only one CT left, don't bother
  7539. if (fnGetHumans() == 1 && fnGetCTs() == 1)
  7540. return;
  7541.  
  7542. // Pick a random one to take his place
  7543. while ((id = fnGetRandomAlive(random_num(1, iPlayersnum))) == leaving_player ) { /* keep looping */ }
  7544.  
  7545. // Show last zombie left notice
  7546. zp_colored_print(0, "^x04[ZP-New]^x01 %L", LANG_PLAYER, "LAST_ZOMBIE_LEFT", g_playername[id])
  7547.  
  7548. // Set player leaving flag
  7549. g_lastplayerleaving = true
  7550.  
  7551. // Turn into a Nemesis or just a zombie?
  7552. if (g_nemesis[leaving_player])
  7553. zombieme(id, 0, 1, 0, 0)
  7554. else
  7555. zombieme(id, 0, 0, 0, 0)
  7556.  
  7557. // Remove player leaving flag
  7558. g_lastplayerleaving = false
  7559.  
  7560. // If Nemesis, set chosen player's health to that of the one who's leaving
  7561. if (get_pcvar_num(cvar_keephealthondisconnect) && g_nemesis[leaving_player])
  7562. fm_set_user_health(id, pev(leaving_player, pev_health))
  7563. }
  7564.  
  7565. // Last human disconnecting
  7566. else if (!g_zombie[leaving_player] && fnGetHumans() == 1)
  7567. {
  7568. // Only one T left, don't bother
  7569. if (fnGetZombies() == 1 && fnGetTs() == 1)
  7570. return;
  7571.  
  7572. // Pick a random one to take his place
  7573. while ((id = fnGetRandomAlive(random_num(1, iPlayersnum))) == leaving_player ) { /* keep looping */ }
  7574.  
  7575. // Show last human left notice
  7576. zp_colored_print(0, "^x04[ZP-New]^x01 %L", LANG_PLAYER, "LAST_HUMAN_LEFT", g_playername[id])
  7577.  
  7578. // Set player leaving flag
  7579. g_lastplayerleaving = true
  7580.  
  7581. // Turn into a Survivor or just a human?
  7582. if (g_survivor[leaving_player])
  7583. humanme(id, 1, 0)
  7584. else
  7585. humanme(id, 0, 0)
  7586.  
  7587. // Remove player leaving flag
  7588. g_lastplayerleaving = false
  7589.  
  7590. // If Survivor, set chosen player's health to that of the one who's leaving
  7591. if (get_pcvar_num(cvar_keephealthondisconnect) && g_survivor[leaving_player])
  7592. fm_set_user_health(id, pev(leaving_player, pev_health))
  7593. }
  7594. }
  7595.  
  7596. // Lighting Effects Task
  7597. public lighting_effects()
  7598. {
  7599. // Cache some CVAR values at every 5 secs
  7600. cache_cvars()
  7601.  
  7602. // Get lighting style
  7603. static lighting[2]
  7604. get_pcvar_string(cvar_lighting, lighting, charsmax(lighting))
  7605. strtolower(lighting)
  7606.  
  7607. // Lighting disabled? ["0"]
  7608. if (lighting[0] == '0')
  7609. return;
  7610.  
  7611. // Darkest light settings?
  7612. if (lighting[0] >= 'a' && lighting[0] <= 'd')
  7613. {
  7614. static thunderclap_in_progress, Float:thunder
  7615. thunderclap_in_progress = task_exists(TASK_THUNDER)
  7616. thunder = get_pcvar_float(cvar_thunder)
  7617.  
  7618. // Set thunderclap tasks if not existant
  7619. if (thunder > 0.0 && !task_exists(TASK_THUNDER_PRE) && !thunderclap_in_progress)
  7620. {
  7621. g_lights_i = 0
  7622. ArrayGetString(lights_thunder, random_num(0, ArraySize(lights_thunder) - 1), g_lights_cycle, charsmax(g_lights_cycle))
  7623. g_lights_cycle_len = strlen(g_lights_cycle)
  7624. set_task(thunder, "thunderclap", TASK_THUNDER_PRE)
  7625. }
  7626.  
  7627. // Set lighting only when no thunderclaps are going on
  7628. if (!thunderclap_in_progress) engfunc(EngFunc_LightStyle, 0, lighting)
  7629. }
  7630. else
  7631. {
  7632. // Remove thunderclap tasks
  7633. remove_task(TASK_THUNDER_PRE)
  7634. remove_task(TASK_THUNDER)
  7635.  
  7636. // Set lighting
  7637. engfunc(EngFunc_LightStyle, 0, lighting)
  7638. }
  7639. }
  7640.  
  7641. // Thunderclap task
  7642. public thunderclap()
  7643. {
  7644. // Play thunder sound
  7645. if (g_lights_i == 0)
  7646. {
  7647. static sound[64]
  7648. ArrayGetString(sound_thunder, random_num(0, ArraySize(sound_thunder) - 1), sound, charsmax(sound))
  7649. PlaySound(sound)
  7650. }
  7651.  
  7652. // Set lighting
  7653. static light[2]
  7654. light[0] = g_lights_cycle[g_lights_i]
  7655. engfunc(EngFunc_LightStyle, 0, light)
  7656.  
  7657. g_lights_i++
  7658.  
  7659. // Lighting cycle end?
  7660. if (g_lights_i >= g_lights_cycle_len)
  7661. {
  7662. remove_task(TASK_THUNDER)
  7663. lighting_effects()
  7664. }
  7665. // Lighting cycle start?
  7666. else if (!task_exists(TASK_THUNDER))
  7667. set_task(0.1, "thunderclap", TASK_THUNDER, _, _, "b")
  7668. }
  7669.  
  7670. // Ambience Sound Effects Task
  7671. public ambience_sound_effects(taskid)
  7672. {
  7673. // Play a random sound depending on the round
  7674. static sound[64], iRand, duration
  7675.  
  7676. if (g_nemround) // Nemesis Mode
  7677. {
  7678. iRand = random_num(0, ArraySize(sound_ambience2) - 1)
  7679. ArrayGetString(sound_ambience2, iRand, sound, charsmax(sound))
  7680. duration = ArrayGetCell(sound_ambience2_duration, iRand)
  7681. }
  7682. else if (g_survround) // Survivor Mode
  7683. {
  7684. iRand = random_num(0, ArraySize(sound_ambience3) - 1)
  7685. ArrayGetString(sound_ambience3, iRand, sound, charsmax(sound))
  7686. duration = ArrayGetCell(sound_ambience3_duration, iRand)
  7687. }
  7688. else if (g_swarmround) // Swarm Mode
  7689. {
  7690. iRand = random_num(0, ArraySize(sound_ambience4) - 1)
  7691. ArrayGetString(sound_ambience4, iRand, sound, charsmax(sound))
  7692. duration = ArrayGetCell(sound_ambience4_duration, iRand)
  7693. }
  7694. else if (g_plagueround) // Plague Mode
  7695. {
  7696. iRand = random_num(0, ArraySize(sound_ambience5) - 1)
  7697. ArrayGetString(sound_ambience5, iRand, sound, charsmax(sound))
  7698. duration = ArrayGetCell(sound_ambience5_duration, iRand)
  7699. }
  7700. else // Infection Mode
  7701. {
  7702. iRand = random_num(0, ArraySize(sound_ambience1) - 1)
  7703. ArrayGetString(sound_ambience1, iRand, sound, charsmax(sound))
  7704. duration = ArrayGetCell(sound_ambience1_duration, iRand)
  7705. }
  7706.  
  7707. // Play it on clients
  7708. PlaySound(sound)
  7709.  
  7710. // Set the task for when the sound is done playing
  7711. set_task(float(duration), "ambience_sound_effects", TASK_AMBIENCESOUNDS)
  7712. }
  7713.  
  7714. // Ambience Sounds Stop Task
  7715. ambience_sound_stop()
  7716. {
  7717. client_cmd(0, "mp3 stop; stopsound")
  7718. }
  7719.  
  7720. // Flashlight Charge Task
  7721. public flashlight_charge(taskid)
  7722. {
  7723. // Drain or charge?
  7724. if (g_flashlight[ID_CHARGE])
  7725. g_flashbattery[ID_CHARGE] -= get_pcvar_num(cvar_flashdrain)
  7726. else
  7727. g_flashbattery[ID_CHARGE] += get_pcvar_num(cvar_flashcharge)
  7728.  
  7729. // Battery fully charged
  7730. if (g_flashbattery[ID_CHARGE] >= 100)
  7731. {
  7732. // Don't exceed 100%
  7733. g_flashbattery[ID_CHARGE] = 100
  7734.  
  7735. // Update flashlight battery on HUD
  7736. message_begin(MSG_ONE, g_msgFlashBat, _, ID_CHARGE)
  7737. write_byte(100) // battery
  7738. message_end()
  7739.  
  7740. // Task not needed anymore
  7741. remove_task(taskid);
  7742. return;
  7743. }
  7744.  
  7745. // Battery depleted
  7746. if (g_flashbattery[ID_CHARGE] <= 0)
  7747. {
  7748. // Turn it off
  7749. g_flashlight[ID_CHARGE] = false
  7750. g_flashbattery[ID_CHARGE] = 0
  7751.  
  7752. // Play flashlight toggle sound
  7753. emit_sound(ID_CHARGE, CHAN_ITEM, sound_flashlight, 1.0, ATTN_NORM, 0, PITCH_NORM)
  7754.  
  7755. // Update flashlight status on HUD
  7756. message_begin(MSG_ONE, g_msgFlashlight, _, ID_CHARGE)
  7757. write_byte(0) // toggle
  7758. write_byte(0) // battery
  7759. message_end()
  7760.  
  7761. // Remove flashlight task for this player
  7762. remove_task(ID_CHARGE+TASK_FLASH)
  7763. }
  7764. else
  7765. {
  7766. // Update flashlight battery on HUD
  7767. message_begin(MSG_ONE_UNRELIABLE, g_msgFlashBat, _, ID_CHARGE)
  7768. write_byte(g_flashbattery[ID_CHARGE]) // battery
  7769. message_end()
  7770. }
  7771. }
  7772.  
  7773. // Remove Spawn Protection Task
  7774. public remove_spawn_protection(taskid)
  7775. {
  7776. // Not alive
  7777. if (!g_isalive[ID_SPAWN])
  7778. return;
  7779.  
  7780. // Remove spawn protection
  7781. g_nodamage[ID_SPAWN] = false
  7782. set_pev(ID_SPAWN, pev_effects, pev(ID_SPAWN, pev_effects) & ~EF_NODRAW)
  7783. }
  7784.  
  7785. // Hide Player's Money Task
  7786. public task_hide_money(taskid)
  7787. {
  7788. // Not alive
  7789. if (!g_isalive[ID_SPAWN])
  7790. return;
  7791.  
  7792. // Hide money
  7793. message_begin(MSG_ONE, g_msgHideWeapon, _, ID_SPAWN)
  7794. write_byte(HIDE_MONEY) // what to hide bitsum
  7795. message_end()
  7796.  
  7797. // Hide the HL crosshair that's drawn
  7798. message_begin(MSG_ONE, g_msgCrosshair, _, ID_SPAWN)
  7799. write_byte(0) // toggle
  7800. message_end()
  7801. }
  7802.  
  7803. // Turn Off Flashlight and Restore Batteries
  7804. turn_off_flashlight(id)
  7805. {
  7806. // Restore batteries for the next use
  7807. fm_cs_set_user_batteries(id, 100)
  7808.  
  7809. // Check if flashlight is on
  7810. if (pev(id, pev_effects) & EF_DIMLIGHT)
  7811. {
  7812. // Turn it off
  7813. set_pev(id, pev_impulse, IMPULSE_FLASHLIGHT)
  7814. }
  7815. else
  7816. {
  7817. // Clear any stored flashlight impulse (bugfix)
  7818. set_pev(id, pev_impulse, 0)
  7819. }
  7820.  
  7821. // Turn off custom flashlight
  7822. if (g_cached_customflash)
  7823. {
  7824. // Turn it off
  7825. g_flashlight[id] = false
  7826. g_flashbattery[id] = 100
  7827.  
  7828. // Update flashlight HUD
  7829. message_begin(MSG_ONE, g_msgFlashlight, _, id)
  7830. write_byte(0) // toggle
  7831. write_byte(100) // battery
  7832. message_end()
  7833.  
  7834. // Remove previous tasks
  7835. remove_task(id+TASK_CHARGE)
  7836. remove_task(id+TASK_FLASH)
  7837. }
  7838. }
  7839.  
  7840. // Infection Bomb Explosion
  7841. infection_explode(ent)
  7842. {
  7843. // Round ended (bugfix)
  7844. if (g_endround) return;
  7845.  
  7846. // Get origin
  7847. static Float:originF[3]
  7848. pev(ent, pev_origin, originF)
  7849.  
  7850. // Make the explosion
  7851. create_blast(originF)
  7852.  
  7853. // Infection nade explode sound
  7854. static sound[64]
  7855. ArrayGetString(grenade_infect, random_num(0, ArraySize(grenade_infect) - 1), sound, charsmax(sound))
  7856. emit_sound(ent, CHAN_WEAPON, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  7857.  
  7858. // Get attacker
  7859. static attacker
  7860. attacker = pev(ent, pev_owner)
  7861.  
  7862. // Infection bomb owner disconnected? (bugfix)
  7863. if (!is_user_valid_connected(attacker))
  7864. {
  7865. // Get rid of the grenade
  7866. engfunc(EngFunc_RemoveEntity, ent)
  7867. return;
  7868. }
  7869.  
  7870. // Collisions
  7871. static victim
  7872. victim = -1
  7873.  
  7874. while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, NADE_EXPLOSION_RADIUS)) != 0)
  7875. {
  7876. // Only effect alive non-spawnprotected humans
  7877. if (!is_user_valid_alive(victim) || g_zombie[victim] || g_nodamage[victim])
  7878. continue;
  7879.  
  7880. // Last human is killed
  7881. if (fnGetHumans() == 1)
  7882. {
  7883. ExecuteHamB(Ham_Killed, victim, attacker, 0)
  7884. continue;
  7885. }
  7886.  
  7887. // Infected victim's sound
  7888. ArrayGetString(grenade_infect_player, random_num(0, ArraySize(grenade_infect_player) - 1), sound, charsmax(sound))
  7889. emit_sound(victim, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  7890.  
  7891. // Turn into zombie
  7892. zombieme(victim, attacker, 0, 1, 1)
  7893. }
  7894.  
  7895. // Get rid of the grenade
  7896. engfunc(EngFunc_RemoveEntity, ent)
  7897. }
  7898.  
  7899. // Fire Grenade Explosion
  7900. fire_explode(ent)
  7901. {
  7902. // Get origin
  7903. static Float:originF[3]
  7904. pev(ent, pev_origin, originF)
  7905.  
  7906. // Make the explosion
  7907. create_blast2(originF)
  7908.  
  7909. // Fire nade explode sound
  7910. static sound[64]
  7911. ArrayGetString(grenade_fire, random_num(0, ArraySize(grenade_fire) - 1), sound, charsmax(sound))
  7912. emit_sound(ent, CHAN_WEAPON, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  7913.  
  7914. // Collisions
  7915. static victim
  7916. victim = -1
  7917.  
  7918. while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, NADE_EXPLOSION_RADIUS)) != 0)
  7919. {
  7920. // Only effect alive zombies
  7921. if (!is_user_valid_alive(victim) || !g_zombie[victim] || g_nodamage[victim])
  7922. continue;
  7923.  
  7924. // Heat icon?
  7925. if (get_pcvar_num(cvar_hudicons))
  7926. {
  7927. message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, _, victim)
  7928. write_byte(0) // damage save
  7929. write_byte(0) // damage take
  7930. write_long(DMG_BURN) // damage type
  7931. write_coord(0) // x
  7932. write_coord(0) // y
  7933. write_coord(0) // z
  7934. message_end()
  7935. }
  7936.  
  7937. if (g_nemesis[victim]) // fire duration (nemesis is fire resistant)
  7938. g_burning_duration[victim] += get_pcvar_num(cvar_fireduration)
  7939. else
  7940. g_burning_duration[victim] += get_pcvar_num(cvar_fireduration) * 5
  7941.  
  7942. // Set burning task on victim if not present
  7943. if (!task_exists(victim+TASK_BURN))
  7944. set_task(0.2, "burning_flame", victim+TASK_BURN, _, _, "b")
  7945. }
  7946.  
  7947. // Get rid of the grenade
  7948. engfunc(EngFunc_RemoveEntity, ent)
  7949. }
  7950.  
  7951. // Frost Grenade Explosion
  7952. frost_explode(ent)
  7953. {
  7954. // Get origin
  7955. static Float:originF[3]
  7956. pev(ent, pev_origin, originF)
  7957.  
  7958. // Make the explosion
  7959. create_blast3(originF)
  7960.  
  7961. // Frost nade explode sound
  7962. static sound[64]
  7963. ArrayGetString(grenade_frost, random_num(0, ArraySize(grenade_frost) - 1), sound, charsmax(sound))
  7964. emit_sound(ent, CHAN_WEAPON, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  7965.  
  7966. // Collisions
  7967. static victim
  7968. victim = -1
  7969.  
  7970. while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, NADE_EXPLOSION_RADIUS)) != 0)
  7971. {
  7972. // Only effect alive unfrozen zombies
  7973. if (!is_user_valid_alive(victim) || !g_zombie[victim] || g_frozen[victim] || g_nodamage[victim])
  7974. continue;
  7975.  
  7976. // Nemesis shouldn't be frozen
  7977. if (g_nemesis[victim])
  7978. {
  7979. // Get player's origin
  7980. static origin2[3]
  7981. get_user_origin(victim, origin2)
  7982.  
  7983. // Broken glass sound
  7984. ArrayGetString(grenade_frost_break, random_num(0, ArraySize(grenade_frost_break) - 1), sound, charsmax(sound))
  7985. emit_sound(victim, CHAN_BODY, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  7986.  
  7987. // Glass shatter
  7988. message_begin(MSG_PVS, SVC_TEMPENTITY, origin2)
  7989. write_byte(TE_BREAKMODEL) // TE id
  7990. write_coord(origin2[0]) // x
  7991. write_coord(origin2[1]) // y
  7992. write_coord(origin2[2]+24) // z
  7993. write_coord(16) // size x
  7994. write_coord(16) // size y
  7995. write_coord(16) // size z
  7996. write_coord(random_num(-50, 50)) // velocity x
  7997. write_coord(random_num(-50, 50)) // velocity y
  7998. write_coord(25) // velocity z
  7999. write_byte(10) // random velocity
  8000. write_short(g_glassSpr) // model
  8001. write_byte(10) // count
  8002. write_byte(25) // life
  8003. write_byte(BREAK_GLASS) // flags
  8004. message_end()
  8005.  
  8006. continue;
  8007. }
  8008.  
  8009. // Freeze icon?
  8010. if (get_pcvar_num(cvar_hudicons))
  8011. {
  8012. message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, _, victim)
  8013. write_byte(0) // damage save
  8014. write_byte(0) // damage take
  8015. write_long(DMG_DROWN) // damage type - DMG_FREEZE
  8016. write_coord(0) // x
  8017. write_coord(0) // y
  8018. write_coord(0) // z
  8019. message_end()
  8020. }
  8021.  
  8022. // Light blue glow while frozen
  8023. if (g_handle_models_on_separate_ent)
  8024. fm_set_rendering(g_ent_playermodel[victim], kRenderFxGlowShell, 0, 100, 200, kRenderNormal, 25)
  8025. else
  8026. fm_set_rendering(victim, kRenderFxGlowShell, 0, 100, 200, kRenderNormal, 25)
  8027.  
  8028. // Freeze sound
  8029. ArrayGetString(grenade_frost_player, random_num(0, ArraySize(grenade_frost_player) - 1), sound, charsmax(sound))
  8030. emit_sound(victim, CHAN_BODY, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  8031.  
  8032. // Add a blue tint to their screen
  8033. message_begin(MSG_ONE, g_msgScreenFade, _, victim)
  8034. write_short(0) // duration
  8035. write_short(0) // hold time
  8036. write_short(FFADE_STAYOUT) // fade type
  8037. write_byte(0) // red
  8038. write_byte(50) // green
  8039. write_byte(200) // blue
  8040. write_byte(100) // alpha
  8041. message_end()
  8042.  
  8043. // Set the frozen flag
  8044. g_frozen[victim] = true
  8045.  
  8046. // Save player's old gravity (bugfix)
  8047. pev(victim, pev_gravity, g_frozen_gravity[victim])
  8048.  
  8049. // Prevent from jumping
  8050. if (pev(victim, pev_flags) & FL_ONGROUND)
  8051. set_pev(victim, pev_gravity, 999999.9) // set really high
  8052. else
  8053. set_pev(victim, pev_gravity, 0.000001) // no gravity
  8054.  
  8055. // Prevent from moving
  8056. ExecuteHamB(Ham_Player_ResetMaxSpeed, victim)
  8057.  
  8058. // Set a task to remove the freeze
  8059. set_task(get_pcvar_float(cvar_freezeduration), "remove_freeze", victim)
  8060. }
  8061.  
  8062. // Get rid of the grenade
  8063. engfunc(EngFunc_RemoveEntity, ent)
  8064. }
  8065.  
  8066. // Remove freeze task
  8067. public remove_freeze(id)
  8068. {
  8069. // Not alive or not frozen anymore
  8070. if (!g_isalive[id] || !g_frozen[id])
  8071. return;
  8072.  
  8073. // Unfreeze
  8074. g_frozen[id] = false;
  8075.  
  8076. // Restore gravity and maxspeed (bugfix)
  8077. set_pev(id, pev_gravity, g_frozen_gravity[id])
  8078. ExecuteHamB(Ham_Player_ResetMaxSpeed, id)
  8079.  
  8080. // Restore rendering
  8081. if (g_handle_models_on_separate_ent)
  8082. {
  8083. // Nemesis or Survivor glow / remove glow on player model entity
  8084. if (g_nemesis[id] && get_pcvar_num(cvar_nemglow))
  8085. fm_set_rendering(g_ent_playermodel[id], kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 25)
  8086. else if (g_survivor[id] && get_pcvar_num(cvar_survglow))
  8087. fm_set_rendering(g_ent_playermodel[id], kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 25)
  8088. else
  8089. fm_set_rendering(g_ent_playermodel[id])
  8090. }
  8091. else
  8092. {
  8093. // Nemesis or Survivor glow / remove glow
  8094. if (g_nemesis[id] && get_pcvar_num(cvar_nemglow))
  8095. fm_set_rendering(id, kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 25)
  8096. else if (g_survivor[id] && get_pcvar_num(cvar_survglow))
  8097. fm_set_rendering(id, kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 25)
  8098. else
  8099. fm_set_rendering(id)
  8100. }
  8101.  
  8102. // Gradually remove screen's blue tint
  8103. message_begin(MSG_ONE, g_msgScreenFade, _, id)
  8104. write_short(UNIT_SECOND) // duration
  8105. write_short(0) // hold time
  8106. write_short(FFADE_IN) // fade type
  8107. write_byte(0) // red
  8108. write_byte(50) // green
  8109. write_byte(200) // blue
  8110. write_byte(100) // alpha
  8111. message_end()
  8112.  
  8113. // Broken glass sound
  8114. static sound[64]
  8115. ArrayGetString(grenade_frost_break, random_num(0, ArraySize(grenade_frost_break) - 1), sound, charsmax(sound))
  8116. emit_sound(id, CHAN_BODY, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  8117.  
  8118. // Get player's origin
  8119. static origin2[3]
  8120. get_user_origin(id, origin2)
  8121.  
  8122. // Glass shatter
  8123. message_begin(MSG_PVS, SVC_TEMPENTITY, origin2)
  8124. write_byte(TE_BREAKMODEL) // TE id
  8125. write_coord(origin2[0]) // x
  8126. write_coord(origin2[1]) // y
  8127. write_coord(origin2[2]+24) // z
  8128. write_coord(16) // size x
  8129. write_coord(16) // size y
  8130. write_coord(16) // size z
  8131. write_coord(random_num(-50, 50)) // velocity x
  8132. write_coord(random_num(-50, 50)) // velocity y
  8133. write_coord(25) // velocity z
  8134. write_byte(10) // random velocity
  8135. write_short(g_glassSpr) // model
  8136. write_byte(10) // count
  8137. write_byte(25) // life
  8138. write_byte(BREAK_GLASS) // flags
  8139. message_end()
  8140.  
  8141. ExecuteForward(g_fwUserUnfrozen, g_fwDummyResult, id);
  8142. }
  8143.  
  8144. // Remove Stuff Task
  8145. public remove_stuff()
  8146. {
  8147. static ent
  8148.  
  8149. // Remove rotating doors
  8150. if (get_pcvar_num(cvar_removedoors) > 0)
  8151. {
  8152. ent = -1;
  8153. while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "func_door_rotating")) != 0)
  8154. engfunc(EngFunc_SetOrigin, ent, Float:{8192.0 ,8192.0 ,8192.0})
  8155. }
  8156.  
  8157. // Remove all doors
  8158. if (get_pcvar_num(cvar_removedoors) > 1)
  8159. {
  8160. ent = -1;
  8161. while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "func_door")) != 0)
  8162. engfunc(EngFunc_SetOrigin, ent, Float:{8192.0 ,8192.0 ,8192.0})
  8163. }
  8164.  
  8165. // Triggered lights
  8166. if (!get_pcvar_num(cvar_triggered))
  8167. {
  8168. ent = -1
  8169. while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "light")) != 0)
  8170. {
  8171. dllfunc(DLLFunc_Use, ent, 0); // turn off the light
  8172. set_pev(ent, pev_targetname, 0) // prevent it from being triggered
  8173. }
  8174. }
  8175. }
  8176.  
  8177. // Set Custom Weapon Models
  8178. replace_weapon_models(id, weaponid)
  8179. {
  8180. switch (weaponid)
  8181. {
  8182. case CSW_KNIFE: // Custom knife models
  8183. {
  8184. if (g_zombie[id])
  8185. {
  8186. if (g_nemesis[id]) // Nemesis
  8187. {
  8188. set_pev(id, pev_viewmodel2, model_vknife_nemesis)
  8189. set_pev(id, pev_weaponmodel2, "")
  8190. }
  8191. else // Zombies
  8192. {
  8193. // Admin knife models?
  8194. if (get_pcvar_num(cvar_adminknifemodelszombie) && get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS])
  8195. {
  8196. set_pev(id, pev_viewmodel2, model_vknife_admin_zombie)
  8197. set_pev(id, pev_weaponmodel2, "")
  8198. }
  8199. else
  8200. {
  8201. static clawmodel[100]
  8202. ArrayGetString(g_zclass_clawmodel, g_zombieclass[id], clawmodel, charsmax(clawmodel))
  8203. format(clawmodel, charsmax(clawmodel), "models/zombie_plague/%s", clawmodel)
  8204. set_pev(id, pev_viewmodel2, clawmodel)
  8205. set_pev(id, pev_weaponmodel2, "")
  8206. }
  8207. }
  8208. }
  8209. else // Humans
  8210. {
  8211. // Admin knife models?
  8212. if (get_pcvar_num(cvar_adminknifemodelshuman) && get_user_flags(id) & g_access_flag[ACCESS_ADMIN_MODELS])
  8213. {
  8214. set_pev(id, pev_viewmodel2, model_vknife_admin_human)
  8215. set_pev(id, pev_weaponmodel2, "models/p_knife.mdl")
  8216. }
  8217. else
  8218. {
  8219. set_pev(id, pev_viewmodel2, model_vknife_human)
  8220. set_pev(id, pev_weaponmodel2, "models/p_knife.mdl")
  8221. }
  8222. }
  8223. }
  8224. case CSW_HEGRENADE: // Infection bomb or fire grenade
  8225. {
  8226. if (g_zombie[id])
  8227. set_pev(id, pev_viewmodel2, model_grenade_infect)
  8228. else
  8229. set_pev(id, pev_viewmodel2, model_grenade_fire)
  8230. }
  8231. case CSW_FLASHBANG: // Frost grenade
  8232. {
  8233. set_pev(id, pev_viewmodel2, model_grenade_frost)
  8234. }
  8235. case CSW_SMOKEGRENADE: // Flare grenade
  8236. {
  8237. set_pev(id, pev_viewmodel2, model_grenade_flare)
  8238. }
  8239. }
  8240.  
  8241. // Survivor's custom weapon model
  8242. static survweaponname[32]
  8243. get_pcvar_string(cvar_survweapon, survweaponname, charsmax(survweaponname))
  8244. if (g_survivor[id] && weaponid == cs_weapon_name_to_id(survweaponname))
  8245. set_pev(id, pev_viewmodel2, model_vweapon_survivor)
  8246.  
  8247. // Update model on weaponmodel ent
  8248. if (g_handle_models_on_separate_ent) fm_set_weaponmodel_ent(id)
  8249. }
  8250.  
  8251. // Reset Player Vars
  8252. reset_vars(id, resetall)
  8253. {
  8254. g_zombie[id] = false
  8255. g_nemesis[id] = false
  8256. g_survivor[id] = false
  8257. g_firstzombie[id] = false
  8258. g_lastzombie[id] = false
  8259. g_lasthuman[id] = false
  8260. g_frozen[id] = false
  8261. g_nodamage[id] = false
  8262. g_respawn_as_zombie[id] = false
  8263. g_nvision[id] = false
  8264. g_nvisionenabled[id] = false
  8265. g_flashlight[id] = false
  8266. g_flashbattery[id] = 100
  8267. g_canbuy[id] = true
  8268. g_burning_duration[id] = 0
  8269.  
  8270. if (resetall)
  8271. {
  8272. g_ammopacks[id] = get_pcvar_num(cvar_startammopacks)
  8273. g_zombieclass[id] = ZCLASS_NONE
  8274. g_zombieclassnext[id] = ZCLASS_NONE
  8275. g_damagedealt_human[id] = 0
  8276. g_damagedealt_zombie[id] = 0
  8277. WPN_AUTO_ON = 0
  8278. WPN_STARTID = 0
  8279. PL_ACTION = 0
  8280. MENU_PAGE_ZCLASS = 0
  8281. MENU_PAGE_EXTRAS = 0
  8282. MENU_PAGE_PLAYERS = 0
  8283. }
  8284. }
  8285.  
  8286. // Set spectators nightvision
  8287. public spec_nvision(id)
  8288. {
  8289. // Not connected, alive, or bot
  8290. if (!g_isconnected[id] || g_isalive[id] || g_isbot[id])
  8291. return;
  8292.  
  8293. // Give Night Vision?
  8294. if (get_pcvar_num(cvar_nvggive))
  8295. {
  8296. g_nvision[id] = true
  8297.  
  8298. // Turn on Night Vision automatically?
  8299. if (get_pcvar_num(cvar_nvggive) == 1)
  8300. {
  8301. g_nvisionenabled[id] = true
  8302.  
  8303. // Custom nvg?
  8304. if (get_pcvar_num(cvar_customnvg))
  8305. {
  8306. remove_task(id+TASK_NVISION)
  8307. set_task(0.1, "set_user_nvision", id+TASK_NVISION, _, _, "b")
  8308. }
  8309. else
  8310. set_user_gnvision(id, 1)
  8311. }
  8312. }
  8313. }
  8314.  
  8315. // Show HUD Task
  8316. public ShowHUD(taskid)
  8317. {
  8318. static id
  8319. id = ID_SHOWHUD;
  8320.  
  8321. // Player died?
  8322. if (!g_isalive[id])
  8323. {
  8324. // Get spectating target
  8325. id = pev(id, PEV_SPEC_TARGET)
  8326.  
  8327. // Target not alive
  8328. if (!g_isalive[id]) return;
  8329. }
  8330.  
  8331. // Format classname
  8332. static class[32], red, green, blue
  8333.  
  8334. if (g_zombie[id]) // zombies
  8335. {
  8336. red = 217
  8337. green = 4
  8338. blue = 201
  8339.  
  8340. if (g_nemesis[id])
  8341. formatex(class, charsmax(class), "%L", ID_SHOWHUD, "CLASS_NEMESIS")
  8342. else
  8343. copy(class, charsmax(class), g_zombie_classname[id])
  8344. }
  8345. else // humans
  8346. {
  8347. red = 126
  8348. green = 219
  8349. blue = 2
  8350.  
  8351. if (g_survivor[id])
  8352. formatex(class, charsmax(class), "%L", ID_SHOWHUD, "CLASS_SURVIVOR")
  8353. else
  8354. formatex(class, charsmax(class), "%L", ID_SHOWHUD, "CLASS_HUMAN")
  8355. }
  8356.  
  8357. // Spectating someone else?
  8358. if (id != ID_SHOWHUD)
  8359. {
  8360. // Show name, health, class, and ammo packs
  8361. set_hudmessage(255, 255, 255, HUD_SPECT_X, HUD_SPECT_Y, 0, 6.0, 1.1, 0.0, 0.0, -1)
  8362. ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync2, "%L %s^nHP: %d - %L %s - %L %d", ID_SHOWHUD, "SPECTATING", g_playername[id], pev(id, pev_health), ID_SHOWHUD, "CLASS_CLASS", class, ID_SHOWHUD, "AMMO_PACKS1", g_ammopacks[id])
  8363. }
  8364. else
  8365. {
  8366. // Show health, class and ammo packs
  8367. set_hudmessage(red, green, blue, 0.02, 0.85, 0, 6.0, 1.1, 0.0, 0.0,-1)
  8368. ShowSyncHudMsg(ID_SHOWHUD, g_MsgSync2, "! ^n_____________________________________________________ ^n%L: %d ~ %L %s ~ %L: %d ~ Armor: %d ^n_____________________________________________________", id, "ZOMBIE_ATTRIB1", pev(ID_SHOWHUD, pev_health), ID_SHOWHUD, "CLASS_CLASS", class, ID_SHOWHUD, "AMMO_PACKS1", g_ammopacks[ID_SHOWHUD], get_user_armor(ID_SHOWHUD))
  8369. }
  8370. }
  8371.  
  8372. // Play idle zombie sounds
  8373. public zombie_play_idle(taskid)
  8374. {
  8375. // Round ended/new one starting
  8376. if (g_endround || g_newround)
  8377. return;
  8378.  
  8379. static sound[64]
  8380.  
  8381. // Last zombie?
  8382. if (g_lastzombie[ID_BLOOD])
  8383. {
  8384. ArrayGetString(zombie_idle_last, random_num(0, ArraySize(zombie_idle_last) - 1), sound, charsmax(sound))
  8385. emit_sound(ID_BLOOD, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  8386. }
  8387. else
  8388. {
  8389. ArrayGetString(zombie_idle, random_num(0, ArraySize(zombie_idle) - 1), sound, charsmax(sound))
  8390. emit_sound(ID_BLOOD, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  8391. }
  8392. }
  8393.  
  8394. // Madness Over Task
  8395. public madness_over(taskid)
  8396. {
  8397. g_nodamage[ID_BLOOD] = false
  8398. }
  8399.  
  8400. // Place user at a random spawn
  8401. do_random_spawn(id, regularspawns = 0)
  8402. {
  8403. static hull, sp_index, i
  8404.  
  8405. // Get whether the player is crouching
  8406. hull = (pev(id, pev_flags) & FL_DUCKING) ? HULL_HEAD : HULL_HUMAN
  8407.  
  8408. // Use regular spawns?
  8409. if (!regularspawns)
  8410. {
  8411. // No spawns?
  8412. if (!g_spawnCount)
  8413. return;
  8414.  
  8415. // Choose random spawn to start looping at
  8416. sp_index = random_num(0, g_spawnCount - 1)
  8417.  
  8418. // Try to find a clear spawn
  8419. for (i = sp_index + 1; /*no condition*/; i++)
  8420. {
  8421. // Start over when we reach the end
  8422. if (i >= g_spawnCount) i = 0
  8423.  
  8424. // Free spawn space?
  8425. if (is_hull_vacant(g_spawns[i], hull))
  8426. {
  8427. // Engfunc_SetOrigin is used so ent's mins and maxs get updated instantly
  8428. engfunc(EngFunc_SetOrigin, id, g_spawns[i])
  8429. break;
  8430. }
  8431.  
  8432. // Loop completed, no free space found
  8433. if (i == sp_index) break;
  8434. }
  8435. }
  8436. else
  8437. {
  8438. // No spawns?
  8439. if (!g_spawnCount2)
  8440. return;
  8441.  
  8442. // Choose random spawn to start looping at
  8443. sp_index = random_num(0, g_spawnCount2 - 1)
  8444.  
  8445. // Try to find a clear spawn
  8446. for (i = sp_index + 1; /*no condition*/; i++)
  8447. {
  8448. // Start over when we reach the end
  8449. if (i >= g_spawnCount2) i = 0
  8450.  
  8451. // Free spawn space?
  8452. if (is_hull_vacant(g_spawns2[i], hull))
  8453. {
  8454. // Engfunc_SetOrigin is used so ent's mins and maxs get updated instantly
  8455. engfunc(EngFunc_SetOrigin, id, g_spawns2[i])
  8456. break;
  8457. }
  8458.  
  8459. // Loop completed, no free space found
  8460. if (i == sp_index) break;
  8461. }
  8462. }
  8463. }
  8464.  
  8465. // Get Zombies -returns alive zombies number-
  8466. fnGetZombies()
  8467. {
  8468. static iZombies, id
  8469. iZombies = 0
  8470.  
  8471. for (id = 1; id <= g_maxplayers; id++)
  8472. {
  8473. if (g_isalive[id] && g_zombie[id])
  8474. iZombies++
  8475. }
  8476.  
  8477. return iZombies;
  8478. }
  8479.  
  8480. // Get Humans -returns alive humans number-
  8481. fnGetHumans()
  8482. {
  8483. static iHumans, id
  8484. iHumans = 0
  8485.  
  8486. for (id = 1; id <= g_maxplayers; id++)
  8487. {
  8488. if (g_isalive[id] && !g_zombie[id])
  8489. iHumans++
  8490. }
  8491.  
  8492. return iHumans;
  8493. }
  8494.  
  8495. // Get Nemesis -returns alive nemesis number-
  8496. fnGetNemesis()
  8497. {
  8498. static iNemesis, id
  8499. iNemesis = 0
  8500.  
  8501. for (id = 1; id <= g_maxplayers; id++)
  8502. {
  8503. if (g_isalive[id] && g_nemesis[id])
  8504. iNemesis++
  8505. }
  8506.  
  8507. return iNemesis;
  8508. }
  8509.  
  8510. // Get Survivors -returns alive survivors number-
  8511. fnGetSurvivors()
  8512. {
  8513. static iSurvivors, id
  8514. iSurvivors = 0
  8515.  
  8516. for (id = 1; id <= g_maxplayers; id++)
  8517. {
  8518. if (g_isalive[id] && g_survivor[id])
  8519. iSurvivors++
  8520. }
  8521.  
  8522. return iSurvivors;
  8523. }
  8524.  
  8525. // Get Alive -returns alive players number-
  8526. fnGetAlive()
  8527. {
  8528. static iAlive, id
  8529. iAlive = 0
  8530.  
  8531. for (id = 1; id <= g_maxplayers; id++)
  8532. {
  8533. if (g_isalive[id])
  8534. iAlive++
  8535. }
  8536.  
  8537. return iAlive;
  8538. }
  8539.  
  8540. // Get Random Alive -returns index of alive player number n -
  8541. fnGetRandomAlive(n)
  8542. {
  8543. static iAlive, id
  8544. iAlive = 0
  8545.  
  8546. for (id = 1; id <= g_maxplayers; id++)
  8547. {
  8548. if (g_isalive[id])
  8549. iAlive++
  8550.  
  8551. if (iAlive == n)
  8552. return id;
  8553. }
  8554.  
  8555. return -1;
  8556. }
  8557.  
  8558. // Get Playing -returns number of users playing-
  8559. fnGetPlaying()
  8560. {
  8561. static iPlaying, id, team
  8562. iPlaying = 0
  8563.  
  8564. for (id = 1; id <= g_maxplayers; id++)
  8565. {
  8566. if (g_isconnected[id])
  8567. {
  8568. team = fm_cs_get_user_team(id)
  8569.  
  8570. if (team != FM_CS_TEAM_SPECTATOR && team != FM_CS_TEAM_UNASSIGNED)
  8571. iPlaying++
  8572. }
  8573. }
  8574.  
  8575. return iPlaying;
  8576. }
  8577.  
  8578. // Get CTs -returns number of CTs connected-
  8579. fnGetCTs()
  8580. {
  8581. static iCTs, id
  8582. iCTs = 0
  8583.  
  8584. for (id = 1; id <= g_maxplayers; id++)
  8585. {
  8586. if (g_isconnected[id])
  8587. {
  8588. if (fm_cs_get_user_team(id) == FM_CS_TEAM_CT)
  8589. iCTs++
  8590. }
  8591. }
  8592.  
  8593. return iCTs;
  8594. }
  8595.  
  8596. // Get Ts -returns number of Ts connected-
  8597. fnGetTs()
  8598. {
  8599. static iTs, id
  8600. iTs = 0
  8601.  
  8602. for (id = 1; id <= g_maxplayers; id++)
  8603. {
  8604. if (g_isconnected[id])
  8605. {
  8606. if (fm_cs_get_user_team(id) == FM_CS_TEAM_T)
  8607. iTs++
  8608. }
  8609. }
  8610.  
  8611. return iTs;
  8612. }
  8613.  
  8614. // Get Alive CTs -returns number of CTs alive-
  8615. fnGetAliveCTs()
  8616. {
  8617. static iCTs, id
  8618. iCTs = 0
  8619.  
  8620. for (id = 1; id <= g_maxplayers; id++)
  8621. {
  8622. if (g_isalive[id])
  8623. {
  8624. if (fm_cs_get_user_team(id) == FM_CS_TEAM_CT)
  8625. iCTs++
  8626. }
  8627. }
  8628.  
  8629. return iCTs;
  8630. }
  8631.  
  8632. // Get Alive Ts -returns number of Ts alive-
  8633. fnGetAliveTs()
  8634. {
  8635. static iTs, id
  8636. iTs = 0
  8637.  
  8638. for (id = 1; id <= g_maxplayers; id++)
  8639. {
  8640. if (g_isalive[id])
  8641. {
  8642. if (fm_cs_get_user_team(id) == FM_CS_TEAM_T)
  8643. iTs++
  8644. }
  8645. }
  8646.  
  8647. return iTs;
  8648. }
  8649.  
  8650. // Last Zombie Check -check for last zombie and set its flag-
  8651. fnCheckLastZombie()
  8652. {
  8653. static id
  8654. for (id = 1; id <= g_maxplayers; id++)
  8655. {
  8656. // Last zombie
  8657. if (g_isalive[id] && g_zombie[id] && !g_nemesis[id] && fnGetZombies() == 1)
  8658. {
  8659. if (!g_lastzombie[id])
  8660. {
  8661. // Last zombie forward
  8662. ExecuteForward(g_fwUserLastZombie, g_fwDummyResult, id);
  8663. }
  8664. g_lastzombie[id] = true
  8665. }
  8666. else
  8667. g_lastzombie[id] = false
  8668.  
  8669. // Last human
  8670. if (g_isalive[id] && !g_zombie[id] && !g_survivor[id] && fnGetHumans() == 1)
  8671. {
  8672. if (!g_lasthuman[id])
  8673. {
  8674. // Last human forward
  8675. ExecuteForward(g_fwUserLastHuman, g_fwDummyResult, id);
  8676.  
  8677. // Reward extra hp
  8678. fm_set_user_health(id, pev(id, pev_health) + get_pcvar_num(cvar_humanlasthp))
  8679. }
  8680. g_lasthuman[id] = true
  8681. }
  8682. else
  8683. g_lasthuman[id] = false
  8684. }
  8685. }
  8686.  
  8687. // Save player's stats to database
  8688. save_stats(id)
  8689. {
  8690. // Check whether there is another record already in that slot
  8691. if (db_name[id][0] && !equal(g_playername[id], db_name[id]))
  8692. {
  8693. // If DB size is exceeded, write over old records
  8694. if (db_slot_i >= sizeof db_name)
  8695. db_slot_i = g_maxplayers+1
  8696.  
  8697. // Move previous record onto an additional save slot
  8698. copy(db_name[db_slot_i], charsmax(db_name[]), db_name[id])
  8699. db_ammopacks[db_slot_i] = db_ammopacks[id]
  8700. db_zombieclass[db_slot_i] = db_zombieclass[id]
  8701. db_slot_i++
  8702. }
  8703.  
  8704. // Now save the current player stats
  8705. copy(db_name[id], charsmax(db_name[]), g_playername[id]) // name
  8706. db_ammopacks[id] = g_ammopacks[id] // ammo packs
  8707. db_zombieclass[id] = g_zombieclassnext[id] // zombie class
  8708. }
  8709.  
  8710. // Load player's stats from database (if a record is found)
  8711. load_stats(id)
  8712. {
  8713. // Look for a matching record
  8714. static i
  8715. for (i = 0; i < sizeof db_name; i++)
  8716. {
  8717. if (equal(g_playername[id], db_name[i]))
  8718. {
  8719. // Bingo!
  8720. g_ammopacks[id] = db_ammopacks[i]
  8721. g_zombieclass[id] = db_zombieclass[i]
  8722. g_zombieclassnext[id] = db_zombieclass[i]
  8723. return;
  8724. }
  8725. }
  8726. }
  8727.  
  8728. // Checks if a player is allowed to be zombie
  8729. allowed_zombie(id)
  8730. {
  8731. if ((g_zombie[id] && !g_nemesis[id]) || g_endround || !g_isalive[id] || task_exists(TASK_WELCOMEMSG) || (!g_newround && !g_zombie[id] && fnGetHumans() == 1))
  8732. return false;
  8733.  
  8734. return true;
  8735. }
  8736.  
  8737. // Checks if a player is allowed to be human
  8738. allowed_human(id)
  8739. {
  8740. if ((!g_zombie[id] && !g_survivor[id]) || g_endround || !g_isalive[id] || task_exists(TASK_WELCOMEMSG) || (!g_newround && g_zombie[id] && fnGetZombies() == 1))
  8741. return false;
  8742.  
  8743. return true;
  8744. }
  8745.  
  8746. // Checks if a player is allowed to be survivor
  8747. allowed_survivor(id)
  8748. {
  8749. if (g_endround || g_survivor[id] || !g_isalive[id] || task_exists(TASK_WELCOMEMSG) || (!g_newround && g_zombie[id] && fnGetZombies() == 1))
  8750. return false;
  8751.  
  8752. return true;
  8753. }
  8754.  
  8755. // Checks if a player is allowed to be nemesis
  8756. allowed_nemesis(id)
  8757. {
  8758. if (g_endround || g_nemesis[id] || !g_isalive[id] || task_exists(TASK_WELCOMEMSG) || (!g_newround && !g_zombie[id] && fnGetHumans() == 1))
  8759. return false;
  8760.  
  8761. return true;
  8762. }
  8763.  
  8764. // Checks if a player is allowed to respawn
  8765. allowed_respawn(id)
  8766. {
  8767. static team
  8768. team = fm_cs_get_user_team(id)
  8769.  
  8770. if (g_endround || team == FM_CS_TEAM_SPECTATOR || team == FM_CS_TEAM_UNASSIGNED || g_isalive[id])
  8771. return false;
  8772.  
  8773. return true;
  8774. }
  8775.  
  8776. // Checks if swarm mode is allowed
  8777. allowed_swarm()
  8778. {
  8779. if (g_endround || !g_newround || task_exists(TASK_WELCOMEMSG))
  8780. return false;
  8781.  
  8782. return true;
  8783. }
  8784.  
  8785. // Checks if multi infection mode is allowed
  8786. allowed_multi()
  8787. {
  8788. if (g_endround || !g_newround || task_exists(TASK_WELCOMEMSG) || floatround(fnGetAlive()*get_pcvar_float(cvar_multiratio), floatround_ceil) < 2 || floatround(fnGetAlive()*get_pcvar_float(cvar_multiratio), floatround_ceil) >= fnGetAlive())
  8789. return false;
  8790.  
  8791. return true;
  8792. }
  8793.  
  8794. // Checks if plague mode is allowed
  8795. allowed_plague()
  8796. {
  8797. if (g_endround || !g_newround || task_exists(TASK_WELCOMEMSG) || floatround((fnGetAlive()-(get_pcvar_num(cvar_plaguenemnum)+get_pcvar_num(cvar_plaguesurvnum)))*get_pcvar_float(cvar_plagueratio), floatround_ceil) < 1
  8798. || fnGetAlive()-(get_pcvar_num(cvar_plaguesurvnum)+get_pcvar_num(cvar_plaguenemnum)+floatround((fnGetAlive()-(get_pcvar_num(cvar_plaguenemnum)+get_pcvar_num(cvar_plaguesurvnum)))*get_pcvar_float(cvar_plagueratio), floatround_ceil)) < 1)
  8799. return false;
  8800.  
  8801. return true;
  8802. }
  8803.  
  8804. // Admin Command. zp_zombie
  8805. command_zombie(id, player)
  8806. {
  8807. // Show activity?
  8808. switch (get_pcvar_num(cvar_showactivity))
  8809. {
  8810. case 1: color_print(0, "^4ADMIN - ^3%s ^1%L", g_playername[player], LANG_PLAYER, "CMD_INFECT")
  8811. case 2: color_print(0, "^4ADMIN ^3%s - ^4%s ^1%L", g_playername[id], g_playername[player], LANG_PLAYER, "CMD_INFECT")
  8812. }
  8813.  
  8814. // Log to Zombie Plague log file?
  8815. if (get_pcvar_num(cvar_logcommands))
  8816. {
  8817. static logdata[100], authid[32], ip[16]
  8818. get_user_authid(id, authid, charsmax(authid))
  8819. get_user_ip(id, ip, charsmax(ip), 1)
  8820. formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %s %L (Players: %d/%d)", g_playername[id], authid, ip, g_playername[player], LANG_SERVER, "CMD_INFECT", fnGetPlaying(), g_maxplayers)
  8821. log_to_file("zombieplague.log", logdata)
  8822. }
  8823.  
  8824. // New round?
  8825. if (g_newround)
  8826. {
  8827. // Set as first zombie
  8828. remove_task(TASK_MAKEZOMBIE)
  8829. make_a_zombie(MODE_INFECTION, player)
  8830. }
  8831. else
  8832. {
  8833. // Just infect
  8834. zombieme(player, 0, 0, 0, 0)
  8835. }
  8836. }
  8837.  
  8838. // Admin Command. zp_human
  8839. command_human(id, player)
  8840. {
  8841. // Show activity?
  8842. switch (get_pcvar_num(cvar_showactivity))
  8843. {
  8844. case 1: color_print(0, "^4ADMIN - ^3%s ^1%L", g_playername[player], LANG_PLAYER, "CMD_DISINFECT")
  8845. case 2: color_print(0, "^4ADMIN ^3%s - ^4%s ^1%L", g_playername[id], g_playername[player], LANG_PLAYER, "CMD_DISINFECT")
  8846. }
  8847.  
  8848. // Log to Zombie Plague log file?
  8849. if (get_pcvar_num(cvar_logcommands))
  8850. {
  8851. static logdata[100], authid[32], ip[16]
  8852. get_user_authid(id, authid, charsmax(authid))
  8853. get_user_ip(id, ip, charsmax(ip), 1)
  8854. formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %s %L (Players: %d/%d)", g_playername[id], authid, ip, g_playername[player], LANG_SERVER,"CMD_DISINFECT", fnGetPlaying(), g_maxplayers)
  8855. log_to_file("zombieplague.log", logdata)
  8856. }
  8857.  
  8858. // Turn to human
  8859. humanme(player, 0, 0)
  8860. }
  8861.  
  8862. // Admin Command. zp_survivor
  8863. command_survivor(id, player)
  8864. {
  8865. // Show activity?
  8866. switch (get_pcvar_num(cvar_showactivity))
  8867. {
  8868. case 1: color_print(0, "^4ADMIN - ^3%s ^1%L", g_playername[player], LANG_PLAYER, "CMD_SURVIVAL")
  8869. case 2: color_print(0, "^4ADMIN ^3%s - ^4%s ^1%L", g_playername[id], g_playername[player], LANG_PLAYER, "CMD_SURVIVAL")
  8870. }
  8871.  
  8872. // Log to Zombie Plague log file?
  8873. if (get_pcvar_num(cvar_logcommands))
  8874. {
  8875. static logdata[100], authid[32], ip[16]
  8876. get_user_authid(id, authid, charsmax(authid))
  8877. get_user_ip(id, ip, charsmax(ip), 1)
  8878. formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %s %L (Players: %d/%d)", g_playername[id], authid, ip, g_playername[player], LANG_SERVER,"CMD_SURVIVAL", fnGetPlaying(), g_maxplayers)
  8879. log_to_file("zombieplague.log", logdata)
  8880. }
  8881.  
  8882. // New round?
  8883. if (g_newround)
  8884. {
  8885. // Set as first survivor
  8886. remove_task(TASK_MAKEZOMBIE)
  8887. make_a_zombie(MODE_SURVIVOR, player)
  8888. }
  8889. else
  8890. {
  8891. // Turn player into a Survivor
  8892. humanme(player, 1, 0)
  8893. }
  8894. }
  8895.  
  8896. // Admin Command. zp_nemesis
  8897. command_nemesis(id, player)
  8898. {
  8899. // Show activity?
  8900. switch (get_pcvar_num(cvar_showactivity))
  8901. {
  8902. case 1: color_print(0, "^4ADMIN - ^3%s ^1%L", g_playername[player], LANG_PLAYER, "CMD_NEMESIS")
  8903. case 2: color_print(0, "^4ADMIN ^3%s - ^4%s ^1%L", g_playername[id], g_playername[player], LANG_PLAYER, "CMD_NEMESIS")
  8904. }
  8905.  
  8906. // Log to Zombie Plague log file?
  8907. if (get_pcvar_num(cvar_logcommands))
  8908. {
  8909. static logdata[100], authid[32], ip[16]
  8910. get_user_authid(id, authid, charsmax(authid))
  8911. get_user_ip(id, ip, charsmax(ip), 1)
  8912. formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %s %L (Players: %d/%d)", g_playername[id], authid, ip, g_playername[player], LANG_SERVER,"CMD_NEMESIS", fnGetPlaying(), g_maxplayers)
  8913. log_to_file("zombieplague.log", logdata)
  8914. }
  8915.  
  8916. // New round?
  8917. if (g_newround)
  8918. {
  8919. // Set as first nemesis
  8920. remove_task(TASK_MAKEZOMBIE)
  8921. make_a_zombie(MODE_NEMESIS, player)
  8922. }
  8923. else
  8924. {
  8925. // Turn player into a Nemesis
  8926. zombieme(player, 0, 1, 0, 0)
  8927. }
  8928. }
  8929.  
  8930. // Admin Command. zp_respawn
  8931. command_respawn(id, player)
  8932. {
  8933. // Show activity?
  8934. switch (get_pcvar_num(cvar_showactivity))
  8935. {
  8936. case 1: color_print(0, "^4ADMIN - ^3%s ^1%L", g_playername[player], LANG_PLAYER, "CMD_RESPAWN")
  8937. case 2: color_print(0, "^4ADMIN ^3%s - ^4%s ^1%L", g_playername[id], g_playername[player], LANG_PLAYER, "CMD_RESPAWN")
  8938. }
  8939.  
  8940. // Log to Zombie Plague log file?
  8941. if (get_pcvar_num(cvar_logcommands))
  8942. {
  8943. static logdata[100], authid[32], ip[16]
  8944. get_user_authid(id, authid, charsmax(authid))
  8945. get_user_ip(id, ip, charsmax(ip), 1)
  8946. formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %s %L (Players: %d/%d)", g_playername[id], authid, ip, g_playername[player], LANG_SERVER, "CMD_RESPAWN", fnGetPlaying(), g_maxplayers)
  8947. log_to_file("zombieplague.log", logdata)
  8948. }
  8949.  
  8950. // Respawn as zombie?
  8951. if (get_pcvar_num(cvar_deathmatch) == 2 || (get_pcvar_num(cvar_deathmatch) == 3 && random_num(0, 1)) || (get_pcvar_num(cvar_deathmatch) == 4 && fnGetZombies() < fnGetAlive()/2))
  8952. g_respawn_as_zombie[player] = true
  8953.  
  8954. // Override respawn as zombie setting on nemesis and survivor rounds
  8955. if (g_survround) g_respawn_as_zombie[player] = true
  8956. else if (g_nemround) g_respawn_as_zombie[player] = false
  8957.  
  8958. respawn_player_manually(player);
  8959. }
  8960.  
  8961. // Admin Command. zp_swarm
  8962. command_swarm(id)
  8963. {
  8964. // Show activity?
  8965. switch (get_pcvar_num(cvar_showactivity))
  8966. {
  8967. case 1: color_print(0, "^4ADMIN - ^1%L", LANG_PLAYER, "CMD_SWARM")
  8968. case 2: color_print(0, "^4ADMIN %s - ^1%L", g_playername[id], LANG_PLAYER, "CMD_SWARM")
  8969. }
  8970.  
  8971. // Log to Zombie Plague log file?
  8972. if (get_pcvar_num(cvar_logcommands))
  8973. {
  8974. static logdata[100], authid[32], ip[16]
  8975. get_user_authid(id, authid, charsmax(authid))
  8976. get_user_ip(id, ip, charsmax(ip), 1)
  8977. formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %L (Players: %d/%d)", g_playername[id], authid, ip, LANG_SERVER, "CMD_SWARM", fnGetPlaying(), g_maxplayers)
  8978. log_to_file("zombieplague.log", logdata)
  8979. }
  8980.  
  8981. // Call Swarm Mode
  8982. remove_task(TASK_MAKEZOMBIE)
  8983. make_a_zombie(MODE_SWARM, 0)
  8984. }
  8985.  
  8986. // Admin Command. zp_multi
  8987. command_multi(id)
  8988. {
  8989. // Show activity?
  8990. switch (get_pcvar_num(cvar_showactivity))
  8991. {
  8992. case 1: color_print(0, "^4ADMIN - ^1%L", LANG_PLAYER, "CMD_MULTI")
  8993. case 2: color_print(0, "^4ADMIN ^3%s - ^1%L", g_playername[id], LANG_PLAYER, "CMD_MULTI")
  8994. }
  8995.  
  8996. // Log to Zombie Plague log file?
  8997. if (get_pcvar_num(cvar_logcommands))
  8998. {
  8999. static logdata[100], authid[32], ip[16]
  9000. get_user_authid(id, authid, charsmax(authid))
  9001. get_user_ip(id, ip, charsmax(ip), 1)
  9002. formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %L (Players: %d/%d)", g_playername[id], authid, ip, LANG_SERVER,"CMD_MULTI", fnGetPlaying(), g_maxplayers)
  9003. log_to_file("zombieplague.log", logdata)
  9004. }
  9005.  
  9006. // Call Multi Infection
  9007. remove_task(TASK_MAKEZOMBIE)
  9008. make_a_zombie(MODE_MULTI, 0)
  9009. }
  9010.  
  9011. // Admin Command. zp_plague
  9012. command_plague(id)
  9013. {
  9014. // Show activity?
  9015. switch (get_pcvar_num(cvar_showactivity))
  9016. {
  9017. case 1: color_print(0, "^4ADMIN - ^1%L", LANG_PLAYER, "CMD_PLAGUE")
  9018. case 2: color_print(0, "^4ADMIN ^3%s - ^1%L", g_playername[id], LANG_PLAYER, "CMD_PLAGUE")
  9019. }
  9020.  
  9021. // Log to Zombie Plague log file?
  9022. if (get_pcvar_num(cvar_logcommands))
  9023. {
  9024. static logdata[100], authid[32], ip[16]
  9025. get_user_authid(id, authid, charsmax(authid))
  9026. get_user_ip(id, ip, charsmax(ip), 1)
  9027. formatex(logdata, charsmax(logdata), "ADMIN %s <%s><%s> - %L (Players: %d/%d)", g_playername[id], authid, ip, LANG_SERVER,"CMD_PLAGUE", fnGetPlaying(), g_maxplayers)
  9028. log_to_file("zombieplague.log", logdata)
  9029. }
  9030.  
  9031. // Call Plague Mode
  9032. remove_task(TASK_MAKEZOMBIE)
  9033. make_a_zombie(MODE_PLAGUE, 0)
  9034. }
  9035.  
  9036. // Set proper maxspeed for player
  9037. set_player_maxspeed(id)
  9038. {
  9039. // If frozen, prevent from moving
  9040. if (g_frozen[id])
  9041. {
  9042. set_pev(id, pev_maxspeed, 1.0)
  9043. }
  9044. // Otherwise, set maxspeed directly
  9045. else
  9046. {
  9047. if (g_zombie[id])
  9048. {
  9049. if (g_nemesis[id])
  9050. set_pev(id, pev_maxspeed, get_pcvar_float(cvar_nemspd))
  9051. else
  9052. set_pev(id, pev_maxspeed, g_zombie_spd[id])
  9053. }
  9054. else
  9055. {
  9056. if (g_survivor[id])
  9057. set_pev(id, pev_maxspeed, get_pcvar_float(cvar_survspd))
  9058. else if (get_pcvar_float(cvar_humanspd) > 0.0)
  9059. set_pev(id, pev_maxspeed, get_pcvar_float(cvar_humanspd))
  9060. }
  9061. }
  9062. }
  9063.  
  9064. /*================================================================================
  9065. [Custom Natives]
  9066. =================================================================================*/
  9067.  
  9068. // Native: zp_get_user_zombie
  9069. public native_get_user_zombie(id)
  9070. {
  9071. if (!is_user_valid(id))
  9072. {
  9073. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9074. return -1;
  9075. }
  9076.  
  9077. return g_zombie[id];
  9078. }
  9079.  
  9080. // Native: zp_get_user_nemesis
  9081. public native_get_user_nemesis(id)
  9082. {
  9083. if (!is_user_valid(id))
  9084. {
  9085. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9086. return -1;
  9087. }
  9088.  
  9089. return g_nemesis[id];
  9090. }
  9091.  
  9092. // Native: zp_get_user_survivor
  9093. public native_get_user_survivor(id)
  9094. {
  9095. if (!is_user_valid(id))
  9096. {
  9097. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9098. return -1;
  9099. }
  9100.  
  9101. return g_survivor[id];
  9102. }
  9103.  
  9104. public native_get_user_first_zombie(id)
  9105. {
  9106. if (!is_user_valid(id))
  9107. {
  9108. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9109. return -1;
  9110. }
  9111.  
  9112. return g_firstzombie[id];
  9113. }
  9114.  
  9115. // Native: zp_get_user_last_zombie
  9116. public native_get_user_last_zombie(id)
  9117. {
  9118. if (!is_user_valid(id))
  9119. {
  9120. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9121. return -1;
  9122. }
  9123.  
  9124. return g_lastzombie[id];
  9125. }
  9126.  
  9127. // Native: zp_get_user_last_human
  9128. public native_get_user_last_human(id)
  9129. {
  9130. if (!is_user_valid(id))
  9131. {
  9132. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9133. return -1;
  9134. }
  9135.  
  9136. return g_lasthuman[id];
  9137. }
  9138.  
  9139. // Native: zp_get_user_zombie_class
  9140. public native_get_user_zombie_class(id)
  9141. {
  9142. if (!is_user_valid(id))
  9143. {
  9144. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9145. return -1;
  9146. }
  9147.  
  9148. return g_zombieclass[id];
  9149. }
  9150.  
  9151. // Native: zp_get_user_next_class
  9152. public native_get_user_next_class(id)
  9153. {
  9154. if (!is_user_valid(id))
  9155. {
  9156. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9157. return -1;
  9158. }
  9159.  
  9160. return g_zombieclassnext[id];
  9161. }
  9162.  
  9163. // Native: zp_set_user_zombie_class
  9164. public native_set_user_zombie_class(id, classid)
  9165. {
  9166. if (!is_user_valid(id))
  9167. {
  9168. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9169. return false;
  9170. }
  9171.  
  9172. if (classid < 0 || classid >= g_zclass_i)
  9173. {
  9174. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid zombie class id (%d)", classid)
  9175. return false;
  9176. }
  9177.  
  9178. g_zombieclassnext[id] = classid
  9179. return true;
  9180. }
  9181.  
  9182. // Native: zp_get_user_ammo_packs
  9183. public native_get_user_ammo_packs(id)
  9184. {
  9185. if (!is_user_valid(id))
  9186. {
  9187. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9188. return -1;
  9189. }
  9190.  
  9191. return g_ammopacks[id];
  9192. }
  9193.  
  9194. // Native: zp_set_user_ammo_packs
  9195. public native_set_user_ammo_packs(id, amount)
  9196. {
  9197. if (!is_user_valid(id))
  9198. {
  9199. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9200. return false;
  9201. }
  9202.  
  9203. g_ammopacks[id] = amount;
  9204. return true;
  9205. }
  9206.  
  9207. // Native: zp_get_zombie_maxhealth
  9208. public native_get_zombie_maxhealth(id)
  9209. {
  9210. // ZP disabled
  9211. if (!g_pluginenabled)
  9212. return -1;
  9213.  
  9214. if (!is_user_valid(id))
  9215. {
  9216. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9217. return -1;
  9218. }
  9219.  
  9220. if (!g_zombie[id] || g_nemesis[id])
  9221. {
  9222. log_error(AMX_ERR_NATIVE, "[ZP-New] Player not a normal zombie (%d)", id)
  9223. return -1;
  9224. }
  9225.  
  9226. if (g_firstzombie[id])
  9227. return floatround(float(ArrayGetCell(g_zclass_hp, g_zombieclass[id])) * get_pcvar_float(cvar_zombiefirsthp));
  9228.  
  9229. return ArrayGetCell(g_zclass_hp, g_zombieclass[id]);
  9230. }
  9231.  
  9232. // Native: zp_get_user_batteries
  9233. public native_get_user_batteries(id)
  9234. {
  9235. if (!is_user_valid(id))
  9236. {
  9237. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9238. return -1;
  9239. }
  9240.  
  9241. return g_flashbattery[id];
  9242. }
  9243.  
  9244. // Native: zp_set_user_batteries
  9245. public native_set_user_batteries(id, value)
  9246. {
  9247. // ZP disabled
  9248. if (!g_pluginenabled)
  9249. return false;
  9250.  
  9251. if (!is_user_valid_connected(id))
  9252. {
  9253. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9254. return false;
  9255. }
  9256.  
  9257. g_flashbattery[id] = clamp(value, 0, 100);
  9258.  
  9259. if (g_cached_customflash)
  9260. {
  9261. // Set the flashlight charge task to update battery status
  9262. remove_task(id+TASK_CHARGE)
  9263. set_task(1.0, "flashlight_charge", id+TASK_CHARGE, _, _, "b")
  9264. }
  9265. return true;
  9266. }
  9267.  
  9268. // Native: zp_get_user_nightvision
  9269. public native_get_user_nightvision(id)
  9270. {
  9271. if (!is_user_valid(id))
  9272. {
  9273. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9274. return -1;
  9275. }
  9276.  
  9277. return g_nvision[id];
  9278. }
  9279.  
  9280. // Native: zp_set_user_nightvision
  9281. public native_set_user_nightvision(id, set)
  9282. {
  9283. // ZP disabled
  9284. if (!g_pluginenabled)
  9285. return false;
  9286.  
  9287. if (!is_user_valid_connected(id))
  9288. {
  9289. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9290. return false;
  9291. }
  9292.  
  9293. if (set)
  9294. {
  9295. g_nvision[id] = true
  9296.  
  9297. if (!g_isbot[id])
  9298. {
  9299. g_nvisionenabled[id] = true
  9300.  
  9301. // Custom nvg?
  9302. if (get_pcvar_num(cvar_customnvg))
  9303. {
  9304. remove_task(id+TASK_NVISION)
  9305. set_task(0.1, "set_user_nvision", id+TASK_NVISION, _, _, "b")
  9306. }
  9307. else
  9308. set_user_gnvision(id, 1)
  9309. }
  9310. else
  9311. cs_set_user_nvg(id, 1)
  9312. }
  9313. else
  9314. {
  9315. // Remove CS nightvision if player owns one (bugfix)
  9316. cs_set_user_nvg(id, 0)
  9317.  
  9318. if (get_pcvar_num(cvar_customnvg)) remove_task(id+TASK_NVISION)
  9319. else if (g_nvisionenabled[id]) set_user_gnvision(id, 0)
  9320. g_nvision[id] = false
  9321. g_nvisionenabled[id] = false
  9322. }
  9323. return true;
  9324. }
  9325.  
  9326. // Native: zp_infect_user
  9327. public native_infect_user(id, infector, silent, rewards)
  9328. {
  9329. // ZP disabled
  9330. if (!g_pluginenabled)
  9331. return false;
  9332.  
  9333. if (!is_user_valid_alive(id))
  9334. {
  9335. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9336. return false;
  9337. }
  9338.  
  9339. // Not allowed to be zombie
  9340. if (!allowed_zombie(id))
  9341. return false;
  9342.  
  9343. // New round?
  9344. if (g_newround)
  9345. {
  9346. // Set as first zombie
  9347. remove_task(TASK_MAKEZOMBIE)
  9348. make_a_zombie(MODE_INFECTION, id)
  9349. }
  9350. else
  9351. {
  9352. // Just infect (plus some checks)
  9353. zombieme(id, is_user_valid_alive(infector) ? infector : 0, 0, (silent == 1) ? 1 : 0, (rewards == 1) ? 1 : 0)
  9354. }
  9355. return true;
  9356. }
  9357.  
  9358. // Native: zp_disinfect_user
  9359. public native_disinfect_user(id, silent)
  9360. {
  9361. // ZP disabled
  9362. if (!g_pluginenabled)
  9363. return false;
  9364.  
  9365. if (!is_user_valid_alive(id))
  9366. {
  9367. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9368. return false;
  9369. }
  9370.  
  9371. // Not allowed to be human
  9372. if (!allowed_human(id))
  9373. return false;
  9374.  
  9375. // Turn to human
  9376. humanme(id, 0, (silent == 1) ? 1 : 0)
  9377. return true;
  9378. }
  9379.  
  9380. // Native: zp_make_user_nemesis
  9381. public native_make_user_nemesis(id)
  9382. {
  9383. // ZP disabled
  9384. if (!g_pluginenabled)
  9385. return false;
  9386.  
  9387. if (!is_user_valid_alive(id))
  9388. {
  9389. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9390. return false;
  9391. }
  9392.  
  9393. // Not allowed to be nemesis
  9394. if (!allowed_nemesis(id))
  9395. return false;
  9396.  
  9397. // New round?
  9398. if (g_newround)
  9399. {
  9400. // Set as first nemesis
  9401. remove_task(TASK_MAKEZOMBIE)
  9402. make_a_zombie(MODE_NEMESIS, id)
  9403. }
  9404. else
  9405. {
  9406. // Turn player into a Nemesis
  9407. zombieme(id, 0, 1, 0, 0)
  9408. }
  9409. return true;
  9410. }
  9411.  
  9412. // Native: zp_make_user_survivor
  9413. public native_make_user_survivor(id)
  9414. {
  9415. // ZP disabled
  9416. if (!g_pluginenabled)
  9417. return false;
  9418.  
  9419. if (!is_user_valid_alive(id))
  9420. {
  9421. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9422. return false;
  9423. }
  9424.  
  9425. // Not allowed to be survivor
  9426. if (!allowed_survivor(id))
  9427. return false;
  9428.  
  9429. // New round?
  9430. if (g_newround)
  9431. {
  9432. // Set as first survivor
  9433. remove_task(TASK_MAKEZOMBIE)
  9434. make_a_zombie(MODE_SURVIVOR, id)
  9435. }
  9436. else
  9437. {
  9438. // Turn player into a Survivor
  9439. humanme(id, 1, 0)
  9440. }
  9441.  
  9442. return true;
  9443. }
  9444.  
  9445. // Native: zp_respawn_user
  9446. public native_respawn_user(id, team)
  9447. {
  9448. // ZP disabled
  9449. if (!g_pluginenabled)
  9450. return false;
  9451.  
  9452. if (!is_user_valid_connected(id))
  9453. {
  9454. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9455. return false;
  9456. }
  9457.  
  9458. // Respawn not allowed
  9459. if (!allowed_respawn(id))
  9460. return false;
  9461.  
  9462. // Respawn as zombie?
  9463. g_respawn_as_zombie[id] = (team == ZP_TEAM_ZOMBIE) ? true : false
  9464.  
  9465. // Respawnish!
  9466. respawn_player_manually(id)
  9467. return true;
  9468. }
  9469.  
  9470. // Native: zp_force_buy_extra_item
  9471. public native_force_buy_extra_item(id, itemid, ignorecost)
  9472. {
  9473. // ZP disabled
  9474. if (!g_pluginenabled)
  9475. return false;
  9476.  
  9477. if (!is_user_valid_alive(id))
  9478. {
  9479. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9480. return false;
  9481. }
  9482.  
  9483. if (itemid < 0 || itemid >= g_extraitem_i)
  9484. {
  9485. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid extra item id (%d)", itemid)
  9486. return false;
  9487. }
  9488.  
  9489. buy_extra_item(id, itemid, ignorecost)
  9490. return true;
  9491. }
  9492.  
  9493. // Native: zp_override_user_model
  9494. public native_override_user_model(id, const newmodel[], modelindex)
  9495. {
  9496. // ZP disabled
  9497. if (!g_pluginenabled)
  9498. return false;
  9499.  
  9500. if (!is_user_valid_connected(id))
  9501. {
  9502. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid Player (%d)", id)
  9503. return false;
  9504. }
  9505.  
  9506. // Strings passed byref
  9507. param_convert(2)
  9508.  
  9509. // Remove previous tasks
  9510. remove_task(id+TASK_MODEL)
  9511.  
  9512. // Custom models stuff
  9513. static currentmodel[32]
  9514.  
  9515. if (g_handle_models_on_separate_ent)
  9516. {
  9517. // Set the right model
  9518. copy(g_playermodel[id], charsmax(g_playermodel[]), newmodel)
  9519. if (g_set_modelindex_offset && modelindex) fm_cs_set_user_model_index(id, modelindex)
  9520.  
  9521. // Set model on player model entity
  9522. fm_set_playermodel_ent(id)
  9523. }
  9524. else
  9525. {
  9526. // Get current model for comparing it with the current one
  9527. fm_cs_get_user_model(id, currentmodel, charsmax(currentmodel))
  9528.  
  9529. // Set the right model, after checking that we don't already have it
  9530. if (!equal(currentmodel, newmodel))
  9531. {
  9532. copy(g_playermodel[id], charsmax(g_playermodel[]), newmodel)
  9533. if (g_set_modelindex_offset && modelindex) fm_cs_set_user_model_index(id, modelindex)
  9534.  
  9535. // An additional delay is offset at round start
  9536. // since SVC_BAD is more likely to be triggered there
  9537. if (g_newround)
  9538. set_task(5.0 * g_modelchange_delay, "fm_user_model_update", id+TASK_MODEL)
  9539. else
  9540. fm_user_model_update(id+TASK_MODEL)
  9541. }
  9542. }
  9543. return true;
  9544. }
  9545.  
  9546. // Native: zp_has_round_started
  9547. public native_has_round_started()
  9548. {
  9549. if (g_newround) return 0; // not started
  9550. if (g_modestarted) return 1; // started
  9551. return 2; // starting
  9552. }
  9553.  
  9554. // Native: zp_is_nemesis_round
  9555. public native_is_nemesis_round()
  9556. {
  9557. return g_nemround;
  9558. }
  9559.  
  9560. // Native: zp_is_survivor_round
  9561. public native_is_survivor_round()
  9562. {
  9563. return g_survround;
  9564. }
  9565.  
  9566. // Native: zp_is_swarm_round
  9567. public native_is_swarm_round()
  9568. {
  9569. return g_swarmround;
  9570. }
  9571.  
  9572. // Native: zp_is_plague_round
  9573. public native_is_plague_round()
  9574. {
  9575. return g_plagueround;
  9576. }
  9577.  
  9578. // Native: zp_get_zombie_count
  9579. public native_get_zombie_count()
  9580. {
  9581. return fnGetZombies();
  9582. }
  9583.  
  9584. // Native: zp_get_human_count
  9585. public native_get_human_count()
  9586. {
  9587. return fnGetHumans();
  9588. }
  9589.  
  9590. // Native: zp_get_nemesis_count
  9591. public native_get_nemesis_count()
  9592. {
  9593. return fnGetNemesis();
  9594. }
  9595.  
  9596. // Native: zp_get_survivor_count
  9597. public native_get_survivor_count()
  9598. {
  9599. return fnGetSurvivors();
  9600. }
  9601.  
  9602. // Native: zp_register_extra_item
  9603. public native_register_extra_item(const name[], cost, team)
  9604. {
  9605. // ZP disabled
  9606. if (!g_pluginenabled)
  9607. return -1;
  9608.  
  9609. // Strings passed byref
  9610. param_convert(1)
  9611.  
  9612. // Arrays not yet initialized
  9613. if (!g_arrays_created)
  9614. {
  9615. log_error(AMX_ERR_NATIVE, "[ZP-New] Can't register extra item yet (%s)", name)
  9616. return -1;
  9617. }
  9618.  
  9619. if (strlen(name) < 1)
  9620. {
  9621. log_error(AMX_ERR_NATIVE, "[ZP-New] Can't register extra item with an empty name")
  9622. return -1;
  9623. }
  9624.  
  9625. new index, extraitem_name[32]
  9626. for (index = 0; index < g_extraitem_i; index++)
  9627. {
  9628. ArrayGetString(g_extraitem_name, index, extraitem_name, charsmax(extraitem_name))
  9629. if (equali(name, extraitem_name))
  9630. {
  9631. log_error(AMX_ERR_NATIVE, "[ZP-New] Extra item already registered (%s)", name)
  9632. return -1;
  9633. }
  9634. }
  9635.  
  9636. // For backwards compatibility
  9637. if (team == ZP_TEAM_ANY)
  9638. team = (ZP_TEAM_ZOMBIE|ZP_TEAM_HUMAN)
  9639.  
  9640. // Add the item
  9641. ArrayPushString(g_extraitem_name, name)
  9642. ArrayPushCell(g_extraitem_cost, cost)
  9643. ArrayPushCell(g_extraitem_team, team)
  9644.  
  9645. // Set temporary new item flag
  9646. ArrayPushCell(g_extraitem_new, 1)
  9647.  
  9648. // Override extra items data with our customizations
  9649. new i, buffer[32], size = ArraySize(g_extraitem2_realname)
  9650. for (i = 0; i < size; i++)
  9651. {
  9652. ArrayGetString(g_extraitem2_realname, i, buffer, charsmax(buffer))
  9653.  
  9654. // Check if this is the intended item to override
  9655. if (!equal(name, buffer))
  9656. continue;
  9657.  
  9658. // Remove new item flag
  9659. ArraySetCell(g_extraitem_new, g_extraitem_i, 0)
  9660.  
  9661. // Replace caption
  9662. ArrayGetString(g_extraitem2_name, i, buffer, charsmax(buffer))
  9663. ArraySetString(g_extraitem_name, g_extraitem_i, buffer)
  9664.  
  9665. // Replace cost
  9666. buffer[0] = ArrayGetCell(g_extraitem2_cost, i)
  9667. ArraySetCell(g_extraitem_cost, g_extraitem_i, buffer[0])
  9668.  
  9669. // Replace team
  9670. buffer[0] = ArrayGetCell(g_extraitem2_team, i)
  9671. ArraySetCell(g_extraitem_team, g_extraitem_i, buffer[0])
  9672. }
  9673.  
  9674. // Increase registered items counter
  9675. g_extraitem_i++
  9676.  
  9677. // Return id under which we registered the item
  9678. return g_extraitem_i-1;
  9679. }
  9680.  
  9681. // Function: zp_register_extra_item (to be used within this plugin only)
  9682. native_register_extra_item2(const name[], cost, team)
  9683. {
  9684. // Add the item
  9685. ArrayPushString(g_extraitem_name, name)
  9686. ArrayPushCell(g_extraitem_cost, cost)
  9687. ArrayPushCell(g_extraitem_team, team)
  9688.  
  9689. // Set temporary new item flag
  9690. ArrayPushCell(g_extraitem_new, 1)
  9691.  
  9692. // Increase registered items counter
  9693. g_extraitem_i++
  9694. }
  9695.  
  9696. // Native: zp_register_zombie_class
  9697. public native_register_zombie_class(const name[], const info[], const model[], const clawmodel[], hp, speed, Float:gravity, Float:knockback)
  9698. {
  9699. // ZP disabled
  9700. if (!g_pluginenabled)
  9701. return -1;
  9702.  
  9703. // Strings passed byref
  9704. param_convert(1)
  9705. param_convert(2)
  9706. param_convert(3)
  9707. param_convert(4)
  9708.  
  9709. // Arrays not yet initialized
  9710. if (!g_arrays_created)
  9711. {
  9712. log_error(AMX_ERR_NATIVE, "[ZP-New] Can't register zombie class yet (%s)", name)
  9713. return -1;
  9714. }
  9715.  
  9716. if (strlen(name) < 1)
  9717. {
  9718. log_error(AMX_ERR_NATIVE, "[ZP-New] Can't register zombie class with an empty name")
  9719. return -1;
  9720. }
  9721.  
  9722. new index, zombieclass_name[32]
  9723. for (index = 0; index < g_zclass_i; index++)
  9724. {
  9725. ArrayGetString(g_zclass_name, index, zombieclass_name, charsmax(zombieclass_name))
  9726. if (equali(name, zombieclass_name))
  9727. {
  9728. log_error(AMX_ERR_NATIVE, "[ZP-New] Zombie class already registered (%s)", name)
  9729. return -1;
  9730. }
  9731. }
  9732.  
  9733. // Add the class
  9734. ArrayPushString(g_zclass_name, name)
  9735. ArrayPushString(g_zclass_info, info)
  9736.  
  9737. // Using same zombie models for all classes?
  9738. if (g_same_models_for_all)
  9739. {
  9740. ArrayPushCell(g_zclass_modelsstart, 0)
  9741. ArrayPushCell(g_zclass_modelsend, ArraySize(g_zclass_playermodel))
  9742. }
  9743. else
  9744. {
  9745. ArrayPushCell(g_zclass_modelsstart, ArraySize(g_zclass_playermodel))
  9746. ArrayPushString(g_zclass_playermodel, model)
  9747. ArrayPushCell(g_zclass_modelsend, ArraySize(g_zclass_playermodel))
  9748. ArrayPushCell(g_zclass_modelindex, -1)
  9749. }
  9750.  
  9751. ArrayPushString(g_zclass_clawmodel, clawmodel)
  9752. ArrayPushCell(g_zclass_hp, hp)
  9753. ArrayPushCell(g_zclass_spd, speed)
  9754. ArrayPushCell(g_zclass_grav, gravity)
  9755. ArrayPushCell(g_zclass_kb, knockback)
  9756.  
  9757. // Set temporary new class flag
  9758. ArrayPushCell(g_zclass_new, 1)
  9759.  
  9760. // Override zombie classes data with our customizations
  9761. new i, k, buffer[32], Float:buffer2, nummodels_custom, nummodels_default, prec_mdl[100], size = ArraySize(g_zclass2_realname)
  9762. for (i = 0; i < size; i++)
  9763. {
  9764. ArrayGetString(g_zclass2_realname, i, buffer, charsmax(buffer))
  9765.  
  9766. // Check if this is the intended class to override
  9767. if (!equal(name, buffer))
  9768. continue;
  9769.  
  9770. // Remove new class flag
  9771. ArraySetCell(g_zclass_new, g_zclass_i, 0)
  9772.  
  9773. // Replace caption
  9774. ArrayGetString(g_zclass2_name, i, buffer, charsmax(buffer))
  9775. ArraySetString(g_zclass_name, g_zclass_i, buffer)
  9776.  
  9777. // Replace info
  9778. ArrayGetString(g_zclass2_info, i, buffer, charsmax(buffer))
  9779. ArraySetString(g_zclass_info, g_zclass_i, buffer)
  9780.  
  9781. // Replace models, unless using same models for all classes
  9782. if (!g_same_models_for_all)
  9783. {
  9784. nummodels_custom = ArrayGetCell(g_zclass2_modelsend, i) - ArrayGetCell(g_zclass2_modelsstart, i)
  9785. nummodels_default = ArrayGetCell(g_zclass_modelsend, g_zclass_i) - ArrayGetCell(g_zclass_modelsstart, g_zclass_i)
  9786.  
  9787. // Replace each player model and model index
  9788. for (k = 0; k < min(nummodels_custom, nummodels_default); k++)
  9789. {
  9790. ArrayGetString(g_zclass2_playermodel, ArrayGetCell(g_zclass2_modelsstart, i) + k, buffer, charsmax(buffer))
  9791. ArraySetString(g_zclass_playermodel, ArrayGetCell(g_zclass_modelsstart, g_zclass_i) + k, buffer)
  9792.  
  9793. // Precache player model and replace its modelindex with the real one
  9794. formatex(prec_mdl, charsmax(prec_mdl), "models/player/%s/%s.mdl", buffer, buffer)
  9795. ArraySetCell(g_zclass_modelindex, ArrayGetCell(g_zclass_modelsstart, g_zclass_i) + k, engfunc(EngFunc_PrecacheModel, prec_mdl))
  9796. if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, prec_mdl)
  9797. if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, prec_mdl)
  9798. // Precache modelT.mdl files too
  9799. copy(prec_mdl[strlen(prec_mdl)-4], charsmax(prec_mdl) - (strlen(prec_mdl)-4), "T.mdl")
  9800. if (file_exists(prec_mdl)) engfunc(EngFunc_PrecacheModel, prec_mdl)
  9801. }
  9802.  
  9803. // We have more custom models than what we can accommodate,
  9804. // Let's make some space...
  9805. if (nummodels_custom > nummodels_default)
  9806. {
  9807. for (k = nummodels_default; k < nummodels_custom; k++)
  9808. {
  9809. ArrayGetString(g_zclass2_playermodel, ArrayGetCell(g_zclass2_modelsstart, i) + k, buffer, charsmax(buffer))
  9810. ArrayInsertStringAfter(g_zclass_playermodel, ArrayGetCell(g_zclass_modelsstart, g_zclass_i) + k - 1, buffer)
  9811.  
  9812. // Precache player model and retrieve its modelindex
  9813. formatex(prec_mdl, charsmax(prec_mdl), "models/player/%s/%s.mdl", buffer, buffer)
  9814. ArrayInsertCellAfter(g_zclass_modelindex, ArrayGetCell(g_zclass_modelsstart, g_zclass_i) + k - 1, engfunc(EngFunc_PrecacheModel, prec_mdl))
  9815. if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, prec_mdl)
  9816. if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, prec_mdl)
  9817. // Precache modelT.mdl files too
  9818. copy(prec_mdl[strlen(prec_mdl)-4], charsmax(prec_mdl) - (strlen(prec_mdl)-4), "T.mdl")
  9819. if (file_exists(prec_mdl)) engfunc(EngFunc_PrecacheModel, prec_mdl)
  9820. }
  9821.  
  9822. // Fix models end index for this class
  9823. ArraySetCell(g_zclass_modelsend, g_zclass_i, ArrayGetCell(g_zclass_modelsend, g_zclass_i) + (nummodels_custom - nummodels_default))
  9824. }
  9825.  
  9826. /* --- Not needed since classes can't have more than 1 default model for now ---
  9827. // We have less custom models than what this class has by default,
  9828. // Get rid of those extra entries...
  9829. if (nummodels_custom < nummodels_default)
  9830. {
  9831. for (k = nummodels_custom; k < nummodels_default; k++)
  9832. {
  9833. ArrayDeleteItem(g_zclass_playermodel, ArrayGetCell(g_zclass_modelsstart, g_zclass_i) + nummodels_custom)
  9834. }
  9835.  
  9836. // Fix models end index for this class
  9837. ArraySetCell(g_zclass_modelsend, g_zclass_i, ArrayGetCell(g_zclass_modelsend, g_zclass_i) - (nummodels_default - nummodels_custom))
  9838. }
  9839. */
  9840. }
  9841.  
  9842. // Replace clawmodel
  9843. ArrayGetString(g_zclass2_clawmodel, i, buffer, charsmax(buffer))
  9844. ArraySetString(g_zclass_clawmodel, g_zclass_i, buffer)
  9845.  
  9846. // Precache clawmodel
  9847. formatex(prec_mdl, charsmax(prec_mdl), "models/zombie_plague/%s", buffer)
  9848. engfunc(EngFunc_PrecacheModel, prec_mdl)
  9849.  
  9850. // Replace health
  9851. buffer[0] = ArrayGetCell(g_zclass2_hp, i)
  9852. ArraySetCell(g_zclass_hp, g_zclass_i, buffer[0])
  9853.  
  9854. // Replace speed
  9855. buffer[0] = ArrayGetCell(g_zclass2_spd, i)
  9856. ArraySetCell(g_zclass_spd, g_zclass_i, buffer[0])
  9857.  
  9858. // Replace gravity
  9859. buffer2 = Float:ArrayGetCell(g_zclass2_grav, i)
  9860. ArraySetCell(g_zclass_grav, g_zclass_i, buffer2)
  9861.  
  9862. // Replace knockback
  9863. buffer2 = Float:ArrayGetCell(g_zclass2_kb, i)
  9864. ArraySetCell(g_zclass_kb, g_zclass_i, buffer2)
  9865. }
  9866.  
  9867. // If class was not overriden with customization data
  9868. if (ArrayGetCell(g_zclass_new, g_zclass_i))
  9869. {
  9870. // If not using same models for all classes
  9871. if (!g_same_models_for_all)
  9872. {
  9873. // Precache default class model and replace modelindex with the real one
  9874. formatex(prec_mdl, charsmax(prec_mdl), "models/player/%s/%s.mdl", model, model)
  9875. ArraySetCell(g_zclass_modelindex, ArrayGetCell(g_zclass_modelsstart, g_zclass_i), engfunc(EngFunc_PrecacheModel, prec_mdl))
  9876. if (g_force_consistency == 1) force_unmodified(force_model_samebounds, {0,0,0}, {0,0,0}, prec_mdl)
  9877. if (g_force_consistency == 2) force_unmodified(force_exactfile, {0,0,0}, {0,0,0}, prec_mdl)
  9878. // Precache modelT.mdl files too
  9879. copy(prec_mdl[strlen(prec_mdl)-4], charsmax(prec_mdl) - (strlen(prec_mdl)-4), "T.mdl")
  9880. if (file_exists(prec_mdl)) engfunc(EngFunc_PrecacheModel, prec_mdl)
  9881. }
  9882.  
  9883. // Precache default clawmodel
  9884. formatex(prec_mdl, charsmax(prec_mdl), "models/zombie_plague/%s", clawmodel)
  9885. engfunc(EngFunc_PrecacheModel, prec_mdl)
  9886. }
  9887.  
  9888. // Increase registered classes counter
  9889. g_zclass_i++
  9890.  
  9891. // Return id under which we registered the class
  9892. return g_zclass_i-1;
  9893. }
  9894.  
  9895. // Native: zp_get_extra_item_id
  9896. public native_get_extra_item_id(const name[])
  9897. {
  9898. // ZP disabled
  9899. if (!g_pluginenabled)
  9900. return -1;
  9901.  
  9902. // Strings passed byref
  9903. param_convert(1)
  9904.  
  9905. // Loop through every item (not using Tries since ZP should work on AMXX 1.8.0)
  9906. static i, item_name[32]
  9907. for (i = 0; i < g_extraitem_i; i++)
  9908. {
  9909. ArrayGetString(g_extraitem_name, i, item_name, charsmax(item_name))
  9910.  
  9911. // Check if this is the item to retrieve
  9912. if (equali(name, item_name))
  9913. return i;
  9914. }
  9915.  
  9916. return -1;
  9917. }
  9918.  
  9919. // Native: zp_get_zombie_class_id
  9920. public native_get_zombie_class_id(const name[])
  9921. {
  9922. // ZP disabled
  9923. if (!g_pluginenabled)
  9924. return -1;
  9925.  
  9926. // Strings passed byref
  9927. param_convert(1)
  9928.  
  9929. // Loop through every class (not using Tries since ZP should work on AMXX 1.8.0)
  9930. static i, class_name[32]
  9931. for (i = 0; i < g_zclass_i; i++)
  9932. {
  9933. ArrayGetString(g_zclass_name, i, class_name, charsmax(class_name))
  9934.  
  9935. // Check if this is the class to retrieve
  9936. if (equali(name, class_name))
  9937. return i;
  9938. }
  9939.  
  9940. return -1;
  9941. }
  9942.  
  9943. // Native: zp_get_zombie_class_info
  9944. public native_get_zombie_class_info(classid, info[], len)
  9945. {
  9946. // ZP disabled
  9947. if (!g_pluginenabled)
  9948. return false;
  9949.  
  9950. // Invalid class
  9951. if (classid < 0 || classid >= g_zclass_i)
  9952. {
  9953. log_error(AMX_ERR_NATIVE, "[ZP-New] Invalid zombie class id (%d)", classid)
  9954. return false;
  9955. }
  9956.  
  9957. // Strings passed byref
  9958. param_convert(2)
  9959.  
  9960. // Fetch zombie class info
  9961. ArrayGetString(g_zclass_info, classid, info, len)
  9962. return true;
  9963. }
  9964.  
  9965. /*================================================================================
  9966. [Custom Messages]
  9967. =================================================================================*/
  9968.  
  9969. // Custom Night Vision
  9970. public set_user_nvision(taskid)
  9971. {
  9972. // Get player's origin
  9973. static origin[3]
  9974. get_user_origin(ID_NVISION, origin)
  9975.  
  9976. // Nightvision message
  9977. message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, _, ID_NVISION)
  9978. write_byte(TE_DLIGHT) // TE id
  9979. write_coord(origin[0]) // x
  9980. write_coord(origin[1]) // y
  9981. write_coord(origin[2]) // z
  9982. write_byte(get_pcvar_num(cvar_nvgsize)) // radius
  9983.  
  9984. // Nemesis / Madness / Spectator in nemesis round
  9985. if (g_nemesis[ID_NVISION] || (g_zombie[ID_NVISION] && g_nodamage[ID_NVISION]) || (!g_isalive[ID_NVISION] && g_nemround))
  9986. {
  9987. write_byte(get_pcvar_num(cvar_nemnvgcolor[0])) // r
  9988. write_byte(get_pcvar_num(cvar_nemnvgcolor[1])) // g
  9989. write_byte(get_pcvar_num(cvar_nemnvgcolor[2])) // b
  9990. }
  9991. // Human / Spectator in normal round
  9992. else if (!g_zombie[ID_NVISION] || !g_isalive[ID_NVISION])
  9993. {
  9994. write_byte(get_pcvar_num(cvar_humnvgcolor[0])) // r
  9995. write_byte(get_pcvar_num(cvar_humnvgcolor[1])) // g
  9996. write_byte(get_pcvar_num(cvar_humnvgcolor[2])) // b
  9997. }
  9998. // Zombie
  9999. else
  10000. {
  10001. write_byte(get_pcvar_num(cvar_nvgcolor[0])) // r
  10002. write_byte(get_pcvar_num(cvar_nvgcolor[1])) // g
  10003. write_byte(get_pcvar_num(cvar_nvgcolor[2])) // b
  10004. }
  10005.  
  10006. write_byte(2) // life
  10007. write_byte(0) // decay rate
  10008. message_end()
  10009. }
  10010.  
  10011. // Game Nightvision
  10012. set_user_gnvision(id, toggle)
  10013. {
  10014. // Toggle NVG message
  10015. message_begin(MSG_ONE, g_msgNVGToggle, _, id)
  10016. write_byte(toggle) // toggle
  10017. message_end()
  10018. }
  10019.  
  10020. // Custom Flashlight
  10021. public set_user_flashlight(taskid)
  10022. {
  10023. // Get player and aiming origins
  10024. static Float:originF[3], Float:destoriginF[3]
  10025. pev(ID_FLASH, pev_origin, originF)
  10026. fm_get_aim_origin(ID_FLASH, destoriginF)
  10027.  
  10028. // Max distance check
  10029. if (get_distance_f(originF, destoriginF) > get_pcvar_float(cvar_flashdist))
  10030. return;
  10031.  
  10032. // Send to all players?
  10033. if (get_pcvar_num(cvar_flashshowall))
  10034. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, destoriginF, 0)
  10035. else
  10036. message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, _, ID_FLASH)
  10037.  
  10038. // Flashlight
  10039. write_byte(TE_DLIGHT) // TE id
  10040. engfunc(EngFunc_WriteCoord, destoriginF[0]) // x
  10041. engfunc(EngFunc_WriteCoord, destoriginF[1]) // y
  10042. engfunc(EngFunc_WriteCoord, destoriginF[2]) // z
  10043. write_byte(get_pcvar_num(cvar_flashsize)) // radius
  10044. write_byte(get_pcvar_num(cvar_flashcolor[0])) // r
  10045. write_byte(get_pcvar_num(cvar_flashcolor[1])) // g
  10046. write_byte(get_pcvar_num(cvar_flashcolor[2])) // b
  10047. write_byte(3) // life
  10048. write_byte(0) // decay rate
  10049. message_end()
  10050. }
  10051.  
  10052. // Infection special effects
  10053. infection_effects(id)
  10054. {
  10055. // Screen fade? (unless frozen)
  10056. if (!g_frozen[id] && get_pcvar_num(cvar_infectionscreenfade))
  10057. {
  10058. message_begin(MSG_ONE_UNRELIABLE, g_msgScreenFade, _, id)
  10059. write_short(UNIT_SECOND) // duration
  10060. write_short(0) // hold time
  10061. write_short(FFADE_IN) // fade type
  10062. if (g_nemesis[id])
  10063. {
  10064. write_byte(get_pcvar_num(cvar_nemnvgcolor[0])) // r
  10065. write_byte(get_pcvar_num(cvar_nemnvgcolor[1])) // g
  10066. write_byte(get_pcvar_num(cvar_nemnvgcolor[2])) // b
  10067. }
  10068. else
  10069. {
  10070. write_byte(get_pcvar_num(cvar_nvgcolor[0])) // r
  10071. write_byte(get_pcvar_num(cvar_nvgcolor[1])) // g
  10072. write_byte(get_pcvar_num(cvar_nvgcolor[2])) // b
  10073. }
  10074. write_byte (255) // alpha
  10075. message_end()
  10076. }
  10077.  
  10078. // Screen shake?
  10079. if (get_pcvar_num(cvar_infectionscreenshake))
  10080. {
  10081. message_begin(MSG_ONE_UNRELIABLE, g_msgScreenShake, _, id)
  10082. write_short(UNIT_SECOND*4) // amplitude
  10083. write_short(UNIT_SECOND*2) // duration
  10084. write_short(UNIT_SECOND*10) // frequency
  10085. message_end()
  10086. }
  10087.  
  10088. // Infection icon?
  10089. if (get_pcvar_num(cvar_hudicons))
  10090. {
  10091. message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, _, id)
  10092. write_byte(0) // damage save
  10093. write_byte(0) // damage take
  10094. write_long(DMG_NERVEGAS) // damage type - DMG_RADIATION
  10095. write_coord(0) // x
  10096. write_coord(0) // y
  10097. write_coord(0) // z
  10098. message_end()
  10099. }
  10100.  
  10101. // Get player's origin
  10102. static origin[3]
  10103. get_user_origin(id, origin)
  10104.  
  10105. // Tracers?
  10106. if (get_pcvar_num(cvar_infectiontracers))
  10107. {
  10108. message_begin(MSG_PVS, SVC_TEMPENTITY, origin)
  10109. write_byte(TE_IMPLOSION) // TE id
  10110. write_coord(origin[0]) // x
  10111. write_coord(origin[1]) // y
  10112. write_coord(origin[2]) // z
  10113. write_byte(128) // radius
  10114. write_byte(20) // count
  10115. write_byte(3) // duration
  10116. message_end()
  10117. }
  10118.  
  10119. // Particle burst?
  10120. if (get_pcvar_num(cvar_infectionparticles))
  10121. {
  10122. message_begin(MSG_PVS, SVC_TEMPENTITY, origin)
  10123. write_byte(TE_PARTICLEBURST) // TE id
  10124. write_coord(origin[0]) // x
  10125. write_coord(origin[1]) // y
  10126. write_coord(origin[2]) // z
  10127. write_short(50) // radius
  10128. write_byte(70) // color
  10129. write_byte(3) // duration (will be randomized a bit)
  10130. message_end()
  10131. }
  10132.  
  10133. // Light sparkle?
  10134. if (get_pcvar_num(cvar_infectionsparkle))
  10135. {
  10136. message_begin(MSG_PVS, SVC_TEMPENTITY, origin)
  10137. write_byte(TE_DLIGHT) // TE id
  10138. write_coord(origin[0]) // x
  10139. write_coord(origin[1]) // y
  10140. write_coord(origin[2]) // z
  10141. write_byte(20) // radius
  10142. write_byte(get_pcvar_num(cvar_nvgcolor[0])) // r
  10143. write_byte(get_pcvar_num(cvar_nvgcolor[1])) // g
  10144. write_byte(get_pcvar_num(cvar_nvgcolor[2])) // b
  10145. write_byte(2) // life
  10146. write_byte(0) // decay rate
  10147. message_end()
  10148. }
  10149. }
  10150.  
  10151. // Nemesis/madness aura task
  10152. public zombie_aura(taskid)
  10153. {
  10154. // Not nemesis, not in zombie madness
  10155. if (!g_nemesis[ID_AURA] && !g_nodamage[ID_AURA])
  10156. {
  10157. // Task not needed anymore
  10158. remove_task(taskid);
  10159. return;
  10160. }
  10161.  
  10162. // Get player's origin
  10163. static origin[3]
  10164. get_user_origin(ID_AURA, origin)
  10165.  
  10166. // Colored Aura
  10167. message_begin(MSG_PVS, SVC_TEMPENTITY, origin)
  10168. write_byte(TE_DLIGHT) // TE id
  10169. write_coord(origin[0]) // x
  10170. write_coord(origin[1]) // y
  10171. write_coord(origin[2]) // z
  10172. write_byte(20) // radius
  10173. write_byte(get_pcvar_num(cvar_nemnvgcolor[0])) // r
  10174. write_byte(get_pcvar_num(cvar_nemnvgcolor[1])) // g
  10175. write_byte(get_pcvar_num(cvar_nemnvgcolor[2])) // b
  10176. write_byte(2) // life
  10177. write_byte(0) // decay rate
  10178. message_end()
  10179. }
  10180.  
  10181. // Make zombies leave footsteps and bloodstains on the floor
  10182. public make_blood(taskid)
  10183. {
  10184. // Only bleed when moving on ground
  10185. if (!(pev(ID_BLOOD, pev_flags) & FL_ONGROUND) || fm_get_speed(ID_BLOOD) < 80)
  10186. return;
  10187.  
  10188. // Get user origin
  10189. static Float:originF[3]
  10190. pev(ID_BLOOD, pev_origin, originF)
  10191.  
  10192. // If ducking set a little lower
  10193. if (pev(ID_BLOOD, pev_bInDuck))
  10194. originF[2] -= 18.0
  10195. else
  10196. originF[2] -= 36.0
  10197.  
  10198. // Send the decal message
  10199. engfunc(EngFunc_MessageBegin, MSG_PAS, SVC_TEMPENTITY, originF, 0)
  10200. write_byte(TE_WORLDDECAL) // TE id
  10201. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10202. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10203. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10204. write_byte(ArrayGetCell(zombie_decals, random_num(0, ArraySize(zombie_decals) - 1)) + (g_czero * 12)) // random decal number (offsets +12 for CZ)
  10205. message_end()
  10206. }
  10207.  
  10208. // Flare Lighting Effects
  10209. flare_lighting(entity, duration)
  10210. {
  10211. // Get origin and color
  10212. static Float:originF[3], color[3]
  10213. pev(entity, pev_origin, originF)
  10214. pev(entity, PEV_FLARE_COLOR, color)
  10215.  
  10216. // Lighting
  10217. engfunc(EngFunc_MessageBegin, MSG_PAS, SVC_TEMPENTITY, originF, 0)
  10218. write_byte(TE_DLIGHT) // TE id
  10219. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10220. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10221. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10222. write_byte(get_pcvar_num(cvar_flaresize)) // radius
  10223. write_byte(color[0]) // r
  10224. write_byte(color[1]) // g
  10225. write_byte(color[2]) // b
  10226. write_byte(21) //life
  10227. write_byte((duration < 2) ? 3 : 0) //decay rate
  10228. message_end()
  10229.  
  10230. // Sparks
  10231. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10232. write_byte(TE_SPARKS) // TE id
  10233. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10234. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10235. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10236. message_end()
  10237. }
  10238.  
  10239. // Burning Flames
  10240. public burning_flame(taskid)
  10241. {
  10242. // Get player origin and flags
  10243. static origin[3], flags
  10244. get_user_origin(ID_BURN, origin)
  10245. flags = pev(ID_BURN, pev_flags)
  10246.  
  10247. // Madness mode - in water - burning stopped
  10248. if (g_nodamage[ID_BURN] || (flags & FL_INWATER) || g_burning_duration[ID_BURN] < 1)
  10249. {
  10250. // Smoke sprite
  10251. message_begin(MSG_PVS, SVC_TEMPENTITY, origin)
  10252. write_byte(TE_SMOKE) // TE id
  10253. write_coord(origin[0]) // x
  10254. write_coord(origin[1]) // y
  10255. write_coord(origin[2]-50) // z
  10256. write_short(g_smokeSpr) // sprite
  10257. write_byte(random_num(15, 20)) // scale
  10258. write_byte(random_num(10, 20)) // framerate
  10259. message_end()
  10260.  
  10261. // Task not needed anymore
  10262. remove_task(taskid);
  10263. return;
  10264. }
  10265.  
  10266. // Randomly play burning zombie scream sounds (not for nemesis)
  10267. if (!g_nemesis[ID_BURN] && !random_num(0, 20))
  10268. {
  10269. static sound[64]
  10270. ArrayGetString(grenade_fire_player, random_num(0, ArraySize(grenade_fire_player) - 1), sound, charsmax(sound))
  10271. emit_sound(ID_BURN, CHAN_VOICE, sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
  10272. }
  10273.  
  10274. // Fire slow down, unless nemesis
  10275. if (!g_nemesis[ID_BURN] && (flags & FL_ONGROUND) && get_pcvar_float(cvar_fireslowdown) > 0.0)
  10276. {
  10277. static Float:velocity[3]
  10278. pev(ID_BURN, pev_velocity, velocity)
  10279. xs_vec_mul_scalar(velocity, get_pcvar_float(cvar_fireslowdown), velocity)
  10280. set_pev(ID_BURN, pev_velocity, velocity)
  10281. }
  10282.  
  10283. // Get player's health
  10284. static health
  10285. health = pev(ID_BURN, pev_health)
  10286.  
  10287. // Take damage from the fire
  10288. if (health - floatround(get_pcvar_float(cvar_firedamage), floatround_ceil) > 0)
  10289. fm_set_user_health(ID_BURN, health - floatround(get_pcvar_float(cvar_firedamage), floatround_ceil))
  10290.  
  10291. // Flame sprite
  10292. message_begin(MSG_PVS, SVC_TEMPENTITY, origin)
  10293. write_byte(TE_SPRITE) // TE id
  10294. write_coord(origin[0]+random_num(-5, 5)) // x
  10295. write_coord(origin[1]+random_num(-5, 5)) // y
  10296. write_coord(origin[2]+random_num(-10, 10)) // z
  10297. write_short(g_flameSpr) // sprite
  10298. write_byte(random_num(5, 10)) // scale
  10299. write_byte(200) // brightness
  10300. message_end()
  10301.  
  10302. // Decrease burning duration counter
  10303. g_burning_duration[ID_BURN]--
  10304. }
  10305.  
  10306. // Infection Bomb: Green Blast
  10307. create_blast(const Float:originF[3])
  10308. {
  10309. // Smallest ring
  10310. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10311. write_byte(TE_BEAMCYLINDER) // TE id
  10312. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10313. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10314. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10315. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10316. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10317. engfunc(EngFunc_WriteCoord, originF[2]+385.0) // z axis
  10318. write_short(g_exploSpr) // sprite
  10319. write_byte(0) // startframe
  10320. write_byte(0) // framerate
  10321. write_byte(4) // life
  10322. write_byte(60) // width
  10323. write_byte(0) // noise
  10324. write_byte(0) // red
  10325. write_byte(200) // green
  10326. write_byte(0) // blue
  10327. write_byte(200) // brightness
  10328. write_byte(0) // speed
  10329. message_end()
  10330.  
  10331. // Medium ring
  10332. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10333. write_byte(TE_BEAMCYLINDER) // TE id
  10334. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10335. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10336. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10337. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10338. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10339. engfunc(EngFunc_WriteCoord, originF[2]+470.0) // z axis
  10340. write_short(g_exploSpr) // sprite
  10341. write_byte(0) // startframe
  10342. write_byte(0) // framerate
  10343. write_byte(4) // life
  10344. write_byte(60) // width
  10345. write_byte(0) // noise
  10346. write_byte(0) // red
  10347. write_byte(200) // green
  10348. write_byte(0) // blue
  10349. write_byte(200) // brightness
  10350. write_byte(0) // speed
  10351. message_end()
  10352.  
  10353. // Largest ring
  10354. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10355. write_byte(TE_BEAMCYLINDER) // TE id
  10356. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10357. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10358. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10359. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10360. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10361. engfunc(EngFunc_WriteCoord, originF[2]+555.0) // z axis
  10362. write_short(g_exploSpr) // sprite
  10363. write_byte(0) // startframe
  10364. write_byte(0) // framerate
  10365. write_byte(4) // life
  10366. write_byte(60) // width
  10367. write_byte(0) // noise
  10368. write_byte(0) // red
  10369. write_byte(200) // green
  10370. write_byte(0) // blue
  10371. write_byte(200) // brightness
  10372. write_byte(0) // speed
  10373. message_end()
  10374. }
  10375.  
  10376. // Fire Grenade: Fire Blast
  10377. create_blast2(const Float:originF[3])
  10378. {
  10379. // Smallest ring
  10380. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10381. write_byte(TE_BEAMCYLINDER) // TE id
  10382. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10383. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10384. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10385. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10386. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10387. engfunc(EngFunc_WriteCoord, originF[2]+385.0) // z axis
  10388. write_short(g_exploSpr) // sprite
  10389. write_byte(0) // startframe
  10390. write_byte(0) // framerate
  10391. write_byte(4) // life
  10392. write_byte(60) // width
  10393. write_byte(0) // noise
  10394. write_byte(200) // red
  10395. write_byte(100) // green
  10396. write_byte(0) // blue
  10397. write_byte(200) // brightness
  10398. write_byte(0) // speed
  10399. message_end()
  10400.  
  10401. // Medium ring
  10402. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10403. write_byte(TE_BEAMCYLINDER) // TE id
  10404. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10405. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10406. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10407. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10408. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10409. engfunc(EngFunc_WriteCoord, originF[2]+470.0) // z axis
  10410. write_short(g_exploSpr) // sprite
  10411. write_byte(0) // startframe
  10412. write_byte(0) // framerate
  10413. write_byte(4) // life
  10414. write_byte(60) // width
  10415. write_byte(0) // noise
  10416. write_byte(200) // red
  10417. write_byte(50) // green
  10418. write_byte(0) // blue
  10419. write_byte(200) // brightness
  10420. write_byte(0) // speed
  10421. message_end()
  10422.  
  10423. // Largest ring
  10424. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10425. write_byte(TE_BEAMCYLINDER) // TE id
  10426. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10427. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10428. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10429. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10430. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10431. engfunc(EngFunc_WriteCoord, originF[2]+555.0) // z axis
  10432. write_short(g_exploSpr) // sprite
  10433. write_byte(0) // startframe
  10434. write_byte(0) // framerate
  10435. write_byte(4) // life
  10436. write_byte(60) // width
  10437. write_byte(0) // noise
  10438. write_byte(200) // red
  10439. write_byte(0) // green
  10440. write_byte(0) // blue
  10441. write_byte(200) // brightness
  10442. write_byte(0) // speed
  10443. message_end()
  10444.  
  10445. // TE_SPRITETRAIL
  10446. engfunc(EngFunc_MessageBegin, MSG_BROADCAST ,SVC_TEMPENTITY, originF, 0)
  10447. write_byte(TE_SPRITETRAIL) // TE ID
  10448. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10449. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10450. engfunc(EngFunc_WriteCoord, originF[2]+70) // z axis
  10451. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10452. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10453. engfunc(EngFunc_WriteCoord, originF[2]) // z axis
  10454. write_short(g_fire_gib) // Sprite Index
  10455. write_byte(80) // Count
  10456. write_byte(20) // Life
  10457. write_byte(2) // Scale
  10458. write_byte(50) // Velocity Along Vector
  10459. write_byte(10) // Rendomness of Velocity
  10460. message_end();
  10461.  
  10462. // TE_EXPLOSION
  10463. engfunc(EngFunc_MessageBegin, MSG_BROADCAST,SVC_TEMPENTITY, originF, 0)
  10464. write_byte(TE_EXPLOSION)
  10465. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10466. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10467. engfunc(EngFunc_WriteCoord, originF[2]+75) // z axis
  10468. write_short(g_fire_explode)
  10469. write_byte(22)
  10470. write_byte(35)
  10471. write_byte(TE_EXPLFLAG_NOSOUND)
  10472. message_end()
  10473. }
  10474.  
  10475. // Frost Grenade: Freeze Blast
  10476. create_blast3(const Float:originF[3])
  10477. {
  10478. // Smallest ring
  10479. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10480. write_byte(TE_BEAMCYLINDER) // TE id
  10481. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10482. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10483. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10484. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10485. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10486. engfunc(EngFunc_WriteCoord, originF[2]+385.0) // z axis
  10487. write_short(g_exploSpr) // sprite
  10488. write_byte(0) // startframe
  10489. write_byte(0) // framerate
  10490. write_byte(4) // life
  10491. write_byte(60) // width
  10492. write_byte(0) // noise
  10493. write_byte(0) // red
  10494. write_byte(100) // green
  10495. write_byte(200) // blue
  10496. write_byte(200) // brightness
  10497. write_byte(0) // speed
  10498. message_end()
  10499.  
  10500. // Medium ring
  10501. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10502. write_byte(TE_BEAMCYLINDER) // TE id
  10503. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10504. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10505. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10506. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10507. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10508. engfunc(EngFunc_WriteCoord, originF[2]+470.0) // z axis
  10509. write_short(g_exploSpr) // sprite
  10510. write_byte(0) // startframe
  10511. write_byte(0) // framerate
  10512. write_byte(4) // life
  10513. write_byte(60) // width
  10514. write_byte(0) // noise
  10515. write_byte(0) // red
  10516. write_byte(100) // green
  10517. write_byte(200) // blue
  10518. write_byte(200) // brightness
  10519. write_byte(0) // speed
  10520. message_end()
  10521.  
  10522. // Largest ring
  10523. engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
  10524. write_byte(TE_BEAMCYLINDER) // TE id
  10525. engfunc(EngFunc_WriteCoord, originF[0]) // x
  10526. engfunc(EngFunc_WriteCoord, originF[1]) // y
  10527. engfunc(EngFunc_WriteCoord, originF[2]) // z
  10528. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10529. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10530. engfunc(EngFunc_WriteCoord, originF[2]+555.0) // z axis
  10531. write_short(g_exploSpr) // sprite
  10532. write_byte(0) // startframe
  10533. write_byte(0) // framerate
  10534. write_byte(4) // life
  10535. write_byte(60) // width
  10536. write_byte(0) // noise
  10537. write_byte(0) // red
  10538. write_byte(100) // green
  10539. write_byte(200) // blue
  10540. write_byte(200) // brightness
  10541. write_byte(0) // speed
  10542. message_end()
  10543.  
  10544. // TE_SPRITETRAIL
  10545. engfunc(EngFunc_MessageBegin, MSG_BROADCAST ,SVC_TEMPENTITY, originF, 0)
  10546. write_byte(TE_SPRITETRAIL) // TE ID
  10547. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10548. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10549. engfunc(EngFunc_WriteCoord, originF[2]+70) // z axis
  10550. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10551. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10552. engfunc(EngFunc_WriteCoord, originF[2]) // z axis
  10553. write_short(g_frost_gib) // Sprite Index
  10554. write_byte(80) // Count
  10555. write_byte(20) // Life
  10556. write_byte(2) // Scale
  10557. write_byte(50) // Velocity Along Vector
  10558. write_byte(10) // Rendomness of Velocity
  10559. message_end();
  10560.  
  10561. // TE_EXPLOSION
  10562. engfunc(EngFunc_MessageBegin, MSG_BROADCAST,SVC_TEMPENTITY, originF, 0)
  10563. write_byte(TE_EXPLOSION)
  10564. engfunc(EngFunc_WriteCoord, originF[0]) // x axis
  10565. engfunc(EngFunc_WriteCoord, originF[1]) // y axis
  10566. engfunc(EngFunc_WriteCoord, originF[2]+75) // z axis
  10567. write_short(g_frost_explode)
  10568. write_byte(22)
  10569. write_byte(35)
  10570. write_byte(TE_EXPLFLAG_NOSOUND)
  10571. message_end()
  10572. }
  10573.  
  10574. // Fix Dead Attrib on scoreboard
  10575. FixDeadAttrib(id)
  10576. {
  10577. message_begin(MSG_BROADCAST, g_msgScoreAttrib)
  10578. write_byte(id) // id
  10579. write_byte(0) // attrib
  10580. message_end()
  10581. }
  10582.  
  10583. // Send Death Message for infections
  10584. SendDeathMsg(attacker, victim)
  10585. {
  10586. message_begin(MSG_BROADCAST, g_msgDeathMsg)
  10587. write_byte(attacker) // killer
  10588. write_byte(victim) // victim
  10589. write_byte(1) // headshot flag
  10590. write_string("infection") // killer's weapon
  10591. message_end()
  10592. }
  10593.  
  10594. // Update Player Frags and Deaths
  10595. UpdateFrags(attacker, victim, frags, deaths, scoreboard)
  10596. {
  10597. // Set attacker frags
  10598. set_pev(attacker, pev_frags, float(pev(attacker, pev_frags) + frags))
  10599.  
  10600. // Set victim deaths
  10601. fm_cs_set_user_deaths(victim, cs_get_user_deaths(victim) + deaths)
  10602.  
  10603. // Update scoreboard with attacker and victim info
  10604. if (scoreboard)
  10605. {
  10606. message_begin(MSG_BROADCAST, g_msgScoreInfo)
  10607. write_byte(attacker) // id
  10608. write_short(pev(attacker, pev_frags)) // frags
  10609. write_short(cs_get_user_deaths(attacker)) // deaths
  10610. write_short(0) // class?
  10611. write_short(fm_cs_get_user_team(attacker)) // team
  10612. message_end()
  10613.  
  10614. message_begin(MSG_BROADCAST, g_msgScoreInfo)
  10615. write_byte(victim) // id
  10616. write_short(pev(victim, pev_frags)) // frags
  10617. write_short(cs_get_user_deaths(victim)) // deaths
  10618. write_short(0) // class?
  10619. write_short(fm_cs_get_user_team(victim)) // team
  10620. message_end()
  10621. }
  10622. }
  10623.  
  10624. // Remove Player Frags (when Nemesis/Survivor ignore_frags cvar is enabled)
  10625. RemoveFrags(attacker, victim)
  10626. {
  10627. // Remove attacker frags
  10628. set_pev(attacker, pev_frags, float(pev(attacker, pev_frags) - 1))
  10629.  
  10630. // Remove victim deaths
  10631. fm_cs_set_user_deaths(victim, cs_get_user_deaths(victim) - 1)
  10632. }
  10633.  
  10634. // Plays a sound on clients
  10635. PlaySound(const sound[])
  10636. {
  10637. if (equal(sound[strlen(sound)-4], ".mp3"))
  10638. client_cmd(0, "mp3 play ^"sound/%s^"", sound)
  10639. else
  10640. client_cmd(0, "spk ^"%s^"", sound)
  10641. }
  10642.  
  10643. // Prints a colored message to target (use 0 for everyone), supports ML formatting.
  10644. // Note: I still need to make something like gungame's LANG_PLAYER_C to avoid unintended
  10645. // argument replacement when a function passes -1 (it will be considered a LANG_PLAYER)
  10646. zp_colored_print(target, const message[], any:...)
  10647. {
  10648. static buffer[512], i, argscount
  10649. argscount = numargs()
  10650.  
  10651. // Send to everyone
  10652. if (!target)
  10653. {
  10654. static player
  10655. for (player = 1; player <= g_maxplayers; player++)
  10656. {
  10657. // Not connected
  10658. if (!g_isconnected[player])
  10659. continue;
  10660.  
  10661. // Remember changed arguments
  10662. static changed[5], changedcount // [5] = max LANG_PLAYER occurencies
  10663. changedcount = 0
  10664.  
  10665. // Replace LANG_PLAYER with player id
  10666. for (i = 2; i < argscount; i++)
  10667. {
  10668. if (getarg(i) == LANG_PLAYER)
  10669. {
  10670. setarg(i, 0, player)
  10671. changed[changedcount] = i
  10672. changedcount++
  10673. }
  10674. }
  10675.  
  10676. // Format message for player
  10677. vformat(buffer, charsmax(buffer), message, 3)
  10678.  
  10679. // Send it
  10680. message_begin(MSG_ONE_UNRELIABLE, g_msgSayText, _, player)
  10681. write_byte(player)
  10682. write_string(buffer)
  10683. message_end()
  10684.  
  10685. // Replace back player id's with LANG_PLAYER
  10686. for (i = 0; i < changedcount; i++)
  10687. setarg(changed[i], 0, LANG_PLAYER)
  10688. }
  10689. }
  10690. // Send to specific target
  10691. else
  10692. {
  10693. /*
  10694. // Not needed since you should set the ML argument
  10695. // to the player's id for a targeted print message
  10696.  
  10697. // Replace LANG_PLAYER with player id
  10698. for (i = 2; i < argscount; i++)
  10699. {
  10700. if (getarg(i) == LANG_PLAYER)
  10701. setarg(i, 0, target)
  10702. }
  10703. */
  10704.  
  10705. // Format message for player
  10706. vformat(buffer, charsmax(buffer), message, 3)
  10707.  
  10708. // Send it
  10709. message_begin(MSG_ONE, g_msgSayText, _, target)
  10710. write_byte(target)
  10711. write_string(buffer)
  10712. message_end()
  10713. }
  10714. }
  10715.  
  10716. /*================================================================================
  10717. [Stocks]
  10718. =================================================================================*/
  10719.  
  10720. // Set an entity's key value (from fakemeta_util)
  10721. stock fm_set_kvd(entity, const key[], const value[], const classname[])
  10722. {
  10723. set_kvd(0, KV_ClassName, classname)
  10724. set_kvd(0, KV_KeyName, key)
  10725. set_kvd(0, KV_Value, value)
  10726. set_kvd(0, KV_fHandled, 0)
  10727.  
  10728. dllfunc(DLLFunc_KeyValue, entity, 0)
  10729. }
  10730.  
  10731. // Set entity's rendering type (from fakemeta_util)
  10732. stock fm_set_rendering(entity, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16)
  10733. {
  10734. static Float:color[3]
  10735. color[0] = float(r)
  10736. color[1] = float(g)
  10737. color[2] = float(b)
  10738.  
  10739. set_pev(entity, pev_renderfx, fx)
  10740. set_pev(entity, pev_rendercolor, color)
  10741. set_pev(entity, pev_rendermode, render)
  10742. set_pev(entity, pev_renderamt, float(amount))
  10743. }
  10744.  
  10745. // Get entity's speed (from fakemeta_util)
  10746. stock fm_get_speed(entity)
  10747. {
  10748. static Float:velocity[3]
  10749. pev(entity, pev_velocity, velocity)
  10750.  
  10751. return floatround(vector_length(velocity));
  10752. }
  10753.  
  10754. // Get entity's aim origins (from fakemeta_util)
  10755. stock fm_get_aim_origin(id, Float:origin[3])
  10756. {
  10757. static Float:origin1F[3], Float:origin2F[3]
  10758. pev(id, pev_origin, origin1F)
  10759. pev(id, pev_view_ofs, origin2F)
  10760. xs_vec_add(origin1F, origin2F, origin1F)
  10761.  
  10762. pev(id, pev_v_angle, origin2F);
  10763. engfunc(EngFunc_MakeVectors, origin2F)
  10764. global_get(glb_v_forward, origin2F)
  10765. xs_vec_mul_scalar(origin2F, 9999.0, origin2F)
  10766. xs_vec_add(origin1F, origin2F, origin2F)
  10767.  
  10768. engfunc(EngFunc_TraceLine, origin1F, origin2F, 0, id, 0)
  10769. get_tr2(0, TR_vecEndPos, origin)
  10770. }
  10771.  
  10772. // Find entity by its owner (from fakemeta_util)
  10773. stock fm_find_ent_by_owner(entity, const classname[], owner)
  10774. {
  10775. while ((entity = engfunc(EngFunc_FindEntityByString, entity, "classname", classname)) && pev(entity, pev_owner) != owner) { /* keep looping */ }
  10776. return entity;
  10777. }
  10778.  
  10779. // Set player's health (from fakemeta_util)
  10780. stock fm_set_user_health(id, health)
  10781. {
  10782. (health > 0) ? set_pev(id, pev_health, float(health)) : dllfunc(DLLFunc_ClientKill, id);
  10783. }
  10784.  
  10785. // Give an item to a player (from fakemeta_util)
  10786. stock fm_give_item(id, const item[])
  10787. {
  10788. static ent
  10789. ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, item))
  10790. if (!pev_valid(ent)) return;
  10791.  
  10792. static Float:originF[3]
  10793. pev(id, pev_origin, originF)
  10794. set_pev(ent, pev_origin, originF)
  10795. set_pev(ent, pev_spawnflags, pev(ent, pev_spawnflags) | SF_NORESPAWN)
  10796. dllfunc(DLLFunc_Spawn, ent)
  10797.  
  10798. static save
  10799. save = pev(ent, pev_solid)
  10800. dllfunc(DLLFunc_Touch, ent, id)
  10801. if (pev(ent, pev_solid) != save)
  10802. return;
  10803.  
  10804. engfunc(EngFunc_RemoveEntity, ent)
  10805. }
  10806.  
  10807. // Strip user weapons (from fakemeta_util)
  10808. stock fm_strip_user_weapons(id)
  10809. {
  10810. static ent
  10811. ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "player_weaponstrip"))
  10812. if (!pev_valid(ent)) return;
  10813.  
  10814. dllfunc(DLLFunc_Spawn, ent)
  10815. dllfunc(DLLFunc_Use, ent, id)
  10816. engfunc(EngFunc_RemoveEntity, ent)
  10817. }
  10818.  
  10819. // Collect random spawn points
  10820. stock load_spawns()
  10821. {
  10822. // Check for CSDM spawns of the current map
  10823. new cfgdir[32], mapname[32], filepath[100], linedata[64]
  10824. get_configsdir(cfgdir, charsmax(cfgdir))
  10825. get_mapname(mapname, charsmax(mapname))
  10826. formatex(filepath, charsmax(filepath), "%s/csdm/%s.spawns.cfg", cfgdir, mapname)
  10827.  
  10828. // Load CSDM spawns if present
  10829. if (file_exists(filepath))
  10830. {
  10831. new csdmdata[10][6], file = fopen(filepath,"rt")
  10832.  
  10833. while (file && !feof(file))
  10834. {
  10835. fgets(file, linedata, charsmax(linedata))
  10836.  
  10837. // invalid spawn
  10838. if(!linedata[0] || str_count(linedata,' ') < 2) continue;
  10839.  
  10840. // get spawn point data
  10841. 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)
  10842.  
  10843. // origin
  10844. g_spawns[g_spawnCount][0] = floatstr(csdmdata[0])
  10845. g_spawns[g_spawnCount][1] = floatstr(csdmdata[1])
  10846. g_spawns[g_spawnCount][2] = floatstr(csdmdata[2])
  10847.  
  10848. // increase spawn count
  10849. g_spawnCount++
  10850. if (g_spawnCount >= sizeof g_spawns) break;
  10851. }
  10852. if (file) fclose(file)
  10853. }
  10854. else
  10855. {
  10856. // Collect regular spawns
  10857. collect_spawns_ent("info_player_start")
  10858. collect_spawns_ent("info_player_deathmatch")
  10859. }
  10860.  
  10861. // Collect regular spawns for non-random spawning unstuck
  10862. collect_spawns_ent2("info_player_start")
  10863. collect_spawns_ent2("info_player_deathmatch")
  10864. }
  10865.  
  10866. // Collect spawn points from entity origins
  10867. stock collect_spawns_ent(const classname[])
  10868. {
  10869. new ent = -1
  10870. while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", classname)) != 0)
  10871. {
  10872. // get origin
  10873. new Float:originF[3]
  10874. pev(ent, pev_origin, originF)
  10875. g_spawns[g_spawnCount][0] = originF[0]
  10876. g_spawns[g_spawnCount][1] = originF[1]
  10877. g_spawns[g_spawnCount][2] = originF[2]
  10878.  
  10879. // increase spawn count
  10880. g_spawnCount++
  10881. if (g_spawnCount >= sizeof g_spawns) break;
  10882. }
  10883. }
  10884.  
  10885. // Collect spawn points from entity origins
  10886. stock collect_spawns_ent2(const classname[])
  10887. {
  10888. new ent = -1
  10889. while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", classname)) != 0)
  10890. {
  10891. // get origin
  10892. new Float:originF[3]
  10893. pev(ent, pev_origin, originF)
  10894. g_spawns2[g_spawnCount2][0] = originF[0]
  10895. g_spawns2[g_spawnCount2][1] = originF[1]
  10896. g_spawns2[g_spawnCount2][2] = originF[2]
  10897.  
  10898. // increase spawn count
  10899. g_spawnCount2++
  10900. if (g_spawnCount2 >= sizeof g_spawns2) break;
  10901. }
  10902. }
  10903.  
  10904. // Drop primary/secondary weapons
  10905. stock drop_weapons(id, dropwhat)
  10906. {
  10907. // Get user weapons
  10908. static weapons[32], num, i, weaponid
  10909. num = 0 // reset passed weapons count (bugfix)
  10910. get_user_weapons(id, weapons, num)
  10911.  
  10912. // Loop through them and drop primaries or secondaries
  10913. for (i = 0; i < num; i++)
  10914. {
  10915. // Prevent re-indexing the array
  10916. weaponid = weapons[i]
  10917.  
  10918. if ((dropwhat == 1 && ((1<<weaponid) & PRIMARY_WEAPONS_BIT_SUM)) || (dropwhat == 2 && ((1<<weaponid) & SECONDARY_WEAPONS_BIT_SUM)))
  10919. {
  10920. // Get weapon entity
  10921. static wname[32], weapon_ent
  10922. get_weaponname(weaponid, wname, charsmax(wname))
  10923. weapon_ent = fm_find_ent_by_owner(-1, wname, id)
  10924.  
  10925. // Hack: store weapon bpammo on PEV_ADDITIONAL_AMMO
  10926. set_pev(weapon_ent, PEV_ADDITIONAL_AMMO, cs_get_user_bpammo(id, weaponid))
  10927.  
  10928. // Player drops the weapon and looses his bpammo
  10929. engclient_cmd(id, "drop", wname)
  10930. cs_set_user_bpammo(id, weaponid, 0)
  10931. }
  10932. }
  10933. }
  10934.  
  10935. // Stock by (probably) Twilight Suzuka -counts number of chars in a string
  10936. stock str_count(const str[], searchchar)
  10937. {
  10938. new count, i, len = strlen(str)
  10939.  
  10940. for (i = 0; i <= len; i++)
  10941. {
  10942. if(str[i] == searchchar)
  10943. count++
  10944. }
  10945.  
  10946. return count;
  10947. }
  10948.  
  10949. // Checks if a space is vacant (credits to VEN)
  10950. stock is_hull_vacant(Float:origin[3], hull)
  10951. {
  10952. engfunc(EngFunc_TraceHull, origin, origin, 0, hull, 0, 0)
  10953.  
  10954. if (!get_tr2(0, TR_StartSolid) && !get_tr2(0, TR_AllSolid) && get_tr2(0, TR_InOpen))
  10955. return true;
  10956.  
  10957. return false;
  10958. }
  10959.  
  10960. // Check if a player is stuck (credits to VEN)
  10961. stock is_player_stuck(id)
  10962. {
  10963. static Float:originF[3]
  10964. pev(id, pev_origin, originF)
  10965.  
  10966. engfunc(EngFunc_TraceHull, originF, originF, 0, (pev(id, pev_flags) & FL_DUCKING) ? HULL_HEAD : HULL_HUMAN, id, 0)
  10967.  
  10968. if (get_tr2(0, TR_StartSolid) || get_tr2(0, TR_AllSolid) || !get_tr2(0, TR_InOpen))
  10969. return true;
  10970.  
  10971. return false;
  10972. }
  10973.  
  10974. // Simplified get_weaponid (CS only)
  10975. stock cs_weapon_name_to_id(const weapon[])
  10976. {
  10977. static i
  10978. for (i = 0; i < sizeof WEAPONENTNAMES; i++)
  10979. {
  10980. if (equal(weapon, WEAPONENTNAMES[i]))
  10981. return i;
  10982. }
  10983.  
  10984. return 0;
  10985. }
  10986.  
  10987. // Get User Current Weapon Entity
  10988. stock fm_cs_get_current_weapon_ent(id)
  10989. {
  10990. // Prevent server crash if entity's private data not initalized
  10991. if (pev_valid(id) != PDATA_SAFE)
  10992. return -1;
  10993.  
  10994. return get_pdata_cbase(id, OFFSET_ACTIVE_ITEM, OFFSET_LINUX);
  10995. }
  10996.  
  10997. // Get Weapon Entity's Owner
  10998. stock fm_cs_get_weapon_ent_owner(ent)
  10999. {
  11000. // Prevent server crash if entity's private data not initalized
  11001. if (pev_valid(ent) != PDATA_SAFE)
  11002. return -1;
  11003.  
  11004. return get_pdata_cbase(ent, OFFSET_WEAPONOWNER, OFFSET_LINUX_WEAPONS);
  11005. }
  11006.  
  11007. // Set User Deaths
  11008. stock fm_cs_set_user_deaths(id, value)
  11009. {
  11010. // Prevent server crash if entity's private data not initalized
  11011. if (pev_valid(id) != PDATA_SAFE)
  11012. return;
  11013.  
  11014. set_pdata_int(id, OFFSET_CSDEATHS, value, OFFSET_LINUX)
  11015. }
  11016.  
  11017. // Get User Team
  11018. stock fm_cs_get_user_team(id)
  11019. {
  11020. // Prevent server crash if entity's private data not initalized
  11021. if (pev_valid(id) != PDATA_SAFE)
  11022. return FM_CS_TEAM_UNASSIGNED;
  11023.  
  11024. return get_pdata_int(id, OFFSET_CSTEAMS, OFFSET_LINUX);
  11025. }
  11026.  
  11027. // Set a Player's Team
  11028. stock fm_cs_set_user_team(id, team)
  11029. {
  11030. // Prevent server crash if entity's private data not initalized
  11031. if (pev_valid(id) != PDATA_SAFE)
  11032. return;
  11033.  
  11034. set_pdata_int(id, OFFSET_CSTEAMS, team, OFFSET_LINUX)
  11035. }
  11036.  
  11037. // Set User Money
  11038. stock fm_cs_set_user_money(id, value)
  11039. {
  11040. // Prevent server crash if entity's private data not initalized
  11041. if (pev_valid(id) != PDATA_SAFE)
  11042. return;
  11043.  
  11044. set_pdata_int(id, OFFSET_CSMONEY, value, OFFSET_LINUX)
  11045. }
  11046.  
  11047. // Set User Flashlight Batteries
  11048. stock fm_cs_set_user_batteries(id, value)
  11049. {
  11050. // Prevent server crash if entity's private data not initalized
  11051. if (pev_valid(id) != PDATA_SAFE)
  11052. return;
  11053.  
  11054. set_pdata_int(id, OFFSET_FLASHLIGHT_BATTERY, value, OFFSET_LINUX)
  11055. }
  11056.  
  11057. // Update Player's Team on all clients (adding needed delays)
  11058. stock fm_user_team_update(id)
  11059. {
  11060. static Float:current_time
  11061. current_time = get_gametime()
  11062.  
  11063. if (current_time - g_teams_targettime >= 0.1)
  11064. {
  11065. set_task(0.1, "fm_cs_set_user_team_msg", id+TASK_TEAM)
  11066. g_teams_targettime = current_time + 0.1
  11067. }
  11068. else
  11069. {
  11070. set_task((g_teams_targettime + 0.1) - current_time, "fm_cs_set_user_team_msg", id+TASK_TEAM)
  11071. g_teams_targettime = g_teams_targettime + 0.1
  11072. }
  11073. }
  11074.  
  11075. // Send User Team Message
  11076. public fm_cs_set_user_team_msg(taskid)
  11077. {
  11078. // Note to self: this next message can now be received by other plugins
  11079.  
  11080. // Set the switching team flag
  11081. g_switchingteam = true
  11082.  
  11083. // Tell everyone my new team
  11084. emessage_begin(MSG_ALL, g_msgTeamInfo)
  11085. ewrite_byte(ID_TEAM) // player
  11086. ewrite_string(CS_TEAM_NAMES[fm_cs_get_user_team(ID_TEAM)]) // team
  11087. emessage_end()
  11088.  
  11089. // Done switching team
  11090. g_switchingteam = false
  11091. }
  11092.  
  11093. // Set the precached model index (updates hitboxes server side)
  11094. stock fm_cs_set_user_model_index(id, value)
  11095. {
  11096. // Prevent server crash if entity's private data not initalized
  11097. if (pev_valid(id) != PDATA_SAFE)
  11098. return;
  11099.  
  11100. set_pdata_int(id, OFFSET_MODELINDEX, value, OFFSET_LINUX)
  11101. }
  11102.  
  11103. // Set Player Model on Entity
  11104. stock fm_set_playermodel_ent(id)
  11105. {
  11106. // Make original player entity invisible without hiding shadows or firing effects
  11107. fm_set_rendering(id, kRenderFxNone, 255, 255, 255, kRenderTransTexture, 1)
  11108.  
  11109. // Format model string
  11110. static model[100]
  11111. formatex(model, charsmax(model), "models/player/%s/%s.mdl", g_playermodel[id], g_playermodel[id])
  11112.  
  11113. // Set model on entity or make a new one if unexistant
  11114. if (!pev_valid(g_ent_playermodel[id]))
  11115. {
  11116. g_ent_playermodel[id] = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
  11117. if (!pev_valid(g_ent_playermodel[id])) return;
  11118.  
  11119. set_pev(g_ent_playermodel[id], pev_classname, MODEL_ENT_CLASSNAME)
  11120. set_pev(g_ent_playermodel[id], pev_movetype, MOVETYPE_FOLLOW)
  11121. set_pev(g_ent_playermodel[id], pev_aiment, id)
  11122. set_pev(g_ent_playermodel[id], pev_owner, id)
  11123. }
  11124.  
  11125. engfunc(EngFunc_SetModel, g_ent_playermodel[id], model)
  11126. }
  11127.  
  11128. // Set Weapon Model on Entity
  11129. stock fm_set_weaponmodel_ent(id)
  11130. {
  11131. // Get player's p_ weapon model
  11132. static model[100]
  11133. pev(id, pev_weaponmodel2, model, charsmax(model))
  11134.  
  11135. // Set model on entity or make a new one if unexistant
  11136. if (!pev_valid(g_ent_weaponmodel[id]))
  11137. {
  11138. g_ent_weaponmodel[id] = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
  11139. if (!pev_valid(g_ent_weaponmodel[id])) return;
  11140.  
  11141. set_pev(g_ent_weaponmodel[id], pev_classname, WEAPON_ENT_CLASSNAME)
  11142. set_pev(g_ent_weaponmodel[id], pev_movetype, MOVETYPE_FOLLOW)
  11143. set_pev(g_ent_weaponmodel[id], pev_aiment, id)
  11144. set_pev(g_ent_weaponmodel[id], pev_owner, id)
  11145. }
  11146.  
  11147. engfunc(EngFunc_SetModel, g_ent_weaponmodel[id], model)
  11148. }
  11149.  
  11150. // Remove Custom Model Entities
  11151. stock fm_remove_model_ents(id)
  11152. {
  11153. // Remove "playermodel" ent if present
  11154. if (pev_valid(g_ent_playermodel[id]))
  11155. {
  11156. engfunc(EngFunc_RemoveEntity, g_ent_playermodel[id])
  11157. g_ent_playermodel[id] = 0
  11158. }
  11159. // Remove "weaponmodel" ent if present
  11160. if (pev_valid(g_ent_weaponmodel[id]))
  11161. {
  11162. engfunc(EngFunc_RemoveEntity, g_ent_weaponmodel[id])
  11163. g_ent_weaponmodel[id] = 0
  11164. }
  11165. }
  11166.  
  11167. stock color_print( id, const message[], { Float, Sql, Result, _ }:... )
  11168. {
  11169. new Buffer[ 128 ],Buffer2[ 128 ];
  11170. new players[ 32 ], index, num, i;
  11171.  
  11172. formatex( Buffer2,charsmax( Buffer2 ), "%s", message );
  11173. vformat( Buffer, charsmax( Buffer ), Buffer2, 3 );
  11174. get_players( players, num, "c" );
  11175.  
  11176. if( id )
  11177. {
  11178. if( !is_user_connected( id ) )
  11179. {
  11180. return;
  11181. }
  11182.  
  11183. message_begin( MSG_ONE_UNRELIABLE, get_user_msgid( "SayText" ), _, id );
  11184. write_byte( id );
  11185. write_string( Buffer );
  11186. message_end();
  11187. }
  11188.  
  11189. else
  11190. {
  11191. for( i = 0; i < num;i++ )
  11192. {
  11193. index = players[ i ];
  11194.  
  11195. if( !is_user_connected( index ) )
  11196. {
  11197. continue;
  11198. }
  11199.  
  11200. message_begin( MSG_ONE_UNRELIABLE, get_user_msgid( "SayText" ), _, index );
  11201. write_byte( index );
  11202. write_string( Buffer );
  11203. message_end();
  11204. }
  11205. }
  11206. }
  11207.  
  11208. // Set User Model
  11209. public fm_cs_set_user_model(taskid)
  11210. {
  11211. set_user_info(ID_MODEL, "model", g_playermodel[ID_MODEL])
  11212. }
  11213.  
  11214. // Get User Model -model passed byref-
  11215. stock fm_cs_get_user_model(player, model[], len)
  11216. {
  11217. get_user_info(player, "model", model, len)
  11218. }
  11219.  
  11220. // Update Player's Model on all clients (adding needed delays)
  11221. public fm_user_model_update(taskid)
  11222. {
  11223. static Float:current_time
  11224. current_time = get_gametime()
  11225.  
  11226. if (current_time - g_models_targettime >= g_modelchange_delay)
  11227. {
  11228. fm_cs_set_user_model(taskid)
  11229. g_models_targettime = current_time
  11230. }
  11231. else
  11232. {
  11233. set_task((g_models_targettime + g_modelchange_delay) - current_time, "fm_cs_set_user_model", taskid)
  11234. g_models_targettime = g_models_targettime + g_modelchange_delay
  11235. }
  11236. }
Add Comment
Please, Sign In to add comment