[ZP] Zombie VIP 1.9.1

Descarcari de pluginuri si discutii despre acestea.

Moderators: Moderatori ajutători, Scripteri TheXForce

Post Reply
User avatar
Rainq
Fost administrator
Fost administrator
Posts: 381
Joined: Mon Jan 18, 2021 7:25 am
Status: Citesc forumul TheXForce.RO...!
Detinator Steam: Da
SteamID: mrainq
Gaming experience: Nu spun..
Reputatie: Fost administrator
Nume anterior: Light
Fost detinator zm.thexforce.ro
Fost detinator dr.thexforce.ro
Location: Bucureşti
Has thanked: 2 times
Been thanked: 1 time
Contact:

[ZP] Zombie VIP 1.9.1

Post by Rainq »

Image
Descriere: Acest plugin este conceput pentru a oferi jucătorilor beneficii suplimentare și ușurință în joc. Puteți să vindeți aceste privilegii sau să le acordați anumitor jucători.
Datorită unor probleme, acest plugin funcționează în prezent doar cu versiunea 1.8.3 amxmodx.

Code: Select all

Salut din nou,
în această versiune, plugin-ul a fost complet rescris. Ideea și funcționalitatea principală rămân aceleași, dar totul sa îmbunătățit mult mai mult. De acum, această versiune acceptă versiunea 4.3 / 5.0 și câteva versiuni modificate ale acesteia. De asemenea, optimizat cu noile actualizări a venit cu versiunea amxmodx 1.8.3. Privilegiile nu se vor pierde la prăbușirea serverului. 
În prezent, aceasta nu este o versiune stabilă, așadar nu vă recomandăm să o puneți pe server pentru o utilizare publică deplină, dar dacă doriți - sunteți binevenit. 
Majoritatea documentației găsiți în fișiere: zm_vip.cfg, vips.ini, zm_vip.inc
Descarcare:

sau

plugins-zm_vip.ini

Code: Select all

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                              ;;
;;   ZM VIP 2.0.0 plugins initialization file   ;;
;;   Author: aaarnas                            ;;
;;                                              ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Symbol - ; is a comment. Will be ingnored.
;; You can add comment before plugins to disable.
;;
;; Main plugin:
zm_vip.amxx

;; Extra VIP plugins (that has #include <zm_vip>
;; at the top of plugin). List copiled files here:

vips.ini

Code: Select all

//////////////////////////////////////////////////////////////////////////////
//                                               //
//   ZM VIP 2.0.0 privilegies set file.          //  Auth FLAGS:
//   Author: aaarnas                             //
//                                               //  a - multijump
///////////////////////////////////////////////////  b - extra armor
// Plugin automaticaly determines if auth        //  c - unlimited clip
// is nick/ip/steamid. No need to specify!       //  d - no fall damage
// If you need to use ip or steamid as nick,     //  e - extra damage reward
// add 'F' before line.                          //  f - extra damage delt
// Symbol - '/' or ';' for comment a line.       //  g - extra hp
// Symbol - 'X' prepare line for delete.         //  h - extra gravity
// (plugin adds 'X' as first symbol              //  i - extra frags
// automatically to mark line for delete)        //  j - extra kill ammo
///////// Pre flags:                             //  k - extra armor for kill
//   C - Auth contains in nick(team tag, etc)    //  l - extra infect ammo
//   N - Not case insensative nick (HAM != haM)  //  m - extra infect health
//   F - Force auth by nick (C,N also does this) //  n - extra items
//   K - Kick from server on invalid password    //  o - vip model
///////// Usage example:                         //  p - vip class
// CN"AUTH" "PASS" "FLAGS" (before line.         //  q - chat tag
// For all formats. Specify if needed).          //  r - vip in score board
///////// Examples:                              //  s - grenade immunity
// "AUTH" - uses all flags by cvar               //  t, u, v, w, x, y - [custom flags,
// "AUTH" "FLAGS" - auth with custom flags       //  does nothing. Can be used for other
// "AUTH" "FLAGS" |2050/01/20|14:15| auth with   //  plugins or functions]
// custom flags and privilegies end time.        //  z - dummy flag (for status)
// "AUTH" "PASS" "FLAGS" - auth with password    //  
// and custom flags. 0 in flags, to use default: //  z flag is used, if you want,
// "auth.." "password.." "0"                     //  to give VIP status for player
///////// Time format:                           //  without any abilities
//   |YEAR/MONTH/DAY|HOUR:MIN|                   //  
//////////////////////////////////////////////////////////////////////////////
// Privilegies lines (example):
;"STEAM_0:0:xxxxxxxxx" |2020/05/05|12:50|
;"xx.xx.xxx.xxx" "abdefhijklmnopqrs"
;K"nick" "password"
zm_vip.txt

Code: Select all

[en]
// Translated by: aaarnas
// Warnings
SERVER_CONFIG_ERROR = Server configuration error. Please tell server administrator about this
NO_VIP_TXT = This function disabled. Contact server administrator to solve this problem

// Command
USAGE = Usage
DOES_NOT_HAVE_VIP = Player "%s" does not have VIP privilege
PRIVILEGE_REMOVED = Player ^"%s^" VIP privilege has been removed
PLUGIN_ERROR_REMOVING = Plugin error removing VIP privilege for player "%s"

// Extra items
BUY_VIP = Buy VIP
NOT_ENOUGHT = Not enought
NO_ITEMS_FOR_TEAM = No items found for your team
NO_PLUGINS_LOADED = No extra plugins loaded

// VIP Buy
BUY_VIP_PRIVILEGE = Buy VIP privilege
PRICE = Price
TIME = Time
BUY = Buy
EXIT = Exit
PURCHASED_VIP = You have purchased a VIP privilege
PURCHASED_VIP_TILL_MD = You have purchased VIP till disconnect or mapchange
PURCHASED_VIP_TILL_D = You have purchased VIP till disconnect

TILL_MAPCHANGE = Till mapchange
TILL_DISCONNECT = Till disconnect (available during map changes)

TIMELEFT = timeleft

WEEK = week
WEEKS = weeks
WEEKSW = weeks
DAY = day
DAYS = days
DAYSW = days
HOUR = hour
HOURS = hours
HOURSW = hours
MINUTE = minute
MINUTES = minutes
MINUTESW = minutes
SECOND = second
SECONDS = seconds
SECONDSW = seconds
PERMANENT = Permanent

// VIP other
NO_VIP_ONLINE = There are no VIP player Online
ONLINE_VIPS = Online VIPs
ADMIN_CONTACTS = Administration contacts
CONNECTED_TO_SERVER = connected to server
INVALID_PASS = Invalid this nick password
PASS_NOT_MATCH = Client password not match! Privileges not granted
AMMO_PACKS = ammo packs
MONEY = Dolars
PURCHASED = Purchased
VIP_MENU_TOP = Vip Menu
ALREADY_VIP_INFO = You already have VIP. From more info, type /vip in chat
YOU_ARE_NOT_VIP = You are not a VIP member. Buy it (/vm)
YOU_ARE_NOT_VIP_INFO = You are not a VIP member. For more info type /vip in chat
YOU_ARE_NOT_VIP_MENU = You have to be a VIP to enter this menu
EXCEEDED_BUY_LIMIT = You exceeded buys limit per round. It's - %d. Please wait for the next round.
NOT_ALIVE = You have to be alive to use this menu
VIPONLY_CLASS = Your selected class in only for *VIP* members
VIPONLY_CLASS_INFO = Your selected class in only for *VIP* members. Please select another class
FREE_VIP_GOT = Free VIP enabled on server, and you got one! Use it till time ends
FREE_VIP_EXPIRED = Unfortunately, free VIP expired. You can't use privileges anymore

[lt]
// Translated by: aaarnas
// Warnings
SERVER_CONFIG_ERROR = Serverio konfigūracijos klaida. Apie tai prašome pranešti serverio administracijai
NO_VIP_TXT = Ši funkcija išjungta. Susisiekite su serverio administratoriumi, kad išspręsti šią problemą

// Command
USAGE = Naudojimas
DOES_NOT_HAVE_VIP = Žaidėjas "%s" neturi VIP privilegijos
PRIVILEGE_REMOVED = Žaidėjo ^"%s^" VIP privilegija pašalinta
PLUGIN_ERROR_REMOVING = Plugino klaida šalinant VIP privilegiją žaidėjui "%s"

// Extra items
BUY_VIP = Pirkti VIP
NOT_ENOUGHT = Nepakankamai
NO_ITEMS_FOR_TEAM = Nerasta pirkinių jūsų komandai
NO_PLUGINS_LOADED = Neužkrauti jokie vip extra pluginai

// VIP Buy
BUY_VIP_PRIVILEGE = Pirkti VIP privilegiją
PRICE = Kaina
TIME = Laikas
BUY = Pirkti
EXIT = Išeiti
PURCHASED_VIP = Jūs įsigijote VIP privilegiją
PURCHASED_VIP_TILL_MD = Jūs įsigijote VIP privilegiją iki atsijungimo nuo serverio ar žemėlapio pakeitimo
PURCHASED_VIP_TILL_D = Jūs įsigijote VIP privilegiją iki atsijungimo nuo serverio

TILL_MAPCHANGE = Iki žemėlapio pasikeitimo
TILL_DISCONNECT = Iki atsijungimo nuo serverio (galioja ir sekantį žemėlapį)

TIMELEFT = likęs laikas

WEEK = savaitė
WEEKS = savaitės
WEEKSW = savaičių
DAY = diena
DAYS = dienos
DAYSW = dienų
HOUR = valanda
HOURS = valandos
HOURSW = valandų
MINUTE = minutė
MINUTES = minutės
MINUTESW = minučių
SECOND = sekundė
SECONDS = sekundės
SECONDSW = sekundžių
PERMANENT = Visam laikui

// VIP other
NO_VIP_ONLINE = Nėra prisijungusių VIP žaidėjų
ONLINE_VIPS = Prisijungę VIP
ADMIN_CONTACTS = Administracijos kontaktai
CONNECTED_TO_SERVER = prisijungė į serverį
INVALID_PASS = Klaidingas šio nick'o slaptažodis
PASS_NOT_MATCH = Slaptažodižiai nesutampa! Privilegijos nesuteiktos
AMMO_PACKS = ammo paketai
MONEY = Dolerių
PURCHASED = Nusipirkta
VIP_MENU_TOP = Vip Meniu
ALREADY_VIP_INFO = Jūs jau turite VIP. Daugiau informacijos: /vip čate
YOU_ARE_NOT_VIP = Jūs nesate VIP narys. Nusipirkite jį (/vm)
YOU_ARE_NOT_VIP_INFO = Jūs nesate VIP narys. Daugiau informacijos: /vip čate
YOU_ARE_NOT_VIP_MENU = Jūs turite būti VIP narys, kad galėtumėte naudoti šį meniu
EXCEEDED_BUY_LIMIT = Jūs viršijote pirkimų limitą per raundą. Jis yra - %d. Laukite kito raundo.
NOT_ALIVE = Jūs turite būti gyvas, kad galėtumėte naudoti šį meniu
VIPONLY_CLASS = Jūsų pasirinkta klasė yra skirta tik *VIP* nariams
VIPONLY_CLASS_INFO = Jūsų pasirinkta klasė yra skirta tik *VIP* nariams. Prašome pasirinkti kitą
FREE_VIP_GOT = Serveryje įjungtas nemokamas VIP režimas. Laiknai turi VIP privilegijas ir gali jas naudotis, kol pasibaigs
FREE_VIP_EXPIRED = Deja, nemokamas VIP pasibaige. Nebegalite naudotis privilegijomis
zm_vip.inc

Code: Select all

/*****************************************************************************
 *      ZM VIP 2.0.0 inlcude file
 *      Author: aaarnas
 *
 *      To make extra items, classes controlable by ZM VIP, add:
 *      #include <zm_vip>
 *      at the end of other #include's in plugin .sma file. Then compile 
 *      plugin and add to server. You don't need to change anything. Just 
 *      include this file to plugin and go on. Easy!
 *
 *****************************************************************************
 *      Geek stuf:
 *      If you writing other plugins (not items or classes) or having problem 
 *      with compability error, you can disable it (if you know what you are 
 *      doing) by adding:
 *      #define ZM_VIP_DISABLE_AUTO_CONVERT
 *      at the top of plugin.
 *      For example, if you want to include <zm_vip> to extra item plugin and
 *      won't affect it to use with zombie VIP (left for main mod), add this
 *      define to the top of plugin and plugin will remains the same and you
 *      will be able to use all <zm_vip> natives and forwards.
 ****************************************************************************/
//----------------------------------------------------------------------------
// Natives
//----------------------------------------------------------------------------
/**
 *  Returns having player VIP flags. If @return > 0 - player is VIP.
 *  @id     - player id
 *	@return - vip flags (return 0 if player not connected)
 *  For flags values check vips.ini file or zm_vip.sma at line:
 *  "enum _:player_attributes"
 *  Example for check if player has VIP model attribute:
 *  if (zv_get_user_flags(id)&AT_VIP_MODEL)
 *
 *  If player is VIP:
 *  if (zv_get_user_flags(id))
 */
native zv_get_user_flags(id)

#define ZV_DURATION_IGNORE            -1
#define ZV_DURATION_PERMANENT         0
#define ZV_DURATION_TILL_DISCONNECT   ~'t'
#define ZV_DURATION_TILL_MAP          ~('t'|'m')
/**
 *  Set VIP flags for player.
 *  @id       - player id, 0 - all players
 *  @duration - time (in seconds), how long player will have VIP.
 *              Can be used ZV_DURATION_ constants.
 *  @flags    - flags, what attributes VIP player will have.
 *              All AT_ constants, or use AT_ALL for all attributes.
 *              If you want to just give a VIP status without any abbilities, use AT_NONE flag.
 *              Because VIP can't exist without any flags set, having only this dummy flag, player can
 *              remain in VIP status on the system.
 *  @return   - [true - VIP created/updated succesfully,
 *              false - used ZV_DURATION_IGNORE for player, that doesn't have VIP
 *                      or player is not connected to server]
 *
 *  NOTE: if id = 0, always returns true.
 *  Examples:
 *	If you want to set a new VIP:
 *      //player will get VIP privilegies for 2 days and only multijump and armor abbilities
 *      zv_set_user_flags(id, 60*60*24*2, AT_MULTIJUMP|AT_ARMOR)
 *      //player will get VIP all VIP privilegies for 30 days (1 month)
 *      zv_set_user_flags(id, 60*60*24*30, AT_ALL)
 *  Update existing:
 *      //update current user flags (adde extra gravity). Privilegie duration remains the same.
 *      //NOTE: if zv_set_user_flags(id, ZV_DURATION_IGNORE... will be called on player, that don't have privilegies
 *      //function will return false and no action will be taken. You need to set duration for first time.
 *      zv_set_user_flags(id, ZV_DURATION_IGNORE, zv_get_user_flags(id)|AT_EXTRA_GRAVITY)
 */
native zv_set_user_flags(id, duration, flags)

/**
 *  Remove player VIP privilegie
 *  @id          - player id, 0 - all players
 *  @return      - [true - success,
 *                  false - player not connected or doesn't have privilegies]
 *
 *  NOTE: if id = 0, always returns true.
 */
native zv_remove_user_flags(id)

/**
 *  Get count of currently existing registered VIPs
 *  @return       - VIP'S count;
 */
native zv_get_vips_num()

//----------------------------------------------------------------------------
// Attributes (Flags)
//----------------------------------------------------------------------------
#define AT_ALL                  0
#define AT_MULTIJUMP            (1<<0) // a
#define AT_ARMOR                (1<<1) // b
#define AT_UNLIMITED_CLIP       (1<<2) // c
#define AT_NO_FALL_DMG          (1<<3) // d
#define AT_DAMAGE_REWARD	(1<<4) // e
#define AT_EXTRA_DMG            (1<<5) // f
#define AT_EXTRA_HP             (1<<6) // g
#define AT_EXTRA_GRAVITY        (1<<7) // h
#define AT_EXTRA_FRAGS          (1<<8) // i
#define AT_EXTRA_KILL_AMMO      (1<<9) // j
#define AT_EXTRA_ARMOR          (1<<10) // k
#define AT_EXTRA_INFECT_AMMO    (1<<11) // l
#define AT_EXTRA_INFECT_HEALTH  (1<<12) // m
#define AT_EXTRA_ITEMS          (1<<12) // n
#define AT_VIP_MODEL            (1<<14) // o
#define AT_VIP_CLASS            (1<<15) // p
#define AT_CHATTAG              (1<<16) // q
#define AT_VIPINSCORE           (1<<17) // r
#define AT_CUSTOM_S     	(1<<18) // s
#define AT_CUSTOM_T		(1<<19) // t
#define AT_CUSTOM_U		(1<<20) // u
#define AT_CUSTOM_V		(1<<21) // v
#define AT_CUSTOM_W		(1<<22) // w
#define AT_CUSTOM_X		(1<<23) // x
#define AT_CUSTOM_Y		(1<<24) // y
#define AT_NONE                 (1<<25) // z

//////////////////////////////////////////////////////////////////////////////
///          Technical stuff, you don't need to do anything below          ///
//////////////////////////////////////////////////////////////////////////////
#pragma reqlib zm_vip
	#if !defined AMXMODX_NOAUTOLOAD
	#pragma loadlib zm_vip
#endif
//Workaround for #elseif bug.
#if !(defined ZM_VIP_DISABLE_AUTO_CONVERT) && defined _zombieplague_included
	native zv_force_buy_extra_item(id, itemid, ignorecost = 0)
	native zv_get_extra_item_id(const name[])
	forward zv_extra_item_selected(id, itemid)
	native zv_register_extra_item(const name[], const description[], cost, team)
	native zv_register_extra_item2(const name[], cost, teams)
	native zv_register_zombie_class(const name[], const info[], const model[], const clawmodel[], hp, speed, Float:gravity, Float:knockback)
	#define zp_force_buy_extra_item zv_force_buy_extra_item
	#define zp_get_extra_item_id zv_get_extra_item_id
	#define zp_extra_item_selected zv_extra_item_selected
	#define zp_register_extra_item zv_register_extra_item2
	#define zp_register_zombie_class zv_register_zombie_class
#endif
#if !(defined ZM_VIP_DISABLE_AUTO_CONVERT) && defined _zp50_items_included
	native zv_items_register(const name[], cost)
    #define zp_items_register zv_items_register
#endif
#if !(defined ZM_VIP_DISABLE_AUTO_CONVERT) && defined _zp50_class_zombie_included
	native zv_class_zombie_register(const name[], const description[], health, Float:speed, Float:gravity)
	#define zp_class_zombie_register zv_class_zombie_register
#endif
#if !(defined ZM_VIP_DISABLE_AUTO_CONVERT) && defined _zp50_class_human_included
	native zv_class_human_register(const name[], const description[], health, Float:speed, Float:gravity)
    #define zp_class_human_register zv_class_human_register
#endif
#if !(defined _zp50_items_included) && !(defined _zombieplague_included) && !(defined _zp50_class_zombie_included) && !(defined _zp50_class_human_included) && !(defined ZM_VIP_DISABLE_AUTO_CONVERT)
	#error "Unknown plugin type. ZM VIP can't do anything with this plugin, or #include <zm_vip> is not at the end of other includes. Plugin should be zombie/human class or extra item"
#endif
zm_vip.sma

Code: Select all

/* Plugin generated by AMXX-Studio */
/* -------------------------------------------------------------------------------------------------

             _____    __  ___   _    __ ____ ____     ___      ____     ____ 
            /__  /   /  |/  /  | |  / //  _// __ \   |__ \    / __ \   / __ \
              / /   / /|_/ /   | | / / / / / /_/ /   __/ /   / / / /  / / / /
             / /__ / /  / /    | |/ /_/ / / ____/   / __/ _ / /_/ /_ / /_/ / 
            /____//_/  /_/     |___//___//_/       /____/(_)\____/(_)\____/  
								BETA VERSION!!!
	    
	Zombie Plague 4.3/5.0 Addon
	ZM VIP - Zombie Plague VIP addon that enables special abilities for players
	and adds VIP system, status and API to server.
	
	Official thread: https://forums.alliedmods.net/showthread.php?t=119719
	
	Author: aaarnas

--------------------------------------------------------------------------------------------------*/

// Ignore thease. Just values for settings.
#define OFF 0
#define ON 1
#define FORCED 2
#define NEW 1
#define OLD 2
#define VAULT 1

#define VERSION "1.9.1 BETA"

// --------------- USER CONFIGURATION START --------------- USER CONFIGURATION START ---------------
// --------------- USER CONFIGURATION START --------------- USER CONFIGURATION START ---------------
// --------------- USER CONFIGURATION START --------------- USER CONFIGURATION START ---------------
// --------------- USER CONFIGURATION START --------------- USER CONFIGURATION START ---------------
// -------------------------------------------------------------------------------------------------
// Choose your using zombie plague version:
// NEW		- Zombie Plague 5.0 or later. (zp_plugin_50.zip | zp508a.zip and later ... )
// OLD		- Zombie Plague 4.3 or earlier. (zp_plugin_43.zip)
// Zombie Plague Advanced - Not supported.
// Daugiau pluginu https://forums.alliedmods.net/showthread.php?t=242196?t=242196

#define MODIFICATION NEW
// -------------------------------------------------------------------------------------------------
// Set wich system to use loading privileges:
// FORCED - Just vips.ini file. Ignores amxmodx.
// ON   - vips.ini and amxmodx (users.ini/database (flag t))
// OFF  - Disables vips.ini file and reads only from amxmodx (users.ini/database (flag t))
#define VIPS_FILE_SYSTEM ON
// -------------------------------------------------------------------------------------------------
// Set if you want to enable extra items menu system (/vm)
// ON  - Enabled
// OFF - Dissabled
#define EXTRA_ITEMS ON
// -------------------------------------------------------------------------------------------------
// Vip privileges flag in users.ini file (t) if NOT using VIPS_FILE_SYSTEM [FORCED] mode. 
#define VIP_SYS_FLAG ADMIN_LEVEL_H
// -------------------------------------------------------------------------------------------------
// Admin flag (from users.ini). Allow access to VIP admin panel, zm_vip_freevip_hour cvar(cmd). 
#define ADMIN_SYS_FLAG ADMIN_LEVEL_E //(ADMIN_LEVEL_E flag is "q")
// -------------------------------------------------------------------------------------------------
// Name of configs/vips.ini|zm_cip.cfg file. In fact, no reason to change.
#define VIPS_FILE "vips.ini"
#define CONFIGS_FILE "zm_vip.cfg"
// -------------------------------------------------------------------------------------------------
//--------------- USER CONFIGURATION END --------------- USER CONFIGURATION END ---------------
//--------------- USER CONFIGURATION END --------------- USER CONFIGURATION END ---------------
//--------------- USER CONFIGURATION END --------------- USER CONFIGURATION END ---------------
//--------------- USER CONFIGURATION END --------------- USER CONFIGURATION END ---------------
//--------------- USER CONFIGURATION END --------------- USER CONFIGURATION END ---------------
//////////////////////////// Editing anyting further - taking own risk /////////////////////////////
////////// This means - no support. Using/stealing anything without credits - not allowed //////////

#define EMPTY(%1) (%1[0]==EOS)
#define BIT(%1) (1<<%1)
#define FLAG_A (1<<0)
#define FLAG_B (1<<1)
#define FLAG_C (1<<2)
#define FLAG_D (1<<3)
#define FLAG_E (1<<4)
#define FLAG_F (1<<4)
#define FLAG_K (1<<10)
#define FLAG_N (1<<13)

#define LOAD_FROM_INI	(1<<31)
#define LOAD_FROM_DAT	(1<<30)
#define LOAD_FROM_AMX	(1<<29)
#define LOAD_FROM_NAMES	(1<<28)
#define LOAD_FROM_MAIN	(1<<27)
#define LOAD_MASK	0xFC000000

#include <amxmodx>
#include <amxmisc>
#include <hamsandwich>
#include <fakemeta>
#include <engine>
#include <fun>
#include <regex>
#if MODIFICATION == NEW
#include <cstrike>
#define ZP_ITEM_AVAILABLE 0
#define ZP_ITEM_NOT_AVAILABLE 1
#define ZP_ITEM_DONT_SHOW 2
#define ZP_CLASS_AVAILABLE 0
#define ZP_CLASS_NOT_AVAILABLE 1
#define ZP_CLASS_DONT_SHOW 2
native zp_core_is_zombie(id)
forward zp_fw_core_spawn_post(id)
forward zp_fw_core_infect_pre(id, attacker)
forward zp_fw_core_infect_post(id, attacker)
forward zp_fw_core_cure_post(id, attacker)
native zp_ammopacks_get(id)
native zp_ammopacks_set(id, amount) 
native zp_class_human_menu_text_add(const text[])
forward zp_fw_class_human_select_pre(id, classid)
native zp_class_human_register(const name[], const description[], health, Float:speed, Float:gravity)
native zp_class_zombie_menu_text_add(const text[])
forward zp_fw_class_zombie_select_pre(id, classid)
native zp_class_zombie_register(const name[], const description[], health, Float:speed, Float:gravity)
native zp_items_register(const name[], cost)
forward zp_fw_items_select_pre(id, itemid, ignorecost)
forward zp_fw_items_select_post(id, itemid, ignorecost)
native zp_items_show_menu(id)
native zp_items_menu_text_add(const text[]) 
native cs_set_player_model(id, const model[])
forward zp_fw_grenade_fire_pre(id)
forward zp_fw_grenade_frost_pre(id)
#else
native zp_get_user_bombardier(id)
#define ZP_TEAM_ANY 0
native zp_get_user_zombie(id)
native zp_get_user_next_class(id)
native zp_set_user_zombie_class(id, classid)
native zp_register_zombie_class(const name[], const info[], const model[], const clawmodel[], hp, speed, Float:gravity, Float:knockback)
native zp_override_user_model(id, const newmodel[], modelindex = 0)
native zp_get_user_nemesis(id)
native zp_get_user_survivor(id)
forward zp_user_infect_attempt(id, infector, nemesis)
forward zp_user_infected_post(id, infector, nemesis)
forward zp_user_humanized_post(id, survivor)
forward zp_user_infected_pre(id, infector, nemesis)
forward zp_extra_item_selected(id, itemid)
forward zp_round_started(gamemode, id)
native zp_register_extra_item(const name[], cost, teams)
native zp_force_buy_extra_item(id, itemid, ignorecost = 0)
native zp_get_extra_item_id(const name[])
native zp_get_user_ammo_packs(id)
native zp_set_user_ammo_packs(id, amount)
#define ZP_PLUGIN_HANDLED 97
#endif

new cvar_multijump, cvar_multijump_allow, cvar_armor, cvar_extra_hp_human, cvar_extra_hp_zombie,
cvar_extra_gravity_human, cvar_extra_gravity_zombie ,cvar_unlimited_clip, cvar_no_fall_dmg, 
cvar_extra_dmg, cvar_extra_frags, cvar_extra_kill_ammo, cvar_extra_armor, cvar_extra_infect_ammo,
cvar_extra_infect_health, cvar_extra_ignore_for_special, cvar_damage_reward, cvar_viponly_class,
cvar_chat_viptag, cvar_vip_connected_to_server, cvar_freevip_flags, cvar_vipniscoretable,
cvar_grenades_immunity, cvar_gamemode_disable_flags
#if VIPS_FILE_SYSTEM != FORCED
new cvar_amx_auth_flags
#endif
#if VIPS_FILE_SYSTEM != OFF
new cvar_vip_store_ini
#endif
new cvar_amxmodx_flags, cvar_vip_price, cvar_vip_buy_duration, cvar_vip_buy_flags,
cvar_vip_buy_in_extra_items

#if EXTRA_ITEMS == ON
new cvar_buys_per_round
#if MODIFICATION == OLD
new chached_show_vip_items
#else
new cvar_vip_show_vip_items
#endif
#endif

enum _:player_attributes
{
	AT_MULTIJUMP,		//a(0)
	AT_ARMOR,		//b(1)
	AT_UNLIMITED_CLIP,	//c(2)
	AT_NO_FALL_DMG,		//d(3)
	AT_DAMAGE_REWARD,	//e(4)
	AT_EXTRA_DMG,		//f(5)
	AT_EXTRA_HP,		//g(6)
	AT_EXTRA_GRAVITY,	//h(7)
	AT_EXTRA_FRAGS,		//i(8)
	AT_EXTRA_KILL_AMMO,	//j(9)
	AT_EXTRA_ARMOR,		//k(10)
	AT_EXTRA_INFECT_AMMO,	//l(11)
	AT_EXTRA_INFECT_HEALTH,	//m(12)
	AT_EXTRA_ITEMS,		//n(13)
	AT_VIP_MODEL,		//o(14)
	AT_VIP_CLASS,		//p(15)
	AT_CHATTAG,		//q(16)
	AT_VIPINSCORE,		//r(17)
	AT_GRENADE_IMMUNITY	//s(18)
}

new p_attribs[33][player_attributes]

#define AT_NONE		(1<<25) // z

#define ZV_DURATION_IGNORE		-1
#define ZV_DURATION_PERMANENT		0
#define ZV_DURATION_TILL_DISCONNECT	~'t'
#define ZV_DURATION_TILL_MAP		~('t'|'m')

enum ClassType:cltypes {
	EXTRA_ITEM = 1,
	CLASS_ZOMBIE,
	CLASS_HUMAN
}
#define VipsItemHandle trie_vip_items
new Trie:trie_vip_items

new p_bought_per_round[33]
new bool:p_zombie[33]
new p_jumpsnum[33]
new Float:p_damage[33]
new Float:p_grenade_time[33]

new p_vip_model_zombie[15]
new p_vip_model_human[15]

new is_amxmodx_new_version
#if MODIFICATION == NEW
new is_module_ammopacks_loaded
#endif

new Trie:trie_vips_database
new Array:array_vips_database
new Array:array_vips_database_nick
new amx_password_field_string[30]
enum _:VipCnt {
	
	INI,
	DAT,
	MAIN,
	NAMES,
	AMX
}
new total_vips_count[VipCnt] //0 - main, 1 - names, 2 - amx
#define VIPCNT(%1) total_vips_count[%1]
#define VIPINC(%1) total_vips_count[%1]++
#define VIPDEC(%1) total_vips_count[%1]--
enum _:vips_database_type
{
	AUTH[40],
	PASS[30],
	SETTINGS,
	FLAGS,
	TIMESTAMP,
	INDEX
}
new p_data[33][vips_database_type]

#if EXTRA_ITEMS == ON
new registered_extra_items_num
#if MODIFICATION == NEW
new bool:p_views_extra_items_menu[33]
#else
enum _:item_struct {
	
	item_plid,
	item_name[100],
	item_cost,
	item_team
}
#define ZP_TEAM_ZOMBIE (1<<0)
#define ZP_TEAM_HUMAN (1<<1)
#define ZP_TEAM_NEMESIS (1<<2)
#define ZP_TEAM_SURVIVOR (1<<3)
new Array:array_vip_extra_items
new fw_extraitemselected
#endif
#endif

new vip_buy_extra_item = -1

new current_gamemode

new bool:freevip_enabled
new bool:freevip_inform[33]
new bool:first_spawn[33]
new freevip_hours[4]
new maxplayers
new msg_saytext
new msg_scoreattrib

new const MAXCLIP[] = { -1, 13, -1, 10, 1, 7, -1, 30, 30, 1, 30, 20, 25, 30, 35, 25, 12, 20, 10, 30, 100, 8, 30, 30, 20, 2, 7, 30, 30, -1, 50 }

#define IS_PLAYER(%1) (1<=%1<=maxplayers)
#define ATTRIB(%1,%2) p_attribs[%1][%2]

#define CURRENCY_MONEY 0
#define CURRENCY_AMMO_PACKS 1
public plugin_init() {
	
	register_plugin("ZM VIP", VERSION, "aaarnas") 
	register_dictionary("zm_vip.txt")

	new amxmodx_version[20], amxmodx_version_num
	get_amxx_verstring(amxmodx_version, charsmax(amxmodx_version))
	replace_all(amxmodx_version, charsmax(amxmodx_version), ".", "")
	amxmodx_version_num = str_to_num(amxmodx_version)
	is_amxmodx_new_version = amxmodx_version_num>=183
	
	/////////////////////// CVARS REGISTRATION ///////////////////////
	cvar_multijump = register_cvar("zm_vip_mutijump", "1")
	cvar_multijump_allow = register_cvar("zm_vip_multijump_allow", "ab")
	cvar_armor = register_cvar("zm_vip_armor", "65")
	cvar_unlimited_clip = register_cvar("zm_vip_unlimited_clip", "0")
	cvar_no_fall_dmg = register_cvar("zm_vip_no_fall_dmg", "1")
	cvar_extra_dmg = register_cvar("zm_vip_extra_dmg", "1.2")
	cvar_extra_hp_human = register_cvar("zm_vip_extra_hp_human", "50")
	cvar_extra_hp_zombie = register_cvar("zm_vip_extra_hp_zombie", "500")
	cvar_extra_gravity_human = register_cvar("zm_vip_extra_gravity_human", "0")
	cvar_extra_gravity_zombie = register_cvar("zm_vip_extra_gravity_zombie", "0")
	cvar_extra_frags = register_cvar("zm_vip_extra_frags", "0")
	cvar_extra_kill_ammo = register_cvar("zm_vip_extra_kill_ammo", "1")
	cvar_extra_armor = register_cvar("zm_vip_extra_armor", "0")
	cvar_extra_infect_ammo = register_cvar("zm_vip_extra_infect_ammo", "1")
	cvar_extra_infect_health = register_cvar("zm_vip_extra_infect_health", "100")
	cvar_extra_ignore_for_special = register_cvar("zm_vip_extra_ignore_for_special", "1")
	cvar_damage_reward = register_cvar("zm_vip_damage_reward", "1000")
	cvar_viponly_class = register_cvar("zm_viponly_class", "1")
	cvar_chat_viptag = register_cvar("zm_vip_chattag", "1")
	cvar_vip_connected_to_server = register_cvar("zm_vip_connected_to_server", "1") // 1-chat/2-hud/3-dhud
	cvar_vipniscoretable = register_cvar("zm_vipinscoretable", "1")
#if VIPS_FILE_SYSTEM != FORCED
	cvar_amx_auth_flags = register_cvar("zm_vip_amx_auth_flags", "0") 
#endif
	cvar_amxmodx_flags = register_cvar("zm_vip_amxmodx_flags", "t")
	cvar_grenades_immunity = register_cvar("zm_vip_grenades_immunity", "0")
	cvar_gamemode_disable_flags = register_cvar("zm_vip_gamemode_disable_flags", "0")
	register_concmd("zm_vip_freevip_hour", "set_freevip_hour", ADMIN_CVAR)
	cvar_freevip_flags = register_cvar("zm_vip_freevip_flags", "0")
#if VIPS_FILE_SYSTEM != OFF
	cvar_vip_store_ini = register_cvar("zm_vip_store_ini", "0")
#endif
	cvar_vip_price = register_cvar("zm_vip_price", "0")
	cvar_vip_buy_duration = register_cvar("zm_vip_buy_duration", "1d") // 1h - val, 1d - day// t - tepm/ tm - temp till map
	
	cvar_vip_buy_flags = register_cvar("zm_vip_buy_flags", "0")
	cvar_vip_buy_in_extra_items = register_cvar("zm_vip_buy_in_extra_items", "1")
	
#if EXTRA_ITEMS == ON
	cvar_buys_per_round = register_cvar("zm_vip_buys_per_round", "0")
#if MODIFICATION == NEW
	cvar_vip_show_vip_items = register_cvar("zm_vip_show_vip_items", "2")
#endif
#if MODIFICATION != NEW
	fw_extraitemselected = CreateMultiForward("zv_extra_item_selected", ET_CONTINUE, FP_CELL, FP_CELL)
#endif
#endif	
	maxplayers = get_maxplayers()
	
	msg_saytext = get_user_msgid("SayText")
	msg_scoreattrib = get_user_msgid("ScoreAttrib")
	
	register_clcmd("say /vm", "show_vip_menu")
	register_clcmd("open_vip_menu", "show_vip_menu_console")
	register_clcmd("say /vip", "show_vip_info")
	register_clcmd("say /vips", "show_vips_online")
	
	register_concmd("zm_vip_list", "cmd_list_vips", ADMIN_SYS_FLAG)
	register_concmd("amx_reloadvips", "cmd_vips_reload", ADMIN_SYS_FLAG)
	register_concmd("zm_vip_reload", "cmd_vips_reload", ADMIN_SYS_FLAG)
	register_concmd("zm_vip_remove", "cmd_vips_remove", ADMIN_SYS_FLAG)
	
	register_menu("Menu Buy", MENU_KEY_0|MENU_KEY_1, "forward_buy_menu_handler")
	
	register_event("HLTV", "forward_event_round_start", "a", "1=0", "2=0")
	register_event("DeathMsg", "forward_event_deathmsg", "a")
	register_event("ResetHUD", "forward_event_reset_hud", "be")
	register_message(get_user_msgid("CurWeapon"), "message_cur_weapon")
	register_message(msg_saytext, "message_say_text")
	register_forward(FM_CmdStart, "forward_cmdstart")
#if MODIFICATION != NEW
	RegisterHam(Ham_Spawn, "player", "forward_player_spawn", 1)
#endif
	RegisterHam(Ham_TakeDamage, "player", "forward_player_takedamage_pre")
	RegisterHam(Ham_TakeDamage, "player", "forward_player_takedamage_post", 1)
	RegisterHam(Ham_Think, "grenade", "forward_grenade_think")
	
	trie_vips_database = TrieCreate()
	array_vips_database = ArrayCreate(45, 15)
	
	register_cvar("zp_vip_version", VERSION, FCVAR_SERVER|FCVAR_SPONLY)
	set_cvar_string("zp_vip_version", VERSION)
}


public plugin_natives() {

	register_library("zm_vip")

	set_native_filter("native_filter")
	
	register_native("zv_get_user_flags", "native_zv_get_user_flags")
	register_native("zv_set_user_flags", "native_zv_set_user_flags")
	register_native("zv_remove_user_flags", "native_zv_remove_user_flags")

#if MODIFICATION == NEW
#if EXTRA_ITEMS == ON
	register_native("zv_items_register", "native_zv_items_register", 1)
#endif
	register_native("zv_class_human_register", "native_zv_class_human_register", 1)
	register_native("zv_class_zombie_register", "native_zv_class_zombie_register", 1)
#else
	register_native("zv_register_zombie_class", "native_zv_register_zombie_class", 1)
#if EXTRA_ITEMS == ON	
	register_native("zv_register_extra_item", "native_zv_register_extra_item", 1)
	register_native("zv_register_extra_item2", "native_zv_register_extra_item2", 1)
	register_native("zv_force_buy_extra_item", "native_zv_force_buy_extra_item", 1)
	register_native("zv_get_extra_item_id", "native_zv_get_extra_item_id", 1)
#endif
#endif
}
#if MODIFICATION == NEW
native zp_class_nemesis_get(id)
native zp_class_survivor_get(id)
native zp_class_assassin_get(id)
native zp_class_sniper_get(id)
#endif
new natives_filter_out
enum {
	NATIVE_ZP_CLASS_NEMESIS_GET,
	NATIVE_ZP_CLASS_SURVIVOR_GET,
	NATIVE_ZP_CLASS_ASSASSIN_GET,
	NATIVE_ZP_CLASS_SNIPER_GET,
	NATIVE_ZP_CLASS_BOMBARDIER_GET,
	NATIVE_OVERRIDE_USER_MODEL
}
public native_filter(const name[], index, trap) {
	
	if (!trap) {
#if MODIFICATION == NEW
		if (equal(name, "zp_class_nemesis_get")) natives_filter_out |= BIT(NATIVE_ZP_CLASS_NEMESIS_GET)
		else if(equal(name, "zp_class_survivor_get")) natives_filter_out |= BIT(NATIVE_ZP_CLASS_SURVIVOR_GET)
		else if(equal(name, "zp_class_assassin_get")) natives_filter_out |= BIT(NATIVE_ZP_CLASS_ASSASSIN_GET)
		else if(equal(name, "zp_class_sniper_get")) natives_filter_out |= BIT(NATIVE_ZP_CLASS_SNIPER_GET)
#else
		if (equal(name, "zp_get_user_bombardier")) natives_filter_out |= BIT(NATIVE_ZP_CLASS_BOMBARDIER_GET)
#endif
#if MODIFICATION == OLD
		else if (equal(name, "zp_override_user_model")) {
			p_vip_model_zombie[0] = EOS
			p_vip_model_human[0] = EOS
			log_amx("ERROR: Vip models are not compatible with old Zombie Plague 4.3 version. Use Zombie Plague 4.3 patched or 5.0 to enable this feature.")
			log_amx("Download: https://forums.alliedmods.net/showthread.php?t=72505"&#41;
			natives_filter_out |= BIT(NATIVE_OVERRIDE_USER_MODEL)
		}
		else if (equal(name, "zp_get_user_zombie")) {
			set_fail_state("ERROR: This plugin compiled with MODIFICATION - OLD setting. \
			This supports only Zombie plague 4.3 versions.^nPlugin was unable to\
			detect this version, so probably, modification is incorrect.")
		}
#endif
		else {
			return PLUGIN_CONTINUE;
		}
		return PLUGIN_HANDLED;
			
	}
	return PLUGIN_CONTINUE;
}

public plugin_precache() {
#if EXTRA_ITEMS == ON && MODIFICATION == OLD
	new value_str[5]
	read_config("zm_vip_show_vip_items", value_str, charsmax(value_str))
	chached_show_vip_items = str_to_num(value_str)
#endif	
#if MODIFICATION == NEW
	read_config("zm_vip_model_zombie", p_vip_model_zombie, charsmax(p_vip_model_zombie))
	read_config("zm_vip_model_human", p_vip_model_human, charsmax(p_vip_model_human))

	if (!EMPTY(p_vip_model_zombie)) {
		
		new model_path[128]
		formatex(model_path, charsmax(model_path), "models/player/%s/%s.mdl", p_vip_model_zombie, p_vip_model_zombie)
		precache_model(model_path)
		formatex(model_path, charsmax(model_path), "models/player/%s/%sT.mdl", p_vip_model_zombie, p_vip_model_zombie)
		if (file_exists(model_path)) precache_model(model_path)
	}
	if (!EMPTY(p_vip_model_human)) {
		
		new model_path[128]
		formatex(model_path, charsmax(model_path), "models/player/%s/%s.mdl", p_vip_model_human, p_vip_model_human)
		precache_model(model_path)
		formatex(model_path, charsmax(model_path), "models/player/%s/%sT.mdl", p_vip_model_human, p_vip_model_human)
		if (file_exists(model_path)) precache_model(model_path)
	}
#endif
}
public plugin_cfg() {
#if MODIFICATION == NEW	

	if (!LibraryExists("zp50_core", LibType_Library))
		set_fail_state("ERROR: This plugin compiled with MODIFICATION - NEW setting. \
		This supports only Zombie plague 5 version and higher.^nPlugin was unable to\
		detect main Zombie Plague Core plugin.")
		
	is_module_ammopacks_loaded = LibraryExists("zp50_ammopacks", LibType_Library)
#endif
	new file_link[45]
	get_configsdir(file_link, charsmax(file_link))
	format(file_link, charsmax(file_link), "%s/%s", file_link, CONFIGS_FILE)
	if (file_exists(file_link)) {
		server_cmd("exec %s", file_link)
		server_exec()
	}
	else {
		log_amx("WARNING: Missing ^"%s^" file in configs folder. Can't load cvars values.", CONFIGS_FILE)
	}
	
	get_cvar_string("amx_password_field", amx_password_field_string, charsmax(amx_password_field_string))
#if VIPS_FILE_SYSTEM != OFF
	load_ini_file()
#endif
	load_datafile()
		
#if VIPS_FILE_SYSTEM != FORCED
	new num = admins_num()
	for (new i=0; i<num; i++) {
		if (admins_lookup(i, AdminProp_Access)&VIP_SYS_FLAG) {
			VIPINC(AMX)
		}
	}
#endif
	if (!VIPCNT(DAT) && !VIPCNT(INI) && !VIPCNT(AMX))
		log_amx("WARNING: No VIPs loaded from zm_vip system. Maybe there aren't any.")
		
	if (get_pcvar_num(cvar_vip_price) > 0 && get_pcvar_num(cvar_vip_buy_in_extra_items)) {
		
		new buy_vip_text[30], langid = LANG_SERVER
		LookupLangKey(buy_vip_text, charsmax(buy_vip_text), "BUY_VIP", langid)
#if MODIFICATION == NEW
		vip_buy_extra_item = zp_items_register(buy_vip_text, get_pcvar_num(cvar_vip_price))
#else
		vip_buy_extra_item = zp_register_extra_item(buy_vip_text, get_pcvar_num(cvar_vip_price), ZP_TEAM_ANY)
#endif
	}
	
#if EXTRA_ITEMS == ON
	if (!registered_extra_items_num)
		log_amx("WARRNING: No vip extra item plugins loaded.")
#endif
	set_task(1.0, "vip_time_check", 0, _, _, "b")
	
	server_print("-------------------------------------------------------------------------------")
	server_print("This server using ZM VIP %s by aaarnas", VERSION)
	server_print("Successfully loaded %d VIPs", VIPCNT(DAT)+VIPCNT(INI)+VIPCNT(AMX))
	server_print("-------------------------------------------------------------------------------")
}

_get_pcvar_flags(pcvar) {

	new flags[30]
	get_pcvar_string(pcvar, flags, charsmax(flags))
	
	if (flags[0] == '0')
		return 0;
	
	return read_flags(flags);
}
set_user_atribs(id, double_attrib_update = false) {
	
	if (id == 0) return;
		
	new hour_flags = 0
	
	new gamemode_disable_flags = 0
	if (current_gamemode != 0) {
		gamemode_disable_flags = _get_pcvar_flags(cvar_gamemode_disable_flags)
	}
	
	if(freevip_enabled && freevip_hour_check()) {
			
		hour_flags = _get_pcvar_flags(cvar_freevip_flags)
		if (hour_flags == 0)
			hour_flags = -1
		
		if (!freevip_inform[id]) {
			freevip_inform[id] = true
			if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L!", id, "FREE_VIP_GOT")
			else _client_print_color(id, "^4[ZMVIP] ^1%L!", id, "FREE_VIP_GOT")
			client_cmd(id, "spk /sound/buttons/bell1.wav")
		}
	}
	else if (freevip_inform[id]) {
		freevip_inform[id] = false
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L...", id, "FREE_VIP_EXPIRED")
		else _client_print_color(id, "^4[ZMVIP] ^1%L...", id, "FREE_VIP_EXPIRED")
		client_cmd(id, "spk /sound/buttons/blip1.wav")
	}
	
	static i, d, value
	static const double_attribs[] = {
		AT_MULTIJUMP,
		AT_EXTRA_HP,
		AT_EXTRA_GRAVITY
	}
	d = 0
	
	for(i=0; i<player_attributes;) {
		
		if (double_attrib_update) {
			
			if (d >= sizeof(double_attribs))
				break;
				
			i = double_attribs[d++];
		}	
		
		if (p_data[id][FLAGS] == 0 && hour_flags == 0)
			break;
		
		if (!(BIT(i) & p_data[id][FLAGS]) && !(BIT(i) & hour_flags) || (BIT(i) & gamemode_disable_flags)) {
			i++
			continue;
		}
		
		value = 0
		switch(i) {
			case AT_MULTIJUMP: {
				new jnum = get_pcvar_num(cvar_multijump)
				if(jnum) {
					static nflags, isspecial
					nflags = _get_pcvar_flags(cvar_multijump_allow)
					isspecial = is_special_character(id)
					
					if((nflags & FLAG_A && !p_zombie[id]) || (nflags & FLAG_B && p_zombie[id]) && !isspecial) value = jnum
					else if((nflags & FLAG_C && !p_zombie[id]) || (nflags & FLAG_D && p_zombie[id]) && isspecial) value = jnum
				}
			}
			case AT_ARMOR: value = get_pcvar_num(cvar_armor)
			case AT_UNLIMITED_CLIP: value = get_pcvar_num(cvar_unlimited_clip)
			case AT_NO_FALL_DMG: value = get_pcvar_num(cvar_no_fall_dmg)
			case AT_EXTRA_DMG: value = ((get_pcvar_float(cvar_extra_dmg)>0)?1:0)
			case AT_EXTRA_HP: value = get_pcvar_num(p_zombie[id]?cvar_extra_hp_zombie:cvar_extra_hp_human)
			case AT_EXTRA_GRAVITY: value = (get_pcvar_float(p_zombie[id]?cvar_extra_gravity_zombie:cvar_extra_gravity_human)>0.0)?1:0
			case AT_EXTRA_FRAGS: value = get_pcvar_num(cvar_extra_frags)
			case AT_EXTRA_KILL_AMMO: value = get_pcvar_num(cvar_extra_kill_ammo)
			case AT_EXTRA_ARMOR: value = get_pcvar_num(cvar_extra_armor)
			case AT_EXTRA_INFECT_AMMO: value = get_pcvar_num(cvar_extra_infect_ammo)
			case AT_EXTRA_INFECT_HEALTH: value = get_pcvar_num(cvar_extra_infect_health)
#if EXTRA_ITEMS == ON
			case AT_EXTRA_ITEMS: value = p_data[id][FLAGS]?1:0
#endif
			case AT_DAMAGE_REWARD: value = get_pcvar_num(cvar_damage_reward)
#if MODIFICATION != OLD
			case AT_VIP_MODEL: value = (p_vip_model_zombie[0]!=EOS||p_vip_model_human[0]!=EOS)
#endif
			case AT_VIP_CLASS: value = get_pcvar_num(cvar_viponly_class)
			case AT_CHATTAG: value = get_pcvar_num(cvar_chat_viptag)
			case AT_VIPINSCORE: value = get_pcvar_num(cvar_vipniscoretable)
			case AT_GRENADE_IMMUNITY: value = _get_pcvar_flags(cvar_grenades_immunity)
		}
		ATTRIB(id, i) = value
		
		if (!double_attrib_update)
			i++
	}
}
public forward_event_round_start() {
		
	arrayset(p_bought_per_round, 0, sizeof(p_bought_per_round))
	current_gamemode = 0
}
public forward_event_deathmsg() {
	
	static attacker, victim
	attacker = read_data(1)
	victim = read_data(2)
	
	if (attacker == victim)
		return;
		
	if(IS_PLAYER(attacker)) {
		if (get_pcvar_num(cvar_extra_ignore_for_special) && is_special_character(attacker))
			return;
			
		if (ATTRIB(attacker, AT_EXTRA_ARMOR) && !p_zombie[attacker] && p_zombie[victim])
			set_user_armor(attacker, get_user_armor(attacker)+ATTRIB(attacker, AT_EXTRA_ARMOR))
		if(ATTRIB(attacker, AT_EXTRA_KILL_AMMO))
			zv_currency_give(attacker, p_attribs[attacker][AT_EXTRA_KILL_AMMO])
		if(ATTRIB(attacker, AT_EXTRA_FRAGS))
			set_user_frags(attacker, get_user_frags(attacker)+ATTRIB(attacker, AT_EXTRA_FRAGS))
	}			
}

public forward_event_reset_hud(id) {
	
	if (ATTRIB(id, AT_VIPINSCORE)) {
		if(is_user_alive(id)) {
			message_begin(MSG_ALL, msg_scoreattrib)
			write_byte(id)
			write_byte(4)
			message_end()
		}
	}
}
#if MODIFICATION == NEW
public zp_fw_core_spawn_post(id) {
#else
public forward_player_spawn(id) {
#endif
#if MODIFICATION == NEW
	p_zombie[id] = zp_core_is_zombie(id)?true:false
#else
	p_zombie[id] = zp_get_user_zombie(id)?true:false
#endif
	set_user_atribs(id)
	
	if (first_spawn[id]) {
		set_task(1.0, "show_vip_timeleft", id, _, _, "a", 6)
		first_spawn[id] = false
	}
}

public forward_player_takedamage_pre(victim, inflictor, attacker, Float:damage, damage_type) {
	
	if(damage_type & DMG_FALL && ATTRIB(victim, AT_NO_FALL_DMG)) return HAM_SUPERCEDE;
	else if(IS_PLAYER(attacker) && ATTRIB(attacker, AT_EXTRA_DMG)) {
			
		if (get_pcvar_num(cvar_extra_ignore_for_special) && is_special_character(attacker))
			return HAM_IGNORED;
			
		SetHamParamFloat(4, damage*get_pcvar_float(cvar_extra_dmg))
		return HAM_HANDLED;
	}
	
	return HAM_IGNORED;
}
public forward_player_takedamage_post(victim, inflictor, attacker, Float:damage, damage_type) {
	
	if(IS_PLAYER(attacker) && ATTRIB(attacker, AT_DAMAGE_REWARD)) {
		
		if(p_damage[attacker] > ATTRIB(attacker, AT_DAMAGE_REWARD)) {
			
			zv_currency_give(attacker, 1)
			p_damage[attacker] = 0.0
		}
		else
			p_damage[attacker] += damage
	}
}

public forward_cmdstart(id, uc_handle) {
	
	static button, flags
	button = get_uc(uc_handle, UC_Buttons)
	flags = entity_get_int(id, EV_INT_flags)
	
	if(flags & FL_ONGROUND)
		p_jumpsnum[id] = 0
	
	if(button & IN_JUMP && !(get_user_oldbutton(id) & IN_JUMP)) {
		
		if(!(flags & FL_ONGROUND) && ++p_jumpsnum[id] <= ATTRIB(id, AT_MULTIJUMP)) {
			
			static Float:velocity[3]
			entity_get_vector(id, EV_VEC_velocity, velocity)
			velocity[2] = random_float(265.0,285.0)
			entity_set_vector(id,EV_VEC_velocity,velocity)
		}
	}
}
#define EV_NADE_TYPE	EV_INT_flTimeStepSound
#define NADE_TYPE_INFECTION	1111 
public forward_grenade_think(ent) {
		
	if (is_valid_ent(ent) && entity_get_int(ent, EV_NADE_TYPE) == NADE_TYPE_INFECTION) {
		p_grenade_time[entity_get_edict(ent, EV_ENT_owner)] = get_gametime()
	}
}
// Credits: MeRcyLeZZ
public message_cur_weapon(msg_id, msg_dest, msg_entity)
{
	if (!is_user_alive(msg_entity) || get_msg_arg_int(1) != 1) return;
	
	static weapon, clip
	weapon = get_msg_arg_int(2)
	clip = get_msg_arg_int(3)
	
	if (MAXCLIP[weapon] > 2 && ATTRIB(msg_entity, AT_UNLIMITED_CLIP)) {
		
		set_msg_arg_int(3, get_msg_argtype(3), MAXCLIP[weapon])
		
		if (clip < 2) {
			
			static wname[32], weapon_ent
			get_weaponname(weapon, wname, sizeof wname - 1)
			weapon_ent = find_ent_by_owner(-1, wname, msg_entity)
			//		   OFFSET_CLIPAMMO	OFFSET_LINUX_WEAPONS
			set_pdata_int(weapon_ent, 51, MAXCLIP[weapon], 4)
		}
	}
}

enum _:ChanellsStruct {
	channel[8],
	translation[42]
}
new const chat_channels[][ChanellsStruct] = {
    {"CT", "^1(Humans) ^4[VIP] ^3%s^1 :  %s"},
    {"T", "^1(Zombies) ^4[VIP] ^3%s^1 :  %s"},
    {"CT_Dead", "^1*DEAD*(Humans) ^4[VIP] ^3%s^1 :  %s"},
    {"T_Dead", "^1*DEAD*(Zombies) ^4[VIP] ^3%s^1 :  %s"},
    {"Spec", "^1(Spectator) ^4[VIP] ^3%s^1 :  %s"},
    {"All", "^4[VIP] ^3%s :  ^1%s"},
    {"AllDead", "^1*DEAD* ^4[VIP] ^3%s^1 :  %s"},
    {"AllSpec", "^1*SPEC* ^4[VIP] ^3%s^1 :  %s"}
}
 
public message_say_text(msg_id, msg_dest, msg_entity) {
	
	if (!ATTRIB(msg_dest, AT_CHATTAG))
		return;
		
	static message[250]
	get_msg_arg_string(2, message, charsmax(message))
	
	if (ATTRIB(msg_dest, AT_CHATTAG) == 1) {
		if (message[0] == '#' && message[9] == 'C' && equali(message, "#Cstrike_Chat_", 14)) {
			new i
			
			for (i=0; i<sizeof(chat_channels); i++) {
				if (equal(message[14], chat_channels[i][channel])) {
					
					set_msg_arg_string(2, chat_channels[i][translation])
					get_user_name(msg_dest, message, charsmax(message))
					set_msg_arg_string(3, message)
					return;
				}
			}
		}
		else {
			format(message, charsmax(message), "^4[VIP]%s", message)
			set_msg_arg_string(2, message)
		}
	}
	else if (ATTRIB(msg_dest, AT_CHATTAG) == 2) {
		if (message[9] == 'C' && equali(message, "#Cstrike_Chat_", 14)) {
			
			get_msg_arg_string(4, message, charsmax(message))
			static tag_index
			
			do {		
				tag_index = findtag(message, "<VIP>")
				if (tag_index != -1) {
					while (message[tag_index+5] != EOS) {
						message[tag_index] = message[tag_index+5]; tag_index++
					}
					message[tag_index] = EOS
				}
			}
			while (tag_index != -1)
				;
				
			if (ATTRIB(msg_dest, AT_CHATTAG))
				format(message, charsmax(message), "<VIP> %s", message)
				
			set_msg_arg_string(4, message)
		}
	}
}

public client_infochanged(id) {
	
	new info[5]
	read_argv(1, info, charsmax(info))
	if (equal(info, "name"))
		VipsDBGet(id)
}

public client_putinserver(id) {
	
	p_data[id][FLAGS] = 0
	p_data[id][SETTINGS] = 0
	p_data[id][TIMESTAMP] = 0
	first_spawn[id] = true
	arrayset(p_attribs[id], 0, player_attributes)
	freevip_inform[id] = false
	p_grenade_time[id] = 0.0
	p_damage[id] = 0.0
	p_jumpsnum[id] = 0
		
	if (!VipsDBGet(id))
		return;
	
	if (p_data[id][TIMESTAMP] > 0 && p_data[id][TIMESTAMP] < get_systime()) {
		
		VipsDBRemove(id)
		return;
	}
	
	if (p_data[id][FLAGS]) {
		new authid[30], ip[30], name[45]
		get_user_name(id, name, charsmax(name))
		get_user_authid(id, authid, charsmax(authid))
		get_user_ip(id, ip, charsmax(ip), 1)
		log_amx("[ZMVIP] VIP Connected: %s (%s) [%s].", name, authid, ip)
	}
		
	if (ATTRIB(id, AT_CHATTAG) && get_pcvar_num(cvar_vip_connected_to_server)) {
		
		new name[35]
		get_user_name(id, name, charsmax(name))
		switch (get_pcvar_num(cvar_vip_connected_to_server)) {
			case 1:
				if (is_amxmodx_new_version) client_print_color(0, 0, "^4[VIP] %s ^1%L.", name, LANG_PLAYER, "CONNECTED_TO_SERVER")
				else _client_print_color(0, "^4[VIP] %s ^1%L.", name, LANG_PLAYER, "CONNECTED_TO_SERVER")
			case 2: {
				set_hudmessage(255, 170, 0, 0.02, 0.71, 0, 6.0, 6.0)
				show_hudmessage(0, "[VIP] %s %L", name, LANG_PLAYER, "CONNECTED_TO_SERVER")
			}
			case 3: {
				if (is_amxmodx_new_version) {
					set_dhudmessage(255, 170, 0, 0.02, 0.71, 0, 6.0, 6.0)
					show_dhudmessage(0, "[VIP] %s %L", name, LANG_PLAYER, "CONNECTED_TO_SERVER")
				}
				else {
					_set_dhudmessage(255, 170, 0, 0.02, 0.71, 0, 6.0, 6.0)
					_show_dhudmessage(0, "[VIP] %s %L", name, LANG_PLAYER, "CONNECTED_TO_SERVER")
				}
			}
		}		
	}
}
public client_disconnect(id) {
	
	p_data[id][FLAGS] = 0
	p_damage[id] = 0.0
	p_jumpsnum[id] = 0
	p_data[id][SETTINGS] = 0
	
	if (p_data[id][TIMESTAMP] == ZV_DURATION_TILL_DISCONNECT) {
		VipsDBRemove(id)
		return;
	}
	
	if (p_data[id][TIMESTAMP] == ZV_DURATION_TILL_MAP) {
		p_data[id][PASS][charsmax(p_data[][PASS])] = floatround(get_gametime()*100, floatround_floor)
		VipsDBSet(id)
	}
}

public show_vip_info(id) {
	
	if (file_exists("vip.txt")) {
		
		show_motd(id, "vip.txt")
	}
	else {
		log_amx("WARNING: Missing vip.txt file in cstrike directory. It's used by /vip command to show information about privileges on server.")
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "NO_VIP_TXT")
		else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "NO_VIP_TXT")
		print_admin_contacts(id)
	}
}
public show_vips_online(id) {
	
	new bool:first = true, message[256], len
	
	for (new i=0; i<maxplayers; i++) {
		
		if (p_data[i][FLAGS]) {
			
			if (!first) {
				
				message[len++] = ','
				message[len++] = ' '
			}
			message[len++] = '^4'
			message[len] = EOS
			len += get_user_name(i, message[len], charsmax(message)-len)
			message[len++] = '^1'
			message[len] = EOS
			
			first = false
		}
	}
	
	if (first) {
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L...", id, "NO_VIP_ONLINE")
		else _client_print_color(id, "^4[ZMVIP] ^1%L...", id, "NO_VIP_ONLINE")
	}
	else {
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L: %s.", id, "ONLINE_VIPS", message)
		else _client_print_color(id, "^4[ZMVIP] ^1%L: %s.", id, "ONLINE_VIPS", message)
	}
	
	print_admin_contacts(id)
	
	return PLUGIN_CONTINUE;
}
show_buy_menu(id) {
	
	new duration = get_cvar_duration(cvar_vip_buy_duration)
	
	if (duration == -1) {
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "SERVER_CONFIG_ERROR")
		else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "SERVER_CONFIG_ERROR")
		return;
	}
		
	new timeleft[100]
	convert_duration_to_string(id, duration, timeleft, charsmax(timeleft))
	
	new menu[250]
	formatex(menu, charsmax(menu),\
	"\r%L^n^n\
	%L: \y%d %L^n\
	\r%L: \y%s^n^n\
	\r1. \w%L^n^n\
	\r0. \w%L", id, "BUY_VIP_PRIVILEGE",
	id, "PRICE", get_pcvar_num(cvar_vip_price), id, zv_get_currency()==CURRENCY_AMMO_PACKS?"AMMO_PACKS":"MONEY",
	id, "TIME", timeleft,
	id, "BUY", id, "EXIT")
	
	show_menu(id, MENU_KEY_0|MENU_KEY_1, menu, -1, "Menu Buy")
}

public forward_buy_menu_handler(id, key) {
	
	if (key == 0) {
		
		new player_has = zv_currency_get(id)
		
		if (player_has >= get_pcvar_num(cvar_vip_price)) {
			
			new duration
			duration = get_cvar_duration(cvar_vip_buy_duration)
			
			if (duration == -1) {
				if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "SERVER_CONFIG_ERROR")
				else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "SERVER_CONFIG_ERROR")
				print_admin_contacts(id)
				return;
			}
			
			zv_currency_set(id, player_has-get_pcvar_num(cvar_vip_price))
			native_zv_set_user_flags(id, duration, _get_pcvar_flags(cvar_vip_buy_flags))
			
			if (duration >= 0) {
				
				if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "PURCHASED_VIP")
				else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "PURCHASED_VIP")
			}
			else {
				if (duration == ZV_DURATION_TILL_MAP) { 
					
					if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "PURCHASED_VIP_TILL_MD")
					else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "PURCHASED_VIP_TILL_MD")
				}
				else if (duration == ZV_DURATION_TILL_DISCONNECT) { 
					
					if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "PURCHASED_VIP_TILL_D")
					else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "PURCHASED_VIP_TILL_D")
				}
			}
			client_cmd(id, "spk /sound/buttons/bell1.wav")
		}
		else {
			if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L %L!", id, "NOT_ENOUGHT", id,\
			zv_get_currency()==CURRENCY_AMMO_PACKS?"AMMO_PACKS":"MONEY")
			else _client_print_color(id, "^4[ZMVIP] ^1%L %L!", id, "NOT_ENOUGHT", id,\
			zv_get_currency()==CURRENCY_AMMO_PACKS?"AMMO_PACKS":"MONEY")
			client_cmd(id, "spk /sound/buttons/blip1.wav")
		}
	}
}

//////////////////////// VIP MENU FUNCTIONS //////////////////////
public show_vip_menu_console(id) {
	
	show_vip_menu(id)
	return PLUGIN_HANDLED;
}
public show_vip_menu(id) {
#if EXTRA_ITEMS == OFF
	if (p_data[id][FLAGS]) {
		
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "ALREADY_VIP_INFO")
		else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "ALREADY_VIP_INFO")
	}
	else if (get_pcvar_num(cvar_vip_price) > 0) {
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "YOU_ARE_NOT_VIP")
		else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "YOU_ARE_NOT_VIP")
		show_buy_menu(id)
		return PLUGIN_CONTINUE;
	}
	else {
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "YOU_ARE_NOT_VIP_INFO")
		else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "YOU_ARE_NOT_VIP_INFO")
		return PLUGIN_CONTINUE;
	}
#else
	if (!ATTRIB(id, AT_EXTRA_ITEMS)) {
		
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "YOU_ARE_NOT_VIP_MENU")
		else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "YOU_ARE_NOT_VIP_MENU")
		show_buy_menu(id)
		return PLUGIN_CONTINUE;
	}
		
	new maximum = get_pcvar_num(cvar_buys_per_round)
	if (maximum && p_bought_per_round[id] > maximum) {
		
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L", id, "EXCEEDED_BUY_LIMIT", maximum)
		else _client_print_color(id, "^4[ZMVIP] ^1%L", id, "EXCEEDED_BUY_LIMIT", maximum)
		return PLUGIN_CONTINUE;
	}
#if MODIFICATION == NEW
	
	if (is_user_alive(id)) {
		p_views_extra_items_menu[id] = true
		zp_items_show_menu(id)
		p_views_extra_items_menu[id] = false
	}
	else {
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "NOT_ALIVE")
		else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "NOT_ALIVE")
	}
#else
	
	if(registered_extra_items_num) {
		
		new item_data[item_struct], item_string[250], menu_header[40]
		formatex(menu_header, charsmax(menu_header), "\r%L:", id, "VIP_MENU_TOP")
		new menu = menu_create(menu_header, "show_vip_menu_handler")
		
		new bool:special = is_special_character(id)?true:false;
		new info[5]
		
		for(new i=0; i<registered_extra_items_num; i++) {
			
			ArrayGetArray(array_vip_extra_items, i, item_data)
			
			if (item_data[item_team] > 0
			&& (item_data[item_team]&ZP_TEAM_ZOMBIE && !p_zombie[id])
			|| (item_data[item_team]&ZP_TEAM_HUMAN && p_zombie[id])
			|| (item_data[item_team]&(ZP_TEAM_NEMESIS|ZP_TEAM_SURVIVOR) && !special)	
			)
				continue;
			
			formatex(item_string, charsmax(item_string), "%s \y%d %L", \
			item_data[item_name], item_data[item_cost], id, zv_get_currency()==CURRENCY_AMMO_PACKS?"AMMO_PACKS":"MONEY")
			num_to_str(i, info, charsmax(info))
			menu_additem(menu, item_string, info)
		}
			
		if(menu_items(menu)) menu_display(id, menu, 0)
		else {
			if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "NO_ITEMS_FOR_TEAM")
			else _client_print_color(id, "^4[ZMVIP] ^3%L.", id, "NO_ITEMS_FOR_TEAM")
		}
	}
	else {
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "NO_PLUGINS_LOADED")
		else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "NO_PLUGINS_LOADED")
	}
#endif
#endif
	static timeleft[100]
	convert_duration_to_string(id, max(p_data[id][TIMESTAMP]-get_systime(), 0), timeleft, charsmax(timeleft))
	
	if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1VIP %L: ^3%s", id, "TIMELEFT", timeleft)
	else _client_print_color(id, "^4[ZMVIP] ^1VIP %L: ^3%s", id, "TIMELEFT", timeleft)
	
	return PLUGIN_CONTINUE
}
#if MODIFICATION != NEW && EXTRA_ITEMS == ON
public show_vip_menu_handler(id, menu, item)
{
	if(item == MENU_EXIT )
	{
		menu_destroy(menu)
		return PLUGIN_HANDLED
	}

	new item_id, _blank, info[5]
	menu_item_getinfo(menu, item, _blank, info, charsmax(info), "", _blank, _blank)
	
	item_id = str_to_num(info)

	new retval, item_data[item_struct]
	ArrayGetArray(array_vip_extra_items, item_id, item_data)
	
	if (chached_show_vip_items)
		ExecuteForward(fw_extraitemselected, retval, id, item_data[item_plid])
	else
		ExecuteForward(fw_extraitemselected, retval, id, item_id)
		
	if (retval < ZP_PLUGIN_HANDLED) {
		zv_currency_set(id, zv_currency_get(id)-item_data[item_cost])
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L '^4%s^1'", id, "PURCHASED", item_data[item_name])
		else _client_print_color(id, "^4[ZMVIP] ^1%L '^4%s^1'", id, "PURCHASED", item_data[item_name])
		p_bought_per_round[id]++
	}
	
	menu_destroy(menu)
	return PLUGIN_HANDLED
}
#endif
public vip_time_check() {
	
	static id, timestamp
	timestamp = get_systime()
	
	for (id=1; id<33; id++) {
		if (p_data[id][TIMESTAMP] > 0 && p_data[id][TIMESTAMP] < timestamp) {
			
			native_zv_remove_user_flags(id)
		}
	}
}

is_special_character(id) {
		
	if(p_zombie[id]) {
#if MODIFICATION == NEW
		if(!(natives_filter_out & BIT(NATIVE_ZP_CLASS_NEMESIS_GET)) && zp_class_nemesis_get(id)
		|| !(natives_filter_out & BIT(NATIVE_ZP_CLASS_ASSASSIN_GET)) && zp_class_assassin_get(id)
		)
			return true;
#else
		if(zp_get_user_nemesis(id)
		|| !(natives_filter_out & BIT(NATIVE_ZP_CLASS_BOMBARDIER_GET)) && zp_get_user_bombardier(id)
		)
			return true;
#endif
	}
	else {
#if MODIFICATION == NEW
		if(!(natives_filter_out & BIT(NATIVE_ZP_CLASS_SURVIVOR_GET)) && zp_class_survivor_get(id)
		|| !(natives_filter_out & BIT(NATIVE_ZP_CLASS_SNIPER_GET)) && zp_class_sniper_get(id)
		)
			return true;
#else
		return zp_get_user_survivor(id)
#endif
	}
	return false;
}

check_named_privileges(id, nick[], pass[]) {
	
	new num
	if (!array_vips_database_nick || !(num = VIPCNT(NAMES))) {
		p_data[id][SETTINGS] = 0
		p_data[id][FLAGS] = 0
		return false;
	}
	
	for (new index=0; index<num; index++) {
		ArrayGetArray(array_vips_database_nick, index, p_data[id])
		if (p_data[id][SETTINGS] & FLAG_C) {
			if (((p_data[id][SETTINGS]&FLAG_N)?contain(nick, p_data[id][AUTH]):containi(nick, p_data[id][AUTH])) == -1)
				continue;
		}
		else {
			if (!((p_data[id][SETTINGS]&FLAG_N)?equal(nick, p_data[id][AUTH]):equali(nick, p_data[id][AUTH])))
				continue;
		}
		
		if (!EMPTY(p_data[id][PASS])) {
		
			p_data[id][PASS][charsmax(p_data[][PASS])] = EOS
			if (!equal(p_data[id][PASS], pass)) {
				if (p_data[id][SETTINGS] & FLAG_K) {
					return false;
				}
				else {
					client_print(id, print_console, "[ZMVIP] %L.", id, "PASS_NOT_MATCH")
					continue;
				}
			}
		}
		p_data[id][INDEX] = index
		return true;
	}
	
	p_data[id][SETTINGS] = 0
	p_data[id][FLAGS] = 0
	return false;
}
public cmd_vips_remove(id, level, cid) {
	
	if(id != 0 && !(get_user_flags(id) & level))
		return PLUGIN_HANDLED;

	if (read_argc() < 1) {
		console_print(id, "[ZM VIP] %L: zm_vip_remove <NICK/AUTH/IP>.", id, "USAGE")
		return PLUGIN_HANDLED;
	}
	
	new argument[40]
	read_argv(1, argument, charsmax(argument))
	
	new player = cmd_target(id, argument, CMDTARGET_OBEY_IMMUNITY|CMDTARGET_ALLOW_SELF|CMDTARGET_NO_BOTS)
	if (!player)
		return PLUGIN_HANDLED;
	
	new name[40]
	get_user_name(player, name, charsmax(name))
	
	if (!p_data[player][FLAGS]) {
		console_print(id, "[ZM VIP] %L", id, "DOES_NOT_HAVE_VIP", name)
		return PLUGIN_HANDLED;
	}
	
	if (native_zv_remove_user_flags(player))
		console_print(id, "[ZM VIP] %L.", id, "PRIVILEGE_REMOVED", name)
	else
		console_print(id, "[ZM VIP] %L.", id, "PLUGIN_ERROR_REMOVING", name)
	
	return PLUGIN_HANDLED;
}

public cmd_vips_reload(id, level, cid) {
	
	if(id != 0 && !(get_user_flags(id) & level))
		return PLUGIN_HANDLED;

	server_cmd("amx_reloadadmins")
	server_exec()
	
	TrieClear(trie_vips_database)
	ArrayClear(array_vips_database)
	if (array_vips_database_nick)
		ArrayClear(array_vips_database_nick)
		
	arrayset(total_vips_count, 0, sizeof(total_vips_count))
#if VIPS_FILE_SYSTEM != OFF
	load_ini_file()
#endif
	load_datafile()
		
#if VIPS_FILE_SYSTEM != FORCED
	new num_admins = admins_num()
	for (new i=0; i<num_admins; i++) {
		if (admins_lookup(i, AdminProp_Access)&VIP_SYS_FLAG) {
			VIPINC(AMX)
		}
	}
#endif
	new players[32], num_players, i
	get_players(players, num_players, "ch")
	
	for (i=0; i<num_players; i++) {
		VipsDBGet(players[i])
	}
	
	if (id) {
		static authid[30], ip[30], name[45]
		get_user_name(id, name, charsmax(name))
		get_user_authid(id, authid, charsmax(authid))
		get_user_ip(id, ip, charsmax(ip), 1)
		log_amx("Cmd exec: zm_vip_reload. By: %s (%s) (%s)", name, authid, ip)
	}
	else
		log_amx("Cmd exec: zm_vip_reload. From server console")
	
	console_print(id, "[ZM VIP] Reloaded %d vips", VIPCNT(DAT)+VIPCNT(INI)+VIPCNT(AMX))
	return PLUGIN_HANDLED;
}

public cmd_list_vips(id, level, cid) {
	
	if(id != 0 && !(get_user_flags(id) & level))
		return PLUGIN_HANDLED;
	
	new key[40], i, size = ArraySize(array_vips_database)
	new data[vips_database_type]
	
	console_print(id, "Main VIPs: %d", VIPCNT(MAIN)+VIPCNT(NAMES))
	new load_types[][] = {"DAT", "INI", "AMX"}
	new load_type, flags_str[30], time_str[25]
	
	for (i=0; i<size; i++) {
		
		ArrayGetString(array_vips_database, i, key, sizeof(key))
		
		if (EMPTY(key))
			continue;
		
		if (!TrieGetArray(trie_vips_database, key, data, vips_database_type))
			continue;
		
		if (data[SETTINGS] & LOAD_FROM_DAT)
			load_type = 0
#if VIPS_FILE_SYSTEM != OFF
		if (data[SETTINGS] & LOAD_FROM_INI)
			load_type = 1
#endif
#if VIPS_FILE_SYSTEM != FORCED
		if (data[SETTINGS] & LOAD_FROM_AMX)
			load_type = 2
#endif
		flags_str[0] = EOS
		time_str[0] = EOS
		if (data[FLAGS] == -1)
			add(flags_str, charsmax(flags_str), "All")
		else
			get_flags(data[FLAGS], flags_str, charsmax(flags_str))
		
		if (data[TIMESTAMP] == ZV_DURATION_PERMANENT)
			add(time_str, charsmax(time_str), "Permanent")
		else if (data[TIMESTAMP] == ZV_DURATION_TILL_DISCONNECT)
			add(time_str, charsmax(time_str), "Disconnect")
		else if (data[TIMESTAMP] == ZV_DURATION_TILL_MAP)
			add(time_str, charsmax(time_str), "Map change")
		else
			format_time(time_str, charsmax(time_str), "%Y/%m/%d-%H:%M", data[TIMESTAMP])
			
		console_print(id, "%s| ^"%s^" ^"%s^" ^"%s^"", load_types[load_type],
		data[AUTH], flags_str, time_str)
	}
	
	if (array_vips_database_nick) {
		size = ArraySize(array_vips_database_nick)
		for (i=0; i<size; i++) {
			
			ArrayGetArray(array_vips_database_nick, i, data)
			
			if (data[SETTINGS] & LOAD_FROM_DAT)
				load_type = 0
#if VIPS_FILE_SYSTEM != OFF
			if (data[SETTINGS] & LOAD_FROM_INI)
				load_type = 1
#endif
#if VIPS_FILE_SYSTEM != FORCED
			if (data[SETTINGS] & LOAD_FROM_AMX)
				load_type = 2
#endif
			
			if (data[FLAGS] == -1)
				add(flags_str, charsmax(flags_str), "All")
			else
				get_flags(data[FLAGS], flags_str, charsmax(flags_str))
			
			if (data[TIMESTAMP] == ZV_DURATION_PERMANENT)
				add(time_str, charsmax(time_str), "Permanent")
			else if (data[TIMESTAMP] == ZV_DURATION_TILL_DISCONNECT)
				add(time_str, charsmax(time_str), "Disconnect")
			else if (data[TIMESTAMP] == ZV_DURATION_TILL_MAP)
				add(time_str, charsmax(time_str), "Map change")
			else
				format_time(time_str, charsmax(time_str), "%Y/%m/%d-%H:%M", data[TIMESTAMP])
				
			console_print(id, "%s| ^"%s^" ^"%s^" ^"%s^"", load_types[load_type],
			data[AUTH], flags_str, time_str)
		}
	}
#if VIPS_FILE_SYSTEM != FORCED
	console_print(id, "Amx VIPs: %d", VIPCNT(AMX))
	
	new num_admins = admins_num()
	for (new i=0; i<num_admins; i++) {
		if (admins_lookup(i, AdminProp_Access)&VIP_SYS_FLAG) {
			new auth[40]
			admins_lookup(i, AdminProp_Auth, auth, charsmax(auth))
			
			console_print(id, "AMX| ^"%s^"", auth)
		}
	}
#endif
	return PLUGIN_HANDLED;
}
		
public set_freevip_hour(id, level, cid) {
	
	if(id != 0 && !(get_user_flags(id) & level))
		return PLUGIN_HANDLED;
	
	if (read_argc() < 2)  {
		
		if (freevip_enabled)
			console_print(id, "^"zm_vip_freevip_hour^" is ^"%d:%d-%d:%d^"", \
			freevip_hours[0], freevip_hours[1], freevip_hours[2], freevip_hours[3])
		else
			console_print(id, "^"zm_vip_freevip_hour^" is ^"off^"")
		return PLUGIN_HANDLED;
	}
	
	new string[12], index
	read_argv(1, string, charsmax(string))
	
	if(string[0] == 'o' || (string[0] == '0' && string[1] == EOS)) {
		freevip_enabled = false
		return PLUGIN_HANDLED;
	}
	
	if (string[2] == ':') {
		freevip_hours[0] = (string[0]-'0')*10+(string[1]-'0')
		freevip_hours[1] = (string[3]-'0')*10+(string[4]-'0')
		index = 5
	}
	else if (string[1] == ':') {
		freevip_hours[0] = (string[0]-'0')
		freevip_hours[1] = (string[2]-'0')*10+(string[3]-'0')
		index = 4
	}
	else {
		log_amx("ERROR: Inccorect zm_freevip_hour cvar value! Set correctly, or turn off by typing ^"off^".")
		return PLUGIN_HANDLED;
	}
	
	if (freevip_hours[0] >= 24 || freevip_hours[1] >= 60) {
		log_amx("ERROR: Inccorect zm_freevip_hour cvar value! Set correctly, or turn off by typing ^"off^".")
		return PLUGIN_HANDLED;
	}
	
	if (string[index++] != '-') {
		log_amx("ERROR: Inccorect zm_freevip_hour cvar value! Set correctly, or turn off by typing ^"off^".")
		return PLUGIN_HANDLED;
	}
	
	if (string[index+2] == ':') {
		freevip_hours[2] = (string[index]-'0')*10+(string[index+1]-'0')
		freevip_hours[3] = (string[index+3]-'0')*10+(string[index+4]-'0')
	}
	else if (string[index+1] == ':') {
		freevip_hours[2] = (string[index]-'0')
		freevip_hours[3] = (string[index+2]-'0')*10+(string[index+3]-'0')
	}
	else {
		log_amx("ERROR: Inccorect zm_freevip_hour cvar value! Set correctly, or turn off by typing ^"off^".")
		return PLUGIN_HANDLED;
	}
	
	if (freevip_hours[2] >= 24 || freevip_hours[3] >= 60) {
		log_amx("ERROR: Inccorect zm_freevip_hour cvar value! Set correctly, or turn off by typing ^"off^".")
		return PLUGIN_HANDLED;
	}
	
	freevip_enabled = true
	
	return PLUGIN_HANDLED;
}

freevip_hour_check() {

	if (freevip_hours[0] == freevip_hours[2] && freevip_hours[1] == freevip_hours[3]) {
		return true;
	}
	
	new h, m, s
	time(h, m, s)
	
	new hour_low, hour_high
	hour_low = freevip_hours[0]*100+freevip_hours[1]
	hour_high = freevip_hours[2]*100+freevip_hours[3]
	
	if ((hour_low <= (h*100+m) < hour_high) || (hour_high <= (h*100+m) < hour_low))
		return true;
	
	return false
}

//////////////////////// API STUFF ///////////////////////////
#if MODIFICATION == NEW
public zp_fw_core_infect_pre(id, attacker) {
#else
public zp_user_infect_attempt(id, attacker, nemesis) {
#endif
	if (ATTRIB(id, AT_GRENADE_IMMUNITY) & FLAG_A && p_grenade_time[attacker] 
	&& get_gametime()-p_grenade_time[attacker] < 0.5)
#if MODIFICATION == NEW
		return PLUGIN_HANDLED;
#else
		return ZP_PLUGIN_HANDLED;
#endif
	
	return PLUGIN_CONTINUE;
}
#if MODIFICATION == NEW
public zp_fw_core_infect_post(id, attacker) {
#else
public zp_user_infected_post(id, attacker) {
#endif	
	p_zombie[id] = true
	p_grenade_time[id] = 0.0
	
	set_user_atribs(id, true)
	set_user_atribs(attacker, true)
	
	if (get_pcvar_num(cvar_extra_ignore_for_special) && is_special_character(id))
		return;
	
	if (ATTRIB(id, AT_EXTRA_GRAVITY)) {
		new Float:gravity = get_user_gravity(id)-get_pcvar_float(cvar_extra_gravity_zombie)
		if (gravity < 0.0) gravity = 0.0
		set_user_gravity(id, gravity)
	}
	
	if(ATTRIB(attacker, AT_EXTRA_INFECT_HEALTH))
		set_user_health(attacker, get_user_health(attacker)+ATTRIB(attacker, AT_EXTRA_INFECT_HEALTH))
		
	if(ATTRIB(id, AT_EXTRA_HP))
		set_user_health(id, get_user_health(id)+ATTRIB(id, AT_EXTRA_HP))
	
	if(ATTRIB(attacker, AT_EXTRA_FRAGS))
		set_user_frags(attacker, get_user_frags(attacker)+ATTRIB(attacker, AT_EXTRA_FRAGS))
	
	if(ATTRIB(attacker, AT_EXTRA_INFECT_AMMO))
			zv_currency_give(attacker, p_attribs[attacker][AT_EXTRA_INFECT_AMMO])
#if MODIFICATION != OLD
	if(ATTRIB(id, AT_VIP_MODEL) && !EMPTY(p_vip_model_zombie))
#if MODIFICATION == NEW
		cs_set_player_model(id, p_vip_model_zombie)
#endif
#if MODIFICATION == OLD
		if (natives_filter_out & BIT(NATIVE_OVERRIDE_USER_MODEL)) {
			log_amx("WARNING: You are using old zombie plague version, that don't support custom VIP models.")
		}
		else
			zp_override_user_model(id, p_vip_model_zombie)
#endif
#endif
}
#if MODIFICATION == NEW
public zp_fw_core_cure_post(id) {
#else
public zp_user_humanized_post(id) {
#endif
	p_zombie[id] = false
	
	set_user_atribs(id, true)
	
	if (get_pcvar_num(cvar_extra_ignore_for_special) && is_special_character(id))
		return;
		
	if (ATTRIB(id, AT_EXTRA_GRAVITY)) {
		new Float:gravity = get_user_gravity(id)-get_pcvar_float(cvar_extra_gravity_human)
		if (gravity < 0.04) gravity = 0.04
		
		set_user_gravity(id, gravity)
	}
	if(ATTRIB(id, AT_EXTRA_HP))
		set_user_health(id, get_user_health(id)+ATTRIB(id, AT_EXTRA_HP))
	
	if(ATTRIB(id, AT_ARMOR))
		set_user_armor(id, ATTRIB(id, AT_ARMOR))
		
#if MODIFICATION != OLD
	if(ATTRIB(id, AT_VIP_MODEL) && !EMPTY(p_vip_model_human))
#if MODIFICATION == NEW
		cs_set_player_model(id, p_vip_model_human)
#endif
#if MODIFICATION == OLD
		if (natives_filter_out & BIT(NATIVE_OVERRIDE_USER_MODEL)) {
			log_amx("WARNING: You are using old zombie plague version, that don't support custom VIP models.")
		}
		else
			zp_override_user_model(id, p_vip_model_human)
#endif
#endif
}
#if MODIFICATION == NEW
public zp_fw_gamemodes_start(gamemode) {
#else
public zp_round_started(gamemode) {
	gamemode -= 1
#endif
	current_gamemode = gamemode
}
#if MODIFICATION == NEW
public zp_fw_grenade_fire_pre(id) {
	return (ATTRIB(id, AT_GRENADE_IMMUNITY) & FLAG_B)?PLUGIN_HANDLED:PLUGIN_CONTINUE;
}
public zp_fw_grenade_frost_pre(id) {
	return (ATTRIB(id, AT_GRENADE_IMMUNITY) & FLAG_C)?PLUGIN_HANDLED:PLUGIN_CONTINUE;
}
#endif
#if MODIFICATION == NEW
#if EXTRA_ITEMS == ON
public zp_fw_items_select_post(id, itemid, ignorecost) {
	
	if (VipsItemIs(EXTRA_ITEM, itemid))
		p_bought_per_round[id]++
}
#endif
public zp_fw_items_select_pre(id, itemid, ignorecost) {

	if (itemid == vip_buy_extra_item) {
		show_buy_menu(id)
		return ZP_ITEM_NOT_AVAILABLE;
	}
#if EXTRA_ITEMS == ON
	if (!registered_extra_items_num)
		return ZP_ITEM_AVAILABLE;
	
	if (VipsItemIs(EXTRA_ITEM, itemid)) {
		if (get_pcvar_num(cvar_vip_show_vip_items) > 0) {
		
			zp_items_menu_text_add("*VIP*")
			
			if (ATTRIB(id, AT_EXTRA_ITEMS)) {
				new maximum = get_pcvar_num(cvar_buys_per_round)
				if (maximum && p_bought_per_round[id] > maximum) {
					if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L", id, "EXCEEDED_BUY_LIMIT", maximum)
					else _client_print_color(id, "^4[ZMVIP] ^1%L", id, "EXCEEDED_BUY_LIMIT", maximum)
					return ZP_ITEM_NOT_AVAILABLE;
				}
				else {
					return ZP_ITEM_AVAILABLE;
				}
			}
			else
				return get_pcvar_num(cvar_vip_show_vip_items)==2?ZP_ITEM_NOT_AVAILABLE:ZP_ITEM_DONT_SHOW;
		}
	}
	else if (p_views_extra_items_menu[id])
		return ZP_ITEM_DONT_SHOW;
#endif
	return ZP_ITEM_AVAILABLE;
}

public zp_fw_class_human_select_pre(id, classid) {
	
	if (!VipsItemHandle)
		return ZP_CLASS_AVAILABLE;
		
	if (VipsItemIs(CLASS_HUMAN, classid)) {
	
		zp_class_human_menu_text_add("*VIP*")
		return (ATTRIB(id, AT_VIP_CLASS))?ZP_CLASS_AVAILABLE:ZP_CLASS_NOT_AVAILABLE;
	}
	
	return ZP_CLASS_AVAILABLE;
}

public zp_fw_class_zombie_select_pre(id, classid) {
	
	if (!VipsItemHandle)
		return ZP_CLASS_AVAILABLE;
		
	if (VipsItemIs(CLASS_ZOMBIE, classid)) {
	
		zp_class_zombie_menu_text_add("*VIP*")
		return (ATTRIB(id, AT_VIP_CLASS))?ZP_CLASS_AVAILABLE:ZP_CLASS_NOT_AVAILABLE;
	}
	
	return ZP_CLASS_AVAILABLE;
}
#endif
#if MODIFICATION != NEW
public zp_user_infected_pre(id) {
	
	if(VipsItemHandle && !ATTRIB(id, AT_VIP_CLASS)) { 
		
		if(VipsItemIs(CLASS_ZOMBIE, zp_get_user_next_class(id))) {
			zp_set_user_zombie_class(id, 0)
			client_print(id, print_center, "%L", id, "VIPONLY_CLASS")
			if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "VIPONLY_CLASS_INFO")
			else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "VIPONLY_CLASS_INFO")
		}
	}
}
public zp_extra_item_selected(id, itemid) {
	
	if (itemid == vip_buy_extra_item) {
		show_buy_menu(id)
		return ZP_PLUGIN_HANDLED;
	}
	return 1;
}
#endif
// Natives

public native_zv_get_user_flags(id) {
	return p_data[id][FLAGS];
}

public native_zv_set_user_flags(id, duration, flags) {
	
	new i, num, timestamp = get_systime(duration)
	
	if (id) {
		if (!is_user_connected(id))
			return false;
			
		goto skip_loop;
	}
	
	new players[32]
	get_players(players, num, "ch")
	
	for (i=0; i<num; i++) {
		id = players[i]
		
		skip_loop:
		
		if (!p_data[id][FLAGS] && duration == ZV_DURATION_IGNORE)
			return false;
		
		p_data[id][FLAGS] = flags==0?-1:flags;
		p_data[id][TIMESTAMP] = timestamp
		
		VipsDBSet(id)
		set_user_atribs(id)
	}
	
	return true;
}

public native_zv_remove_user_flags(id) {
	
	new i, num
	if (!VIPCNT(DAT) && !VIPCNT(INI) && !VIPCNT(AMX))
		return false;
	
	if (id) {
		
		if (!is_user_connected(id) || !p_data[id][FLAGS])
			return false;
		
		p_data[id][FLAGS] = 0
		p_data[id][TIMESTAMP] = 0
		arrayset(p_attribs[id], 0, player_attributes)
		
		return VipsDBRemove(id);
	}
	
	new players[32]
	get_players(players, num, "ch")
	
	for (i=0; i<num; i++) {
		id = players[i]
		
		p_data[id][FLAGS] = 0
		p_data[id][TIMESTAMP] = 0
		arrayset(p_attribs[id], 0, player_attributes)
		
		VipsDBRemove(id)
	}
	
	return true;
}

#if MODIFICATION == NEW
public native_zv_class_human_register(const name[], const description[], health, Float:speed, Float:gravity) {
	
	param_convert(1)
	param_convert(2)
	new class_id = zp_class_human_register(name, description, health, speed, gravity)
	
	VipsItemSet(CLASS_HUMAN, class_id)
	return class_id
}
public native_zv_class_zombie_register(const name[], const description[], health, Float:speed, Float:gravity) {

	param_convert(1)
	param_convert(2)
	new class_id = zp_class_zombie_register(name, description, health, speed, gravity)
	
	VipsItemSet(CLASS_ZOMBIE, class_id)
	return class_id
}
#if EXTRA_ITEMS == ON
public native_zv_items_register(const name[], cost) {
	
	param_convert(1)
	new item_id = zp_items_register(name, cost)
	
	VipsItemSet(EXTRA_ITEM, item_id)
	registered_extra_items_num++
	return item_id
}
#endif
#endif
#if MODIFICATION != NEW
public native_zv_register_zombie_class(const name[], const info[], const model[], const clawmodel[], hp, speed, Float:gravity, Float:knockback) {

	param_convert(1)
	param_convert(2)
	param_convert(3)
	param_convert(4)
	new class_id = zp_register_zombie_class(name, info, model, clawmodel, hp, speed, gravity, knockback)
	
	VipsItemSet(CLASS_ZOMBIE, class_id)
	return class_id
}
#if EXTRA_ITEMS == ON
public native_zv_register_extra_item2(const name[], cost, team) {

	param_convert(1)
	
	new item_data[item_struct]
	
	if(!array_vip_extra_items)
		array_vip_extra_items = ArrayCreate(item_struct)
	
	formatex(item_data[item_name], charsmax(item_data[item_name]), "*VIP* %s", name)
	item_data[item_cost] = cost
	item_data[item_team] = team
	
	if (chached_show_vip_items) {
	
		item_data[item_plid] = zp_register_extra_item(name, cost, team)
		
		VipsItemSet(EXTRA_ITEM, item_data[item_plid])
	}
	
	ArrayPushArray(array_vip_extra_items, item_data)
	registered_extra_items_num++
	
	return chached_show_vip_items?item_data[item_plid]:registered_extra_items_num
}
public native_zv_register_extra_item(const name[], const description[], cost, team) {
	
	param_convert(1)
	param_convert(2)
	
	new item_data[item_struct]
	
	if(!array_vip_extra_items)
		array_vip_extra_items = ArrayCreate(item_struct)
	
	formatex(item_data[item_name], charsmax(item_data[item_name]), "*VIP* %s \r[%s]", name, description)
	item_data[item_cost] = cost
	item_data[item_team] = team
	
	if (chached_show_vip_items) {
		
		item_data[item_plid] = zp_register_extra_item(name, cost, team)
		
		VipsItemSet(EXTRA_ITEM, item_data[item_plid])
	}
	
	ArrayPushArray(array_vip_extra_items, item_data)
	registered_extra_items_num++
	
	return chached_show_vip_items?item_data[item_plid]:registered_extra_items_num
}
public native_zv_force_buy_extra_item(id, itemid, ignorecost) {
	
	if (chached_show_vip_items) {
			
		zp_force_buy_extra_item(id, itemid, ignorecost)
		return;
	}
	
	new retval
	ExecuteForward(fw_extraitemselected, retval, id, itemid)
		
	if (retval >= ZP_PLUGIN_HANDLED && !ignorecost) {
		new item_data[item_struct]
		ArrayGetArray(array_vip_extra_items, itemid, item_data)
		zv_currency_set(id, zv_currency_get(id)+item_data[item_cost])
	}
}
public native_zv_get_extra_item_id(const name[]) {
	
	param_convert(1)
	
	if (chached_show_vip_items) {
		
		return zp_get_extra_item_id(name)
	}
	
	new item_data[item_struct]
	for (new i=0; i<registered_extra_items_num; i++) {
		
		ArrayGetArray(array_vip_extra_items, i, item_data)	
		if (equali(name, item_data[item_name]))
			return i;
	}
	
	return -1;
}
#endif
#endif
new dummy_record_count
public plugin_end() {
	if (dummy_record_count > 5)
		write_datafile()
	
/*	if (trie_vip_zombie_classes)
		TrieDestroy(trie_vip_zombie_classes)
#if MODIFICATION == NEW
	if (trie_vip_human_classes)
		TrieDestroy(trie_vip_human_classes)
#endif
#if EXTRA_ITEMS == ON
	if (trie_vip_extra_items)
		TrieDestroy(trie_vip_extra_items)
#if MODIFICATION != NEW
	if (array_vip_extra_items)
		ArrayDestroy(array_vip_extra_items)
#endif
#endif
	if (trie_vips_database)
		TrieDestroy(trie_vips_database)
	if (array_vips_database_nick)
		ArrayDestroy(array_vips_database_nick)
	*/
}
/*encode_date(d[]) { // TOOD: delete
	
	new ret
	d[4] = d[7] = EOS 
	ret += str_to_num(d)
	ret = (ret<<8)
	ret += str_to_num(d[5])
	ret = (ret<<8)
	ret += str_to_num(d[8])
	
	return ret
}

decode_date(d, ds[]) {

	num_to_str((d>>16), ds, 4)
	num_to_str((d>>8)&0xFF, ds[5], 4)
	num_to_str(d&0xFF, ds[8], 4)
	ds[4] = ds[7] = ':'
	ds[10] = EOS
}*/
stock zv_get_currency() {
#if MODIFICATION == NEW
	if (is_module_ammopacks_loaded)
		return CURRENCY_AMMO_PACKS;
	else
		return CURRENCY_MONEY;
#endif
	return CURRENCY_AMMO_PACKS;
}
stock zv_currency_give(id, amount) {
#if MODIFICATION == NEW
	if (is_module_ammopacks_loaded)
		zp_ammopacks_set(id, zp_ammopacks_get(id)+amount)
	else
		cs_set_user_money(id, cs_get_user_money(id)+amount)
#else
	zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id)+amount)
#endif
}
stock zv_currency_set(id, amount) {
#if MODIFICATION == NEW
	if (is_module_ammopacks_loaded)
		zp_ammopacks_set(id, amount)
	else
		cs_set_user_money(id, amount)
#else
	zp_set_user_ammo_packs(id, amount)
#endif
}
stock zv_currency_get(id) {
#if MODIFICATION == NEW
	if (is_module_ammopacks_loaded)
		return zp_ammopacks_get(id)
	else
		return cs_get_user_money(id)
	
	return 0;
#else
	return zp_get_user_ammo_packs(id)
#endif
}
#if VIPS_FILE_SYSTEM != OFF
load_ini_file() {

	new vipsfile[70]
	get_configsdir(vipsfile, charsmax(vipsfile))
	format(vipsfile, charsmax(vipsfile), "%s/%s", vipsfile, VIPS_FILE)
	new handle = fopen(vipsfile, "rt")
	
	new tempfilename[] = "temp.file";
	new temph = fopen(tempfilename, "wt")
	
	if(handle) {
		
		new vip_data[vips_database_type]

		new str_auth[50], data1[30], data2[30]
		new /*ret, */bool:comma_open, bool:line_removed = false
		new line[200], line_num, line_len;
		new i=0, s=0
		new datatype = 0
		new timestamp = get_systime()
		//new AuthType:authtype

		while(!feof(handle)) {

			comma_open = false
			line_len = fgets(handle, line, charsmax(line))
			line_num++
			
			i = 0
			datatype = 0
				
			if (line[i] == ';'
			|| line[i] == '/'
			|| line[i] == 'X'
			|| line[i] == EOS) {
				fputs(temph, line)
				continue;
			}
			
			vip_data[AUTH][0] = EOS
			vip_data[PASS][0] = EOS
			vip_data[SETTINGS] = 0
			vip_data[FLAGS] = 0
			vip_data[TIMESTAMP] = 0
			
			for(;;) {
				switch (line[i]) {
				case 'C': vip_data[SETTINGS] |= FLAG_C
				case 'N': vip_data[SETTINGS] |= FLAG_N
				case 'F': vip_data[SETTINGS] |= FLAG_F
				case 'K': vip_data[SETTINGS] |= FLAG_K
				default: goto loop_exit;
				}
				i++
			}
			
			loop_exit:
			
			for (;;) {
				
				if (i > charsmax(line)) {
					log_amx("ERROR: ^"%s^" Syntax error on line (%d:%d):^n^"%s^".^nLine too long.", VIPS_FILE, line_num, i+1, line)
					fputs(temph, line)
					goto global_continue;
				}
				if (line[i] == '"') {
					
					comma_open = !comma_open
					i++
					
					if (comma_open) datatype++
					else {
						switch (datatype) {
							
							case 1: str_auth[s] = EOS
							case 2: data1[s] = EOS
							case 3: data2[s] = EOS
							default: {
								log_amx("ERROR: ^"%s^" Syntax error on line (%d:%d):^n^"%s^". Too many parameters.", VIPS_FILE, line_num, i+1, line)
								fputs(temph, line)
								goto global_continue;
							}
						}
					}
					s = 0
					continue;
				}
				
				if (comma_open) {
					
					switch (datatype) {
						
						case 1: str_auth[s++] = line[i]
						case 2: data1[s++] = line[i]
						case 3: data2[s++] = line[i]
					}
				}
				else if (line[i] == '|') {
					
					new idx, fidx
					static frmt[] = "|//|:|"
					idx = i
					fidx = 0
					
					while (i < line_len) {
						
						if (frmt[fidx] == line[i]) {
							if (++fidx == charsmax(frmt))
								break;
						}
						else if (line[i] > '9' || line[i] < '0')
							break;
						i++
					}
					
					if (fidx == charsmax(frmt) && i < line_len) {
						vip_data[TIMESTAMP] = parse_time(line[idx], "|%Y/%m/%d|%H:%M|")
						break;
					}
					else {
						log_amx("ERROR: ^"%s^" Syntax error on line (%d:%d):^n^"%s^". Incorrect time.", VIPS_FILE, line_num, i+1, line)
						fputs(temph, line)
						goto global_continue;
					}
				}
				else if (line[i] == '^r' || line[i] == EOS || line[i] == '^n') {
					break;
				}
				else if (line[i] != ' ') {
					log_amx("ERROR: ^"%s^" Syntax error on line (%d:%d):^n^"%s^". Unknown symbol '%c'.", VIPS_FILE, line_num, i+1, line, line[i])
					fputs(temph, line)
					goto global_continue;
				}
				i++
			}
			
			switch (datatype) {
			case 1: {
				vip_data[FLAGS] = -1	
			}
			case 2: {
				vip_data[FLAGS] = read_flags(data1)
			}
			case 3: {
				copy(vip_data[PASS], charsmax(vip_data[PASS]), data1) 
				vip_data[FLAGS] = read_flags(data2)
			}
			}
			
			copy(vip_data[AUTH], charsmax(vip_data[AUTH]), str_auth)
			
			if (!(vip_data[SETTINGS] & (FLAG_C|FLAG_N|FLAG_F)))
				strtoupper(vip_data[AUTH])
				
			vip_data[SETTINGS] |= LOAD_FROM_INI
			VIPINC(INI)
			
			VipsDBInsert(vip_data)
			
			if (vip_data[TIMESTAMP] > 0 && timestamp > vip_data[TIMESTAMP]) {
				line_removed = true
				continue;
			}
			
			fputs(temph, line)
			
			global_continue:
		}
		
		
		fclose(handle)
		fclose(temph)
    
		if(line_removed) {
			
			delete_file(vipsfile)
			while (!rename_file(tempfilename, vipsfile, 1)) { }
		}
		else {
			delete_file(tempfilename)
		}
	}
	else log_amx("ERROR: Missing %s file in configs folder. Can't load zm_vip privileges.", VIPS_FILE)
}
remove_from_ini(data[vips_database_type]) {
	
	if (!VIPCNT(INI))
		return;
	
	new vipsfile[70]
	get_configsdir(vipsfile, charsmax(vipsfile))
	format(vipsfile, charsmax(vipsfile), "%s/%s", vipsfile, VIPS_FILE)
	new handle = fopen(vipsfile, "r+")
	
	if (handle) {
	
		new i, line[200], line_len, start

		while(!feof(handle)) {
			
			line_len = fgets(handle, line, charsmax(line))
			i = 0
			
			if (line[i] == ';'
			|| line[i] == '/'
			|| line[i] == 'X'
			|| line[i] == EOS) {
				continue;
			}
			
			start = 0
			while (start < line_len) {
				
				if (line[start++] == '"')
					break;
			}
			
			if (start >= line_len) continue;
			
			while (start < line_len) {
				
				if (line[start] == '"') {
					line[start] = EOS
					break;
				}
				start++
			}
			
			if (start >= line_len) continue;
			
			strtoupper(line[start])
			if (equal(line[start], data[AUTH])) {
				fseek(handle, -line_len, SEEK_CUR)
				fputc(handle, 'X')
				VIPDEC(INI)
				break;
			}
		}
		fclose(handle)
	}
	else
		log_amx("ERROR: Failed to read '%s' file.", vipsfile)
}
add_to_ini(data[vips_database_type]) {

	new vipsfile[70]
	get_configsdir(vipsfile, charsmax(vipsfile))
	format(vipsfile, charsmax(vipsfile), "%s/%s", vipsfile, VIPS_FILE)
	new handle = fopen(vipsfile, "at")
	
	if (handle) {
		new line[120], len
		len += formatex(line, charsmax(line), 
		"%s%s%s%s ^"%s^"",
		data[SETTINGS]&FLAG_C?"C":"",
		data[SETTINGS]&FLAG_N?"N":"",
		data[SETTINGS]&FLAG_F?"F":"",
		data[SETTINGS]&FLAG_K?"K":"",
		data[AUTH])
		
		if (!EMPTY(data[PASS]))
			len += formatex(line[len], charsmax(line)-len, " ^"%s^"", data[PASS])
		
		if (data[FLAGS] != -1) {
			new flags_str[30]
			get_flags(data[FLAGS], flags_str, charsmax(flags_str))
			len += formatex(line[len], charsmax(line)-len, " ^"%s^"", flags_str)
		}
		
		if (data[TIMESTAMP])
			len += format_time(line[len], charsmax(line)-len, " |%Y/%m/%d|%H:%M|", data[TIMESTAMP])
		
		VIPINC(INI)
		fputs(handle, line)
		fclose(handle)
	}
}
#endif
convert_duration_to_string(id, duration, string[], len) {
	
	if (duration == ZV_DURATION_TILL_MAP) {
		LookupLangKey(string, len, "TILL_MAPCHANGE", id)
		return;
	}
	else if (duration == ZV_DURATION_TILL_DISCONNECT) {
		LookupLangKey(string, len, "TILL_DISCONNECT", id)
		return;	
	}
	
	new index, time_unit[20] = {' '}, unit
	new week_word[][] = {"WEEK", "WEEKS", "WEEKSW"}
	new day_word[][] = {"DAY", "DAYS", "DAYSW"}
	new hour_word[][] = {"HOUR", "HOURS", "HOURSW"}
	new minute_word[][] = {"MINUTE", "MINUTES", "MINUTESW"}
	new second_word[][] = {"SECOND", "SECONDS", "SECONDSW"}
	
	if (duration >= 604800) {
		unit = duration/604800
		
		index += num_to_str(unit, string[index], len-index)
		LookupLangKey(time_unit[1], charsmax(time_unit), 
		week_word[(unit%10==1)?0:((unit%10==0||10<unit%100<20)?2:1)], id)
		index += add(string[index], len-index, time_unit)
		duration %= 604800
	}
	if (duration >= 86400) {
		if (index) { string[index] = ' '; string[++index] = EOS; }
		unit = duration/86400
		index += num_to_str(unit, string[index], len-index)
		LookupLangKey(time_unit[1], charsmax(time_unit),
		day_word[(unit%10==1)?0:((unit%10==0||10<unit%100<20)?2:1)], id)
		index += add(string[index], len-index, time_unit)
		duration %= 86400
	}
	if (duration >= 3600) {
		if (index) { string[index] = ' '; string[++index] = EOS; }
		unit = duration/3600
		index += num_to_str(unit, string[index], len-index)
		LookupLangKey(time_unit[1], charsmax(time_unit),
		hour_word[(unit%10==1)?0:((unit%10==0||10<unit%100<20)?2:1)], id)
		index += add(string[index], len-index, time_unit)
		duration %= 3600
	}
	if (duration >= 60) {
		if (index) { string[index] = ' '; string[++index] = EOS; }
		unit = duration/60
		index += num_to_str(unit, string[index], len-index)
		LookupLangKey(time_unit[1], charsmax(time_unit),
		minute_word[(unit%10==1)?0:((unit%10==0||10<unit%100<20)?2:1)], id)
		index += add(string[index], len-index, time_unit)
		duration %= 60
	}
	if (duration) {
		if (index) { string[index] = ' '; string[++index] = EOS; }
		index += num_to_str(duration, string[index], len-index)
		LookupLangKey(time_unit[1], charsmax(time_unit),
		second_word[(duration%10==1)?0:((duration%10==0||10<duration%100<20)?2:1)], id)
		index += add(string[index], len-index, time_unit)
	}
}

get_cvar_duration(cvar) {
	
	new dur[20], duration
	get_pcvar_string(cvar, dur, charsmax(dur))
	
	new len = strlen(dur)
	
	if (len) {
		
		switch (dur[len-1]) {

		case 'w': {
			dur[len-1] = EOS
			duration = str_to_num(dur)
			if (duration) {
				duration *= 7*24*3600
			}
		}
		case 'd': {
			dur[len-1] = EOS
			duration = str_to_num(dur)
			if (duration) {
				duration *= 24*3600
			}
		}
		case 'h': {
			dur[len-1] = EOS
			duration = str_to_num(dur)
			if (duration) {
				duration *= 3600
			}
		}
		case 's': {
			dur[len-1] = EOS
			duration = str_to_num(dur)
		}
		case 'm': {
			if (len-2 >= 0 && dur[len-2] == 't') {
				goto case_t
			}
			dur[len-1] = EOS
			duration = str_to_num(dur)
			if (duration) {
				duration *= 60
			}
		}
		case 't': {
			case_t:
			
			duration = ZV_DURATION_TILL_DISCONNECT
			if (dur[len-1] == 'm') {
				duration = ZV_DURATION_TILL_MAP
			}
		}
		default: {

			duration = str_to_num(dur)
			if (duration > 0) {
				duration *= 24*3600
			}
			else {
				log_amx("WARNING: Incorrect zm_vip_buy_duration cvar value ^"%s^".", dur)
				return -1;
			}
		}
		}
	}
	
	return duration
}
add_to_datafile(data[vips_database_type]) {
	
	new datafile[70]
	get_datadir(datafile, charsmax(datafile))
	add(datafile, charsmax(datafile), "/zm_vip.dat")
	
	new handle = fopen(datafile, "ab")
	
	if (handle) {
		
		fwrite_blocks(handle, data, 70, BLOCK_CHAR)
		fwrite_raw(handle, data[SETTINGS], 4, 3)
		fclose(handle)
		VIPINC(DAT)
	}
	else
		log_amx("ERROR: Failed to write '%s' file.", datafile)
}

remove_from_datafile(data[vips_database_type]) {
	
	if (!(data[SETTINGS] & LOAD_FROM_DAT))
		return;
	
	new datafile[70], bytes_in_file
	get_datadir(datafile, charsmax(datafile))
	add(datafile, charsmax(datafile), "/zm_vip.dat")
	
	bytes_in_file = file_size(datafile)
	
	new handle = fopen(datafile, "r+")
	
	if (handle) {
		
		new auth[sizeof(data[AUTH])]
		while (ftell(handle) < bytes_in_file) {
			
			fread_blocks(handle, auth, sizeof(data[AUTH]), BLOCK_CHAR)
			
			if (equal(auth, data[AUTH])) {
				fseek(handle, -sizeof(data[AUTH]), SEEK_CUR)
				fputc(handle, 0)
				VIPDEC(DAT)
				
				fseek(handle, sizeof(data[AUTH])+sizeof(data[PASS])+12-1, SEEK_CUR)
			}
			else {
				fseek(handle, sizeof(data[PASS])+12, SEEK_CUR)
			}
		}
		fclose(handle)
	}
	else
		log_amx("ERROR: Failed to read '%s' file.", datafile)
}
load_datafile() {
	
	new datafile[70]
	get_datadir(datafile, charsmax(datafile))
	add(datafile, charsmax(datafile), "/zm_vip.dat")
	
	if (!file_exists(datafile))
		return;
		
	new handle = fopen(datafile, "rb")
	
	if (handle) {
		
		new data[vips_database_type]
		while (!feof(handle)) {
			
			fread_blocks(handle, data, 70, BLOCK_CHAR)
			fread_raw(handle, data[SETTINGS], 4, 3)
			
			if (EMPTY(data[AUTH])) {
				dummy_record_count++
				continue;
			}
			data[SETTINGS] &= ~LOAD_MASK
			data[SETTINGS] |= LOAD_FROM_DAT
			VIPINC(DAT)
			
			VipsDBInsert(data)
		}
		fclose(handle)
	}
	else
		log_amx("ERROR: Failed to read '%s' file.", datafile)
}

write_datafile() {
	
	new datafile[70]
	get_datadir(datafile, charsmax(datafile))
	add(datafile, charsmax(datafile), "/zm_vip.dat")
	
	if (!VIPCNT(DAT) && file_exists(datafile)) {
		delete_file(datafile)
		return;
	}
	
	new handle = fopen(datafile, "wb")
	
	if (handle) {
		
		new key[40], i, size = ArraySize(array_vips_database)
		new data[vips_database_type]
		new timestamp = get_systime()
		
		for (i=0; i<size; i++) {
			
			ArrayGetString(array_vips_database, i, key, sizeof(key))
			
			if (EMPTY(key))
				continue;
			
			if (!TrieGetArray(trie_vips_database, key, data, vips_database_type))
				continue;
			
			if (!(data[SETTINGS] & LOAD_FROM_DAT))
				continue;
				
			if (data[TIMESTAMP] == ZV_DURATION_TILL_MAP)
				continue;
				
			if (data[TIMESTAMP] == ZV_DURATION_TILL_DISCONNECT) {
				
				if (data[PASS][charsmax(data[PASS])]+1 
				< floatround(get_gametime()*100, floatround_floor))
					continue;
				else
					data[PASS][charsmax(data[PASS])] = EOS
			}
			
			if (data[TIMESTAMP] <= timestamp)
				continue
			
			fwrite_blocks(handle, data, 70, BLOCK_CHAR)
			fwrite_raw(handle, data[SETTINGS], 4, 3)
		}
		
		if (array_vips_database_nick) {
			size = ArraySize(array_vips_database_nick)
			for (i=0; i<size; i++) {
				
				ArrayGetArray(array_vips_database_nick, i, data)
				
				if (EMPTY(data[AUTH]))
					continue;
					
				if (data[TIMESTAMP] == ZV_DURATION_TILL_MAP)
					continue;
					
				if (data[TIMESTAMP] == ZV_DURATION_TILL_DISCONNECT) {
					
					if (data[PASS][charsmax(data[PASS])]+1 
					< floatround(get_gametime()*100, floatround_floor))
						continue;
					else
						data[PASS][charsmax(data[PASS])] = EOS
				}
				
				if (data[TIMESTAMP] <= timestamp)
					continue
				
				data[SETTINGS] &= ~LOAD_MASK
				fwrite_blocks(handle, data, 70, BLOCK_CHAR)
				fwrite_raw(handle, data[SETTINGS], 4, 3)
			}
		}
		
		fclose(handle)
	}
	else
		log_amx("ERROR: Failed to write '%s' file.", datafile)
}

print_admin_contacts(id) {

	new contact[60]
	get_cvar_string("amx_contactinfo", contact, charsmax(contact))
	if(!EMPTY(contact))  {
		if (is_amxmodx_new_version) client_print_color(id, id, "^4%L: ^1%s.", id, "ADMIN_CONTACTS", contact)
		else _client_print_color(id, "^4%L: ^1%s.", id, "ADMIN_CONTACTS", contact)
	}
}

public show_vip_timeleft(id) {
	
	new timeleft[100]
	if (!p_data[id][TIMESTAMP])
		LookupLangKey(timeleft, charsmax(timeleft), "PERMANENT", id)
	else
		convert_duration_to_string(id, max(p_data[id][TIMESTAMP]-get_systime(), 0), timeleft, charsmax(timeleft))
	
	if (is_amxmodx_new_version) {
		set_dhudmessage(51, 118, 4, 0.02, 0.52, 0, 6.0, 0.9, 0.1, 0.3)
		show_dhudmessage(id, "VIP: %s", timeleft)
	}
	else {
		_set_dhudmessage(51, 118, 4, 0.02, 0.52, 0, 6.0, 0.9, 0.1, 0.3)	
		_show_dhudmessage(id, "VIP: %s", timeleft)
	}
}
stock timestamp_to_date(stamp, date_str[], dchars, time_str[], tchars) {
			
	new y=1970, m=1, d=1, cstamp = stamp
	new hours, mins
	
	while(cstamp >= 31536000) {
	
		cstamp -= (!(y%400)||((y%100)&&!(y%4)))?31622400:31536000
		y++;
	}
	
	while(cstamp >=	2419200) {
		
		switch(m) {
			case 2, 4, 6, 9: cstamp -= (!(y%400)||((y%100)&&!(y%4)))?2505600:2419200
			case 11:  cstamp -= 2592000
			case 1, 3, 5, 7, 8, 10, 12: cstamp -= 2678400
		}
		m++
	}

	while(cstamp >= 86400) {
	
		cstamp -= 86400
		d++
	}
	
	hours = cstamp/3600
	mins = (cstamp%3600)/60
	
	formatex(date_str, dchars, "%d/%d/%d%", y, m, d)
	formatex(time_str, tchars, "%d:%d", hours, mins)
}
/*stock date_to_timestamp(date_str[], time_str[]) {
		
	new y, m, d, i
	new hours, mins
	new temp_str[15], num[6]
	strtok(date_str, num, charsmax(num), temp_str, charsmax(temp_str), '/')
	y = str_to_num(num)
	strtok(temp_str, num, charsmax(num), temp_str, charsmax(temp_str), '/')
	m = str_to_num(num)
	d = str_to_num(temp_str)
	strtok(time_str, num, charsmax(num), temp_str, charsmax(temp_str), ':')
	hours = str_to_num(num)
	mins = str_to_num(temp_str)
	
	new stamp
	
	for (i=1970; y > i; i++)
		stamp += (!(i%400)||((i%100)&&!(i%4)))?31622400:31536000

	for (i=1; m > i; i++) {
		
		switch(i) {
			case 2, 4, 6, 9: stamp += (!(y%400)||((y%100)&&!(y%4)))?2505600:2419200
			case 11:  stamp += 2592000
			case 1, 3, 5, 7, 8, 10, 12: stamp += 2678400
		}
	}
	stamp += d*86400
	stamp += hours*3600
	stamp += mins*60
	return stamp;
}*/

stock findtag(msg[], tag[]) {
	
	static i, d
	i = 0
	while (msg[i] != EOS) {
		if (msg[i] == tag[0]) {
			
			d = 0
			while (tag[d]!=EOS&&msg[i+d]!=EOS) {
				if (tag[d]!=msg[i+d] && ((65<=tag[d]<=90) && (tag[d]+32)!=msg[i+d]))
					break;
				d++
			}
			if (tag[d] == EOS) {
				return i;
			}
		}
		i++
	}
	return -1;
}
stock read_config(cvar[], value[], len) {
	
	new directory[40]
	get_configsdir(directory, charsmax(directory))
	format(directory, charsmax(directory), "%s/%s", directory, CONFIGS_FILE)
	value[0] = EOS
	
	new handle = fopen(directory, "rt")
	if (handle) {
		
		new line[100], place
		while (!feof(handle)) {
			fgets(handle, line, charsmax(line))
			
			if ((place = contain(line, cvar)) != -1) {
				
				while (line[place] != '"' && line[place] != EOS) { place++; }
				
				if (line[place] == '"') {
					
					place++
					new index
					while (line[place] != '"' && line[place] != EOS && index < len) {
						
						value[index++] = line[place++] 
					}
					value[index] = EOS
					break;
				}
			}
		}
		fclose(handle)
	}
}
#if AMXX_VERSION_NUM < 183
native client_print_color(index, sender, const message[], any:...);
#endif
stock _client_print_color(id, const message[], any:...)
{	
	static buffer[512], argscount
	argscount = numargs()
	
	if (!id) {
		
		static players[32], num, player, i, i2
		get_players(players, num , "ch")
			
		for (i = 0; i < num; i++) {
			
			player = players[i]
			
			static changed[5], changedcount
			changedcount = 0
			
			for (i2 = 2; i2 < argscount; i2++)
			{
				if (getarg(i2) == LANG_PLAYER)
				{
					setarg(i2, 0, player)
					changed[changedcount] = i2
					changedcount++
				}
			}
			
			vformat(buffer, charsmax(buffer), message, 3)
					
			message_begin(MSG_ONE_UNRELIABLE, msg_saytext, _, player)
			write_byte(player)
			write_string(buffer)
			message_end()
			
			for (i2 = 0; i2 < changedcount; i2++)
				setarg(changed[i2], 0, LANG_PLAYER)
		}
	}
	else {
		
		vformat(buffer, charsmax(buffer), message, 3)
				
		message_begin(MSG_ONE_UNRELIABLE, msg_saytext, _, id)
		write_byte(id)
		write_string(buffer)
		message_end()
	}
}

stock __dhud_color;
stock __dhud_x;
stock __dhud_y;
stock __dhud_effect;
stock __dhud_fxtime;
stock __dhud_holdtime;
stock __dhud_fadeintime;
stock __dhud_fadeouttime;
stock __dhud_reliable;

#if AMXX_VERSION_NUM < 183
native set_dhudmessage(red=200, green=100, blue=0, Float:x=-1.0, Float:y=0.35, effects=0, Float:fxtime=6.0, Float:holdtime=12.0, Float:fadeintime=0.1, Float:fadeouttime=0.2);
#endif
stock _set_dhudmessage( red = 0, green = 160, blue = 0, Float:x = -1.0, Float:y = 0.65, effects = 2, Float:fxtime = 6.0, Float:holdtime = 3.0, Float:fadeintime = 0.1, Float:fadeouttime = 1.5, bool:reliable = false )
{
	#define clamp_byte(%1)       ( clamp( %1, 0, 255 ) )
	#define pack_color(%1,%2,%3) ( %3 + ( %2 << 8 ) + ( %1 << 16 ) )

	__dhud_color       = pack_color( clamp_byte( red ), clamp_byte( green ), clamp_byte( blue ) );
	__dhud_x           = _:x;
	__dhud_y           = _:y;
	__dhud_effect      = effects;
	__dhud_fxtime      = _:fxtime;
	__dhud_holdtime    = _:holdtime;
	__dhud_fadeintime  = _:fadeintime;
	__dhud_fadeouttime = _:fadeouttime;
	__dhud_reliable    = _:reliable;

	return 1;
}
#if AMXX_VERSION_NUM < 183
native show_dhudmessage(index, const message[], any:...);
#endif
stock _show_dhudmessage(index, const message[], any:... )
{	
	new buffer[ 128 ];
	new numArguments = numargs();

	if( numArguments == 2 )
	{
		send_dhudMessage( index, message );
	}
	else if( index || numArguments == 3 )
	{
		vformat( buffer, charsmax( buffer ), message, 3 );
		send_dhudMessage( index, buffer );
	}
	else
	{
		new playersList[ 32 ], numPlayers;
		get_players( playersList, numPlayers, "ch" );

		if( !numPlayers )
		{
			return 0;
		}

		new Array:handleArrayML = ArrayCreate();

		for( new i = 2, j; i < numArguments; i++ )
		{
			if( getarg( i ) == LANG_PLAYER )
			{
				while( ( buffer[ j ] = getarg( i + 1, j++ ) ) ) {}
				j = 0;

				if( GetLangTransKey( buffer ) != TransKey_Bad )
				{
					ArrayPushCell( handleArrayML, i++ );
				}
			}
		}

		new size = ArraySize( handleArrayML );

		if( !size )
		{
			vformat( buffer, charsmax( buffer ), message, 3 );
			send_dhudMessage( index, buffer );
		}
		else
		{
			for( new i = 0, j; i < numPlayers; i++ )
			{
				index = playersList[ i ];

				for( j = 0; j < size; j++ )
				{
					setarg( ArrayGetCell( handleArrayML, j ), 0, index );
				}

				vformat( buffer, charsmax( buffer ), message, 3 );
				send_dhudMessage( index, buffer );
			}
		}

		ArrayDestroy( handleArrayML );
	}

	return 1;
}
stock send_dhudMessage( const index, const message[] )
{
	message_begin( __dhud_reliable ? ( index ? MSG_ONE : MSG_ALL ) : ( index ? MSG_ONE_UNRELIABLE : MSG_BROADCAST ), SVC_DIRECTOR, _, index );
	{
		write_byte( strlen( message ) + 31 );
		write_byte( DRC_CMD_MESSAGE );
		write_byte( __dhud_effect );
		write_long( __dhud_color );
		write_long( __dhud_x );
		write_long( __dhud_y );
		write_long( __dhud_fadeintime );
		write_long( __dhud_fadeouttime );
		write_long( __dhud_holdtime );
		write_long( __dhud_fxtime );
		write_string( message );
	}
	message_end();
}

VipsItemIs(ClassType:type, itemid) {
	
	static strnum[6]
	num_to_str(itemid, strnum[1], charsmax(strnum)-1)
	strnum[0] = _:type
	
	return TrieKeyExists(trie_vip_items, strnum)
}
VipsItemSet(ClassType:type, itemid) {
	
	if (!trie_vip_items)
		trie_vip_items = TrieCreate()
		
	new strnum[6]
	num_to_str(itemid, strnum[1], charsmax(strnum)-1)
	strnum[0] = _:type
	
	return TrieSetCell(trie_vip_items, strnum, 1)
}

stock VipsDBGet(const id) {
	
	if (!(1 <= id < 33))
		return false;
		
	p_data[id][FLAGS] = 0
	p_data[id][SETTINGS] = 0
	
	if (!VIPCNT(DAT) && !VIPCNT(INI) && !VIPCNT(AMX))
		return false;
	
	static authid[30], ip[30], name[45]
	get_user_info(id, "name", name, charsmax(name))
	get_user_authid(id, authid, charsmax(authid))
	get_user_ip(id, ip, charsmax(ip), 1)
	
	static uppername[45], client_password[30]
	
	copy(uppername, charsmax(uppername), name)
	strtoupper(uppername)
	get_user_info(id, amx_password_field_string, client_password, charsmax(client_password))
	
	if (VIPCNT(MAIN) && TrieGetArray(trie_vips_database, authid, p_data[id], vips_database_type)) 
	{ p_data[id][SETTINGS] |= LOAD_FROM_MAIN; }
	else if(VIPCNT(MAIN) && TrieGetArray(trie_vips_database, ip, p_data[id], vips_database_type)) 
	{ p_data[id][SETTINGS] |= LOAD_FROM_MAIN; }
	else if(VIPCNT(MAIN) && TrieGetArray(trie_vips_database, uppername, p_data[id], vips_database_type)) 
	{ p_data[id][SETTINGS] |= LOAD_FROM_MAIN; }
	else if (VIPCNT(NAMES) && check_named_privileges(id, name, client_password) > 0) 
	{ p_data[id][SETTINGS] |= LOAD_FROM_NAMES; }
	
	if (!EMPTY(p_data[id][PASS]) && p_data[id][SETTINGS] & FLAG_K && !equal(p_data[id][PASS], client_password)) {
		p_data[id][SETTINGS] = 0
		p_data[id][FLAGS] = 0
		server_cmd("kick #%d ^"[ZMVIP] %L.^"", get_user_userid(id), id, "INVALID_PASS")
		return false;
	}
		
#if VIPS_FILE_SYSTEM != FORCED
	if(get_user_flags(id) & VIP_SYS_FLAG) {
		
		new flags = _get_pcvar_flags(cvar_amx_auth_flags)
		if (flags == 0)
			p_data[id][FLAGS] = -1
		else
			p_data[id][FLAGS] |= flags
		p_data[id][TIMESTAMP] = 0
		p_data[id][SETTINGS] |= LOAD_FROM_AMX
	}
#endif
	if (p_data[id][FLAGS]) {
		new flags = _get_pcvar_flags(cvar_amxmodx_flags)
		if (flags > 0)
		set_user_flags(id, flags)
	}
	
	if (!p_data[id][FLAGS]) {
		p_data[id][SETTINGS] = 0
		p_data[id][TIMESTAMP] = 0
		arrayset(p_attribs[id], 0, player_attributes)
		return false;
	}
	
	console_print(id, "* VIP Privileges set")
	return true;
}
	

stock VipsDBSet(const id) {
	
	if (!(1 <= id < 33))
		return false;
	
	if (p_data[id][SETTINGS]&LOAD_MASK) {
		
		if (p_data[id][SETTINGS]&(LOAD_FROM_MAIN)) {
			TrieSetArray(trie_vips_database, p_data[id][AUTH], p_data[id], vips_database_type)
		}
		else if (p_data[id][SETTINGS]&LOAD_FROM_NAMES) {
			ArraySetArray(array_vips_database_nick, p_data[id][INDEX], p_data[id])
		}
#if VIPS_FILE_SYSTEM != FORCED
		else if (p_data[id][SETTINGS]&LOAD_FROM_AMX) {
			
			p_data[id][SETTINGS] = 0
			VipsDBSet(id)
		}
#endif
#if VIPS_FILE_SYSTEM != OFF
		if (p_data[id][SETTINGS]&LOAD_FROM_INI) {
			remove_from_ini(p_data[id])
			add_to_ini(p_data[id])
		}
		else if (p_data[id][SETTINGS]&LOAD_FROM_DAT) {
			remove_from_datafile(p_data[id])
			add_to_datafile(p_data[id])
		}
#else
		remove_from_datafile(p_data[id])
		add_to_datafile(p_data[id])	
#endif
		return true;
	}
	
	get_user_authid(id, p_data[id][AUTH], charsmax(p_data[][AUTH]))
	if (p_data[id][AUTH][7] != ':')
		get_user_ip(id, p_data[id][AUTH], charsmax(p_data[][AUTH]), 1)
	
	p_data[id][PASS] = EOS
#if VIPS_FILE_SYSTEM != OFF
	if (get_pcvar_num(cvar_vip_store_ini)&&(p_data[id][TIMESTAMP]!=ZV_DURATION_TILL_MAP)){
		
		p_data[id][SETTINGS] = LOAD_FROM_INI
	}
	else {
		p_data[id][SETTINGS] = LOAD_FROM_DAT
	}
#else
	p_data[id][SETTINGS] = LOAD_FROM_DAT
#endif
	if (p_data[id][SETTINGS] & LOAD_FROM_DAT)
		add_to_datafile(p_data[id])
#if VIPS_FILE_SYSTEM != OFF
	if (p_data[id][SETTINGS] & LOAD_FROM_INI)
		add_to_ini(p_data[id])
#endif	
	return VipsDBInsert(p_data[id]);
}
stock VipsDBInsert(data[vips_database_type]) {
	
	if (data[SETTINGS] & ~(LOAD_MASK|FLAG_K)) {
		
		if(!array_vips_database_nick)
			array_vips_database_nick = ArrayCreate(vips_database_type, 10)
			
		data[SETTINGS] |= LOAD_FROM_NAMES
		data[INDEX] = ArraySize(array_vips_database_nick)
		ArrayPushArray(array_vips_database_nick, data)
		VIPINC(NAMES)
		
		return true;
	}
	
	data[INDEX] = ArraySize(array_vips_database)
	ArrayPushString(array_vips_database, data[AUTH])
	TrieSetArray(trie_vips_database, data[AUTH], data, vips_database_type)
	VIPINC(MAIN)
	
	return true;
}

stock VipsDBRemove(const id) {
	
	if (!(1 <= id < 33))
		return false;
	
	if (p_data[id][SETTINGS]&LOAD_MASK) {
		
		p_data[id][FLAGS] = 0
		p_data[id][TIMESTAMP] = 0
		if (p_data[id][SETTINGS]&(LOAD_FROM_MAIN)) {
			
			TrieDeleteKey(trie_vips_database, p_data[id][AUTH])
			ArraySetString(array_vips_database, p_data[id][INDEX], "")
			VIPDEC(MAIN)
			
			if (p_data[id][SETTINGS]&LOAD_FROM_MAIN)
				remove_from_datafile(p_data[id])
#if VIPS_FILE_SYSTEM != OFF
			if (p_data[id][SETTINGS]&LOAD_FROM_INI)
				remove_from_ini(p_data[id])
#endif
		}
		else if (p_data[id][SETTINGS]&LOAD_FROM_NAMES) {
			
			p_data[id][AUTH][0] = EOS
			ArraySetArray(array_vips_database_nick, p_data[id][INDEX], p_data[id])
			VIPDEC(NAMES)
		}
#if VIPS_FILE_SYSTEM != FORCED
		else if (p_data[id][SETTINGS]&LOAD_FROM_AMX) {
			
			remove_user_flags(id, VIP_SYS_FLAG)
			// VIPCNT(AMX) not decremented, because we don't delete from amxmodx dynamic
			// admin list. There is no efficient way to do this. Only by flushing all admins
		}
#endif
		new flags = _get_pcvar_flags(cvar_amxmodx_flags)
		if (flags > 0)
			remove_user_flags(id, flags)
		
		p_data[id][SETTINGS] = 0
		return true;
	}
	
	return false;
}
zm_vip.cfg

Code: Select all

/*****************************************************************************
 *      ZM VIP 2.0.0 configs file
 *      Author: aaarnas
 *
 *      This is mod settings file.
 *      Settings are updated at server start/restart/mapchanges
 *****************************************************************************/

amx_contactinfo "" // Admin contact info. Leave empty or delete this line not to use it.

//////////////////////////////  VIP abilities  ///////////////////////////////
zm_vip_mutijump 1			// How many multijumps can VIP player do. [0-disabled] (FLAG a)
zm_vip_multijump_allow ab		// Who can do multijump: a-human, b-zombie, c-nemesis,assasin,bombardier, d-survivor,sniper.
zm_vip_armor 65				// Amount of armour for HUMAN on spawn. [0-disabled] (FLAG b)
zm_vip_unlimited_clip 0			// Unlimited clip for VIP player (Don't need to reload). [0-disabled] (FLAG c)
zm_vip_no_fall_dmg 1			// If 1, VIPs don't take fall damage. [0-disabled] (FLAG d)
zm_vip_damage_reward 1000		// Extra (one) Ammo pack for amount of damage delt. [0-disabled] (FLAG e)
zm_vip_extra_dmg 1.2			// Extra damage from VIPs guns. dealtdmg = 1.2*damage [0-disabled] (FLAG f)
zm_vip_extra_hp_human 50		// Extra HP for HUMAN on spawn. [0-disabled] (FLAG g)
zm_vip_extra_hp_zombie 500		// Extra HP for ZOMBIE on spawn/infect. [0-disabled] (FLAG g)
zm_vip_extra_gravity_human 0		// Extra gravity for HUMAN. Interval 0.0-1.0 (Ex 0.2). Higher value - jumps higher [0-disabled] (FLAG h)
zm_vip_extra_gravity_zombie 0		// Extra gravity for ZOMBIE. Interval 0.0-1.0 (Ex 0.2). Higher value - jumps higher [0-disabled](FLAG h)
zm_vip_extra_frags 0			// Extra frags for VIP players on kill/infect (in Score table). [0-disabled] (FLAG i)
zm_vip_extra_kill_ammo 1		// Extra ammo packs for VIP players on killing. [0-disabled] (FLAG j)
zm_vip_extra_armor 0			// Extra armour gain for HUMANS on killing zombies. [0-disabled] (FLAG k)
zm_vip_extra_infect_ammo 1		// Extra ammo packs for infecting. [0-disabled] (FLAG l)
zm_vip_extra_infect_health 100		// Extra HP for infecting. [0-disabled] (FLAG m)
zm_vip_extra_ignore_for_special 1	// Ignore extra features for nemesis,survivor,assasin,bombardier,sniper [0-disabled]
zm_viponly_class 1			// Enable VIP only classes (if available). [0-disabled (all players can choose)]
zm_vip_chattag 1			// Add chat tag <VIP> for VIP players. Set 2 if you having chat plugins compability problems [0-disabled] (FLAG q)
zm_vip_connected_to_server 1		// Write message to all players, that VIP connected to server. 1-chat/2-hud/3-hud(big letters) [0-disabled] (FLAG q)
zm_vipinscoretable 1			// Show VIP tag in Score table for VIP players. [0-disabled] (FLAG r)
zm_vip_grenades_immunity 0		// Immunity from grenades. a - infection, b - fire, c - frost [0-disabled] (FLAG s)
								// b and c only available from version zp 5.0.6 and higher!
zm_vip_gamemode_disable_flags 0		// flags, that should be removed for each player during any gamemode (look vips.ini) [0-disabled]
////////////////////////////// Player Authentication /////////////////////////								
zm_vip_amx_auth_flags 0				// Flags that players authenticated by amxmodx will get (from users.ini file has 't' flag).
								// Flags meanings can be found in vips.ini. [0 - all flags (full privilegies)]
zm_vip_amxmodx_flags "t"		// Flags that will be added to default amxmodx auth system (same as users.ini), to support VIP plugins
								// using t flag check in amxmodx user flags. Will be added if player identified as VIP. [0-disabled]
								
////////////////////////////// Models ////////////////////////////////////////
zm_vip_model_zombie ""			// VIP model for zombie [Empty - dissabled] (FLAG o)
zm_vip_model_human ""			// VIP model for human [Empty - dissabled] (FLAG o)

////////////////////////////// Free VIP //////////////////////////////////////
zm_vip_freevip_hour "off"		// Set hour when all players get VIP. (Example "00:30-13:15", "00:00-00:00"-all time) [0/off-disabled]
zm_vip_freevip_flags bdfglmopr	// What flags players gets from free VIP. (Check vips.ini). [0 - all flags]

////////////////////////////// VIP Buy ///////////////////////////////////////
zm_vip_price 100				// VIP price to buy it with ammo packs (or money). [0-disabled]
zm_vip_store_ini 0			// If enabled, bought VIP privilegies will be saved to vips.ini file (if enabled VIPS_FILE_SYSTEM)
							// If disabled, privilegies are saved to binary file (can't edit)
////////////////////////////// Time how long buyed VIP lasts. ////////////////
// ["10s"-10seconds,"15m"-15min,"2h"-2hours,"1d"-1day,"2w"-2weeks]
// Flags:
//	"t" - player will have VIP till he disconnects from server. Also have during mapchanges.
//  "tm" - player will have VIP till disconnect or mapchange
// usage example: zm_vip_buy_duration "tm"
zm_vip_buy_duration 2d			// <- Cvar
//////////////////////////////
zm_vip_buy_flags 0			// What flags players gets when buys VIP. (Check vips.ini). [0-all flags]
zm_vip_buy_in_extra_items 1		// Show buy VIP privilegie as extra item for all players.

////////////////////////////// Extra items (Only if EXTRA_ITEMS is ON) ///////
zm_vip_buys_per_round 0			// Maximum amount of buys VIP extra items per round. [0-disabled]
zm_vip_show_vip_items "2"		// Show VIP extra items in all items menu: 1 - for VIPs only, 2 - for all players [0-disabled]
								// NOTE: don't remove quotation marks from this cvar! ("2")

Nume: [ZP] Zombie VIP 1.9.1
Versiune: 1.9.1 BETA
Link oficial: click , l-am postat pentru ca am vazut ca nu e si aici pe forum :)


Instalare:

Code: Select all

Descărcați ZIP și extrageți în directorul dvs. de servere
Deschideți fișierul configs / zm_vip.cfg și setați setările.
Plugin-ul este pregătit să se utilizeze cu Zombie Plague
1. Fisierul zm_vip.sma il puneti in addons/amxmodx/scripting
2. Fisierul zm_vip.amxx il puneti in addons/amxmodx/plugins
3. Intrati in fisierul addons/amxmodx/configs/plugins.ini si adaugati la urma:

Code: Select all

zm_vip.amxx
4. Alti pasi necesari....

Cvar-uri (se adauga in fisierul amxmodx\configs\amxx.cfg):
zm_vip_list - lista tuturor privilegiilor încărcate (în consola)
zm_vip_reload - reîncărcați toate VIP-urile încărcate
zm_vip_remove [Player] - eliminați privilegiile jucătorului

Configuratia pluginului:

Code: Select all

MODIFICARE - Alegeți ce versiune de Zombie Plague veți folosi
NEW - Zombie Plague 5 sau mai mare. Funcționează și cu versiuni modificate (bazate pe 5.x).
OLD - Zombie Plague 4.3. Funcționează de asemenea cu versiuni modificate (bazate pe 4.3).
-------------------------------------------------- ----
VIPS_FILE_SYSTEM - Activează sau dezactivează fișierul vips.ini. Acest fișier este folosit pentru a adăuga privilegii VIP pentru jucători, similar, ca fișier users.ini.
FORCED - Încărcați VIP-uri numai din fișierul vips.ini
ON - Încărcați VIP-urile din vips.ini și amxmodx (fișiere users.ini, care au flagul t)
OFF - Dezactivați fișierul vips.ini și utilizați numai sistemul de autentificare amxmodx.
Plugin-ul are sistemul intern de stocare a privilegiilor. Acesta va fi activat automat dacă pluginul cere acest lucru.
-------------------------------------------------- ----
EXTRA_ITEMS - Dezactivați sau activați elemente suplimentare separate pentru sistemul VIP.
ON - Activat
OFF - Dezactivat
-------------------------------------------------- ----
VIP_SYS_FLAG - steagul VIP implicit în amxmodx ("t")
ADMIN_SYS_FLAG - pavilion admin pentru accesarea comenzilor consolei ("q")
Salvați fișierul și compilați pluginul. Puneți fișierul generat amxx în dosarul pluginurilor.
Reporniți serverul sau schimbați harta.

Comanda in chat:
/vip - deschide fereastra motd. Ai creat propriul fișier vips.txt și ai pus în folderul cstrike!
/vips - arată jucători VIP conectați
/vm - meniul VIP

Cum faci extra items special pentru vip sau o clasa speciala pentru vip:

1.Deschideți fișierul .sma de element sau de clasă.
2.În partea de sus, unde toate sunt #include, adăugați #include <zm_vip> ca fiind ultima dintre ele. Nu mai schimba nimic!
3.Compilați pluginul, adăugați fișierul .amxx în dosarul pluginuri.
4.Scrieți numele fișierului plugin (cu extensia .amxx) în fișierul configs / plugins-zp_zm_vip.ini la sfârșit.
5.Salveaza fisierul. Reporniți serverul
6.Terminat!

Servere care utilizează acest plugin

VIP Extra:

zm_vip_extra_adv_antidotegun.sma

Code: Select all

/*================================================================================

	[ZP] Extra Item: Advanced Antidote Gun
	Copyright (C) 2010 by meTaLiCroSS, Viña del Mar, Chile
	
	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
	
	In addition, as a special exception, the author gives permission to
	link the code of this program with the Half-Life Game Engine ("HL
	Engine") and Modified Game Libraries ("MODs") developed by Valve,
	L.L.C ("Valve"). You must obey the GNU General Public License in all
	respects for all of the code used other than the HL Engine and MODs
	from Valve. If you modify this file, you may extend this exception
	to your version of the file, but you are not obligated to do so. If
	you do not wish to do so, delete this exception statement from your
	version.
	
	** Credits:
		
	- ConnorMcLeod: His MaxClip and Reload Speed plugin
	- KCE: His "Blocking weapon fire" tutorial
	- XxAvalanchexX: His "Beampoints from a player's weapon tip" tutorial

=================================================================================*/

#include <amxmodx>
#include <hamsandwich>
#include <fun>
#include <engine>
#include <cstrike>
#include <fakemeta>
#include <xs>
#include <zombieplague>
#include <zmvip>

/*================================================================================
 [Customizations]
=================================================================================*/

// Item Cost
const antidotegun_ap_cost = 30

// Sprites
new const antidotegun_sprite_beam[] = "sprites/zbeam6.spr"
new const antidotegun_sprite_ring[] = "sprites/shockwave.spr"

// Weapon Fire Sound, you can add more than 1
new const antidotegun_firesound[][] = { "weapons/gauss2.wav" }

// Hit Sound, you can add more than 1
new const antidotegun_hitsound[][] = { "warcraft3/frostnova.wav" }

// Ammo bought Sound, you can add more than 1
new const antidotegun_ammopickupsound[][] = { "items/9mmclip1.wav" }

// Weaponbox Glow RGB Colors	R	G	B
new antidotegun_wb_color[] = {	0, 	255, 	255 	}

// Uncomment this line if you want to add support to old ZP versions
// Use if it's necessary, from version 4.2 to below
// If you uncomment this line, this item can be buyed only in infection
// rounds, because the main disinfect native in old versions works
// only on infection rounds.
//#define OLD_VERSION_SUPPORT

/*================================================================================
 Customization ends here! Yes, that's it. Editing anything beyond
 here is not officially supported. Proceed at your own risk...
=================================================================================*/

// Booleans
new bool:g_bHasAntidoteGun[33], bool:g_bIsConnected[33], bool:g_bIsAlive[33]

// Cvar pointers
new cvar_enable, cvar_oneround, cvar_firerate, cvar_maxclip, cvar_maxbpammo, cvar_wboxglow, 
cvar_buyindelay, cvar_reloadspeed, cvar_hitslowdown

// Arrays
new g_iCurrentWeapon[33], Float:g_flLastFireTime[33]

// Variables
new g_iItemID, g_iMaxPlayers, g_msgSayText, g_msgDeathMsg, g_msgCurWeapon, g_msgAmmoX, 
g_msgAmmoPickup, g_msgScreenFade, g_sprBeam, g_sprRing, HamHook:g_iHhPostFrame_fw

// Offsets
const m_pPlayer = 		41
const m_fInReload =		54
const m_pActiveItem = 		373
const m_flNextAttack = 		83
const m_flTimeWeaponIdle = 	48
const m_flNextPrimaryAttack = 	46
const m_flNextSecondaryAttack =	47

// Some constants
const FFADE_IN = 		0x0000
const ENG_NULLENT = 		-1
const UNIT_SECOND =		(1<<12)
const AMMOID_GALIL = 		4
const GALIL_DFT_MAXCLIP =	35
const V_GAUSS_ANIM_FIRE = 	6
const V_GAUSS_ANIM_DRAW = 	8
const V_GAUSS_ANIM_RELOAD = 	2
const EV_INT_WEAPONKEY = 	EV_INT_impulse
const ANTIDOTEGUN_WPNKEY = 	2816

// Buy in delay cvar it's disabled 
// for old versions
#if defined OLD_VERSION_SUPPORT
	#pragma unused cvar_buyindelay
#endif

// Cached cvars
new bool:g_bCvar_Enabled, bool:g_bCvar_BuyUntilMode, Float:g_flCvar_FireRate,
Float:g_flCvar_ReloadSpeed, Float:g_flCvar_HitSlowdown, g_iCvar_MaxClip, g_iCvar_MaxBPAmmo

// Plug info.
#define PLUG_VERSION "0.6"
#define PLUG_AUTH "meTaLiCroSS"

// Macros
#define is_user_valid_alive(%1) 	(1 <= %1 <= g_iMaxPlayers && g_bIsAlive[%1])
#define is_user_valid_connected(%1) 	(1 <= %1 <= g_iMaxPlayers && g_bIsConnected[%1])

/*================================================================================
 [Init and Precache]
=================================================================================*/

public plugin_init() 
{
	// Plugin info
	register_plugin("[ZP] Extra Item: Advanced Antidote Gun", PLUG_VERSION, PLUG_AUTH)
	
	// Events
	register_event("CurWeapon", "event_CurWeapon", "b", "1=1")	
	register_event("HLTV", "event_RoundStart", "a", "1=0", "2=0")
	
	// Fakemeta Forwards
	register_forward(FM_SetModel, "fw_SetModel")
	register_forward(FM_CmdStart, "fw_CmdStart")
	register_forward(FM_UpdateClientData, "fw_UpdateClientData_Post", 1)
	
	// Hamsandwich Forwards
	RegisterHam(Ham_Killed, "player", "fw_PlayerKilled")
	RegisterHam(Ham_Spawn, "player", "fw_PlayerSpawn_Post", 1)
	RegisterHam(Ham_Item_Deploy, "weapon_galil", "fw_Galil_Deploy_Post", 1)
	RegisterHam(Ham_Item_AddToPlayer, "weapon_galil", "fw_Galil_AddToPlayer")
	RegisterHam(Ham_Weapon_Reload, "weapon_galil", "fw_Galil_Reload_Post", 1)
	g_iHhPostFrame_fw = RegisterHam(Ham_Item_PostFrame, "weapon_galil", "fw_Galil_PostFrame")
	
	// Cvars
	cvar_enable = register_cvar("zp_antidotegun_enable", "1")
	cvar_oneround = register_cvar("zp_antidotegun_oneround", "0")
	cvar_firerate = register_cvar("zp_antidotegun_fire_rate", "0.6")
	cvar_maxclip = register_cvar("zp_antidotegun_max_clip", "3")
	cvar_maxbpammo = register_cvar("zp_antidotegun_max_bpammo", "25")
	cvar_reloadspeed = register_cvar("zp_antidotegun_reload_speed", "2.5")
	cvar_wboxglow = register_cvar("zp_antidotegun_wbox_glow", "1")
	cvar_buyindelay = register_cvar("zp_antidotegun_buy_before_modestart", "0")
	cvar_hitslowdown = register_cvar("zp_antidotegun_hit_slowdown", "0.4")
	
	static szCvar[30]
	formatex(szCvar, charsmax(szCvar), "v%s by %s", PLUG_VERSION, PLUG_AUTH)
	register_cvar("zp_extra_adv_antidotegun", szCvar, FCVAR_SERVER|FCVAR_SPONLY)
	
	// Variables
	g_iMaxPlayers = get_maxplayers()
	g_msgAmmoX = get_user_msgid("AmmoX")
	g_msgSayText = get_user_msgid("SayText")
	g_msgDeathMsg = get_user_msgid("DeathMsg")
	g_msgCurWeapon = get_user_msgid("CurWeapon")
	g_msgAmmoPickup = get_user_msgid("AmmoPickup")
	g_msgScreenFade = get_user_msgid("ScreenFade")
	g_iItemID = zv_register_extra_item("Antidote Gun", "Desinfecting people", antidotegun_ap_cost, ZV_TEAM_HUMAN)
}

public plugin_precache()
{
	// Models
	precache_model("models/v_gauss.mdl")
	precache_model("models/p_gauss.mdl")
	precache_model("models/w_gauss.mdl")
	
	// Sprites
	g_sprBeam = precache_model(antidotegun_sprite_beam)
	g_sprRing = precache_model(antidotegun_sprite_ring)
	
	// Sounds
	static i
	for(i = 0; i < sizeof antidotegun_firesound; i++)
		precache_sound(antidotegun_firesound[i])
	for(i = 0; i < sizeof antidotegun_ammopickupsound; i++)
		precache_sound(antidotegun_ammopickupsound[i])
	for(i = 0; i < sizeof antidotegun_hitsound; i++)
		precache_sound(antidotegun_hitsound[i])
		
		
}

public plugin_cfg()
{
	// Cache some cvars after init is called
	cache_cvars()
	
	// Check the max clip cvar
	if(g_iCvar_MaxClip && g_iCvar_MaxClip != GALIL_DFT_MAXCLIP)
	{
		EnableHamForward(g_iHhPostFrame_fw)
	}
	else
	{
		// Should disable it if isn't necesary to check
		DisableHamForward(g_iHhPostFrame_fw)
	}
}

/*================================================================================
 [Main Events]
=================================================================================*/

public event_CurWeapon(id)
{
	// Not alive...
	if(!g_bIsAlive[id])
		return PLUGIN_CONTINUE
		
	// Updating weapon array
	g_iCurrentWeapon[id] = read_data(2)
	
	// Zombie or Survivor
	if(zp_get_user_zombie(id) || zp_get_user_survivor(id))
		return PLUGIN_CONTINUE
		
	// Doesn't has an Antidote Gun and weapon isn't Galil
	if(!g_bHasAntidoteGun[id] || g_iCurrentWeapon[id] != CSW_GALIL) 
		return PLUGIN_CONTINUE
		
	// Change his models
	entity_set_string(id, EV_SZ_viewmodel, "models/v_gauss.mdl")
	entity_set_string(id, EV_SZ_weaponmodel, "models/p_gauss.mdl")
		
	return PLUGIN_CONTINUE
}

public event_RoundStart()
{
	// Some cvars cache on round start
	cache_cvars()
}

/*================================================================================
 [Zombie Plague Forwards]
=================================================================================*/

public zp_user_humanized_pre(id)
{
	// Update bool when was buyed an antidote
	g_bHasAntidoteGun[id] = false
}

public zp_user_infected_post(id)
{
	// Update bool when was infected
	g_bHasAntidoteGun[id] = false
}

public zv_extra_item_selected(id, itemid)
{
	// It's an antidote gun itemid
	if(itemid == g_iItemID)
	{
		// Should be enabled
		if(g_bCvar_Enabled)
		{
			// Buy until round starts?
			if (!zp_has_round_started() && !g_bCvar_BuyUntilMode)
			{
				client_printcolor(id, "/g[ZP]/y You must wait until the round starts")
				
				#if defined OLD_VERSION_SUPPORT
				zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + antidotegun_ap_cost)
				return PLUGIN_CONTINUE
				#else
				return ZV_PLUGIN_HANDLED
				#endif
			}
			
			#if defined OLD_VERSION_SUPPORT
			// Check actual mode id
			if(zp_is_plague_round() || zp_is_swarm_round() || zp_is_nemesis_round() || zp_is_survivor_round())
			{
				client_printcolor(id, "/g[ZP]/y You can't buy this gun in this round")
				zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + antidotegun_ap_cost)
				return PLUGIN_CONTINUE
			}
			#endif
			
			// Some vars with info
			new iWpnID, iAmmo, iBPAmmo, bool:bAlreadyHasGalil = bool:user_has_weapon(id, CSW_GALIL)
			
			// Already has this gun
			if(g_bHasAntidoteGun[id] && bAlreadyHasGalil)
			{
				// Update the current backpack ammo
				iBPAmmo = cs_get_user_bpammo(id, CSW_GALIL)
				
				// We can't give more ammo
				if(iBPAmmo >= g_iCvar_MaxBPAmmo)
				{
					client_printcolor(id, "/g[ZP]/y Your Antidote Gun backpack ammo it's full")
					
					#if defined OLD_VERSION_SUPPORT
					zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + antidotegun_ap_cost)
					return PLUGIN_CONTINUE
					#else
					return ZV_PLUGIN_HANDLED
					#endif
				}

				// Get the new ammo it are going to be used by the player
				static iNewAmmo
				iNewAmmo = g_iCvar_MaxBPAmmo - iBPAmmo
				
				// Give the new amount of ammo
				cs_set_user_bpammo(id, CSW_GALIL, iBPAmmo + iNewAmmo)
				
				// Flash ammo in hud
				message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoPickup, _, id)
				write_byte(AMMOID_GALIL) // ammo id
				write_byte(iNewAmmo) // ammo amount
				message_end()
				
				// Play clip purchase sound
				emit_sound(id, CHAN_ITEM, antidotegun_ammopickupsound[random_num(0, sizeof antidotegun_ammopickupsound - 1)], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
			}
			else
			{	
				// We need to get if has an ordinary galil
				if(bAlreadyHasGalil)
					ham_strip_weapon(id, "weapon_galil")
					
				// Update player bool
				g_bHasAntidoteGun[id] = true
				
				// Give and store the weapon id
				iWpnID = give_item(id, "weapon_galil")
				
				// Set the normal weapon ammo
				if(g_iCvar_MaxClip && g_iCvar_MaxClip != GALIL_DFT_MAXCLIP)
					cs_set_weapon_ammo(iWpnID, g_iCvar_MaxClip)
					
				// Set the max bpammo
				cs_set_user_bpammo(id, CSW_GALIL, g_iCvar_MaxBPAmmo)
			}
			
			// We should update this var if isn't info into.
			if(!iWpnID) iWpnID = find_ent_by_owner(ENG_NULLENT, "weapon_galil", id)
				
			// Yes or yes we need to update this vars with the current ammo amount
			iAmmo = cs_get_weapon_ammo(iWpnID)
			iBPAmmo = cs_get_user_bpammo(id, CSW_GALIL)
				
			// Force to change his gun
			engclient_cmd(id, "weapon_galil")
			
			// Update the player ammo
			update_ammo_hud(id, iAmmo, iBPAmmo)
		}
		else
		{
			// A message
			client_printcolor(id, "/g[ZP]/y Antidote Gun item has been disabled. /gContact Admin")
			
			#if defined OLD_VERSION_SUPPORT
			zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + antidotegun_ap_cost)
			return PLUGIN_CONTINUE
			#else
			return ZV_PLUGIN_HANDLED
			#endif
		}
	}
	
	return PLUGIN_CONTINUE
}

/*================================================================================
 [Main Forwards]
=================================================================================*/

public client_putinserver(id)
{
	// Updating bools
	g_bIsConnected[id] = true
	g_bHasAntidoteGun[id] = false
}

public client_disconnect(id)
{
	// Updating bools
	g_bIsAlive[id] = false
	g_bIsConnected[id] = false
	g_bHasAntidoteGun[id] = false
}

public fw_PlayerSpawn_Post(id)
{
	// Not alive...
	if(!is_user_alive(id))
		return HAM_IGNORED
		
	// Player is alive
	g_bIsAlive[id] = true
	
	// Remove Weapon
	if(get_pcvar_num(cvar_oneround) || !g_bCvar_Enabled)
	{
		if(g_bHasAntidoteGun[id])
		{
			// Reset player vars
			g_bHasAntidoteGun[id] = false
			
			// Strip his galil
			ham_strip_weapon(id, "weapon_galil")
		}
	}
	
	return HAM_IGNORED
}

public fw_PlayerKilled(victim, attacker, shouldgib)
{
	// Player victim
	if(is_user_valid_connected(victim))
	{
		// Victim is not alive
		g_bIsAlive[victim] = false
		
		// Reset player vars
		g_bHasAntidoteGun[victim] = false
		
		return HAM_HANDLED
	}
	
	return HAM_IGNORED
}

public fw_CmdStart(id, handle, seed)
{
	// Skip not alive users
	if(!is_user_valid_alive(id))
		return FMRES_IGNORED
		
	// Without an antidote gun
	if(!g_bHasAntidoteGun[id])
		return FMRES_IGNORED
		
	// Not human
	if(zp_get_user_zombie(id) || zp_get_user_survivor(id))
		return FMRES_IGNORED
	
	// Isn't holding a Galil
	if(g_iCurrentWeapon[id] != CSW_GALIL)
		return FMRES_IGNORED
		
	// Get Buttons
	static iButton
	iButton = get_uc(handle, UC_Buttons)
	
	// User pressing +attack Button
	if(iButton & IN_ATTACK)
	{
		// Buttons
		set_uc(handle, UC_Buttons, iButton & ~IN_ATTACK)
		
		// Some vars
		static Float:flCurrentTime
		flCurrentTime = halflife_time()
		
		// Fire rate not over yet
		if (flCurrentTime - g_flLastFireTime[id] < g_flCvar_FireRate)
			return FMRES_IGNORED
			
		// Another vars with info
		static iWpnID, iClip
		iWpnID = get_pdata_cbase(id, m_pActiveItem, 5)
		iClip = cs_get_weapon_ammo(iWpnID)
		
		// Skip if is in reload
		if(get_pdata_int(iWpnID, m_fInReload, 4))
			return FMRES_IGNORED
		
		// To don't reload instantly (bugfix)
		set_pdata_float(iWpnID, m_flNextPrimaryAttack, g_flCvar_FireRate, 4)
		set_pdata_float(iWpnID, m_flNextSecondaryAttack, g_flCvar_FireRate, 4)
		set_pdata_float(iWpnID, m_flTimeWeaponIdle, g_flCvar_FireRate, 4)
		
		// Update last fire time array
		g_flLastFireTime[id] = flCurrentTime
		
		// 0 bullets
		if(iClip <= 0)
		{
			// Play empty clip sound
			ExecuteHamB(Ham_Weapon_PlayEmptySound, iWpnID)

			return FMRES_IGNORED
		}
			
		// Process fire
		primary_attack(id)
		
		// Real fire push knockback
		launch_push(id, 40)
		
		// Update Ammo
		cs_set_weapon_ammo(iWpnID, --iClip)
		update_ammo_hud(id, iClip, cs_get_user_bpammo(id, CSW_GALIL))
		
		return FMRES_IGNORED
	}
	
	return FMRES_IGNORED
}

public fw_SetModel(entity, model[])
{
	// Entity is not valid
	if(!is_valid_ent(entity))
		return FMRES_IGNORED;
		
	// Entity model is not w_galil
	if(!equal(model, "models/w_galil.mdl")) 
		return FMRES_IGNORED;
		
	// Get classname
	static szClassName[33]
	entity_get_string(entity, EV_SZ_classname, szClassName, charsmax(szClassName))
		
	// Not a Weapon box
	if(!equal(szClassName, "weaponbox"))
		return FMRES_IGNORED
	
	// Some vars
	static iOwner, iStoredGalilID
	
	// Get owner
	iOwner = entity_get_edict(entity, EV_ENT_owner)
	
	// Get drop weapon index (galil) to use in fw_Galil_AddToPlayer forward
	iStoredGalilID = find_ent_by_owner(ENG_NULLENT, "weapon_galil", entity)
	
	// Entity classname is weaponbox, and galil has founded
	if(g_bHasAntidoteGun[iOwner] && is_valid_ent(iStoredGalilID))
	{
		// Setting weapon options
		entity_set_int(iStoredGalilID, EV_INT_WEAPONKEY, ANTIDOTEGUN_WPNKEY)
		
		// Reset user vars
		g_bHasAntidoteGun[iOwner] = false
		
		// Set weaponbox new model
		entity_set_model(entity, "models/w_gauss.mdl")
		
		// Glow
		if(get_pcvar_num(cvar_wboxglow))
			set_rendering(entity, kRenderFxGlowShell, antidotegun_wb_color[0], antidotegun_wb_color[1], antidotegun_wb_color[2], kRenderNormal, 25)
		
		return FMRES_SUPERCEDE
	}
	
	return FMRES_IGNORED
}

public fw_UpdateClientData_Post(id, sendweapons, handle)
{
	// Skip not alive users
	if(!is_user_valid_alive(id))
		return FMRES_IGNORED
		
	// Without an antidote gun
	if(!g_bHasAntidoteGun[id])
		return FMRES_IGNORED
		
	// Not human
	if(zp_get_user_zombie(id) || zp_get_user_survivor(id))
		return FMRES_IGNORED
	
	// Isn't holding a Galil
	if(g_iCurrentWeapon[id] != CSW_GALIL)
		return FMRES_IGNORED
		
	// Player can't attack with the AG
	set_cd(handle, CD_flNextAttack, halflife_time() + 0.001)

	return FMRES_HANDLED
}

public fw_Galil_Deploy_Post(galil)
{
	// Get galil owner
	static id
	id = get_pdata_cbase(galil, m_pPlayer, 4)
	
	// The current galil owner has an antidote gun?
	if(is_user_valid_connected(id) && g_bHasAntidoteGun[id])
	{
		// Update the current ammo
		update_ammo_hud(id, cs_get_weapon_ammo(galil), cs_get_user_bpammo(id, CSW_GALIL))
		
		// Send the draw animation
		set_user_weaponanim(id, V_GAUSS_ANIM_DRAW)
	}
	
	return HAM_IGNORED
}

public fw_Galil_AddToPlayer(galil, player)
{
	// Is an antidote gun?
	if(is_valid_ent(galil) && is_user_valid_connected(player) && entity_get_int(galil, EV_INT_WEAPONKEY) == ANTIDOTEGUN_WPNKEY)
	{
		// Set vars
		g_bHasAntidoteGun[player] = true
		
		// Reset weapon options
		entity_set_int(galil, EV_INT_WEAPONKEY, 0)
		
		return HAM_HANDLED
	}
	
	return HAM_IGNORED
}

public fw_Galil_PostFrame(galil)
{
	// Get galil owner
	static id
	id = get_pdata_cbase(galil, m_pPlayer, 4)
	
	// His owner has an antidote gun?
	if(is_user_valid_alive(id) && g_bHasAntidoteGun[id])
	{
		// Some vars
		static Float:flNextAttack, iBpAmmo, iClip, iInReload
		
		// Weapon is on middle reload
		iInReload = get_pdata_int(galil, m_fInReload, 4)
		
		// Next player attack
		flNextAttack = get_pdata_float(id, m_flNextAttack, 5)
		
		// Player back pack ammo
		iBpAmmo = cs_get_user_bpammo(id, CSW_GALIL)
		
		// Current weapon clip
		iClip = cs_get_weapon_ammo(galil)
		
		// End of reload
		if(iInReload && flNextAttack <= 0.0)
		{
			// Get the minimun amount between maxclip sub. current clip 
			// and the player backpack ammo
			new j = min(g_iCvar_MaxClip - iClip, iBpAmmo)
			
			// Set the new weapon clip
			cs_set_weapon_ammo(galil, iClip + j)
	
			// Set the new player backpack ammo
			cs_set_user_bpammo(id, CSW_GALIL, iBpAmmo-j)
			
			// Update the weapon offset "inreload" to 0 ("false")
			iInReload = 0
			set_pdata_int(galil, m_fInReload, 0, 4)
		}
	
		// Get the current player buttons
		static iButton
		iButton = get_user_button(id)
		
		// The player stills pressing the fire button
		if((iButton & IN_ATTACK2 && get_pdata_float(galil, m_flNextSecondaryAttack, 4) <= 0.0) || (iButton & IN_ATTACK && get_pdata_float(galil, m_flNextPrimaryAttack, 4) <= 0.0))
			return
	
		// Trying to reload pressing the reload button when isn't it
		if(iButton & IN_RELOAD && !iInReload)
		{
			// The current weapon clip exceed the new max clip
			if(iClip >= g_iCvar_MaxClip)
			{
				// Retrieve player reload button
				entity_set_int(id, EV_INT_button, iButton & ~IN_RELOAD)
				
				// Send idle animation
				set_user_weaponanim(id, 0)
			}
			// The current weapon clip it's the same like the old max weapon clip
			else if(iClip == GALIL_DFT_MAXCLIP)
			{
				// Has an amount of bpammo?
				if(iBpAmmo)
				{
					// Should make a reload
					antidotegun_reload(id, galil, 1)
				}
			}
		}
	}
	
	// Credits and thanks to ConnorMcLeod for his Weapon MaxClip plugin!
}

public fw_Galil_Reload_Post(galil)
{
	// Get galil owner
	static id
	id = get_pdata_cbase(galil, m_pPlayer, 4)
	
	// It's in reload and his owner has an antidote gun?
	if(is_user_valid_alive(id) && g_bHasAntidoteGun[id] && get_pdata_int(galil, m_fInReload, 4))
	{	
		// Change normal reload options
		antidotegun_reload(id, galil)
	}
}

/*================================================================================
 [Internal Functions]
=================================================================================*/

cache_cvars()
{
	// Some cvars
	g_bCvar_Enabled = bool:get_pcvar_num(cvar_enable)
	g_flCvar_FireRate = get_pcvar_float(cvar_firerate)
	g_flCvar_ReloadSpeed = get_pcvar_float(cvar_reloadspeed)
	g_flCvar_HitSlowdown = get_pcvar_float(cvar_hitslowdown)
	g_iCvar_MaxClip = clamp(get_pcvar_num(cvar_maxclip), 0, 120)
	g_iCvar_MaxBPAmmo = clamp(get_pcvar_num(cvar_maxbpammo), 1, 90)
	
	#if defined OLD_VERSION_SUPPORT
	g_bCvar_BuyUntilMode = false
	#else
	g_bCvar_BuyUntilMode = bool:get_pcvar_num(cvar_buyindelay)
	#endif
}

primary_attack(id)
{
	// Fire Effect
	set_user_weaponanim(id, V_GAUSS_ANIM_FIRE)
	entity_set_vector(id, EV_VEC_punchangle, Float:{ -1.5, 0.0, 0.0 })
	emit_sound(id, CHAN_WEAPON, antidotegun_firesound[random_num(0, sizeof antidotegun_firesound - 1)], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
	
	// Some vars
	static iTarget, iBody, iEndOrigin[3]
	
	// Get end origin from eyes
	get_user_origin(id, iEndOrigin, 3)
	
	// Make gun beam
	beam_from_gun(id, iEndOrigin)
	
	// Get user aiming
	get_user_aiming(id, iTarget, iBody)
	
	// Do sound by a new entity
	new iEnt = create_entity("info_target")
	
	// Integer vector into a Float vector
	static Float:flOrigin[3]
	IVecFVec(iEndOrigin, flOrigin)
	
	// Set entity origin
	entity_set_origin(iEnt, flOrigin)
	
	// Sound
	emit_sound(iEnt, CHAN_WEAPON, antidotegun_hitsound[random_num(0, sizeof antidotegun_firesound - 1)], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
	
	// Remove entity
	remove_entity(iEnt)
	
	// Aim target it's a player
	if(is_user_valid_alive(iTarget))
	{	
		// Hit slowdown, first should be enabled
		if(g_flCvar_HitSlowdown > 0.0)
		{
			// Get his current velocity vector
			static Float:flVelocity[3]
			get_user_velocity(iTarget, flVelocity)
			
			// Multiply his velocity by a number
			xs_vec_mul_scalar(flVelocity, g_flCvar_HitSlowdown, flVelocity)
			
			// Set his new velocity vector
			set_user_velocity(iTarget, flVelocity)	
		}
		
		// It's allowed to be disinfected
		if(zp_get_user_zombie(iTarget) && !zp_get_user_nemesis(iTarget) && !zp_get_user_last_zombie(iTarget))
		{
			// Disinfect user
			#if defined OLD_VERSION_SUPPORT
			zp_disinfect_user(iTarget)
			#else
			zp_disinfect_user(iTarget, 1)
			#endif
			
			// Death message
			message_begin(MSG_BROADCAST, g_msgDeathMsg)
			write_byte(id) // killer
			write_byte(iTarget) // victim
			write_byte(iBody == HIT_HEAD ? 1 : 0) // headshot flag
			write_string("antidote gun") // killer's weapon
			message_end()
			
			// Screen fade fx
			message_begin(MSG_ONE_UNRELIABLE, g_msgScreenFade, _, iTarget)
			write_short(UNIT_SECOND*1) // duration
			write_short(UNIT_SECOND/2) // hold time
			write_short(FFADE_IN) // fade type
			write_byte(0) // r
			write_byte(255) // g
			write_byte(255) // b
			write_byte(227) // alpha
			message_end()
			
			// Beam Cylinder fx
			message_begin(MSG_PVS, SVC_TEMPENTITY, iEndOrigin)
			write_byte(TE_BEAMCYLINDER) // TE id
			write_coord(iEndOrigin[0]) // position.x
			write_coord(iEndOrigin[1]) // position.y
			write_coord(iEndOrigin[2]) // position.z
			write_coord(iEndOrigin[0]) // x axis
			write_coord(iEndOrigin[1]) // y axis
			write_coord(iEndOrigin[2] + 385) // z axis
			write_short(g_sprRing) // sprite
			write_byte(0) // startframe
			write_byte(0) // framerate
			write_byte(4) // life
			write_byte(30) // width
			write_byte(0) // noise
			write_byte(0) // red
			write_byte(255) // green
			write_byte(255) // blue
			write_byte(200) // brightness
			write_byte(0) // speed
			message_end()
		}
		// Can't be disinfected
		else
		{
			// Faster particles
			message_begin(MSG_PVS, SVC_TEMPENTITY, iEndOrigin)
			write_byte(TE_PARTICLEBURST) // TE id
			write_coord(iEndOrigin[0]) // position.x
			write_coord(iEndOrigin[1]) // position.y
			write_coord(iEndOrigin[2]) // position.z
			write_short(45) // radius
			write_byte(208) // particle color
			write_byte(10) // duration * 10 will be randomized a bit
			message_end()
		}
	}
	else
	{
		// Aim target entity it's valid and isn't worldspawn?
		if((iTarget > 0) && is_valid_ent(iTarget))
		{
			// Get aim target classname
			static szClassname[32]
			entity_get_string(iTarget, EV_SZ_classname, szClassname, charsmax(szClassname))
			
			// It's a breakable entity
			if(equal(szClassname, "func_breakable"))
			{
				// Get destroy this ent
				force_use(id, iTarget)
			}
		}
	}
}

antidotegun_reload(id, galil, force_reload = 0)
{
	// Next player attack time
	set_pdata_float(id, m_flNextAttack, g_flCvar_ReloadSpeed, 5)

	// Send to the player the reload animation
	set_user_weaponanim(id, V_GAUSS_ANIM_RELOAD)
	
	// Update the weapon offset "inreload" to 1 ("true")
	if(force_reload)
		set_pdata_int(galil, m_fInReload, 1, 4)

	// Next idle weapon time, soonest time ItemPostFrame will call WeaponIdle.
	set_pdata_float(galil, m_flTimeWeaponIdle, g_flCvar_ReloadSpeed + 0.5, 4)
	
	// I'll be honest, i don't know what do this.
	entity_set_float(id, EV_FL_frame, 200.0)
}

update_ammo_hud(id, iAmmoAmount, iBPAmmoAmount)
{
	// Display the new antidotegun bullets
	if(iAmmoAmount != -1)
	{
		message_begin(MSG_ONE_UNRELIABLE, g_msgCurWeapon, _, id)
		write_byte(1) // active
		write_byte(CSW_GALIL) // weapon
		write_byte(iAmmoAmount) // clip
		message_end()
	}
	
	// Display the new amount of BPAmmo
	if(iBPAmmoAmount != -1)
	{
		message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoX, _, id)
		write_byte(AMMOID_GALIL) // ammoid
		write_byte(iBPAmmoAmount) // ammo amount
		message_end()
	}
}

beam_from_gun(id, iEndOrigin[3])
{
	// Make a cool beam
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(TE_BEAMENTPOINT) // TE id
	write_short(id | 0x1000) // start entity
	write_coord(iEndOrigin[0]) // endposition.x
	write_coord(iEndOrigin[1]) // endposition.y
	write_coord(iEndOrigin[2]) // endposition.z
	write_short(g_sprBeam)    // sprite index
	write_byte(1)	// framestart
	write_byte(1)	// framerate
	write_byte(1)	// life in 0.1's
	write_byte(10)	// width
	write_byte(0)	// noise
	write_byte(0)	// r
	write_byte(255)	// g
	write_byte(255)	// b
	write_byte(200)	// brightness
	write_byte(0)	// speed
	message_end()
	
	// Dynamic Light
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY, iEndOrigin)
	write_byte(TE_DLIGHT) // TE id
	write_coord(iEndOrigin[0]) // position.x
	write_coord(iEndOrigin[1]) // position.y
	write_coord(iEndOrigin[2]) // position.z
	write_byte(30) // radius
	write_byte(0) // red
	write_byte(255) // green
	write_byte(255) // blue
	write_byte(10) // life
	write_byte(45) // decay rate
	message_end()
	
	// Sparks
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY, iEndOrigin)
	write_byte(TE_SPARKS) // TE id
	write_coord(iEndOrigin[0]) // position.x
	write_coord(iEndOrigin[1]) // position.y
	write_coord(iEndOrigin[2]) // position.z
	message_end()
}

/*================================================================================
 [Stocks]
=================================================================================*/

stock set_user_weaponanim(id, anim)
{
	entity_set_int(id, EV_INT_weaponanim, anim)
	message_begin(MSG_ONE, SVC_WEAPONANIM, {0, 0, 0}, id)
	write_byte(anim)
	write_byte(entity_get_int(id, EV_INT_body))
	message_end()
}

stock launch_push(id, velamount) // from my Nemesis Rocket Launcher plugin.
{
	static Float:flNewVelocity[3], Float:flCurrentVelocity[3]
	
	velocity_by_aim(id, -velamount, flNewVelocity)
	
	get_user_velocity(id, flCurrentVelocity)
	xs_vec_add(flNewVelocity, flCurrentVelocity, flNewVelocity)
	
	set_user_velocity(id, flNewVelocity)	
}

stock ham_strip_weapon(id, weapon[])
{
	if(!equal(weapon,"weapon_",7)) 
		return 0
	
	new wId = get_weaponid(weapon)
	
	if(!wId) return 0
	
	new wEnt
	
	while((wEnt = find_ent_by_class(wEnt, weapon)) && entity_get_edict(wEnt, EV_ENT_owner) != id) {}
	
	if(!wEnt) return 0
	
	if(get_user_weapon(id) == wId) 
		ExecuteHamB(Ham_Weapon_RetireWeapon,wEnt);
	
	if(!ExecuteHamB(Ham_RemovePlayerItem,id,wEnt)) 
		return 0
		
	ExecuteHamB(Ham_Item_Kill, wEnt)
	
	entity_set_int(id, EV_INT_weapons, entity_get_int(id, EV_INT_weapons) & ~(1<<wId))

	return 1
}

stock client_printcolor(id, const input[], any:...)
{
	static iPlayersNum[32], iCount; iCount = 1
	static szMsg[191]
	
	vformat(szMsg, charsmax(szMsg), input, 3)
	
	replace_all(szMsg, 190, "/g", "^4") // green txt
	replace_all(szMsg, 190, "/y", "^1") // orange txt
	replace_all(szMsg, 190, "/ctr", "^3") // team txt
	replace_all(szMsg, 190, "/w", "^0") // team txt
	
	if(id) iPlayersNum[0] = id
	else get_players(iPlayersNum, iCount, "ch")
		
	for (new i = 0; i < iCount; i++)
	{
		if (g_bIsConnected[iPlayersNum[i]])
		{
			message_begin(MSG_ONE_UNRELIABLE, g_msgSayText, _, iPlayersNum[i])
			write_byte(iPlayersNum[i])
			write_string(szMsg)
			message_end()
		}
	}
}
zm_vip_extra_bazooka.sma

Code: Select all

#include <amxmodx>
#include <fun>
#include <engine>
#include <fakemeta>
#include <hamsandwich>
#include <zombieplague>
#include <zmvip>

#define PLUGINNAME		"Extra Item Bazooka"
#define VERSION			"1.0"
#define AUTHOR			"B!gBud"

#define ACCESS_LEVEL	ADMIN_LEVEL_A
#define VOTE_ACCESS	ADMIN_CFG

#define TE_EXPLOSION	3
#define TE_BEAMFOLLOW	22
#define TE_BEAMCYLINDER	21

#define JETPACK_COST 20 // set how may ammopacks the Jatpack+Rocket cost

new ROCKET_MDL[64] = "models/rpgrocket.mdl"
new ROCKET_SOUND[64] = "weapons/rocketfire1.wav"
new getrocket[64] = "items/9mmclip2.wav"

new bool:fly[33] = false
new bool:rocket[33] = false
new bool:rksound[33] = false
new bool:shot[33] = false

new Float:gltime = 0.0
new Float:last_Rocket[33] = 0.0
new Float:jp_cal[33] = 0.0
new Float:jp_soun[33] = 0.0
new flame, explosion, trail, white
new g_flyEnergy[33], hasjet[33]
new cvar_jetpack, cvar_jetpackSpeed, cvar_jetpackUpSpeed, cvar_jetpackAcrate ,cvar_RocketDelay, cvar_RocketSpeed, cvar_RocketDmg, cvar_Dmg_range, cvar_fly_max_engery, cvar_fly_engery, cvar_regain_energy, g_item_jetpack, cvar_cal_time, cvar_oneround


public plugin_init() {
	register_plugin(PLUGINNAME, VERSION, AUTHOR)
	
	g_item_jetpack = zv_register_extra_item("Bazooka", "High damage weapon", JETPACK_COST, ZV_TEAM_HUMAN)
	register_clcmd("drop","cmdDrop")
	register_clcmd("say /jphelp","cmdHelp",0,": Displays Jetpack help")
	
	new ver[64]
	format(ver,63,"%s v%s",PLUGINNAME,VERSION)
	register_cvar("zp_jp_version",ver,FCVAR_SERVER)	
	
	cvar_jetpack = register_cvar("zp_jetpack", "0")
	
	cvar_jetpackSpeed=register_cvar("zp_jp_forward_speed","300.0")
	cvar_jetpackUpSpeed=register_cvar("zp_jp_up_speed","35.0")
	cvar_jetpackAcrate=register_cvar("zp_jp_accelerate","100.0")
	
	cvar_RocketDelay=register_cvar("zp_bz_rocket_delay","12.0")
	cvar_RocketSpeed=register_cvar("zp_bz_rocket_speed","1500")
	cvar_RocketDmg=register_cvar("zp_bz_rocket_damage","1500")
	cvar_Dmg_range=register_cvar("zp_bz_damage_radius","350")
	
	cvar_fly_max_engery = register_cvar("zp_jp_max_engery", "100")
	cvar_fly_engery = register_cvar("zp_jp_engery", "10")
	cvar_regain_energy = register_cvar("zp_jp_regain_energy", "3")
	cvar_cal_time = register_cvar("zp_jp_energy_cal", "1.0")
	cvar_oneround = register_cvar("zp_jp_oneround", "0")

	
	register_event("CurWeapon", "check_models", "be")
	register_event("DeathMsg", "player_die", "a")
	register_event("HLTV", "event_round_start", "a", "1=0", "2=0")
	
	register_forward(FM_StartFrame, "fm_startFrame")
	register_forward(FM_EmitSound, "emitsound")
}

public plugin_precache() {
	precache_model("models/p_rpg.mdl")
	precache_model("models/v_rpg.mdl")
	precache_model("models/w_rpg.mdl")
	precache_sound("jetpack.wav")
	precache_sound("jp_blow.wav")
	
	precache_model(ROCKET_MDL)
	precache_sound(ROCKET_SOUND)
	precache_sound(getrocket)
	
	explosion = precache_model("sprites/zerogxplode.spr")
	trail = precache_model("sprites/smoke.spr")
	flame = precache_model("sprites/xfireball3.spr")
	white = precache_model("sprites/white.spr")
}

public client_putinserver(id) {
	fly[id] = false
	rocket[id] = false
	hasjet[id] = 0
	g_flyEnergy[id] = 0
}

public client_disconnect(id) {
	fly[id] = false
	rocket[id] = false
	hasjet[id] = 0
	g_flyEnergy[id] = 0
}

public event_round_start()
{
	remove_jetpacks();
	if (get_pcvar_num(cvar_oneround) == 1) {
		for (new id; id <= 32; id++) hasjet[id] = 0, g_flyEnergy[id] = 0,	fly[id] = false;
	}
}

public fm_startFrame(){
		
	gltime = get_gametime()
	static id
	for (id = 1; id <= 32; id++)
	{
		jp_forward(id)
	}
}

public jp_forward(player) {
	
	if (!hasjet[player])
		return FMRES_IGNORED
	
	if(jp_cal[player] < gltime){
		jp_energy(player); jp_cal[player] = gltime + get_pcvar_float(cvar_cal_time)
	}
	
	check_rocket(player)
	
	new clip,ammo
	new wpnid = get_user_weapon(player,clip,ammo)
	if (wpnid == CSW_KNIFE){
		if(get_pcvar_num(cvar_jetpack) == 1){
			if(!(pev(player, pev_flags)&FL_ONGROUND) && pev(player,pev_button)&IN_ATTACK){
				if((g_flyEnergy[player] > get_pcvar_num(cvar_fly_max_engery)*0.3) && (g_flyEnergy[player] <= get_pcvar_num(cvar_fly_max_engery))){
					if(jp_soun[player] < gltime){
						emit_sound(player,CHAN_ITEM,"jetpack.wav",1.0,ATTN_NORM,1,PITCH_HIGH)
						jp_soun[player] = gltime + 1.0
					}
				}			
				else if((g_flyEnergy[player] > 0) && (g_flyEnergy[player] < get_pcvar_num(cvar_fly_max_engery)*0.3)){
					if(jp_soun[player] < gltime){
							emit_sound(player,CHAN_ITEM,"jp_blow.wav",1.0,ATTN_NORM,1,PITCH_HIGH)
							jp_soun[player] = gltime + 1.0
					}
				}
			}
			human_fly(player)
			attack(player)	
		}
		if((pev(player,pev_button)&IN_ATTACK2)){
				attack2(player)	
			}	
	}
	if((get_pcvar_num(cvar_jetpack) == 2 && !(pev(player, pev_flags)&FL_ONGROUND)) && (pev(player,pev_button)&IN_JUMP && pev(player,pev_button)&IN_DUCK)){			
		if((g_flyEnergy[player] > get_pcvar_num(cvar_fly_max_engery)*0.3) && (g_flyEnergy[player] <= get_pcvar_num(cvar_fly_max_engery))){
			if(jp_soun[player] < gltime){
				emit_sound(player,CHAN_ITEM,"jetpack.wav",1.0,ATTN_NORM,1,PITCH_HIGH)
				jp_soun[player] = gltime + 1.0
			}
		}					
		else if((g_flyEnergy[player] > 0) && (g_flyEnergy[player] < get_pcvar_num(cvar_fly_max_engery)*0.3)){
			if(jp_soun[player] < gltime){
				emit_sound(player,CHAN_ITEM,"jp_blow.wav",1.0,ATTN_NORM,1,PITCH_HIGH)
				jp_soun[player] = gltime + 1.0
			}
		}
		human_fly(player)
		attack(player)
	}
	// Icon Show system
	/*if (!is_user_alive(player) && zp_get_user_zombie(player) && zp_get_user_nemesis(player) && zp_get_user_survivor(player))	
		Icon_Energy({0, 255, 0}, 0, player);
				//Icon_Energy({128, 128, 0}, 0, player);
				//Icon_Energy({255, 255, 0}, 0, player);
						
	}*/
	if((g_flyEnergy[player] >= get_pcvar_num(cvar_fly_max_engery)*0.8) && (g_flyEnergy[player] <= get_pcvar_num(cvar_fly_max_engery))){
		Icon_Energy({0, 255, 0}, 1, player); // Green
	}
	else if((g_flyEnergy[player] >= get_pcvar_num(cvar_fly_max_engery)*0.5) && (g_flyEnergy[player] < get_pcvar_num(cvar_fly_max_engery)*0.8)){
		Icon_Energy({255, 255, 0}, 1, player); // yellow
	}
	else if((g_flyEnergy[player] >= get_pcvar_num(cvar_fly_max_engery)*0.3) && (g_flyEnergy[player] < get_pcvar_num(cvar_fly_max_engery)*0.5)){
		Icon_Energy({255, 215, 0}, 2, player);
	}
	else if((g_flyEnergy[player] > 0) && (g_flyEnergy[player] < get_pcvar_num(cvar_fly_max_engery)*0.3)){
		Icon_Energy({255, 0, 0}, 1, player);
	}
	
	return FMRES_IGNORED
}

public jp_energy(player) {
			
		if (!(pev(player, pev_flags)&FL_ONGROUND) && pev(player,pev_button)&IN_ATTACK)	
		{
			// Get our current velocity		
			new clip,ammo
			new wpnid = get_user_weapon(player,clip,ammo)
			if (wpnid == CSW_KNIFE) 
			{
			// flying
			if(g_flyEnergy[player] > get_pcvar_num(cvar_fly_max_engery)*0.09)
				g_flyEnergy[player] = g_flyEnergy[player] - get_pcvar_num(cvar_fly_engery);	 // Increase distance counter		
			}
		}
		else if ((get_pcvar_num(cvar_jetpack) == 2 && !(pev(player, pev_flags)&FL_ONGROUND)) && (pev(player,pev_button)&IN_JUMP && pev(player,pev_button)&IN_DUCK))
		{
			if(g_flyEnergy[player] > get_pcvar_num(cvar_fly_max_engery)*0.09)
				g_flyEnergy[player] = g_flyEnergy[player] - get_pcvar_num(cvar_fly_engery);	 // Increase distance counter	
		}
		// Walking/Runnig
		if (pev(player, pev_flags) & FL_ONGROUND)	
			g_flyEnergy[player] = g_flyEnergy[player] + get_pcvar_num(cvar_regain_energy);// Decrease distance counter
}

public attack(player) {
//code snippa from TS_Jetpack 1.0 - Jetpack plugin for The Specialists.
//http://forums.alliedmods.net/showthread.php?s=3ea22295e3e5a292fa82899676583326&t=55709&highlight=jetpack
//By: Bad_Bud
	if(fly[player])
	{	
		static Float:JetpackData[3]
		pev(player,pev_velocity,JetpackData)
					
		new fOrigin[3],Float:Aim[3]
		VelocityByAim(player, 10, Aim)
		get_user_origin(player,fOrigin)
		fOrigin[0] -= floatround(Aim[0])
		fOrigin[1] -= floatround(Aim[1])
		fOrigin[2] -= floatround(Aim[2])
		
		
		if((pev(player,pev_button)&IN_FORWARD) && !(pev(player, pev_flags) & FL_ONGROUND))
			{
				
				message_begin(MSG_ALL,SVC_TEMPENTITY)
				write_byte(17) 
				write_coord(fOrigin[0])
				write_coord(fOrigin[1])
				write_coord(fOrigin[2])
				write_short(flame)
				write_byte(10)
				write_byte(255)
				message_end()	
				
				static Float:Speed
				Speed=floatsqroot(JetpackData[0]*JetpackData[0]+JetpackData[1]*JetpackData[1])
					
				if(Speed!=0.0)//Makes players only lay down if their speed isn't 0; if they are thrusting forward.
				{
					set_pev(player,pev_gaitsequence,0)
					set_pev(player,pev_sequence,111)
				}
					
				if(Speed<get_pcvar_float(cvar_jetpackSpeed))
					Speed+=get_pcvar_float(cvar_jetpackAcrate)
						
				static Float:JetpackData2[3]
				pev(player,pev_angles,JetpackData2)
				JetpackData2[2]=0.0//Remove the Z value/
					
				angle_vector(JetpackData2,ANGLEVECTOR_FORWARD,JetpackData2)
				JetpackData2[0]*=Speed
				JetpackData2[1]*=Speed
					
				JetpackData[0]=JetpackData2[0]
				JetpackData[1]=JetpackData2[1]
			}
			
		if(JetpackData[2]<get_pcvar_float(cvar_jetpackSpeed)&&JetpackData[2]>0.0)//Jetpacks get more power on the way down -- it helps landing.
				JetpackData[2]+=get_pcvar_float(cvar_jetpackUpSpeed)
			else if(JetpackData[2]<0.0)
				JetpackData[2]+=(get_pcvar_float(cvar_jetpackUpSpeed)*1.15)
					
		set_pev(player,pev_velocity,JetpackData)
	}
}

public attack2(player) {
		
	if (rocket[player])
	{
		
		new rocket = create_entity("info_target")
		if(rocket == 0) return PLUGIN_CONTINUE
		
		entity_set_string(rocket, EV_SZ_classname, "zp_jp_rocket")
		entity_set_model(rocket, ROCKET_MDL)
		
		entity_set_size(rocket, Float:{0.0, 0.0, 0.0}, Float:{0.0, 0.0, 0.0})
		entity_set_int(rocket, EV_INT_movetype, MOVETYPE_FLY)
		entity_set_int(rocket, EV_INT_solid, SOLID_BBOX)
		
		new Float:vSrc[3]
		entity_get_vector(player, EV_VEC_origin, vSrc)
		
		new Float:Aim[3],Float:origin[3]
		VelocityByAim(player, 64, Aim)
		entity_get_vector(player,EV_VEC_origin,origin)
		
		vSrc[0] += Aim[0]
		vSrc[1] += Aim[1]
		entity_set_origin(rocket, vSrc)
		
		new Float:velocity[3], Float:angles[3]
		VelocityByAim(player, get_pcvar_num(cvar_RocketSpeed), velocity)
		
		entity_set_vector(rocket, EV_VEC_velocity, velocity)
		vector_to_angle(velocity, angles)
		entity_set_vector(rocket, EV_VEC_angles, angles)
		entity_set_edict(rocket,EV_ENT_owner,player)
		entity_set_float(rocket, EV_FL_takedamage, 1.0)
		
		message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
		write_byte(TE_BEAMFOLLOW)
		write_short(rocket)
		write_short(trail)
		write_byte(25)
		write_byte(5)
		write_byte(224)
		write_byte(224)
		write_byte(255)
		write_byte(255)
		message_end()

		emit_sound(rocket, CHAN_WEAPON, ROCKET_SOUND, 1.0, ATTN_NORM, 0, PITCH_NORM)
		
		shot[player] = true
		last_Rocket[player] = gltime + get_pcvar_num(cvar_RocketDelay)
	}
	return PLUGIN_CONTINUE
}

public check_models(id) {

	if (zp_get_user_zombie(id) || zp_get_user_nemesis(id) || zp_get_user_survivor(id))
		return FMRES_IGNORED
	
	if(hasjet[id]) {
		new clip,ammo
		new wpnid = get_user_weapon(id,clip,ammo)
		
		if ( wpnid == CSW_KNIFE ) {
			switchmodel(id)
		}
		return PLUGIN_CONTINUE
	}
	return PLUGIN_CONTINUE
}

public switchmodel(id) {
	entity_set_string(id,EV_SZ_viewmodel,"models/v_rpg.mdl")
	entity_set_string(id,EV_SZ_weaponmodel,"models/p_rpg.mdl")
}

public remove_jetpacks() {
	new nextitem  = find_ent_by_class(-1,"zp_jp_jetpack")
	while(nextitem) {
		remove_entity(nextitem)
		nextitem = find_ent_by_class(-1,"zp_jp_jetpack")
	}
	return PLUGIN_CONTINUE
}

public emitsound(entity, channel, const sample[]) {
	if(is_user_alive(entity)) {
		new clip,ammo
		new weapon = get_user_weapon(entity,clip,ammo)
		
		if(hasjet[entity] && weapon == CSW_KNIFE) {
			if(equal(sample,"weapons/knife_slash1.wav")) return FMRES_SUPERCEDE
			if(equal(sample,"weapons/knife_slash2.wav")) return FMRES_SUPERCEDE
			
			if(equal(sample,"weapons/knife_deploy1.wav")) return FMRES_SUPERCEDE
			if(equal(sample,"weapons/knife_hitwall1.wav")) return FMRES_SUPERCEDE
			
			if(equal(sample,"weapons/knife_hit1.wav")) return FMRES_SUPERCEDE
			if(equal(sample,"weapons/knife_hit2.wav")) return FMRES_SUPERCEDE
			if(equal(sample,"weapons/knife_hit3.wav")) return FMRES_SUPERCEDE
			if(equal(sample,"weapons/knife_hit4.wav")) return FMRES_SUPERCEDE
			
			if(equal(sample,"weapons/knife_stab.wav")) return FMRES_SUPERCEDE
		}
	}
	return FMRES_IGNORED
}

public Icon_Show(icon[], color[3], mode, player) {
			
	message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("StatusIcon"), {0,0,0}, player);
	write_byte(mode); 	// status (0=hide, 1=show, 2=flash)
	write_string(icon); 	// sprite name
	write_byte(color[0]); 	// red
	write_byte(color[1]); 	// green
	write_byte(color[2]); 	// blue
	message_end();

}

public Icon_Energy(color[3], mode, player) {
	
	Icon_Show("item_longjump", color, mode, player)
}

public human_fly(player) {
	
	if (g_flyEnergy[player] <= get_pcvar_num(cvar_fly_max_engery)*0.1)
	{
		jp_off(player);	
	}
	if (g_flyEnergy[player] > get_pcvar_num(cvar_fly_max_engery)*0.1)
	{
		jp_on(player);
	}
}

public jp_on(player) {

	fly[player] = true
	
}

public jp_off(player) {

	fly[player] = false
	
}

public check_rocket(player) {
		
	if (last_Rocket[player] > gltime)
	{	
		rk_forbidden(player)
		rksound[player] = true
	}
	else
	{	

		if (shot[player])
		{
			rksound[player] = false
			shot[player] = false
		}
		rk_sound(player)
		rk_allow(player)
	}
	
}

public rk_allow(player) {
		
	rocket[player] = true
}

public rk_forbidden(player) {

	rocket[player] = false
	
}

public rk_sound(player) {

	if (!rksound[player])
	{
		engfunc(EngFunc_EmitSound, player, CHAN_WEAPON, getrocket, 1.0, ATTN_NORM, 0, PITCH_NORM)
		client_print(player, print_center, "[Bazooka] Recargada y Lista !!!")
		rksound[player] = true
	}
	else if (rksound[player])
	{
		
	}
	
}
		
public cmdHelp(id) {
	
	new g_max = get_pcvar_num(cvar_fly_max_engery)
	new g_lost = get_pcvar_num(cvar_fly_engery)
	new g_back = get_pcvar_num(cvar_regain_energy)
	new g_dmg = get_pcvar_num(cvar_RocketDmg)
	new g_delay = get_pcvar_num(cvar_RocketDelay) 
	
	new jpmotd[2048], title[64], dpos = 0
	format(title,63,"[ZP] %s ver.%s",PLUGINNAME,VERSION)
	
	
	dpos += format(jpmotd[dpos],2047-dpos,"<html><head><style type=^"text/css^">pre{color:#FF0505;}body{background:#000000;margin-left:16px;margin-top:1px;}</style></head><pre><body>")
	dpos += format(jpmotd[dpos],2047-dpos,"<b>%s</b>^n^n",title)
	
	dpos += format(jpmotd[dpos],2047-dpos,"How to use:^n")
	dpos += format(jpmotd[dpos],2047-dpos,"=============^n^n")
	if(get_pcvar_num(cvar_jetpack) == 1) {
		dpos += format(jpmotd[dpos],2047-dpos,"- choose/have Knive & use/hold ATTACK to fly^n")
		dpos += format(jpmotd[dpos],2047-dpos,"^n")
		dpos += format(jpmotd[dpos],2047-dpos,"- choose/have Knive(Bazooka) & use ATTACK2 to shoot a Rocket^n^n")
	}
	else if(get_pcvar_num(cvar_jetpack) == 2){
		dpos += format(jpmotd[dpos],2047-dpos,"- use/hold JUMP & DUCK to flyn")
		dpos += format(jpmotd[dpos],2047-dpos,"^n")
		dpos += format(jpmotd[dpos],2047-dpos,"choose/have Knive(Bazooka) & use ATTACK2 to shoot a Rocket^n^n")
	}
	dpos += format(jpmotd[dpos],2047-dpos,"INFO's^n")
	dpos += format(jpmotd[dpos],2047-dpos,"MAX Energy set to : <b>%i Units</b>^n^n", g_max)
	dpos += format(jpmotd[dpos],2047-dpos,"Jetpack need %i Units per 1 Sec. to work^n", g_lost)
	dpos += format(jpmotd[dpos],2047-dpos,"Energy regain %i Units per 1 Sec. (when you are on the ground)^n^n", g_back)
	dpos += format(jpmotd[dpos],2047-dpos,"MAX Rocket Dmg set to: <b>%i dmg</b>^n",g_dmg)
	dpos += format(jpmotd[dpos],2047-dpos,"New Rocket comes ervry <b>%i Sec.</b>^n^n", g_delay )
	dpos += format(jpmotd[dpos],2047-dpos,"-Have Fun!^n")
	

	show_motd(id,jpmotd,title)
}

public player_die() {
	
	new id = read_data(2)
	if(hasjet[id]) {
		drop_jetpack(id)
		hasjet[id] = 0
		rocket[id] = false
		g_flyEnergy[id] = 0
	}
	
	return PLUGIN_CONTINUE
}

public cmdDrop(id) {

	if(hasjet[id]) {
		new clip,ammo
		new weapon = get_user_weapon(id,clip,ammo)
		if(weapon == CSW_KNIFE) {
			drop_jetpack(id)
			if(!zp_get_user_zombie(id)){
				entity_set_string(id,EV_SZ_viewmodel,"models/v_knife.mdl")
				entity_set_string(id,EV_SZ_weaponmodel,"models/p_knife.mdl")
				}
			return PLUGIN_HANDLED
		}
	}
	return PLUGIN_CONTINUE
}

public drop_jetpack(player) {
	if(hasjet[player]) {
		new Float:Aim[3],Float:origin[3]
		VelocityByAim(player, 64, Aim)
		entity_get_vector(player,EV_VEC_origin,origin)
		
		origin[0] += Aim[0]
		origin[1] += Aim[1]
		
		new jetpack = create_entity("info_target")
		entity_set_string(jetpack,EV_SZ_classname,"zp_jp_jetpack")
		entity_set_model(jetpack,"models/w_rpg.mdl")	
		
		entity_set_size(jetpack,Float:{-16.0,-16.0,-16.0},Float:{16.0,16.0,16.0})
		entity_set_int(jetpack,EV_INT_solid,1)
		
		entity_set_int(jetpack,EV_INT_movetype,6)
		
		entity_set_vector(jetpack,EV_VEC_origin,origin)
		
		Icon_Energy({255, 255, 0}, 0, player)
		Icon_Energy({128, 128, 0}, 0, player )
		Icon_Energy({0, 255, 0}, 0, player)
		
		hasjet[player] = 0
		rocket[player] = false
	}	
}

public pfn_touch(ptr, ptd) {
	if(is_valid_ent(ptr)) {
		new classname[32]
		entity_get_string(ptr,EV_SZ_classname,classname,31)
		
		if(equal(classname, "zp_jp_jetpack")) {
			if(is_valid_ent(ptd)) {
				new id = ptd
				if(id > 0 && id < 34) {
					if(!hasjet[id] && !zp_get_user_zombie(id) && is_user_alive(id)) {
						
						hasjet[id] = 1
						g_flyEnergy[id] = get_pcvar_num(cvar_fly_max_engery)
						rocket[id] = true
						client_cmd(id,"spk items/gunpickup2.wav")
						engclient_cmd(id,"weapon_knife")
						switchmodel(id)
						remove_entity(ptr)
					}
				}
			}
		}else if(equal(classname, "zp_jp_rocket")) {
			new Float:fOrigin[3]
			new iOrigin[3]
			entity_get_vector(ptr, EV_VEC_origin, fOrigin)
			FVecIVec(fOrigin,iOrigin)
			jp_radius_damage(ptr)
				
			message_begin(MSG_BROADCAST,SVC_TEMPENTITY,iOrigin)
			write_byte(TE_EXPLOSION)
			write_coord(iOrigin[0])
			write_coord(iOrigin[1])
			write_coord(iOrigin[2])
			write_short(explosion)
			write_byte(30)
			write_byte(15)
			write_byte(0)
			message_end()
				
			message_begin(MSG_ALL,SVC_TEMPENTITY,iOrigin)
			write_byte(TE_BEAMCYLINDER)
			write_coord(iOrigin[0])
			write_coord(iOrigin[1])
			write_coord(iOrigin[2])
			write_coord(iOrigin[0])
			write_coord(iOrigin[1])
			write_coord(iOrigin[2]+200)
			write_short(white)
			write_byte(0)
			write_byte(1)
			write_byte(6)
			write_byte(8)
			write_byte(1)
			write_byte(255)
			write_byte(255)
			write_byte(192)
			write_byte(128)
			write_byte(5)
			message_end()
			
			if(is_valid_ent(ptd)) {
				new classname2[32]
				entity_get_string(ptd,EV_SZ_classname,classname2,31)
				
				if(equal(classname2,"func_breakable"))
					force_use(ptr,ptd)
			}
			
			remove_entity(ptr)
		}
	}
	return PLUGIN_CONTINUE
}

public zp_user_infected_pre(player, infector){
	
	Icon_Energy({0, 255, 0}, 0, player);
	cmdDrop(player);
	hasjet[player] = 0;
	g_flyEnergy[player] = 0;
	rocket[player] = false;
}

public zv_extra_item_selected(player, itemid){
	

	new clip,ammo
	new weapon = get_user_weapon(player,clip,ammo)
		
	if (itemid == g_item_jetpack)
	{
		client_print(player, print_chat, "[ZP] say /jphelp for Display the help page")
		hasjet[player] = 1
		g_flyEnergy[player] = get_pcvar_num(cvar_fly_max_engery)
		rocket[player] = true
		client_cmd(player,"spk items/gunpickup2.wav")
		if(weapon == CSW_KNIFE){
			switchmodel(player)
		}
		else
		{
			engclient_cmd(player,"weapon_knife"),switchmodel(player)
		}
	}
}

stock jp_radius_damage(entity) {
	new id = entity_get_edict(entity,EV_ENT_owner)
	for(new i = 1; i < 33; i++) {
		if(is_user_alive(i)) {
			new dist = floatround(entity_range(entity,i))
			
			if(dist <= get_pcvar_num(cvar_Dmg_range)) {
				new hp = get_user_health(i)
				new Float:damage = get_pcvar_float(cvar_RocketDmg)-(get_pcvar_float(cvar_RocketDmg)/get_pcvar_float(cvar_Dmg_range))*float(dist)
				
				new Origin[3]
				get_user_origin(i,Origin)
				
				if(zp_get_user_zombie(id) != zp_get_user_zombie(i)) {
						if(hp > damage)
							jp_take_damage(i,floatround(damage),Origin,DMG_BLAST)
						else
							log_kill(id,i,"Jetpack Rocket",0)
					}
			}
		}
	}
}

stock log_kill(killer, victim, weapon[], headshot)
{
// code from MeRcyLeZZ
	set_msg_block(get_user_msgid("DeathMsg"), BLOCK_SET)
	ExecuteHamB(Ham_Killed, victim, killer, 2) // set last param to 2 if you want victim to gib
	set_msg_block(get_user_msgid("DeathMsg"), BLOCK_NOT)

	
	message_begin(MSG_BROADCAST, get_user_msgid("DeathMsg"))
	write_byte(killer)
	write_byte(victim)
	write_byte(headshot)
	write_string(weapon)
	message_end()
//
	
	if(get_user_team(killer)!=get_user_team(victim))
		set_user_frags(killer,get_user_frags(killer) +1)
	if(get_user_team(killer)==get_user_team(victim))
		set_user_frags(killer,get_user_frags(killer) -1)
		
	new kname[32], vname[32], kauthid[32], vauthid[32], kteam[10], vteam[10]

	get_user_name(killer, kname, 31)
	get_user_team(killer, kteam, 9)
	get_user_authid(killer, kauthid, 31)
 
	get_user_name(victim, vname, 31)
	get_user_team(victim, vteam, 9)
	get_user_authid(victim, vauthid, 31)
		
	log_message("^"%s<%d><%s><%s>^" killed ^"%s<%d><%s><%s>^" with ^"%s^"", 
	kname, get_user_userid(killer), kauthid, kteam, 
 	vname, get_user_userid(victim), vauthid, vteam, weapon)

 	return PLUGIN_CONTINUE;
}

stock jp_take_damage(victim,damage,origin[3],bit) {
	message_begin(MSG_ONE,get_user_msgid("Damage"),{0,0,0},victim)
	write_byte(21)
	write_byte(20)
	write_long(bit)
	write_coord(origin[0])
	write_coord(origin[1])
	write_coord(origin[2])
	message_end()
	
	set_user_health(victim,get_user_health(victim)-damage)
}
zm_vip_extra_buy_survnem.sma

Code: Select all

/* Plugin generated by AMXX-Studio */

#include <amxmodx>
#include <zombieplague>
#include <zmvip>

#define PLUGIN "[ZP] S/N Buy"
#define VERSION "1.1"
#define AUTHOR "aaarnas"

new g_msgSayText
new nemesis, survivor
new g_bought[33], bought
new cvar_n_price, cvar_s_price, cvar_limit_all, cvar_everytime, cvar_show_bought, cvar_allow_times

public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR)
	cvar_everytime = register_cvar("zp_allow_buy", "2")
	cvar_allow_times = register_cvar("zp_allow_times", "4")
	cvar_limit_all = register_cvar("zp_limit_for_all", "1")
	cvar_n_price = register_cvar("zp_nemesis_price", "2500")
	cvar_s_price = register_cvar("zp_survivor_price", "2500")
	cvar_show_bought = register_cvar("zp_show_who_bought", "1")
	
	g_msgSayText = get_user_msgid("SayText")
	
	// Extra items
	nemesis = zv_register_extra_item("Buy Nemesis", "For one round", get_pcvar_num(cvar_n_price), 0)
	survivor = zv_register_extra_item("Buy Survivor","For one round", get_pcvar_num(cvar_s_price), 0)
}

public zp_round_ended()
	bought = false

public zv_extra_item_selected(id, itemid) {
	
	new value = get_pcvar_num(cvar_everytime)
	
	if(itemid == nemesis) {
		
		if(get_pcvar_num(cvar_limit_all) && bought) {
			client_printcolor(id, "/g[ZP] This is no more avaible in this round. Try next round.")
			return ZV_PLUGIN_HANDLED
		}
		if(g_bought[id] >= get_pcvar_num(cvar_allow_times)) {
			client_printcolor(id, "/g[ZP] You can't buy it more than %d times.", get_pcvar_num(cvar_allow_times))
			return ZV_PLUGIN_HANDLED
		}
		if(value == 2) {
			zp_make_user_nemesis(id)
			new name[64]
			get_user_name(id, name, 63)
			client_printcolor(0, "/g[ZP] %s /ybought nemesis", name)
			g_bought[id]++
		}
		else if(zp_has_round_started() == value) {
			zp_make_user_nemesis(id)
			if(get_pcvar_num(cvar_show_bought)) {
				new name[64]
				get_user_name(id, name, 63)
				client_printcolor(0, "/g[ZP] %s /ybought nemesis", name)
				g_bought[id]++
				bought = true
			}
		}
		else {
			client_printcolor(id, "/g[ZP] /yYou can buy Nemesis only when %s.", value ? "round started":"round not started")
			return ZV_PLUGIN_HANDLED
		}
	}
	else if(itemid == survivor) {
		
		if(get_pcvar_num(cvar_limit_all) && bought) {
			client_printcolor(id, "/g[ZP] This is no more avaible in this round. Try next round.")
			return ZV_PLUGIN_HANDLED
		}
		if(g_bought[id] >= get_pcvar_num(cvar_allow_times)) {
			client_printcolor(id, "/g[ZP] You can't buy it more than %d times.", get_pcvar_num(cvar_allow_times))
			return ZV_PLUGIN_HANDLED
		}
		if(value == 2) {
			zp_make_user_survivor(id)
			new name[64]
			get_user_name(id, name, 63)
			client_printcolor(0, "/g[ZP] %s /ybought nemesis", name)
			g_bought[id]++
		}
		else if(zp_has_round_started() == value) {
			zp_make_user_survivor(id)
			if(get_pcvar_num(cvar_show_bought)) {
				new name[64]
				get_user_name(id, name, 63)
				client_printcolor(0, "/g[ZP] %s /ybought survivor", name)
				g_bought[id]++
				bought = true
			}
		}
		else {
			client_printcolor(id, "/g[ZP] /yYou can buy Survivor only when %s.", value ? "round started":"round not started")
			return ZV_PLUGIN_HANDLED
		}
	}
	return 1
}

stock client_printcolor(const id, const input[], any:...)
{
	new iCount = 1, iPlayers[32]
	
	static szMsg[191]
	vformat(szMsg, charsmax(szMsg), input, 3)
	
	replace_all(szMsg, 190, "/g", "^4") // green txt
	replace_all(szMsg, 190, "/y", "^1") // orange txt
	replace_all(szMsg, 190, "/ctr", "^3") // team txt
	replace_all(szMsg, 190, "/w", "^0") // team txt
	
	if(id) iPlayers[0] = id
	else get_players(iPlayers, iCount, "ch")
		
	for (new i = 0; i < iCount; i++)
	{
		if (is_user_connected(iPlayers[i]))
		{
			message_begin(MSG_ONE_UNRELIABLE, g_msgSayText, _, iPlayers[i])
			write_byte(iPlayers[i])
			write_string(szMsg)
			message_end()
		}
	}
}
zm_vip_extra_lasersight.sma

Code: Select all

#include <amxmodx>
#include <zombieplague>
#include <zmvip>

new bool:haslaser[33] = false
new sprite, red, green , blue
new g_lsight
new g_iMaxPlayers

public plugin_init()
{
	register_plugin("[ZP] Extra Item: Laser Sight","1.0","fiendshard")
	register_event("HLTV", "event_round_start", "a", "1=0", "2=0") 
	g_lsight = zv_register_extra_item("Laser Sight (1 Round)", "Laser Sight", 10, ZP_TEAM_HUMAN)
	g_iMaxPlayers = get_maxplayers()
}

public plugin_precache() 
{
	sprite = precache_model("sprites/white.spr")
}

public client_putinserver(id)
{
	haslaser[id] = false
}

public client_disconnect(id)
{
	haslaser[id] = false
}

public zp_extra_item_selected(id, itemid)
{
	if (itemid == g_lsight)
		haslaser[id] = true
	red = 255
	green = 0
	blue = 0
	return PLUGIN_CONTINUE
}

public client_PreThink(id)
{	
	if(haslaser[id] == true)
	{
		new e[3]
		get_user_origin(id, e, 3)
		
		message_begin( MSG_BROADCAST,SVC_TEMPENTITY)
		write_byte (TE_BEAMENTPOINT)
		write_short(id | 0x1000)
		write_coord (e[0])		// Start X
		write_coord (e[1])		// Start Y
		write_coord (e[2])		// Start Z

		write_short(sprite)		// Sprite
		
		write_byte (1)      		// Start frame				
		write_byte (10)     		// Frame rate					
		write_byte (1)			// Life
		write_byte (5)   		// Line width				
		write_byte (0)    		// Noise
		write_byte (red) 		// Red
		write_byte (green)		// Green
		write_byte (blue)		// Blue
		write_byte (150)     		// Brightness					
		write_byte (25)      		// Scroll speed					
		message_end()
	}
	return PLUGIN_HANDLED
}

public hook_death(id)
{
	haslaser[id] = false
}

public zv_user_infected_post(id, infector)
{
	haslaser[id] = false
	return PLUGIN_CONTINUE
}

public event_round_start()
{
	for (new i = 1; i <= g_iMaxPlayers; i++)
	{
		if (!is_user_connected(i))
			continue
		if (haslaser[i])
		{
			haslaser[i] = false
		}
	}
}
zm_vip_extra_playeraura.sma

Code: Select all

/*================================================================================
 
 -----------------------------------
 -*- [ZP] Extra Item : Player Aura -*-
 -----------------------------------
 
 ~~~~~~~~~~~~~~~
 - Description -
 ~~~~~~~~~~~~~~~
 
 This is just an extra item which gives the player a player aura. The player
 aura helps players to navigate and find zombies throughout the map. 

 ~~~~~~~~~~~~~~~
 - CVARS -
 ~~~~~~~~~~~~~~~
 ("zp_aura_radius", "20.0")
 This is the radius of the aura. 
 ("zp_aura_red", "255")
 This is the red colour of the aura. 
 ("zp_aura_green", "255")
 This is the green colour of the aura. 
 ("zp_aura_blue", "255")
 This is the blue colour of the aura. 
 ("zp_glow_on", "1")
 This is to have a glow or not. 
 ("zp_aura_round", "1")
 This is whether or not to remove aura every round. 
 
 ~~~~~~~~~~~~~~~
 - Change Logs -
 ~~~~~~~~~~~~~~~
 Version : 1.0
 First Release. 

 Version : 1.1
 Added some codes, removed hamsandwich module which wasnt required. 

 Version : 1.2
 Changed almost all of the codes, thanks to alan_el_more for his help. 

 Version : 1.3
 Fixed bug with some codes where player doesnt get aura after buying it. 
 (Had to change most of the codes back to the old ones. Sorry alan_el_more)

 Version : 1.4
 Added a CVAR for players to have a glow or not. 
 Also updated codes so that you lose the aura on every respawn. 

 Version : 1.5
 Want to have the aura every round? Added a CVAR for that. 
 Check the CVARs section above for the information. 
 
 Version : 1.6
 Fixed a minor misplacement of a code. Glow color should be okay now. 

================================================================================*/

#include <amxmodx>
#include <fakemeta>
#include <fakemeta_util>
#include <zombieplague>
#include <zmvip>

/*================================================================================
 [Plugin Customization]
=================================================================================*/

new const g_item_name[] = { "Player Aura" }
new const g_item_discription[] = { "Gives aura & glow" }
const g_item_cost = 10
new const g_sound_buyaura[] = { "items/nvg_on.wav" }

/*============================================================================*/

new g_itemid_playeraura, g_extra_glow, g_aura_round

public plugin_precache()
{
	precache_sound(g_sound_buyaura)
}

public plugin_init()
{
	register_plugin("[ZP] Extra Item: Player Aura", "1.6", "Zombie Lurker")
	
	g_itemid_playeraura = zv_register_extra_item(g_item_name, g_item_discription, g_item_cost, ZV_TEAM_HUMAN)
	g_extra_glow = register_cvar("zp_glow_on", "1")
	g_aura_round = register_cvar("zp_aura_round", "1")
	
	register_cvar("zp_aura_radius", "20.0")
	register_cvar("zp_aura_red", "255")
	register_cvar("zp_aura_green", "255")
	register_cvar("zp_aura_blue", "255")
}

public zv_extra_item_selected(player, itemid)
{
if (itemid == g_itemid_playeraura)
{
set_task(0.1, "BUYAURA", player, _, _, "b")
set_task(0.2, "BUYGLOW", player, _, _, "b")
engfunc(EngFunc_EmitSound, player, CHAN_BODY, g_sound_buyaura, 1.0, ATTN_NORM, 0, PITCH_NORM)
}
}

public BUYAURA(player)
{
if ((!zp_get_user_zombie(player)) && (is_user_alive(player)))
{
	static Float:originF[3]
	pev(player, pev_origin, originF)
	
	engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
	write_byte(TE_DLIGHT)
	engfunc(EngFunc_WriteCoord, originF[0]) // x
	engfunc(EngFunc_WriteCoord, originF[1]) // y
	engfunc(EngFunc_WriteCoord, originF[2]) // z
	write_byte(get_cvar_num("zp_aura_radius")) // radius
	write_byte(get_cvar_num("zp_aura_red")) // red
	write_byte(get_cvar_num("zp_aura_green")) // green
	write_byte(get_cvar_num("zp_aura_blue")) // blue
	write_byte(2) // life
	write_byte(0) // decay rate
	message_end()
	}
	else
	{
	if (get_pcvar_num(g_aura_round))
		remove_task(player)
	}
return PLUGIN_CONTINUE
}

public BUYGLOW(player)
{
if ((!zp_get_user_zombie(player)) && (is_user_alive(player)) && (get_pcvar_num(g_extra_glow)))
{
	fm_set_rendering(player, kRenderFxGlowShell, (get_cvar_num("zp_aura_red")), (get_cvar_num("zp_aura_green")), (get_cvar_num("zp_aura_blue")), kRenderNormal, 16);
	}
return PLUGIN_CONTINUE
}
zm_vip_extra_unlimited_clip.sma

Code: Select all

/*================================================================================
	
	-------------------------------------------
	-*- [ZP] Extra Item: Unlimited Clip 1.0 -*-
	-------------------------------------------
	
	~~~~~~~~~~~~~~~
	- Description -
	~~~~~~~~~~~~~~~
	
	This item/upgrade gives players unlimited clip ammo for a single round.
	
================================================================================*/

#include <amxmodx>
#include <fakemeta>
#include <zombieplague>
#include <zmvip>

/*================================================================================
 [Plugin Customization]
=================================================================================*/

new const g_item_name[] = { "Unlimited Clip" } // Item name
new const g_item_descritpion[] = { "(single round)" } // Item descritpion
const g_item_cost = 10 // Price (ammo)

/*============================================================================*/

// CS Offsets
#if cellbits == 32
const OFFSET_CLIPAMMO = 51
#else
const OFFSET_CLIPAMMO = 65
#endif
const OFFSET_LINUX_WEAPONS = 4

// Max Clip for weapons
new const MAXCLIP[] = { -1, 13, -1, 10, 1, 7, -1, 30, 30, 1, 30, 20, 25, 30, 35, 25, 12, 20,
			10, 30, 100, 8, 30, 30, 20, 2, 7, 30, 30, -1, 50 }

new g_itemid_infammo, g_has_unlimited_clip[33]

public plugin_init()
{
	register_plugin("[ZP] Extra: Unlimited Clip", "1.0", "MeRcyLeZZ")
	
	g_itemid_infammo = zv_register_extra_item(g_item_name, g_item_descritpion, g_item_cost, ZV_TEAM_HUMAN)	
	
	register_event("HLTV", "event_round_start", "a", "1=0", "2=0")
	register_message(get_user_msgid("CurWeapon"), "message_cur_weapon")
	set_cvar_num("zp_vip_unlimited_ammo", 0)
}

// Player buys our upgrade, set the unlimited ammo flag
public zv_extra_item_selected(player, itemid)
{
	if (itemid == g_itemid_infammo)
		g_has_unlimited_clip[player] = true
}

// Reset flags for all players on newround
public event_round_start()
{
	for (new id; id <= 32; id++) g_has_unlimited_clip[id] = false;
}

// Unlimited clip code
public message_cur_weapon(msg_id, msg_dest, msg_entity)
{
	// Player doesn't have the unlimited clip upgrade
	if (!g_has_unlimited_clip[msg_entity])
		return;
	
	// Player not alive or not an active weapon
	if (!is_user_alive(msg_entity) || get_msg_arg_int(1) != 1)
		return;
	
	static weapon, clip
	weapon = get_msg_arg_int(2) // get weapon ID
	clip = get_msg_arg_int(3) // get weapon clip
	
	// Unlimited Clip Ammo
	if (MAXCLIP[weapon] > 2) // skip grenades
	{
		set_msg_arg_int(3, get_msg_argtype(3), MAXCLIP[weapon]) // HUD should show full clip all the time
		
		if (clip < 2) // refill when clip is nearly empty
		{
			// Get the weapon entity
			static wname[32], weapon_ent
			get_weaponname(weapon, wname, sizeof wname - 1)
			weapon_ent = fm_find_ent_by_owner(-1, wname, msg_entity)
			
			// Set max clip on weapon
			fm_set_weapon_ammo(weapon_ent, MAXCLIP[weapon])
		}
	}
}

// Find entity by its owner (from fakemeta_util)
stock fm_find_ent_by_owner(entity, const classname[], owner)
{
	while ((entity = engfunc(EngFunc_FindEntityByString, entity, "classname", classname)) && pev(entity, pev_owner) != owner) {}
	
	return entity;
}

// Set Weapon Clip Ammo
stock fm_set_weapon_ammo(entity, amount)
{
	set_pdata_int(entity, OFFSET_CLIPAMMO, amount, OFFSET_LINUX_WEAPONS);
}
zm_vip_extra_weapons.sma

Code: Select all

/* Plugin generated by AMXX-Studio */

#include <amxmodx>
#include <hamsandwich>
#include <fun>
#include <cstrike>
#include <zmvip>

// IMPORTANT: You should enable weapons only witch you need, not all.
// Uncomment weapon if you want to add it to menu.
// ON/OFF || Wepon     || * damage increase 

#define P228		1.5
//#define SCOUT		1.5
//#define XM1014	1.5
//#define MAC10		1.5
//#define AUG		1.5
//#define ELITE		1.5
//#define FIVESEVEN	1.5
//#define UMP45		1.5
//#define SG550		1.5
//#define GALI		1.5
//#define FAMAS		1.5
//#define USP		1.5
//#define GLOCK18	1.5
//#define AWP		1.5
//#define MP5NAVY	1.5
//#define M249		1.5
//#define M3		1.5
//#define M4A1		1.5
//#define TMP		1.5
//#define G3SG1		1.5
//#define DEAGLE	1.5
//#define SG552		1.5
//#define AK47		1.5
//#define P90		1.5

#define PLUGIN "Plugin"
#define VERSION "1.0"
#define AUTHOR "aaarnas"

#if defined P228
	new p228[33], item1
#endif
#if defined SCOUT
	new scout[33], item2
#endif
#if defined XM1014
	new xm1014[33], item3
#endif
#if defined MAC10
	new mac_10[33], item4
#endif
#if defined AUG
	new aug[33], item5
#endif
#if defined ELITE
	new dual_elites[33], item6
#endif
#if defined FIVESEVEN
	new five_seven[33], item7
#endif
#if defined UMP45
	new ump45[33], item8
#endif
#if defined SG550
	new sig_550[33], item9
#endif
#if defined GALI
	new galil[33], item10
#endif
#if defined FAMAS
	new famas[33], item11
#endif
#if defined USP
	new usp[33], item12
#endif
#if defined GLOCK18
	new glock[33], item13
#endif
#if defined AWP
	new awp[33], item14
#endif
#if defined MP5NAVY
	new mp5[33], item15
#endif
#if defined M249
	new m249[33], item16
#endif
#if defined M3
	new m3[33], item17
#endif
#if defined M4A1
	new m4a1[33], item18
#endif
#if defined TMP
	new tmp[33], item19
#endif
#if defined G3SG1
	new g3_sg_1[33], item20
#endif
#if defined DEAGLE
	new desert_eagle[33], item21
#endif
#if defined SG552
	new sig_552[33], item22
#endif
#if defined AK47
	new ak_47[33], item23
#endif
#if defined P90
	new p90[33], item24
#endif

new maxplayers
public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR)
	RegisterHam(Ham_TakeDamage, "player", "TakeDamage")
	register_event("HLTV", "RoundStart", "a", "1=0", "2=0")
	RegisterHam(Ham_Killed, "player", "PlayerKilled")
	maxplayers = get_maxplayers()
	
	new holder[30]
#if defined P228
	formatex(holder, charsmax(holder), "Extra damage*%1.1f", P228+0.0001)
	item1 = zv_register_extra_item("Buy weapon Sig P228", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined SCOUT
	formatex(holder, charsmax(holder), "Extra damage*%f", SCOUT+0.0001)
	item2 = zv_register_extra_item("Buy weapon Scout", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined XM1014
	formatex(holder, charsmax(holder), "Extra damage*%d", XM1014+0.0001)
	item3 = zv_register_extra_item("Buy weapon XM1014", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined MAC10
	formatex(holder, charsmax(holder), "Extra damage*%d", MAC10+0.0001)
	item4 = zv_register_extra_item("Buy weapon MAC-10", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined AUG
	formatex(holder, charsmax(holder), "Extra damage*%d", AUG+0.0001)
	item5 = zv_register_extra_item("Buy weapon Aug", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined ELITE
	formatex(holder, charsmax(holder), "Extra damage*%d", ELITE+0.0001)
	item6 = zv_register_extra_item("Buy weapon Dual Elites", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined FIVESEVEN
	formatex(holder, charsmax(holder), "Extra damage*%d", FIVESEVEN+0.0001)
	item7 = zv_register_extra_item("Buy weapon Five-Seven", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined UMP45
	formatex(holder, charsmax(holder), "Extra damage*%d", UMP45+0.0001)
	item8 = zv_register_extra_item("Buy weapon UMP45", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined SG550
	formatex(holder, charsmax(holder), "Extra damage*%d", SG550+0.0001)
	item9 = zv_register_extra_item("Buy weapon Sig 550", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined GALI
	formatex(holder, charsmax(holder), "Extra damage*%d", GALI+0.0001)
	item10 = zv_register_extra_item("Buy weapon Galil", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined FAMAS
	formatex(holder, charsmax(holder), "Extra damage*%d", FAMAS+0.0001)
	item11 = zv_register_extra_item("Buy weapon Famas", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined USP
	formatex(holder, charsmax(holder), "Extra damage*%d", USP+0.0001)
	item12 = zv_register_extra_item("Buy weapon USP", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined GLOCK18
	formatex(holder, charsmax(holder), "Extra damage*%d", GLOCK18+0.0001)
	item13 = zv_register_extra_item("Buy weapon Glock", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined AWP
	formatex(holder, charsmax(holder), "Extra damage*%d", AWP+0.0001)
	item14 = zv_register_extra_item("Buy weapon Awp", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined MP5NAVY
	formatex(holder, charsmax(holder), "Extra damage*%d", MP5NAVY+0.0001)
	item15 = zv_register_extra_item("Buy weapon MP5", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined M249
	formatex(holder, charsmax(holder), "Extra damage*%d", M249+0.0001)
	item16 = zv_register_extra_item("Buy weapon M249", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined M3
	formatex(holder, charsmax(holder), "Extra damage*%d", M3+0.0001)
	item17 = zv_register_extra_item("Buy weapon M3", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined M4A1
	formatex(holder, charsmax(holder), "Extra damage*%d", M4A1+0.0001)
	item18 = zv_register_extra_item("Buy weapon M4A1", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined TMP
	formatex(holder, charsmax(holder), "Extra damage*%d", TMP+0.0001)
	item19 = zv_register_extra_item("Buy weapon TMP", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined G3SG1
	formatex(holder, charsmax(holder), "Extra damage*%d", G3SG1+0.0001)
	item20 = zv_register_extra_item("Buy weapon G3/SG-1", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined DEAGLE
	formatex(holder, charsmax(holder), "Extra damage*%d", DEAGLE+0.0001)
	item21 = zv_register_extra_item("Buy weapon Desert Eagle", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined SG552
	formatex(holder, charsmax(holder), "Extra damage*%d", SG552+0.0001)
	item22 = zv_register_extra_item("Buy weapon Sig 552", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined AK47
	formatex(holder, charsmax(holder), "Extra damage*%d", AK47+0.0001)
	item23 = zv_register_extra_item("Buy weapon AK-47", holder, 10, ZV_TEAM_HUMAN)
#endif
#if defined P90
	formatex(holder, charsmax(holder), "Extra damage*%d", P90+0.0001)
	item24 = zv_register_extra_item("Buy weapon P90", holder, 10, ZV_TEAM_HUMAN)
#endif
}

public zv_extra_item_selected(id, itemid) {
	
#if defined P228
	if(itemid == item1) {
		p228[id] = true
		give_item(id, "weapon_p228")
		cs_set_user_bpammo(id, CSW_P228, 90)
	}
#endif
#if defined SCOUT
	if(itemid == item2) {
		scout[id] = true
		give_item(id, "weapon_scout")
		cs_set_user_bpammo(id, CSW_SCOUT, 90)
	}
#endif
#if defined XM1014
	if(itemid == item3) {
		xm1014[id] = true
		give_item(id, "weapon_xm1014")
		cs_set_user_bpammo(id, CSW_XM1014, 90)
	}
#endif
#if defined MAC10
	if(itemid == item4) {
		mac_10[id] = true
		give_item(id, "weapon_mac10")
		cs_set_user_bpammo(id, CSW_MAC10, 90)
	}
#endif
#if defined AUG
	if(itemid == item5) {
		aug[id] = true
		give_item(id, "weapon_mac10")
		cs_set_user_bpammo(id, CSW_AUG, 90)
	}
#endif
#if defined ELITE
	if(itemid == item6) {
		dual_elites[id] = true
		give_item(id, "weapon_elite")
		cs_set_user_bpammo(id, CSW_ELITE, 90)
	}
#endif
#if defined FIVESEVEN
	if(itemid == item7) {
		five_seven[id] = true
		give_item(id, "weapon_fiveseven")
		cs_set_user_bpammo(id, CSW_FIVESEVEN, 90)
	}
#endif
#if defined UMP45
	if(itemid == item8) {
		ump45[id] = true
		give_item(id, "weapon_ump45")
		cs_set_user_bpammo(id, CSW_UMP45, 90)
	}
#endif
#if defined SG550
	if(itemid == item9) {
		sig_550[id] = true
		give_item(id, "weapon_sg550")
		cs_set_user_bpammo(id, CSW_SG550, 90)
	}
#endif
#if defined GALI
	if(itemid == item10) {
		galil[id] = true
		give_item(id, "weapon_galil")
		cs_set_user_bpammo(id, CSW_GALI, 90)
	}
#endif
#if defined FAMAS
	if(itemid == item11) {
		famas[id] = true
		give_item(id, "weapon_famas")
		cs_set_user_bpammo(id, CSW_FAMAS, 90)
	}
#endif
#if defined USP
	if(itemid == item12) {
		usp[id] = true
		give_item(id, "weapon_usp")
		cs_set_user_bpammo(id, CSW_USP, 90)
	}
#endif
#if defined GLOCK18
	if(itemid == item13) {
		glock[id] = true
		give_item(id, "weapon_glock18")
		cs_set_user_bpammo(id, CSW_GLOCK18, 90)
	}
#endif
#if defined AWP
	if(itemid == item14) {
		awp[id] = true
		give_item(id, "weapon_awp")
		cs_set_user_bpammo(id, CSW_AWP, 90)
	}
#endif
#if defined MP5NAVY
	if(itemid == item15) {
		mp5[id] = true
		give_item(id, "weapon_mp5navy")
		cs_set_user_bpammo(id, CSW_MP5NAVY, 90)
	}
#endif
#if defined M249
	if(itemid == item16) {
		m249[id] = true
		give_item(id, "weapon_m249")
		cs_set_user_bpammo(id, CSW_M249, 90)
	}
#endif
#if defined M3
	if(itemid == item17) {
		m3[id] = true
		give_item(id, "weapon_m3")
		cs_set_user_bpammo(id, CSW_M3, 90)
	}
#endif
#if defined M4A1
	if(itemid == item18) {
		m4a1[id] = true
		give_item(id, "weapon_m4a1")
		cs_set_user_bpammo(id, CSW_M4A1, 90)
	}
#endif
#if defined TMP
	if(itemid == item19) {
		tmp[id] = true
		give_item(id, "weapon_tmp")
		cs_set_user_bpammo(id, CSW_TMP, 90)
	}
#endif
#if defined G3SG1
	if(itemid == item20) {
		g3_sg_1[id] = true
		give_item(id, "weapon_g3sg1")
		cs_set_user_bpammo(id, CSW_G3SG1, 90)
	}
#endif
#if defined DEAGLE
	if(itemid == item21) {
		desert_eagle[id] = true
		give_item(id, "weapon_deagle")
		cs_set_user_bpammo(id, CSW_DEAGLE, 90)
	}
#endif
#if defined SG552
	if(itemid == item22) {
		sig_552[id] = true
		give_item(id, "weapon_sg552")
		cs_set_user_bpammo(id, CSW_SG552, 90)
	}
#endif
#if defined AK47
	if(itemid == item23) {
		ak_47[id] = true
		give_item(id, "weapon_ak47")
		cs_set_user_bpammo(id, CSW_AK47, 90)
	}
#endif
#if defined P90
	if(itemid == item24) {
		p90[id] = true
		give_item(id, "weapon_p90")
		cs_set_user_bpammo(id, CSW_P90, 90)
	}
#endif
}

public TakeDamage(victim, inflictor, attacker, Float:damage, damage_type) {
	
	if(victim == attacker || !(1 <= attacker <= maxplayers)) return HAM_IGNORED;
	
	static weapon
	weapon = get_user_weapon(attacker)
#if defined P228
	if(p228[attacker] && weapon == CSW_P228) {
		damage*=P228
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined SCOUT
	if(scout[attacker] && weapon == CSW_SCOUT) {
		damage*=SCOUT
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined XM1014
	if(xm1014[attacker] && weapon == CSW_XM1014) {
		damage*=XM1014
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined MAC10
	if(mac_10[attacker] && weapon == CSW_MAC10) {
		damage*=MAC10
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined AUG
	if(aug[attacker] && weapon == CSW_AUG) {
		damage*=AUG
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined ELITE
	if(dual_elites[attacker] && weapon == CSW_ELITE) {
		damage*=ELITE
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined FIVESEVEN
	if(five_seven[attacker] && weapon == CSW_FIVESEVEN) {
		damage*=FIVESEVEN
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined UMP45
	if(ump45[attacker] && weapon == CSW_UMP45) {
		damage*=UMP45
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined SG550
	if(sig_550[attacker] && weapon == CSW_SG550) {
		damage*=SG550
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined GALI
	if(galil[attacker] && weapon == CSW_GALI) {
		damage*=GALI
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined FAMAS
	if(famas[attacker] && weapon == CSW_FAMAS) {
		damage*=FAMAS
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined USP
	if(usp[attacker] && weapon == CSW_USP) {
		damage*=USP
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined GLOCK18
	if(glock[attacker] && weapon == CSW_GLOCK18) {
		damage*=GLOCK18
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined AWP
	if(awp[attacker] && weapon == CSW_AWP) {
		damage*=AWP
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined MP5NAVY
	if(mp5[attacker] && weapon == CSW_MP5NAVY) {
		damage*=MP5NAVY
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined M249
	if(m249[attacker] && weapon == CSW_M249) {
		damage*=M249
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined M3
	if(m3[attacker] && weapon == CSW_M3) {
		damage*=M3
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined M4A1
	if(m4a1[attacker] && weapon == CSW_M4A1) {
		damage*=M4A1
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined TMP
	if(tmp[attacker] && weapon == CSW_TMP) {
		damage*=TMP
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined G3SG1
	if(g3_sg_1[attacker] && weapon == CSW_G3SG1) {
		damage*=G3SG1
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined DEAGLE
	if(desert_eagle[attacker] && weapon == CSW_DEAGLE) {
		damage*=DEAGLE
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined SG552
	if(sig_552[attacker] && weapon == CSW_SG552) {
		damage*=SG552
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined AK47
	if(ak_47[3attacker] && weapon == CSW_AK47) {
		damage*=AK47
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
#if defined P90
	if(p90[attacker] && weapon == CSW_P90) {
		damage*=P90
		SetHamParamFloat(4, damage)
		return HAM_HANDLED
	}
#endif
	return HAM_IGNORED
}

public PlayerKilled(victim, attacker) {
	
#if defined P228
	p228[victim] = false
#endif
#if defined SCOUT
	scout[victim] = false
#endif
#if defined XM1014
	xm1014[victim] = false
#endif
#if defined MAC10
	mac_10[victim] = false
#endif
#if defined AUG
	aug[victim] = false
#endif
#if defined ELITE
	dual_elites[victim] = false
#endif
#if defined FIVESEVEN
	five_seven[victim] = false
#endif
#if defined UMP45
	ump45[victim] = false
#endif
#if defined SG550
	sig_550[victim] = false
#endif
#if defined GALI
	galil[victim] = false
#endif
#if defined FAMAS
	famas[victim] = false
#endif
#if defined USP
	usp[victim] = false
#endif
#if defined GLOCK18
	glock[victim] = false
#endif
#if defined AWP
	awp[victim] = false
#endif
#if defined MP5NAVY
	mp5[victim] = false
#endif
#if defined M249
	m249[victim] = false
#endif
#if defined M3
	m3[victim] = false
#endif
#if defined M4A1
	m4a1[victim] = false
#endif
#if defined TMP
	tmp[victim] = false
#endif
#if defined G3SG1
	g3_sg_1[victim] = false
#endif
#if defined DEAGLE
	desert_eagle[victim] = false
#endif
#if defined SG552
	sig_552[victim] = false
#endif
#if defined AK47
	ak_47[victim] = false
#endif
#if defined P90
	p90[victim] = false
#endif
}


public RoundStart() {

#if defined P228
	arrayset(p228, false, 32)
#endif
#if defined SCOUT
	arrayset(scout, false, 32)
#endif
#if defined XM1014
	arrayset(xm1014, false, 32)
#endif
#if defined MAC10
	arrayset(mac_10, false, 32)
#endif
#if defined AUG
	arrayset(aug, false, 32)
#endif
#if defined ELITE
	arrayset(dual_elites, false, 32)
#endif
#if defined FIVESEVEN
	arrayset(five_seven, false, 32)
#endif
#if defined UMP45
	arrayset(ump45, false, 32)
#endif
#if defined SG550
	arrayset(sig_550, false, 32)
#endif
#if defined GALI
	arrayset(galil, false, 32)
#endif
#if defined FAMAS
	arrayset(famas, false, 32)
#endif
#if defined USP
	arrayset(usp, false, 32)
#endif
#if defined GLOCK18
	arrayset(glock, false, 32)
#endif
#if defined AWP
	arrayset(awp, false, 32)
#endif
#if defined MP5NAVY
	arrayset(mp5, false, 32)
#endif
#if defined M249
	arrayset(m249, false, 32)
#endif
#if defined M3
	arrayset(m3, false, 32)
#endif
#if defined M4A1
	arrayset(m4a1, false, 32)
#endif
#if defined TMP
	arrayset(tmp, false, 32)
#endif
#if defined G3SG1
	arrayset(g3_sg_1, false, 32)
#endif
#if defined DEAGLE
	arrayset(desert_eagle, false, 32)
#endif
#if defined SG552
	arrayset(sig_552, false, 32)
#endif
#if defined AK47
	arrayset(ak_47, false, 32)
#endif
#if defined P90
	arrayset(p90, false, 32)
#endif
}

public client_connect(victim) {
	
#if defined P228
	p228[victim] = false
#endif
#if defined SCOUT
	scout[victim] = false
#endif
#if defined XM1014
	xm1014[victim] = false
#endif
#if defined MAC10
	mac_10[victim] = false
#endif
#if defined AUG
	aug[victim] = false
#endif
#if defined ELITE
	dual_elites[victim] = false
#endif
#if defined FIVESEVEN
	five_seven[victim] = false
#endif
#if defined UMP45
	ump45[victim] = false
#endif
#if defined SG550
	sig_550[victim] = false
#endif
#if defined GALI
	galil[victim] = false
#endif
#if defined FAMAS
	famas[victim] = false
#endif
#if defined USP
	usp[victim] = false
#endif
#if defined GLOCK18
	glock[victim] = false
#endif
#if defined AWP
	awp[victim] = false
#endif
#if defined MP5NAVY
	mp5[victim] = false
#endif
#if defined M249
	m249[victim] = false
#endif
#if defined M3
	m3[victim] = false
#endif
#if defined M4A1
	m4a1[victim] = false
#endif
#if defined TMP
	tmp[victim] = false
#endif
#if defined G3SG1
	g3_sg_1[victim] = false
#endif
#if defined DEAGLE
	desert_eagle[victim] = false
#endif
#if defined SG552
	sig_552[victim] = false
#endif
#if defined AK47
	ak_47[victim] = false
#endif
#if defined P90
	p90[victim] = false
#endif
}
zm_vip_zkill_bomb_v1-2.sma

Code: Select all

/***************************************************************************\
		  ===========================================
		   * || [ZP] Kill Bomb For Zombies v1.2 || *
		  ===========================================

	-------------------
	 *||DESCRIPTION||*
	-------------------

	This plugins adds another extra item to Zombie Plague, A Kill Bomb.
	This item is for zombies and where the grenade is thrown the human 
	who is in range is killed.

	-------------
	 *||CVARS||*
	-------------

	- zp_zkill_bomb_extra_hp 100 
		- How much extra HP is awarded to the zombie who kills the
		  humans through this grenade.

	- zp_zkill_bomb_extra_frags 1
		- No of Frags awarded to zombies who kill humans through this 
		  grenade.
	
	- zp_zkill_bomb_ammo_packs 1
		- No of Ammo packs awarded to zombies who kill humans through this
		  grenade

	- zp_zkill_bomb_nem 1
		- Whether a Nemesis should be given the nade
		
	- zp_zkill_bomb_assassin 1
		- Whether an Assassin should be given the nade

	---------------
	 *||DEFINES||*
	---------------

	- #define EDITTED_VERSION
		- Of u use the editted version of ZP with Sniper And Assassin
		  mode than uncomment this.
		 [U need the zombieplaguenew1.3 include for the editted version]

	---------------
	 *||CREDITS||*
	---------------

	- MeRcyLeZZ ----> For some of the code parts
	- NiHiLaNTh ----> For the concussion grenade plugin which was handy
	- Sn!ff3r ------> For the kill bomb plugin 
	- meTaLiCroSS --> For the colour printing function
			  For Fixing a major bug

	------------------
	 *||CHANGE LOG||*
	------------------
	
	v1.0 ====> Initial Release
	v1.1 ====> Added a cvar for whether a nemesis and assassin can 
		   have the nade.
		   Fixed the bug regarding HE grenades
	v1.1 ====> Added a define for EDITTED VERSIONS of ZP
		   Fixed a bug regarding the model 

\***************************************************************************/

// Needed for detecting servers with this plugin
#define FCVAR_FLAGS (FCVAR_SERVER | FCVAR_SPONLY | FCVAR_UNLOGGED)

new const NADE_TYPE_ZKILLBOMB = 7979

/************************************************************\
|                  Customizations Section                    |
|         You can edit here according to your liking         |
\************************************************************/

// This is for those who use the editted version of ZP
// If you use that version then uncomment this line
// By removing the two slashed ( // )
//#define EDITTED_VERSION

// Radius of the explosion of the bomb
// No need to change this [Default=240.0]
new const Float:RADIUS = 240.0

// The trail sprite of the bomb after it is thrown
new const sprite_grenade_trail[] = "sprites/laserbeam.spr"

// The explosion ring sprite
new const sprite_grenade_ring[] = "sprites/shockwave.spr"

// Cost of this grenade in ammo packs
new const item_cost = 20

// Name of this grenade in extra items
new const item_name[] = "Kill Bomb"

// Description of this grenade in extra items
new const item_description[] = "Kills humans"

// The sound emitted when someone buys the grenade
new const recieving_sound[] = "items/9mmclip1.wav"

// The sound emitted when the grenade explodes
new const kill_sound[] = "zombie_plague/grenade_infect.wav"

// Notice given to the player who buys the grenade
new const info_notice[] = { "You have brought a Kill Bomb. Enjoy killing humans !" }

// HUD message given to the player who is Nemesis or Assassin
new const info_notice2[] = { "You have a Kill Bomb. Use it to kill humans !" }

// Model of the grenade
new const model_grenade_infect[] = "models/zombie_plague/v_grenade_infect.mdl"

/************************************************************\
|                  Customizations Ends Here..!!              |
|         You can edit the cvars in the plugin init          |
\************************************************************/

#include <amxmodx>
#include <hamsandwich>
#include <cstrike>
#include <fakemeta_util>
#include <zmvip>
#if defined EDITTED_VERSION
	#include <zombieplaguenew1.3>
#else
	#include <zombieplague>
#endif

// Variables
new item_id
new has_bomb[33]
new cvar_fragsinfect, cvar_ammoinfect, cvar_humanbonushp , cvar_nemnade
#if defined EDITTED_VERSION
new cvar_assnade
#endif
new g_SyncMsg
new g_trailSpr, g_exploSpr, g_msgScoreInfo, g_msgDeathMsg, g_msgAmmoPickup, g_msgSayText 

/************************************************************\
|            [Plugin Initialization And Precache]            |
\************************************************************/

public plugin_init() 
{
	// Registrations
	register_plugin("[ZP] Kill Bomb For Zombies", "1.0", "@bdul!")
	RegisterHam(Ham_Think, "grenade", "fw_ThinkGrenade")
	RegisterHam(Ham_Killed, "player", "fw_PlayerKilled")
	register_forward(FM_SetModel, "fw_SetModel")	
	register_message(get_user_msgid("CurWeapon"), "message_cur_weapon")
	register_message(g_msgAmmoPickup, "message_ammopickup")
	register_event ( "HLTV", "event_round_start", "a", "1=0", "2=0" );
	
	// Cvars [You can edit these to you're liking]
	cvar_humanbonushp = register_cvar("zp_zkill_bomb_extra_hp","100")	
	cvar_fragsinfect = register_cvar("zp_zkill_bomb_extra_frags","1")
	cvar_ammoinfect = register_cvar("zp_zkill_bomb_ammo_packs","1")
	cvar_nemnade = register_cvar("zp_zkill_bomb_nem","1")
	#if defined EDITTED_VERSION
	cvar_assnade = register_cvar("zp_zkill_bomb_assassin","1")
	#endif
	
	// Add the cvar so we can detect it
	register_cvar ( "zp_zkill_bomb", "1.0", FCVAR_FLAGS )
	
	// Register it in the extra items
	item_id = zv_register_extra_item(item_name, item_description, item_cost, ZV_TEAM_ZOMBIE)
	
	// Messages needed for the plugin
	g_msgScoreInfo = get_user_msgid("ScoreInfo")
	g_msgDeathMsg = get_user_msgid("DeathMsg")
	g_msgAmmoPickup = get_user_msgid("AmmoPickup")
	g_msgSayText = get_user_msgid("SayText")
	
	g_SyncMsg = CreateHudSyncObj()
}

public plugin_precache()
{
	// Sprites precache
	g_trailSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_trail)
	g_exploSpr = engfunc(EngFunc_PrecacheModel, sprite_grenade_ring)
	
	// Model precache
	engfunc(EngFunc_PrecacheModel, model_grenade_infect)
	
	// Sounds precache
	engfunc(EngFunc_PrecacheSound, recieving_sound)
	engfunc(EngFunc_PrecacheSound, kill_sound)
	
}

/************************************************************\
|                     [Main Forwards]                        |
\************************************************************/

// New round started so reset the variable
public event_round_start()
{
	arrayset(has_bomb, false, 33)
}

// Client disconnected so reset the variable
public client_disconnect(id)
{
	has_bomb[id] = 0
}

// Someone was turned into nemesis
public zp_user_infected_post(id, infector)
{
	// Make sure it is a nemesis and the cvar is also on
	if (zp_get_user_nemesis(id) && (get_pcvar_num(cvar_nemnade) == 1))
		give_the_bomb(id) // Give him the bomb

	#if defined EDITTED_VERSION
	// Make sure it is an assassin and the cvar is also on
	else if (zp_get_user_assassin(id) && (get_pcvar_num(cvar_assnade) == 1))
		give_the_bomb(id) // Give him the bomb
	#endif
}

// Someone selected our extra item
public zv_extra_item_selected(id, itemid)
{
	// Make sure that the selected item is our item
	if(itemid == item_id)
	{	
		// Give him the bomb
		give_the_bomb(id)
	}
}

// The player turned back to a human
public zp_user_humanized_post ( Player, Survivor )
{
	// He doesn't haves the nade anymore
	if (has_bomb[Player])
		has_bomb[Player] = 0
}

// Player got killed reset the variable
public fw_PlayerKilled(victim, attacker, shouldgib)
{
	has_bomb[victim] = 0	
}

public fw_ThinkGrenade(entity)
{    
	if(!pev_valid(entity))
		return HAM_IGNORED
        
	static Float:dmgtime    
	pev(entity, pev_dmgtime, dmgtime)
    
	if (dmgtime > get_gametime())
		return HAM_IGNORED    
    
	if(pev(entity, pev_flTimeStepSound) == NADE_TYPE_ZKILLBOMB)
	{
		kill_explode(entity)
		return HAM_SUPERCEDE
	}
    
	return HAM_IGNORED
} 

public fw_SetModel(entity, const model[])
{
	static Float:dmgtime
	pev(entity, pev_dmgtime, dmgtime)
	
	if (dmgtime == 0.0)
		return
	
	if (equal(model[7], "w_sm", 4))
	{	
		// Check whos is the owner of the nade
		new owner = pev(entity, pev_owner)		
		
		// Make sure only a zombie can own it
		if(zp_get_user_zombie(owner) && has_bomb[owner]) 
		{	
			// Set the glow on the model
			fm_set_rendering(entity, kRenderFxGlowShell, 255, 128, 0, kRenderNormal, 16)
			
			// Set the trail sprite 
			message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
			write_byte(TE_BEAMFOLLOW) // TE id
			write_short(entity) // entity
			write_short(g_trailSpr) // sprite
			write_byte(10) // life
			write_byte(10) // width
			write_byte(255) // r
			write_byte(128) // g
			write_byte(0) // b
			write_byte(200) // brightness
			message_end()
			
			set_pev(entity, pev_flTimeStepSound, NADE_TYPE_ZKILLBOMB)
		}
	}
	
}

/************************************************************\
|                     [Main funtions]                        |
\************************************************************/

// Grenade has exploded
public kill_explode(ent)
{
	// Has the round started ?
	if (!zp_has_round_started()) return
	
	// Get the Origin
	static Float:originF[3]
	pev(ent, pev_origin, originF)
	
	// Create the blast
	create_blast(originF)
	
	// Emit explosion sound
	engfunc(EngFunc_EmitSound, ent, CHAN_ITEM, kill_sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
	
	// Get the attacker
	static attacker
	attacker = pev(ent, pev_owner)
	has_bomb[attacker] = 0
	
	// Collisions
	static victim , deathmsg_block
	
	// Get the current state of DeathMsg
	deathmsg_block = get_msg_block(g_msgDeathMsg)
	
	// Set it to be blocked [Bug Fix]
	set_msg_block(g_msgDeathMsg, BLOCK_SET)
	victim = -1
	
	#if defined EDITTED_VERSION
	while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, RADIUS)) != 0)
	{
		// If dead, zombie, survivor or sniper then continue the loop
		if (!is_user_alive(victim) || zp_get_user_zombie(victim) || zp_get_user_survivor(victim)|| zp_get_user_sniper(victim))
			continue;
		
		// Send the Death message
		SendDeathMsg(attacker, victim)
		
		// Update the frags
		UpdateFrags(attacker, victim, get_pcvar_num(cvar_fragsinfect), 1, 1)
		
		// Kill the victim
		user_kill(victim, 0)
		
		// Set the attackers ammo packs
		zp_set_user_ammo_packs(attacker,zp_get_user_ammo_packs(attacker) + get_pcvar_num(cvar_ammoinfect))
		
		// Set the attackers health
		fm_set_user_health(attacker, pev(attacker, pev_health)+get_pcvar_num(cvar_humanbonushp))
	}
	#else
	while ((victim = engfunc(EngFunc_FindEntityInSphere, victim, originF, RADIUS)) != 0)
	{
		// If dead, zombie, survivor then continue the loop
		if (!is_user_alive(victim) || zp_get_user_zombie(victim) || zp_get_user_survivor(victim))
			continue;
		
		// Send the Death message
		SendDeathMsg(attacker, victim)
		
		// Update the frags
		UpdateFrags(attacker, victim, get_pcvar_num(cvar_fragsinfect), 1, 1)
		
		// Kill the victim
		user_kill(victim, 0)
		
		// Set the attackers ammo packs
		zp_set_user_ammo_packs(attacker,zp_get_user_ammo_packs(attacker) + get_pcvar_num(cvar_ammoinfect))
		
		// Set the attackers health
		fm_set_user_health(attacker, pev(attacker, pev_health)+get_pcvar_num(cvar_humanbonushp))
	}
	#endif
	
	// Set the previous blocking state
	set_msg_block(g_msgDeathMsg, deathmsg_block)
	
	// Get the rid of the grenade
	engfunc(EngFunc_RemoveEntity, ent)
}

// This function creates the rings when the grenade explodes
public create_blast(const Float:originF[3])
{
	engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
	write_byte(TE_BEAMCYLINDER) // TE id
	engfunc(EngFunc_WriteCoord, originF[0]) // x
	engfunc(EngFunc_WriteCoord, originF[1]) // y
	engfunc(EngFunc_WriteCoord, originF[2]) // z
	engfunc(EngFunc_WriteCoord, originF[0]) // x axis
	engfunc(EngFunc_WriteCoord, originF[1]) // y axis
	engfunc(EngFunc_WriteCoord, originF[2]+385.0) // z axis
	write_short(g_exploSpr) // sprite
	write_byte(0) // startframe
	write_byte(0) // framerate
	write_byte(4) // life
	write_byte(60) // width
	write_byte(0) // noise
	write_byte(255) // red
	write_byte(128) // green
	write_byte(0) // blue
	write_byte(200) // brightness
	write_byte(0) // speed
	message_end()
	
	engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
	write_byte(TE_BEAMCYLINDER) // TE id
	engfunc(EngFunc_WriteCoord, originF[0]) // x
	engfunc(EngFunc_WriteCoord, originF[1]) // y
	engfunc(EngFunc_WriteCoord, originF[2]) // z
	engfunc(EngFunc_WriteCoord, originF[0]) // x axis
	engfunc(EngFunc_WriteCoord, originF[1]) // y axis
	engfunc(EngFunc_WriteCoord, originF[2]+470.0) // z axis
	write_short(g_exploSpr) // sprite
	write_byte(0) // startframe
	write_byte(0) // framerate
	write_byte(4) // life
	write_byte(60) // width
	write_byte(0) // noise
	write_byte(255) // red
	write_byte(164) // green
	write_byte(0) // blue
	write_byte(200) // brightness
	write_byte(0) // speed
	message_end()
	
	engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
	write_byte(TE_BEAMCYLINDER) // TE id
	engfunc(EngFunc_WriteCoord, originF[0]) // x
	engfunc(EngFunc_WriteCoord, originF[1]) // y
	engfunc(EngFunc_WriteCoord, originF[2]) // z
	engfunc(EngFunc_WriteCoord, originF[0]) // x axis
	engfunc(EngFunc_WriteCoord, originF[1]) // y axis
	engfunc(EngFunc_WriteCoord, originF[2]+555.0) // z axis
	write_short(g_exploSpr) // sprite
	write_byte(0) // startframe
	write_byte(0) // framerate
	write_byte(4) // life
	write_byte(60) // width
	write_byte(0) // noise
	write_byte(255) // red
	write_byte(200) // green
	write_byte(0) // blue
	write_byte(200) // brightness
	write_byte(0) // speed
	message_end()
}

// Updates the frags of the attacker
public UpdateFrags(attacker, victim, frags, deaths, scoreboard)
{
	// Set the frags
	set_pev(attacker, pev_frags, float(pev(attacker, pev_frags) + frags))
	
	// Set the deaths
	fm_set_user_deaths(victim, fm_get_user_deaths(victim) + deaths)
	
	// Update scoreboard
	if (scoreboard)
	{	
		message_begin(MSG_BROADCAST, g_msgScoreInfo)
		write_byte(attacker) // id
		write_short(pev(attacker, pev_frags)) // frags
		write_short(fm_get_user_deaths(attacker)) // deaths
		write_short(0) // class?
		write_short(fm_get_user_team(attacker)) // team
		message_end()
		
		message_begin(MSG_BROADCAST, g_msgScoreInfo)
		write_byte(victim) // id
		write_short(pev(victim, pev_frags)) // frags
		write_short(fm_get_user_deaths(victim)) // deaths
		write_short(0) // class?
		write_short(fm_get_user_team(victim)) // team
		message_end()
	}
}

// Send the death message
public SendDeathMsg(attacker, victim)
{
	message_begin(MSG_BROADCAST, g_msgDeathMsg)
	write_byte(attacker) // killer
	write_byte(victim) // victim
	write_byte(0) // headshot flag
	write_string("infection") // killer's weapon
	message_end()
}

// Replace models
public replace_models(id)
{
	if (!is_user_alive(id))
		return
	
	if(get_user_weapon(id) == CSW_SMOKEGRENADE && has_bomb[id])
	{
		set_pev(id, pev_viewmodel2, model_grenade_infect)
		
	}
}

public message_cur_weapon(msg_id, msg_dest, msg_entity)
{
	replace_models(msg_entity)
}

give_the_bomb(id)
{
	// Now he haves the bomb!
	has_bomb[id] = 1
	
	#if defined EDITTED_VERSION
	// Make sure that the person is not an Assassin or Nemesis
	if (!zp_get_user_nemesis(id) && !zp_get_user_assassin(id))
		// Notify him
		zp_colored_print(id, "|g|[ZP]|y| %s", info_notice)
	#else  // Person is using a normal ZP 4.3
	// Make sure that the person is not a Nemesis
	if (!zp_get_user_nemesis(id))
		// Notify him
		zp_colored_print(id, "|g|[ZP]|y| %s", info_notice)
	#endif
	
	#if defined EDITTED_VERSION
	// If the person is Nemesis or Assassin notify him through HUD message
	if (zp_get_user_nemesis(id) || zp_get_user_assassin(id))
	{
		set_hudmessage(250, 120, 5, -1.0, 0.25, 2, 2.0, 10.0)
		ShowSyncHudMsg(id, g_SyncMsg,"%s", info_notice2)
	}
	#else // Person is using a normal ZP 4.3
	// If the person is Nemesis notify him through HUD message
	if (zp_get_user_nemesis(id))
	{
		set_hudmessage(250, 120, 5, -1.0, 0.25, 2, 2.0, 10.0)
		ShowSyncHudMsg(id, g_SyncMsg,"%s", info_notice2)
	}
	#endif
	
	// Already own one
	if (user_has_weapon(id, CSW_SMOKEGRENADE))
	{
		// Increase BP ammo on it instead
		cs_set_user_bpammo(id, CSW_SMOKEGRENADE, cs_get_user_bpammo(id, CSW_SMOKEGRENADE) + 1)
		
		// Flash the ammo in hud
		message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoPickup, _, id)
		write_byte(CSW_SMOKEGRENADE)
		write_byte(1)
		message_end()
		
		// Play Clip Purchase Sound
		engfunc(EngFunc_EmitSound, id, CHAN_ITEM, recieving_sound, 1.0, ATTN_NORM, 0, PITCH_NORM)
	}
	else
		// Give weapon to the player
		fm_give_item(id, "weapon_smokegrenade")
}

/************************************************************\
|                     [Stock funtions]                       |
\************************************************************/

stock fm_set_user_deaths(id, value)
{
	set_pdata_int(id, 444, value, 5)
}

stock fm_get_user_deaths(id)
{
	return get_pdata_int(id, 444, 5)
}


stock fm_get_user_team(id)
{
	return get_pdata_int(id, 114, 5)
}

// Prints chat in colours [ BY meTaLiCroSS ]
stock zp_colored_print(const id, const input[], any:...)
{
	new iCount = 1, iPlayers[32]
	
	static szMsg[191]
	vformat(szMsg, charsmax(szMsg), input, 3)
	
	replace_all(szMsg, 190, "|g|", "^4") // green txt
	replace_all(szMsg, 190, "|y|", "^1") // orange txt
	replace_all(szMsg, 190, "|ctr|", "^3") // team txt
	replace_all(szMsg, 190, "|w|", "^0") // team txt
	
	if(id) iPlayers[0] = id
	else get_players(iPlayers, iCount, "ch")
		
	for (new i = 0; i < iCount; i++)
	{
		if (is_user_connected(iPlayers[i]))
		{
			message_begin(MSG_ONE_UNRELIABLE, g_msgSayText, _, iPlayers[i])
			write_byte(iPlayers[i])
			write_string(szMsg)
			message_end()
		}
	}
}
Le-am pus doar pe cele care nu este nevoie de model sau orice alta resursa.

Versiunea 1.8.2: Pentru că este clar scris că acest mod funcționează și compilează doar cu 1.8.3 amxmodx.
Foloseste asta. Ar trebui să lucreze și să compileze cu 1.8.2

zm_vip.sma

Code: Select all

/* Plugin generated by AMXX-Studio */
/* -------------------------------------------------------------------------------------------------

             _____    __  ___   _    __ ____ ____     ___      ____     ____ 
            /__  /   /  |/  /  | |  / //  _// __ \   |__ \    / __ \   / __ \
              / /   / /|_/ /   | | / / / / / /_/ /   __/ /   / / / /  / / / /
             / /__ / /  / /    | |/ /_/ / / ____/   / __/ _ / /_/ /_ / /_/ / 
            /____//_/  /_/     |___//___//_/       /____/(_)\____/(_)\____/  
								BETA VERSION!!!
	    
	Zombie Plague 4.3/5.0 Addon
	ZM VIP - Zombie Plague VIP addon that enables special abilities for players
	and adds VIP system, status and API to server.
	
	Official thread: https://forums.alliedmods.net/showthread.php?t=119719
	
	Author: aaarnas

--------------------------------------------------------------------------------------------------*/

// Ignore thease. Just values for settings.
#define OFF 0
#define ON 1
#define FORCED 2
#define NEW 1
#define OLD 2
#define VAULT 1

#define VERSION "1.9.1 CUSTOM"

// --------------- USER CONFIGURATION START --------------- USER CONFIGURATION START ---------------
// --------------- USER CONFIGURATION START --------------- USER CONFIGURATION START ---------------
// --------------- USER CONFIGURATION START --------------- USER CONFIGURATION START ---------------
// --------------- USER CONFIGURATION START --------------- USER CONFIGURATION START ---------------
// -------------------------------------------------------------------------------------------------
// Choose your using zombie plague version:
// NEW		- Zombie Plague 5.0 or later. (zp_plugin_50.zip | zp508a.zip and later ... )
// OLD		- Zombie Plague 4.3 or earlier. (zp_plugin_43.zip)
// Zombie Plague Advanced - Not supported.
// Daugiau pluginu https://forums.alliedmods.net/showthread.php?t=242196?t=242196

#define MODIFICATION NEW
// -------------------------------------------------------------------------------------------------
// Set wich system to use loading privileges:
// FORCED - Just vips.ini file. Ignores amxmodx.
// ON   - vips.ini and amxmodx (users.ini/database (flag t))
// OFF  - Disables vips.ini file and reads only from amxmodx (users.ini/database (flag t))
#define VIPS_FILE_SYSTEM ON
// -------------------------------------------------------------------------------------------------
// Set if you want to enable extra items menu system (/vm)
// ON  - Enabled
// OFF - Dissabled
#define EXTRA_ITEMS ON
// -------------------------------------------------------------------------------------------------
// Vip privileges flag in users.ini file (t) if NOT using VIPS_FILE_SYSTEM [FORCED] mode. 
#define VIP_SYS_FLAG ADMIN_LEVEL_H
// -------------------------------------------------------------------------------------------------
// Admin flag (from users.ini). Allow access to VIP admin panel, zm_vip_freevip_hour cvar(cmd). 
#define ADMIN_SYS_FLAG ADMIN_LEVEL_E //(ADMIN_LEVEL_E flag is "q")
// -------------------------------------------------------------------------------------------------
// Name of configs/vips.ini|zm_cip.cfg file. In fact, no reason to change.
#define VIPS_FILE "vips.ini"
#define CONFIGS_FILE "zm_vip.cfg"
// -------------------------------------------------------------------------------------------------
//--------------- USER CONFIGURATION END --------------- USER CONFIGURATION END ---------------
//--------------- USER CONFIGURATION END --------------- USER CONFIGURATION END ---------------
//--------------- USER CONFIGURATION END --------------- USER CONFIGURATION END ---------------
//--------------- USER CONFIGURATION END --------------- USER CONFIGURATION END ---------------
//--------------- USER CONFIGURATION END --------------- USER CONFIGURATION END ---------------
//////////////////////////// Editing anyting further - taking own risk /////////////////////////////
////////// This means - no support. Using/stealing anything without credits - not allowed //////////

#define EMPTY(%1) (%1[0]==EOS)
#define BIT(%1) (1<<%1)
#define FLAG_A (1<<0)
#define FLAG_B (1<<1)
#define FLAG_C (1<<2)
#define FLAG_D (1<<3)
#define FLAG_E (1<<4)
#define FLAG_F (1<<4)
#define FLAG_K (1<<10)
#define FLAG_N (1<<13)

#define LOAD_FROM_INI	(1<<31)
#define LOAD_FROM_DAT	(1<<30)
#define LOAD_FROM_AMX	(1<<29)
#define LOAD_FROM_NAMES	(1<<28)
#define LOAD_FROM_MAIN	(1<<27)
#define LOAD_MASK	0xFC000000

#include <amxmodx>
#include <amxmisc>
#include <hamsandwich>
#include <fakemeta>
#include <engine>
#include <fun>
#include <regex>
#if MODIFICATION == NEW
#include <cstrike>
#define ZP_ITEM_AVAILABLE 0
#define ZP_ITEM_NOT_AVAILABLE 1
#define ZP_ITEM_DONT_SHOW 2
#define ZP_CLASS_AVAILABLE 0
#define ZP_CLASS_NOT_AVAILABLE 1
#define ZP_CLASS_DONT_SHOW 2
native zp_core_is_zombie(id)
forward zp_fw_core_spawn_post(id)
forward zp_fw_core_infect_pre(id, attacker)
forward zp_fw_core_infect_post(id, attacker)
forward zp_fw_core_cure_post(id, attacker)
native zp_ammopacks_get(id)
native zp_ammopacks_set(id, amount) 
native zp_class_human_menu_text_add(const text[])
forward zp_fw_class_human_select_pre(id, classid)
native zp_class_human_register(const name[], const description[], health, Float:speed, Float:gravity)
native zp_class_zombie_menu_text_add(const text[])
forward zp_fw_class_zombie_select_pre(id, classid)
native zp_class_zombie_register(const name[], const description[], health, Float:speed, Float:gravity)
native zp_items_register(const name[], cost)
forward zp_fw_items_select_pre(id, itemid, ignorecost)
forward zp_fw_items_select_post(id, itemid, ignorecost)
native zp_items_show_menu(id)
native zp_items_menu_text_add(const text[]) 
native cs_set_player_model(id, const model[])
forward zp_fw_grenade_fire_pre(id)
forward zp_fw_grenade_frost_pre(id)
#else
native zp_get_user_bombardier(id)
#define ZP_TEAM_ANY 0
native zp_get_user_zombie(id)
native zp_get_user_next_class(id)
native zp_set_user_zombie_class(id, classid)
native zp_register_zombie_class(const name[], const info[], const model[], const clawmodel[], hp, speed, Float:gravity, Float:knockback)
native zp_override_user_model(id, const newmodel[], modelindex = 0)
native zp_get_user_nemesis(id)
native zp_get_user_survivor(id)
forward zp_user_infect_attempt(id, infector, nemesis)
forward zp_user_infected_post(id, infector, nemesis)
forward zp_user_humanized_post(id, survivor)
forward zp_user_infected_pre(id, infector, nemesis)
forward zp_extra_item_selected(id, itemid)
forward zp_round_started(gamemode, id)
native zp_register_extra_item(const name[], cost, teams)
native zp_force_buy_extra_item(id, itemid, ignorecost = 0)
native zp_get_extra_item_id(const name[])
native zp_get_user_ammo_packs(id)
native zp_set_user_ammo_packs(id, amount)
#define ZP_PLUGIN_HANDLED 97
#endif

new cvar_multijump, cvar_multijump_allow, cvar_armor, cvar_extra_hp_human, cvar_extra_hp_zombie,
cvar_extra_gravity_human, cvar_extra_gravity_zombie ,cvar_unlimited_clip, cvar_no_fall_dmg, 
cvar_extra_dmg, cvar_extra_frags, cvar_extra_kill_ammo, cvar_extra_armor, cvar_extra_infect_ammo,
cvar_extra_infect_health, cvar_extra_ignore_for_special, cvar_damage_reward, cvar_viponly_class,
cvar_chat_viptag, cvar_vip_connected_to_server, cvar_freevip_flags, cvar_vipniscoretable,
cvar_grenades_immunity, cvar_gamemode_disable_flags
#if VIPS_FILE_SYSTEM != FORCED
new cvar_amx_auth_flags
#endif
#if VIPS_FILE_SYSTEM != OFF
new cvar_vip_store_ini
#endif
new cvar_amxmodx_flags, cvar_vip_price, cvar_vip_buy_duration, cvar_vip_buy_flags,
cvar_vip_buy_in_extra_items

#if EXTRA_ITEMS == ON
new cvar_buys_per_round
#if MODIFICATION == OLD
new chached_show_vip_items
#else
new cvar_vip_show_vip_items
#endif
#endif

enum _:player_attributes
{
	AT_MULTIJUMP,		//a(0)
	AT_ARMOR,		//b(1)
	AT_UNLIMITED_CLIP,	//c(2)
	AT_NO_FALL_DMG,		//d(3)
	AT_DAMAGE_REWARD,	//e(4)
	AT_EXTRA_DMG,		//f(5)
	AT_EXTRA_HP,		//g(6)
	AT_EXTRA_GRAVITY,	//h(7)
	AT_EXTRA_FRAGS,		//i(8)
	AT_EXTRA_KILL_AMMO,	//j(9)
	AT_EXTRA_ARMOR,		//k(10)
	AT_EXTRA_INFECT_AMMO,	//l(11)
	AT_EXTRA_INFECT_HEALTH,	//m(12)
	AT_EXTRA_ITEMS,		//n(13)
	AT_VIP_MODEL,		//o(14)
	AT_VIP_CLASS,		//p(15)
	AT_CHATTAG,		//q(16)
	AT_VIPINSCORE,		//r(17)
	AT_GRENADE_IMMUNITY	//s(18)
}

new p_attribs[33][player_attributes]

#define AT_NONE		(1<<25) // z

#define ZV_DURATION_IGNORE		-1
#define ZV_DURATION_PERMANENT		0
#define ZV_DURATION_TILL_DISCONNECT	~'t'
#define ZV_DURATION_TILL_MAP		~('t'|'m')

enum ClassType:cltypes {
	EXTRA_ITEM = 1,
	CLASS_ZOMBIE,
	CLASS_HUMAN
}
#define VipsItemHandle trie_vip_items
new Trie:trie_vip_items

new p_bought_per_round[33]
new bool:p_zombie[33]
new p_jumpsnum[33]
new Float:p_damage[33]
new Float:p_grenade_time[33]

new p_vip_model_zombie[15]
new p_vip_model_human[15]

#if MODIFICATION == NEW
new is_module_ammopacks_loaded
#endif

new Trie:trie_vips_database
new Array:array_vips_database
new Array:array_vips_database_nick
new amx_password_field_string[30]
enum _:VipCnt {
	
	INI,
	DAT,
	MAIN,
	NAMES,
	AMX
}
new total_vips_count[VipCnt] //0 - main, 1 - names, 2 - amx
#define VIPCNT(%1) total_vips_count[%1]
#define VIPINC(%1) total_vips_count[%1]++
#define VIPDEC(%1) total_vips_count[%1]--
enum _:vips_database_type
{
	AUTH[40],
	PASS[30],
	SETTINGS,
	FLAGS,
	TIMESTAMP,
	INDEX
}
new p_data[33][vips_database_type]

#if EXTRA_ITEMS == ON
new registered_extra_items_num
#if MODIFICATION == NEW
new bool:p_views_extra_items_menu[33]
#else
enum _:item_struct {
	
	item_plid,
	item_name[100],
	item_cost,
	item_team
}
#define ZP_TEAM_ZOMBIE (1<<0)
#define ZP_TEAM_HUMAN (1<<1)
#define ZP_TEAM_NEMESIS (1<<2)
#define ZP_TEAM_SURVIVOR (1<<3)
new Array:array_vip_extra_items
new fw_extraitemselected
#endif
#endif

new vip_buy_extra_item = -1

new current_gamemode

new bool:freevip_enabled
new bool:freevip_inform[33]
new bool:first_spawn[33]
new freevip_hours[4]
new maxplayers
new msg_saytext
new msg_scoreattrib

new const MAXCLIP[] = { -1, 13, -1, 10, 1, 7, -1, 30, 30, 1, 30, 20, 25, 30, 35, 25, 12, 20, 10, 30, 100, 8, 30, 30, 20, 2, 7, 30, 30, -1, 50 }

#define IS_PLAYER(%1) (1<=%1<=maxplayers)
#define ATTRIB(%1,%2) p_attribs[%1][%2]

#define CURRENCY_MONEY 0
#define CURRENCY_AMMO_PACKS 1
public plugin_init() {
	
	register_plugin("ZM VIP", VERSION, "aaarnas") 
	register_dictionary("zm_vip.txt")
	
	/////////////////////// CVARS REGISTRATION ///////////////////////
	cvar_multijump = register_cvar("zm_vip_mutijump", "1")
	cvar_multijump_allow = register_cvar("zm_vip_multijump_allow", "ab")
	cvar_armor = register_cvar("zm_vip_armor", "65")
	cvar_unlimited_clip = register_cvar("zm_vip_unlimited_clip", "0")
	cvar_no_fall_dmg = register_cvar("zm_vip_no_fall_dmg", "1")
	cvar_extra_dmg = register_cvar("zm_vip_extra_dmg", "1.2")
	cvar_extra_hp_human = register_cvar("zm_vip_extra_hp_human", "50")
	cvar_extra_hp_zombie = register_cvar("zm_vip_extra_hp_zombie", "500")
	cvar_extra_gravity_human = register_cvar("zm_vip_extra_gravity_human", "0")
	cvar_extra_gravity_zombie = register_cvar("zm_vip_extra_gravity_zombie", "0")
	cvar_extra_frags = register_cvar("zm_vip_extra_frags", "0")
	cvar_extra_kill_ammo = register_cvar("zm_vip_extra_kill_ammo", "1")
	cvar_extra_armor = register_cvar("zm_vip_extra_armor", "0")
	cvar_extra_infect_ammo = register_cvar("zm_vip_extra_infect_ammo", "1")
	cvar_extra_infect_health = register_cvar("zm_vip_extra_infect_health", "100")
	cvar_extra_ignore_for_special = register_cvar("zm_vip_extra_ignore_for_special", "1")
	cvar_damage_reward = register_cvar("zm_vip_damage_reward", "1000")
	cvar_viponly_class = register_cvar("zm_viponly_class", "1")
	cvar_chat_viptag = register_cvar("zm_vip_chattag", "1")
	cvar_vip_connected_to_server = register_cvar("zm_vip_connected_to_server", "1") // 1-chat/2-hud/3-dhud
	cvar_vipniscoretable = register_cvar("zm_vipinscoretable", "1")
#if VIPS_FILE_SYSTEM != FORCED
	cvar_amx_auth_flags = register_cvar("zm_vip_amx_auth_flags", "0") 
#endif
	cvar_amxmodx_flags = register_cvar("zm_vip_amxmodx_flags", "t")
	cvar_grenades_immunity = register_cvar("zm_vip_grenades_immunity", "0")
	cvar_gamemode_disable_flags = register_cvar("zm_vip_gamemode_disable_flags", "0")
	register_concmd("zm_vip_freevip_hour", "set_freevip_hour", ADMIN_CVAR)
	cvar_freevip_flags = register_cvar("zm_vip_freevip_flags", "0")
#if VIPS_FILE_SYSTEM != OFF
	cvar_vip_store_ini = register_cvar("zm_vip_store_ini", "0")
#endif
	cvar_vip_price = register_cvar("zm_vip_price", "0")
	cvar_vip_buy_duration = register_cvar("zm_vip_buy_duration", "1d") // 1h - val, 1d - day// t - tepm/ tm - temp till map
	
	cvar_vip_buy_flags = register_cvar("zm_vip_buy_flags", "0")
	cvar_vip_buy_in_extra_items = register_cvar("zm_vip_buy_in_extra_items", "1")
	
#if EXTRA_ITEMS == ON
	cvar_buys_per_round = register_cvar("zm_vip_buys_per_round", "0")
#if MODIFICATION == NEW
	cvar_vip_show_vip_items = register_cvar("zm_vip_show_vip_items", "2")
#endif
#if MODIFICATION != NEW
	fw_extraitemselected = CreateMultiForward("zv_extra_item_selected", ET_CONTINUE, FP_CELL, FP_CELL)
#endif
#endif	
	maxplayers = get_maxplayers()
	
	msg_saytext = get_user_msgid("SayText")
	msg_scoreattrib = get_user_msgid("ScoreAttrib")
	
	register_clcmd("say /vm", "show_vip_menu")
	register_clcmd("open_vip_menu", "show_vip_menu_console")
	register_clcmd("say /vip", "show_vip_info")
	register_clcmd("say /vips", "show_vips_online")
	
	register_concmd("zm_vip_list", "cmd_list_vips", ADMIN_SYS_FLAG)
	register_concmd("amx_reloadvips", "cmd_vips_reload", ADMIN_SYS_FLAG)
	register_concmd("zm_vip_reload", "cmd_vips_reload", ADMIN_SYS_FLAG)
	register_concmd("zm_vip_remove", "cmd_vips_remove", ADMIN_SYS_FLAG)
	
	register_menu("Menu Buy", MENU_KEY_0|MENU_KEY_1, "forward_buy_menu_handler")
	
	register_event("HLTV", "forward_event_round_start", "a", "1=0", "2=0")
	register_event("DeathMsg", "forward_event_deathmsg", "a")
	register_event("ResetHUD", "forward_event_reset_hud", "be")
	register_message(get_user_msgid("CurWeapon"), "message_cur_weapon")
	register_message(msg_saytext, "message_say_text")
	register_forward(FM_CmdStart, "forward_cmdstart")
#if MODIFICATION != NEW
	RegisterHam(Ham_Spawn, "player", "forward_player_spawn", 1)
#endif
	RegisterHam(Ham_TakeDamage, "player", "forward_player_takedamage_pre")
	RegisterHam(Ham_TakeDamage, "player", "forward_player_takedamage_post", 1)
	RegisterHam(Ham_Think, "grenade", "forward_grenade_think")
	
	trie_vips_database = TrieCreate()
	array_vips_database = ArrayCreate(45, 15)
	
	register_cvar("zp_vip_version", VERSION, FCVAR_SERVER|FCVAR_SPONLY)
	set_cvar_string("zp_vip_version", VERSION)
}

public plugin_natives() {

	register_library("zm_vip")

	set_native_filter("native_filter")
	
	register_native("zv_get_user_flags", "native_zv_get_user_flags")
	register_native("zv_set_user_flags", "native_zv_set_user_flags")
	register_native("zv_remove_user_flags", "native_zv_remove_user_flags")

#if MODIFICATION == NEW
#if EXTRA_ITEMS == ON
	register_native("zv_items_register", "native_zv_items_register", 1)
#endif
	register_native("zv_class_human_register", "native_zv_class_human_register", 1)
	register_native("zv_class_zombie_register", "native_zv_class_zombie_register", 1)
#else
	register_native("zv_register_zombie_class", "native_zv_register_zombie_class", 1)
#if EXTRA_ITEMS == ON	
	register_native("zv_register_extra_item", "native_zv_register_extra_item", 1)
	register_native("zv_register_extra_item2", "native_zv_register_extra_item2", 1)
	register_native("zv_force_buy_extra_item", "native_zv_force_buy_extra_item", 1)
	register_native("zv_get_extra_item_id", "native_zv_get_extra_item_id", 1)
#endif
#endif
}
#if MODIFICATION == NEW
native zp_class_nemesis_get(id)
native zp_class_survivor_get(id)
native zp_class_assassin_get(id)
native zp_class_sniper_get(id)
#endif
new natives_filter_out
enum {
	NATIVE_ZP_CLASS_NEMESIS_GET,
	NATIVE_ZP_CLASS_SURVIVOR_GET,
	NATIVE_ZP_CLASS_ASSASSIN_GET,
	NATIVE_ZP_CLASS_SNIPER_GET,
	NATIVE_ZP_CLASS_BOMBARDIER_GET,
	NATIVE_OVERRIDE_USER_MODEL
}
public native_filter(const name[], index, trap) {
	
	if (!trap) {
#if MODIFICATION == NEW
		if (equal(name, "zp_class_nemesis_get")) natives_filter_out |= BIT(NATIVE_ZP_CLASS_NEMESIS_GET)
		else if(equal(name, "zp_class_survivor_get")) natives_filter_out |= BIT(NATIVE_ZP_CLASS_SURVIVOR_GET)
		else if(equal(name, "zp_class_assassin_get")) natives_filter_out |= BIT(NATIVE_ZP_CLASS_ASSASSIN_GET)
		else if(equal(name, "zp_class_sniper_get")) natives_filter_out |= BIT(NATIVE_ZP_CLASS_SNIPER_GET)
#else
		if (equal(name, "zp_get_user_bombardier")) natives_filter_out |= BIT(NATIVE_ZP_CLASS_BOMBARDIER_GET)
#endif
#if MODIFICATION == OLD
		else if (equal(name, "zp_override_user_model")) {
			p_vip_model_zombie[0] = EOS
			p_vip_model_human[0] = EOS
			log_amx("ERROR: Vip models are not compatible with old Zombie Plague 4.3 version. Use Zombie Plague 4.3 patched or 5.0 to enable this feature.")
			log_amx("Download: https://forums.alliedmods.net/showthread.php?t=72505"&#41;
			natives_filter_out |= BIT(NATIVE_OVERRIDE_USER_MODEL)
		}
		else if (equal(name, "zp_get_user_zombie")) {
			set_fail_state("ERROR: This plugin compiled with MODIFICATION - OLD setting. \
			This supports only Zombie plague 4.3 versions.^nPlugin was unable to\
			detect this version, so probably, modification is incorrect.")
		}
#endif
		else {
			return PLUGIN_CONTINUE;
		}
		return PLUGIN_HANDLED;
			
	}
	return PLUGIN_CONTINUE;
}

public plugin_precache() {
#if EXTRA_ITEMS == ON && MODIFICATION == OLD
	new value_str[5]
	read_config("zm_vip_show_vip_items", value_str, charsmax(value_str))
	chached_show_vip_items = str_to_num(value_str)
#endif	
#if MODIFICATION == NEW
	read_config("zm_vip_model_zombie", p_vip_model_zombie, charsmax(p_vip_model_zombie))
	read_config("zm_vip_model_human", p_vip_model_human, charsmax(p_vip_model_human))

	if (!EMPTY(p_vip_model_zombie)) {
		
		new model_path[128]
		formatex(model_path, charsmax(model_path), "models/player/%s/%s.mdl", p_vip_model_zombie, p_vip_model_zombie)
		precache_model(model_path)
		formatex(model_path, charsmax(model_path), "models/player/%s/%sT.mdl", p_vip_model_zombie, p_vip_model_zombie)
		if (file_exists(model_path)) precache_model(model_path)
	}
	if (!EMPTY(p_vip_model_human)) {
		
		new model_path[128]
		formatex(model_path, charsmax(model_path), "models/player/%s/%s.mdl", p_vip_model_human, p_vip_model_human)
		precache_model(model_path)
		formatex(model_path, charsmax(model_path), "models/player/%s/%sT.mdl", p_vip_model_human, p_vip_model_human)
		if (file_exists(model_path)) precache_model(model_path)
	}
#endif
}
public plugin_cfg() {
#if MODIFICATION == NEW	

	if (!LibraryExists("zp50_core", LibType_Library))
		set_fail_state("ERROR: This plugin compiled with MODIFICATION - NEW setting. \
		This supports only Zombie plague 5 version and higher.^nPlugin was unable to\
		detect main Zombie Plague Core plugin.")
		
	is_module_ammopacks_loaded = LibraryExists("zp50_ammopacks", LibType_Library)
#endif
	new file_link[45]
	get_configsdir(file_link, charsmax(file_link))
	format(file_link, charsmax(file_link), "%s/%s", file_link, CONFIGS_FILE)
	if (file_exists(file_link)) {
		server_cmd("exec %s", file_link)
		server_exec()
	}
	else {
		log_amx("WARNING: Missing ^"%s^" file in configs folder. Can't load cvars values.", CONFIGS_FILE)
	}
	
	get_cvar_string("amx_password_field", amx_password_field_string, charsmax(amx_password_field_string))
#if VIPS_FILE_SYSTEM != OFF
	load_ini_file()
#endif
	load_datafile()
		
#if VIPS_FILE_SYSTEM != FORCED
	new num = admins_num()
	for (new i=0; i<num; i++) {
		if (admins_lookup(i, AdminProp_Access)&VIP_SYS_FLAG) {
			VIPINC(AMX)
		}
	}
#endif
	if (!VIPCNT(DAT) && !VIPCNT(INI) && !VIPCNT(AMX))
		log_amx("WARNING: No VIPs loaded from zm_vip system. Maybe there aren't any.")
		
	if (get_pcvar_num(cvar_vip_price) > 0 && get_pcvar_num(cvar_vip_buy_in_extra_items)) {
		
		new buy_vip_text[30], langid = LANG_SERVER
		LookupLangKey(buy_vip_text, charsmax(buy_vip_text), "BUY_VIP", langid)
#if MODIFICATION == NEW
		vip_buy_extra_item = zp_items_register(buy_vip_text, get_pcvar_num(cvar_vip_price))
#else
		vip_buy_extra_item = zp_register_extra_item(buy_vip_text, get_pcvar_num(cvar_vip_price), ZP_TEAM_ANY)
#endif
	}
	
#if EXTRA_ITEMS == ON
	if (!registered_extra_items_num)
		log_amx("WARRNING: No vip extra item plugins loaded.")
#endif
	set_task(1.0, "vip_time_check", 0, _, _, "b")
	
	server_print("-------------------------------------------------------------------------------")
	server_print("This server using ZM VIP %s by aaarnas", VERSION)
	server_print("Successfully loaded %d VIPs", VIPCNT(DAT)+VIPCNT(INI)+VIPCNT(AMX))
	server_print("-------------------------------------------------------------------------------")
}

_get_pcvar_flags(pcvar) {

	new flags[30]
	get_pcvar_string(pcvar, flags, charsmax(flags))
	
	if (flags[0] == '0')
		return 0;
	
	return read_flags(flags);
}
set_user_atribs(id, double_attrib_update = false) {
	
	if (id == 0) return;
		
	new hour_flags = 0
	
	new gamemode_disable_flags = 0
	if (current_gamemode != 0) {
		gamemode_disable_flags = _get_pcvar_flags(cvar_gamemode_disable_flags)
	}
	
	if(freevip_enabled && freevip_hour_check()) {
			
		hour_flags = _get_pcvar_flags(cvar_freevip_flags)
		if (hour_flags == 0)
			hour_flags = -1
		
		if (!freevip_inform[id]) {
			freevip_inform[id] = true
			client_print_color(id, id, "^4[ZMVIP] ^1%L!", id, "FREE_VIP_GOT")
			client_cmd(id, "spk /sound/buttons/bell1.wav")
		}
	}
	else if (freevip_inform[id]) {
		freevip_inform[id] = false
		client_print_color(id, id, "^4[ZMVIP] ^1%L...", id, "FREE_VIP_EXPIRED")
		client_cmd(id, "spk /sound/buttons/blip1.wav")
	}
	
	static i, d, value
	static const double_attribs[] = {
		AT_MULTIJUMP,
		AT_EXTRA_HP,
		AT_EXTRA_GRAVITY
	}
	d = 0
	
	for(i=0; i<player_attributes;) {
		
		if (double_attrib_update) {
			
			if (d >= sizeof(double_attribs))
				break;
				
			i = double_attribs[d++];
		}	
		
		if (p_data[id][FLAGS] == 0 && hour_flags == 0)
			break;
		
		if (!(BIT(i) & p_data[id][FLAGS]) && !(BIT(i) & hour_flags) || (BIT(i) & gamemode_disable_flags)) {
			i++
			continue;
		}
		
		value = 0
		switch(i) {
			case AT_MULTIJUMP: {
				new jnum = get_pcvar_num(cvar_multijump)
				if(jnum) {
					static nflags, isspecial
					nflags = _get_pcvar_flags(cvar_multijump_allow)
					isspecial = is_special_character(id)
					
					if((nflags & FLAG_A && !p_zombie[id]) || (nflags & FLAG_B && p_zombie[id]) && !isspecial) value = jnum
					else if((nflags & FLAG_C && !p_zombie[id]) || (nflags & FLAG_D && p_zombie[id]) && isspecial) value = jnum
				}
			}
			case AT_ARMOR: value = get_pcvar_num(cvar_armor)
			case AT_UNLIMITED_CLIP: value = get_pcvar_num(cvar_unlimited_clip)
			case AT_NO_FALL_DMG: value = get_pcvar_num(cvar_no_fall_dmg)
			case AT_EXTRA_DMG: value = ((get_pcvar_float(cvar_extra_dmg)>0)?1:0)
			case AT_EXTRA_HP: value = get_pcvar_num(p_zombie[id]?cvar_extra_hp_zombie:cvar_extra_hp_human)
			case AT_EXTRA_GRAVITY: value = (get_pcvar_float(p_zombie[id]?cvar_extra_gravity_zombie:cvar_extra_gravity_human)>0.0)?1:0
			case AT_EXTRA_FRAGS: value = get_pcvar_num(cvar_extra_frags)
			case AT_EXTRA_KILL_AMMO: value = get_pcvar_num(cvar_extra_kill_ammo)
			case AT_EXTRA_ARMOR: value = get_pcvar_num(cvar_extra_armor)
			case AT_EXTRA_INFECT_AMMO: value = get_pcvar_num(cvar_extra_infect_ammo)
			case AT_EXTRA_INFECT_HEALTH: value = get_pcvar_num(cvar_extra_infect_health)
#if EXTRA_ITEMS == ON
			case AT_EXTRA_ITEMS: value = p_data[id][FLAGS]?1:0
#endif
			case AT_DAMAGE_REWARD: value = get_pcvar_num(cvar_damage_reward)
#if MODIFICATION != OLD
			case AT_VIP_MODEL: value = (p_vip_model_zombie[0]!=EOS||p_vip_model_human[0]!=EOS)
#endif
			case AT_VIP_CLASS: value = get_pcvar_num(cvar_viponly_class)
			case AT_CHATTAG: value = get_pcvar_num(cvar_chat_viptag)
			case AT_VIPINSCORE: value = get_pcvar_num(cvar_vipniscoretable)
			case AT_GRENADE_IMMUNITY: value = _get_pcvar_flags(cvar_grenades_immunity)
		}
		ATTRIB(id, i) = value
		
		if (!double_attrib_update)
			i++
	}
}
public forward_event_round_start() {
		
	arrayset(p_bought_per_round, 0, sizeof(p_bought_per_round))
	current_gamemode = 0
}
public forward_event_deathmsg() {
	
	static attacker, victim
	attacker = read_data(1)
	victim = read_data(2)
	
	if (attacker == victim)
		return;
		
	if(IS_PLAYER(attacker)) {
		if (get_pcvar_num(cvar_extra_ignore_for_special) && is_special_character(attacker))
			return;
			
		if (ATTRIB(attacker, AT_EXTRA_ARMOR) && !p_zombie[attacker] && p_zombie[victim])
			set_user_armor(attacker, get_user_armor(attacker)+ATTRIB(attacker, AT_EXTRA_ARMOR))
		if(ATTRIB(attacker, AT_EXTRA_KILL_AMMO))
			zv_currency_give(attacker, p_attribs[attacker][AT_EXTRA_KILL_AMMO])
		if(ATTRIB(attacker, AT_EXTRA_FRAGS))
			set_user_frags(attacker, get_user_frags(attacker)+ATTRIB(attacker, AT_EXTRA_FRAGS))
	}			
}

public forward_event_reset_hud(id) {
	
	if (ATTRIB(id, AT_VIPINSCORE)) {
		if(is_user_alive(id)) {
			message_begin(MSG_ALL, msg_scoreattrib)
			write_byte(id)
			write_byte(4)
			message_end()
		}
	}
}
#if MODIFICATION == NEW
public zp_fw_core_spawn_post(id) {
#else
public forward_player_spawn(id) {
#endif
#if MODIFICATION == NEW
	p_zombie[id] = zp_core_is_zombie(id)?true:false
#else
	p_zombie[id] = zp_get_user_zombie(id)?true:false
#endif
	set_user_atribs(id)
	
	if (first_spawn[id]) {
		set_task(1.0, "show_vip_timeleft", id, _, _, "a", 6)
		first_spawn[id] = false
	}
}

public forward_player_takedamage_pre(victim, inflictor, attacker, Float:damage, damage_type) {
	
	if(damage_type & DMG_FALL && ATTRIB(victim, AT_NO_FALL_DMG)) return HAM_SUPERCEDE;
	else if(IS_PLAYER(attacker) && ATTRIB(attacker, AT_EXTRA_DMG)) {
			
		if (get_pcvar_num(cvar_extra_ignore_for_special) && is_special_character(attacker))
			return HAM_IGNORED;
			
		SetHamParamFloat(4, damage*get_pcvar_float(cvar_extra_dmg))
		return HAM_HANDLED;
	}
	
	return HAM_IGNORED;
}
public forward_player_takedamage_post(victim, inflictor, attacker, Float:damage, damage_type) {
	
	if(IS_PLAYER(attacker) && ATTRIB(attacker, AT_DAMAGE_REWARD)) {
		
		if(p_damage[attacker] > ATTRIB(attacker, AT_DAMAGE_REWARD)) {
			
			zv_currency_give(attacker, 1)
			p_damage[attacker] = 0.0
		}
		else
			p_damage[attacker] += damage
	}
}

public forward_cmdstart(id, uc_handle) {
	
	static button, flags
	button = get_uc(uc_handle, UC_Buttons)
	flags = entity_get_int(id, EV_INT_flags)
	
	if(flags & FL_ONGROUND)
		p_jumpsnum[id] = 0
	
	if(button & IN_JUMP && !(get_user_oldbutton(id) & IN_JUMP)) {
		
		if(!(flags & FL_ONGROUND) && ++p_jumpsnum[id] <= ATTRIB(id, AT_MULTIJUMP)) {
			
			static Float:velocity[3]
			entity_get_vector(id, EV_VEC_velocity, velocity)
			velocity[2] = random_float(265.0,285.0)
			entity_set_vector(id,EV_VEC_velocity,velocity)
		}
	}
}
#define EV_NADE_TYPE	EV_INT_flTimeStepSound
#define NADE_TYPE_INFECTION	1111 
public forward_grenade_think(ent) {
		
	if (is_valid_ent(ent) && entity_get_int(ent, EV_NADE_TYPE) == NADE_TYPE_INFECTION) {
		p_grenade_time[entity_get_edict(ent, EV_ENT_owner)] = get_gametime()
	}
}
// Credits: MeRcyLeZZ
public message_cur_weapon(msg_id, msg_dest, msg_entity)
{
	if (!is_user_alive(msg_entity) || get_msg_arg_int(1) != 1) return;
	
	static weapon, clip
	weapon = get_msg_arg_int(2)
	clip = get_msg_arg_int(3)
	
	if (MAXCLIP[weapon] > 2 && ATTRIB(msg_entity, AT_UNLIMITED_CLIP)) {
		
		set_msg_arg_int(3, get_msg_argtype(3), MAXCLIP[weapon])
		
		if (clip < 2) {
			
			static wname[32], weapon_ent
			get_weaponname(weapon, wname, sizeof wname - 1)
			weapon_ent = find_ent_by_owner(-1, wname, msg_entity)
			//		   OFFSET_CLIPAMMO	OFFSET_LINUX_WEAPONS
			set_pdata_int(weapon_ent, 51, MAXCLIP[weapon], 4)
		}
	}
}

enum _:ChanellsStruct {
	channel[8],
	translation[42]
}
new const chat_channels[][ChanellsStruct] = {
    {"CT", "^1(Humans) ^4[VIP] ^3%s^1 :  %s"},
    {"T", "^1(Zombies) ^4[VIP] ^3%s^1 :  %s"},
    {"CT_Dead", "^1*DEAD*(Humans) ^4[VIP] ^3%s^1 :  %s"},
    {"T_Dead", "^1*DEAD*(Zombies) ^4[VIP] ^3%s^1 :  %s"},
    {"Spec", "^1(Spectator) ^4[VIP] ^3%s^1 :  %s"},
    {"All", "^4[VIP] ^3%s :  ^1%s"},
    {"AllDead", "^1*DEAD* ^4[VIP] ^3%s^1 :  %s"},
    {"AllSpec", "^1*SPEC* ^4[VIP] ^3%s^1 :  %s"}
}
 
public message_say_text(msg_id, msg_dest, msg_entity) {
	
	if (!ATTRIB(msg_dest, AT_CHATTAG))
		return;
		
	static message[250]
	get_msg_arg_string(2, message, charsmax(message))
	
	if (ATTRIB(msg_dest, AT_CHATTAG) == 1) {
		if (message[0] == '#' && message[9] == 'C' && equali(message, "#Cstrike_Chat_", 14)) {
			new i
			
			for (i=0; i<sizeof(chat_channels); i++) {
				if (equal(message[14], chat_channels[i][channel])) {
					
					set_msg_arg_string(2, chat_channels[i][translation])
					get_user_name(msg_dest, message, charsmax(message))
					set_msg_arg_string(3, message)
					return;
				}
			}
		}
		else {
			format(message, charsmax(message), "^4[VIP]%s", message)
			set_msg_arg_string(2, message)
		}
	}
	else if (ATTRIB(msg_dest, AT_CHATTAG) == 2) {
		if (message[9] == 'C' && equali(message, "#Cstrike_Chat_", 14)) {
			
			get_msg_arg_string(4, message, charsmax(message))
			static tag_index
			
			do {		
				tag_index = findtag(message, "<VIP>")
				if (tag_index != -1) {
					while (message[tag_index+5] != EOS) {
						message[tag_index] = message[tag_index+5]; tag_index++
					}
					message[tag_index] = EOS
				}
			}
			while (tag_index != -1)
				;
				
			if (ATTRIB(msg_dest, AT_CHATTAG))
				format(message, charsmax(message), "<VIP> %s", message)
				
			set_msg_arg_string(4, message)
		}
	}
}

public client_infochanged(id) {
	
	new info[5]
	read_argv(1, info, charsmax(info))
	if (equal(info, "name"))
		VipsDBGet(id)
}

public client_putinserver(id) {
	
	p_data[id][FLAGS] = 0
	p_data[id][SETTINGS] = 0
	p_data[id][TIMESTAMP] = 0
	first_spawn[id] = true
	arrayset(p_attribs[id], 0, player_attributes)
	freevip_inform[id] = false
	p_grenade_time[id] = 0.0
	p_damage[id] = 0.0
	p_jumpsnum[id] = 0
		
	if (!VipsDBGet(id))
		return;
	
	if (p_data[id][TIMESTAMP] > 0 && p_data[id][TIMESTAMP] < get_systime()) {
		
		VipsDBRemove(id)
		return;
	}
	
	if (p_data[id][FLAGS]) {
		new authid[30], ip[30], name[45]
		get_user_name(id, name, charsmax(name))
		get_user_authid(id, authid, charsmax(authid))
		get_user_ip(id, ip, charsmax(ip), 1)
		log_amx("[ZMVIP] VIP Connected: %s (%s) [%s].", name, authid, ip)
	}
		
	if (ATTRIB(id, AT_CHATTAG) && get_pcvar_num(cvar_vip_connected_to_server)) {
		
		new name[35]
		get_user_name(id, name, charsmax(name))
		switch (get_pcvar_num(cvar_vip_connected_to_server)) {
			case 1:
				client_print_color(0, 0, "^4[VIP] %s ^1%L.", name, LANG_PLAYER, "CONNECTED_TO_SERVER")
			case 2: {
				set_hudmessage(255, 170, 0, 0.02, 0.71, 0, 6.0, 6.0)
				show_hudmessage(0, "[VIP] %s %L", name, LANG_PLAYER, "CONNECTED_TO_SERVER")
			}
			case 3: {
				set_dhudmessage(255, 170, 0, 0.02, 0.71, 0, 6.0, 6.0)
				show_dhudmessage(0, "[VIP] %s %L", name, LANG_PLAYER, "CONNECTED_TO_SERVER")
			}
		}		
	}
}
public client_disconnect(id) {
	
	p_data[id][FLAGS] = 0
	p_damage[id] = 0.0
	p_jumpsnum[id] = 0
	p_data[id][SETTINGS] = 0
	
	if (p_data[id][TIMESTAMP] == ZV_DURATION_TILL_DISCONNECT) {
		VipsDBRemove(id)
		return;
	}
	
	if (p_data[id][TIMESTAMP] == ZV_DURATION_TILL_MAP) {
		p_data[id][PASS][charsmax(p_data[][PASS])] = floatround(get_gametime()*100, floatround_floor)
		VipsDBSet(id)
	}
}

public show_vip_info(id) {
	
	if (file_exists("vip.txt")) {
		
		show_motd(id, "vip.txt")
	}
	else {
		log_amx("WARNING: Missing vip.txt file in cstrike directory. It's used by /vip command to show information about privileges on server.")
		client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "NO_VIP_TXT")
		print_admin_contacts(id)
	}
}
public show_vips_online(id) {
	
	new bool:first = true, message[256], len
	
	for (new i=0; i<maxplayers; i++) {
		
		if (p_data[i][FLAGS]) {
			
			if (!first) {
				
				message[len++] = ','
				message[len++] = ' '
			}
			message[len++] = '^4'
			message[len] = EOS
			len += get_user_name(i, message[len], charsmax(message)-len)
			message[len++] = '^1'
			message[len] = EOS
			
			first = false
		}
	}
	
	if (first) {
		client_print_color(id, id, "^4[ZMVIP] ^1%L...", id, "NO_VIP_ONLINE")
	}
	else {
		client_print_color(id, id, "^4[ZMVIP] ^1%L: %s.", id, "ONLINE_VIPS", message)
	}
	
	print_admin_contacts(id)
	
	return PLUGIN_CONTINUE;
}
show_buy_menu(id) {
	
	new duration = get_cvar_duration(cvar_vip_buy_duration)
	
	if (duration == -1) {
		client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "SERVER_CONFIG_ERROR")
		return;
	}
		
	new timeleft[100]
	convert_duration_to_string(id, duration, timeleft, charsmax(timeleft))
	
	new menu[250]
	formatex(menu, charsmax(menu),\
	"\r%L^n^n\
	%L: \y%d %L^n\
	\r%L: \y%s^n^n\
	\r1. \w%L^n^n\
	\r0. \w%L", id, "BUY_VIP_PRIVILEGE",
	id, "PRICE", get_pcvar_num(cvar_vip_price), id, zv_get_currency()==CURRENCY_AMMO_PACKS?"AMMO_PACKS":"MONEY",
	id, "TIME", timeleft,
	id, "BUY", id, "EXIT")
	
	show_menu(id, MENU_KEY_0|MENU_KEY_1, menu, -1, "Menu Buy")
}

public forward_buy_menu_handler(id, key) {
	
	if (key == 0) {
		
		new player_has = zv_currency_get(id)
		
		if (player_has >= get_pcvar_num(cvar_vip_price)) {
			
			new duration
			duration = get_cvar_duration(cvar_vip_buy_duration)
			
			if (duration == -1) {
				client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "SERVER_CONFIG_ERROR")
				print_admin_contacts(id)
				return;
			}
			
			zv_currency_set(id, player_has-get_pcvar_num(cvar_vip_price))
			native_zv_set_user_flags(id, duration, _get_pcvar_flags(cvar_vip_buy_flags))
			
			if (duration >= 0) {
				
				client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "PURCHASED_VIP")
			}
			else {
				if (duration == ZV_DURATION_TILL_MAP) { 
					
					client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "PURCHASED_VIP_TILL_MD")
				}
				else if (duration == ZV_DURATION_TILL_DISCONNECT) { 
					
					client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "PURCHASED_VIP_TILL_D")
				}
			}
			client_cmd(id, "spk /sound/buttons/bell1.wav")
		}
		else {
			client_print_color(id, id, "^4[ZMVIP] ^1%L %L!", id, "NOT_ENOUGHT", id,\
			zv_get_currency()==CURRENCY_AMMO_PACKS?"AMMO_PACKS":"MONEY")
			client_cmd(id, "spk /sound/buttons/blip1.wav")
		}
	}
}

//////////////////////// VIP MENU FUNCTIONS //////////////////////
public show_vip_menu_console(id) {
	
	show_vip_menu(id)
	return PLUGIN_HANDLED;
}
public show_vip_menu(id) {
#if EXTRA_ITEMS == OFF
	if (p_data[id][FLAGS]) {
		
		client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "ALREADY_VIP_INFO")
	}
	else if (get_pcvar_num(cvar_vip_price) > 0) {
		
		client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "YOU_ARE_NOT_VIP")
		show_buy_menu(id)
		return PLUGIN_CONTINUE;
	}
	else {
		
		client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "YOU_ARE_NOT_VIP_INFO")
		return PLUGIN_CONTINUE;
	}
#else
	if (!ATTRIB(id, AT_EXTRA_ITEMS)) {
		
		client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "YOU_ARE_NOT_VIP_MENU")
		show_buy_menu(id)
		return PLUGIN_CONTINUE;
	}
		
	new maximum = get_pcvar_num(cvar_buys_per_round)
	if (maximum && p_bought_per_round[id] > maximum) {
		
		client_print_color(id, id, "^4[ZMVIP] ^1%L", id, "EXCEEDED_BUY_LIMIT", maximum)
		return PLUGIN_CONTINUE;
	}
#if MODIFICATION == NEW
	
	if (is_user_alive(id)) {
		p_views_extra_items_menu[id] = true
		zp_items_show_menu(id)
		p_views_extra_items_menu[id] = false
	}
	else {
		client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "NOT_ALIVE")
	}
#else
	if(registered_extra_items_num) {
		
		new item_data[item_struct], item_string[250], menu_header[40]
		formatex(menu_header, charsmax(menu_header), "\r%L:", id, "VIP_MENU_TOP")
		new menu = menu_create(menu_header, "show_vip_menu_handler")
		
		new bool:special = is_special_character(id)?true:false;
		new info[5]
		
		for(new i=0; i<registered_extra_items_num; i++) {
			
			ArrayGetArray(array_vip_extra_items, i, item_data)
			
			if (item_data[item_team] > 0
			&& (item_data[item_team]&ZP_TEAM_ZOMBIE && !p_zombie[id])
			|| (item_data[item_team]&ZP_TEAM_HUMAN && p_zombie[id])
			|| (item_data[item_team]&(ZP_TEAM_NEMESIS|ZP_TEAM_SURVIVOR) && !special)	
			)
				continue;
			
			formatex(item_string, charsmax(item_string), "%s \y%d %L", \
			item_data[item_name], item_data[item_cost], id, zv_get_currency()==CURRENCY_AMMO_PACKS?"AMMO_PACKS":"MONEY")
			num_to_str(i, info, charsmax(info))
			menu_additem(menu, item_string, info)
		}
			
		if(menu_items(menu)) menu_display(id, menu, 0)
		else {
			client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "NO_ITEMS_FOR_TEAM")
		}
	}
	else {
		client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "NO_PLUGINS_LOADED")
	}
#endif
#endif
	static timeleft[100]
	convert_duration_to_string(id, max(p_data[id][TIMESTAMP]-get_systime(), 0), timeleft, charsmax(timeleft))
	
	client_print_color(id, id, "^4[ZMVIP] ^1VIP %L: ^3%s", id, "TIMELEFT", timeleft)
	
	return PLUGIN_CONTINUE
}
#if MODIFICATION != NEW && EXTRA_ITEMS == ON
public show_vip_menu_handler(id, menu, item)
{
	if(item == MENU_EXIT )
	{
		menu_destroy(menu)
		return PLUGIN_HANDLED
	}

	new item_id, _blank, info[5]
	menu_item_getinfo(menu, item, _blank, info, charsmax(info), "", _blank, _blank)
	
	item_id = str_to_num(info)

	new retval, item_data[item_struct]
	ArrayGetArray(array_vip_extra_items, item_id, item_data)
	
	if (chached_show_vip_items)
		ExecuteForward(fw_extraitemselected, retval, id, item_data[item_plid])
	else
		ExecuteForward(fw_extraitemselected, retval, id, item_id)
		
	if (retval < ZP_PLUGIN_HANDLED) {
		zv_currency_set(id, zv_currency_get(id)-item_data[item_cost])
		client_print_color(id, id, "^4[ZMVIP] ^1%L '^4%s^1'", id, "PURCHASED", item_data[item_name])
		p_bought_per_round[id]++
	}
	
	menu_destroy(menu)
	return PLUGIN_HANDLED
}
#endif
public vip_time_check() {
	
	static id, timestamp
	timestamp = get_systime()
	
	for (id=1; id<33; id++) {
		if (p_data[id][TIMESTAMP] > 0 && p_data[id][TIMESTAMP] < timestamp) {
			
			native_zv_remove_user_flags(id)
		}
	}
}

is_special_character(id) {
		
	if(p_zombie[id]) {
#if MODIFICATION == NEW
		if(!(natives_filter_out & BIT(NATIVE_ZP_CLASS_NEMESIS_GET)) && zp_class_nemesis_get(id)
		|| !(natives_filter_out & BIT(NATIVE_ZP_CLASS_ASSASSIN_GET)) && zp_class_assassin_get(id)
		)
			return true;
#else
		if(zp_get_user_nemesis(id)
		|| !(natives_filter_out & BIT(NATIVE_ZP_CLASS_BOMBARDIER_GET)) && zp_get_user_bombardier(id)
		)
			return true;
#endif
	}
	else {
#if MODIFICATION == NEW
		if(!(natives_filter_out & BIT(NATIVE_ZP_CLASS_SURVIVOR_GET)) && zp_class_survivor_get(id)
		|| !(natives_filter_out & BIT(NATIVE_ZP_CLASS_SNIPER_GET)) && zp_class_sniper_get(id)
		)
			return true;
#else
		return zp_get_user_survivor(id)
#endif
	}
	return false;
}

check_named_privileges(id, nick[], pass[]) {
	
	new num
	if (!array_vips_database_nick || !(num = VIPCNT(NAMES))) {
		p_data[id][SETTINGS] = 0
		p_data[id][FLAGS] = 0
		return false;
	}
	
	for (new index=0; index<num; index++) {
		ArrayGetArray(array_vips_database_nick, index, p_data[id])
		if (p_data[id][SETTINGS] & FLAG_C) {
			if (((p_data[id][SETTINGS]&FLAG_N)?contain(nick, p_data[id][AUTH]):containi(nick, p_data[id][AUTH])) == -1)
				continue;
		}
		else {
			if (!((p_data[id][SETTINGS]&FLAG_N)?equal(nick, p_data[id][AUTH]):equali(nick, p_data[id][AUTH])))
				continue;
		}
		
		if (!EMPTY(p_data[id][PASS])) {
		
			p_data[id][PASS][charsmax(p_data[][PASS])] = EOS
			if (!equal(p_data[id][PASS], pass)) {
				if (p_data[id][SETTINGS] & FLAG_K) {
					return false;
				}
				else {
					client_print(id, print_console, "[ZMVIP] %L.", id, "PASS_NOT_MATCH")
					continue;
				}
			}
		}
		p_data[id][INDEX] = index
		return true;
	}
	
	p_data[id][SETTINGS] = 0
	p_data[id][FLAGS] = 0
	return false;
}
public cmd_vips_remove(id, level, cid) {
	
	if(id != 0 && !(get_user_flags(id) & level))
		return PLUGIN_HANDLED;

	if (read_argc() < 1) {
		console_print(id, "[ZM VIP] %L: zm_vip_remove <NICK/AUTH/IP>.", id, "USAGE")
		return PLUGIN_HANDLED;
	}
	
	new argument[40]
	read_argv(1, argument, charsmax(argument))
	
	new player = cmd_target(id, argument, CMDTARGET_OBEY_IMMUNITY|CMDTARGET_ALLOW_SELF|CMDTARGET_NO_BOTS)
	if (!player)
		return PLUGIN_HANDLED;
	
	new name[40]
	get_user_name(player, name, charsmax(name))
	
	if (!p_data[player][FLAGS]) {
		console_print(id, "[ZM VIP] %L", id, "DOES_NOT_HAVE_VIP", name)
		return PLUGIN_HANDLED;
	}
	
	if (native_zv_remove_user_flags(player))
		console_print(id, "[ZM VIP] %L.", id, "PRIVILEGE_REMOVED", name)
	else
		console_print(id, "[ZM VIP] %L.", id, "PLUGIN_ERROR_REMOVING", name)
	
	return PLUGIN_HANDLED;
}

public cmd_vips_reload(id, level, cid) {
	
	if(id != 0 && !(get_user_flags(id) & level))
		return PLUGIN_HANDLED;

	server_cmd("amx_reloadadmins")
	server_exec()
	
	TrieClear(trie_vips_database)
	ArrayClear(array_vips_database)
	if (array_vips_database_nick)
		ArrayClear(array_vips_database_nick)
		
	arrayset(total_vips_count, 0, sizeof(total_vips_count))
#if VIPS_FILE_SYSTEM != OFF
	load_ini_file()
#endif
	load_datafile()
		
#if VIPS_FILE_SYSTEM != FORCED
	new num_admins = admins_num()
	for (new i=0; i<num_admins; i++) {
		if (admins_lookup(i, AdminProp_Access)&VIP_SYS_FLAG) {
			VIPINC(AMX)
		}
	}
#endif
	new players[32], num_players, i
	get_players(players, num_players, "ch")
	
	for (i=0; i<num_players; i++) {
		VipsDBGet(players[i])
	}
	
	if (id) {
		static authid[30], ip[30], name[45]
		get_user_name(id, name, charsmax(name))
		get_user_authid(id, authid, charsmax(authid))
		get_user_ip(id, ip, charsmax(ip), 1)
		log_amx("Cmd exec: zm_vip_reload. By: %s (%s) (%s)", name, authid, ip)
	}
	else
		log_amx("Cmd exec: zm_vip_reload. From server console")
	
	console_print(id, "[ZM VIP] Reloaded %d vips", VIPCNT(DAT)+VIPCNT(INI)+VIPCNT(AMX))
	return PLUGIN_HANDLED;
}

public cmd_list_vips(id, level, cid) {
	
	if(id != 0 && !(get_user_flags(id) & level))
		return PLUGIN_HANDLED;
	
	new key[40], i, size = ArraySize(array_vips_database)
	new data[vips_database_type]
	
	console_print(id, "Main VIPs: %d", VIPCNT(MAIN)+VIPCNT(NAMES))
	new load_types[][] = {"DAT", "INI", "AMX"}
	new load_type, flags_str[30], time_str[25]
	
	for (i=0; i<size; i++) {
		
		ArrayGetString(array_vips_database, i, key, sizeof(key))
		
		if (EMPTY(key))
			continue;
		
		if (!TrieGetArray(trie_vips_database, key, data, vips_database_type))
			continue;
		
		if (data[SETTINGS] & LOAD_FROM_DAT)
			load_type = 0
#if VIPS_FILE_SYSTEM != OFF
		if (data[SETTINGS] & LOAD_FROM_INI)
			load_type = 1
#endif
#if VIPS_FILE_SYSTEM != FORCED
		if (data[SETTINGS] & LOAD_FROM_AMX)
			load_type = 2
#endif
		flags_str[0] = EOS
		time_str[0] = EOS
		if (data[FLAGS] == -1)
			add(flags_str, charsmax(flags_str), "All")
		else
			get_flags(data[FLAGS], flags_str, charsmax(flags_str))
		
		if (data[TIMESTAMP] == ZV_DURATION_PERMANENT)
			add(time_str, charsmax(time_str), "Permanent")
		else if (data[TIMESTAMP] == ZV_DURATION_TILL_DISCONNECT)
			add(time_str, charsmax(time_str), "Disconnect")
		else if (data[TIMESTAMP] == ZV_DURATION_TILL_MAP)
			add(time_str, charsmax(time_str), "Map change")
		else
			format_time(time_str, charsmax(time_str), "%Y/%m/%d-%H:%M", data[TIMESTAMP])
			
		console_print(id, "%s| ^"%s^" ^"%s^" ^"%s^"", load_types[load_type],
		data[AUTH], flags_str, time_str)
	}
	
	if (array_vips_database_nick) {
		size = ArraySize(array_vips_database_nick)
		for (i=0; i<size; i++) {
			
			ArrayGetArray(array_vips_database_nick, i, data)
			
			if (data[SETTINGS] & LOAD_FROM_DAT)
				load_type = 0
#if VIPS_FILE_SYSTEM != OFF
			if (data[SETTINGS] & LOAD_FROM_INI)
				load_type = 1
#endif
#if VIPS_FILE_SYSTEM != FORCED
			if (data[SETTINGS] & LOAD_FROM_AMX)
				load_type = 2
#endif
			
			if (data[FLAGS] == -1)
				add(flags_str, charsmax(flags_str), "All")
			else
				get_flags(data[FLAGS], flags_str, charsmax(flags_str))
			
			if (data[TIMESTAMP] == ZV_DURATION_PERMANENT)
				add(time_str, charsmax(time_str), "Permanent")
			else if (data[TIMESTAMP] == ZV_DURATION_TILL_DISCONNECT)
				add(time_str, charsmax(time_str), "Disconnect")
			else if (data[TIMESTAMP] == ZV_DURATION_TILL_MAP)
				add(time_str, charsmax(time_str), "Map change")
			else
				format_time(time_str, charsmax(time_str), "%Y/%m/%d-%H:%M", data[TIMESTAMP])
				
			console_print(id, "%s| ^"%s^" ^"%s^" ^"%s^"", load_types[load_type],
			data[AUTH], flags_str, time_str)
		}
	}
#if VIPS_FILE_SYSTEM != FORCED
	console_print(id, "Amx VIPs: %d", VIPCNT(AMX))
	
	new num_admins = admins_num()
	for (new i=0; i<num_admins; i++) {
		if (admins_lookup(i, AdminProp_Access)&VIP_SYS_FLAG) {
			new auth[40]
			admins_lookup(i, AdminProp_Auth, auth, charsmax(auth))
			
			console_print(id, "AMX| ^"%s^"", auth)
		}
	}
#endif
	return PLUGIN_HANDLED;
}
		
public set_freevip_hour(id, level, cid) {
	
	if(id != 0 && !(get_user_flags(id) & level))
		return PLUGIN_HANDLED;
	
	if (read_argc() < 2)  {
		
		if (freevip_enabled)
			console_print(id, "^"zm_vip_freevip_hour^" is ^"%d:%d-%d:%d^"", \
			freevip_hours[0], freevip_hours[1], freevip_hours[2], freevip_hours[3])
		else
			console_print(id, "^"zm_vip_freevip_hour^" is ^"off^"")
		return PLUGIN_HANDLED;
	}
	
	new string[12], index
	read_argv(1, string, charsmax(string))
	
	if(string[0] == 'o' || (string[0] == '0' && string[1] == EOS)) {
		freevip_enabled = false
		return PLUGIN_HANDLED;
	}
	
	if (string[2] == ':') {
		freevip_hours[0] = (string[0]-'0')*10+(string[1]-'0')
		freevip_hours[1] = (string[3]-'0')*10+(string[4]-'0')
		index = 5
	}
	else if (string[1] == ':') {
		freevip_hours[0] = (string[0]-'0')
		freevip_hours[1] = (string[2]-'0')*10+(string[3]-'0')
		index = 4
	}
	else {
		log_amx("ERROR: Inccorect zm_freevip_hour cvar value! Set correctly, or turn off by typing ^"off^".")
		return PLUGIN_HANDLED;
	}
	
	if (freevip_hours[0] >= 24 || freevip_hours[1] >= 60) {
		log_amx("ERROR: Inccorect zm_freevip_hour cvar value! Set correctly, or turn off by typing ^"off^".")
		return PLUGIN_HANDLED;
	}
	
	if (string[index++] != '-') {
		log_amx("ERROR: Inccorect zm_freevip_hour cvar value! Set correctly, or turn off by typing ^"off^".")
		return PLUGIN_HANDLED;
	}
	
	if (string[index+2] == ':') {
		freevip_hours[2] = (string[index]-'0')*10+(string[index+1]-'0')
		freevip_hours[3] = (string[index+3]-'0')*10+(string[index+4]-'0')
	}
	else if (string[index+1] == ':') {
		freevip_hours[2] = (string[index]-'0')
		freevip_hours[3] = (string[index+2]-'0')*10+(string[index+3]-'0')
	}
	else {
		log_amx("ERROR: Inccorect zm_freevip_hour cvar value! Set correctly, or turn off by typing ^"off^".")
		return PLUGIN_HANDLED;
	}
	
	if (freevip_hours[2] >= 24 || freevip_hours[3] >= 60) {
		log_amx("ERROR: Inccorect zm_freevip_hour cvar value! Set correctly, or turn off by typing ^"off^".")
		return PLUGIN_HANDLED;
	}
	
	freevip_enabled = true
	
	return PLUGIN_HANDLED;
}

freevip_hour_check() {

	if (freevip_hours[0] == freevip_hours[2] && freevip_hours[1] == freevip_hours[3]) {
		return true;
	}
	
	new h, m, s
	time(h, m, s)
	
	new hour_low, hour_high
	hour_low = freevip_hours[0]*100+freevip_hours[1]
	hour_high = freevip_hours[2]*100+freevip_hours[3]
	
	if ((hour_low <= (h*100+m) < hour_high) || (hour_high <= (h*100+m) < hour_low))
		return true;
	
	return false
}

//////////////////////// API STUFF ///////////////////////////
#if MODIFICATION == NEW
public zp_fw_core_infect_pre(id, attacker) {
#else
public zp_user_infect_attempt(id, attacker, nemesis) {
#endif
	if (ATTRIB(id, AT_GRENADE_IMMUNITY) & FLAG_A && p_grenade_time[attacker] 
	&& get_gametime()-p_grenade_time[attacker] < 0.5)
#if MODIFICATION == NEW
		return PLUGIN_HANDLED;
#else
		return ZP_PLUGIN_HANDLED;
#endif
	
	return PLUGIN_CONTINUE;
}
#if MODIFICATION == NEW
public zp_fw_core_infect_post(id, attacker) {
#else
public zp_user_infected_post(id, attacker) {
#endif	
	p_zombie[id] = true
	p_grenade_time[id] = 0.0
	
	set_user_atribs(id, true)
	set_user_atribs(attacker, true)
	
	if (get_pcvar_num(cvar_extra_ignore_for_special) && is_special_character(id))
		return;
	
	if (ATTRIB(id, AT_EXTRA_GRAVITY)) {
		new Float:gravity = get_user_gravity(id)-get_pcvar_float(cvar_extra_gravity_zombie)
		if (gravity < 0.0) gravity = 0.0
		set_user_gravity(id, gravity)
	}
	
	if(ATTRIB(attacker, AT_EXTRA_INFECT_HEALTH))
		set_user_health(attacker, get_user_health(attacker)+ATTRIB(attacker, AT_EXTRA_INFECT_HEALTH))
		
	if(ATTRIB(id, AT_EXTRA_HP))
		set_user_health(id, get_user_health(id)+ATTRIB(id, AT_EXTRA_HP))
	
	if(ATTRIB(attacker, AT_EXTRA_FRAGS))
		set_user_frags(attacker, get_user_frags(attacker)+ATTRIB(attacker, AT_EXTRA_FRAGS))
	
	if(ATTRIB(attacker, AT_EXTRA_INFECT_AMMO))
			zv_currency_give(attacker, p_attribs[attacker][AT_EXTRA_INFECT_AMMO])
#if MODIFICATION != OLD
	if(ATTRIB(id, AT_VIP_MODEL) && !EMPTY(p_vip_model_zombie))
#if MODIFICATION == NEW
		cs_set_player_model(id, p_vip_model_zombie)
#endif
#if MODIFICATION == OLD
		if (natives_filter_out & BIT(NATIVE_OVERRIDE_USER_MODEL)) {
			log_amx("WARNING: You are using old zombie plague version, that don't support custom VIP models.")
		}
		else
			zp_override_user_model(id, p_vip_model_zombie)
#endif
#endif
}
#if MODIFICATION == NEW
public zp_fw_core_cure_post(id) {
#else
public zp_user_humanized_post(id) {
#endif
	p_zombie[id] = false
	
	set_user_atribs(id, true)
	
	if (get_pcvar_num(cvar_extra_ignore_for_special) && is_special_character(id))
		return;
		
	if (ATTRIB(id, AT_EXTRA_GRAVITY)) {
		new Float:gravity = get_user_gravity(id)-get_pcvar_float(cvar_extra_gravity_human)
		if (gravity < 0.04) gravity = 0.04
		
		set_user_gravity(id, gravity)
	}
	if(ATTRIB(id, AT_EXTRA_HP))
		set_user_health(id, get_user_health(id)+ATTRIB(id, AT_EXTRA_HP))
	
	if(ATTRIB(id, AT_ARMOR))
		set_user_armor(id, ATTRIB(id, AT_ARMOR))
		
#if MODIFICATION != OLD
	if(ATTRIB(id, AT_VIP_MODEL) && !EMPTY(p_vip_model_human))
#if MODIFICATION == NEW
		cs_set_player_model(id, p_vip_model_human)
#endif
#if MODIFICATION == OLD
		if (natives_filter_out & BIT(NATIVE_OVERRIDE_USER_MODEL)) {
			log_amx("WARNING: You are using old zombie plague version, that don't support custom VIP models.")
		}
		else
			zp_override_user_model(id, p_vip_model_human)
#endif
#endif
}
#if MODIFICATION == NEW
public zp_fw_gamemodes_start(gamemode) {
#else
public zp_round_started(gamemode) {
	gamemode -= 1
#endif
	current_gamemode = gamemode
}
#if MODIFICATION == NEW
public zp_fw_grenade_fire_pre(id) {
	return (ATTRIB(id, AT_GRENADE_IMMUNITY) & FLAG_B)?PLUGIN_HANDLED:PLUGIN_CONTINUE;
}
public zp_fw_grenade_frost_pre(id) {
	return (ATTRIB(id, AT_GRENADE_IMMUNITY) & FLAG_C)?PLUGIN_HANDLED:PLUGIN_CONTINUE;
}
#endif
#if MODIFICATION == NEW
#if EXTRA_ITEMS == ON
public zp_fw_items_select_post(id, itemid, ignorecost) {
	
	if (VipsItemIs(EXTRA_ITEM, itemid))
		p_bought_per_round[id]++
}
#endif
public zp_fw_items_select_pre(id, itemid, ignorecost) {

	if (itemid == vip_buy_extra_item) {
		show_buy_menu(id)
		return ZP_ITEM_NOT_AVAILABLE;
	}
#if EXTRA_ITEMS == ON
	if (!registered_extra_items_num)
		return ZP_ITEM_AVAILABLE;
	
	if (VipsItemIs(EXTRA_ITEM, itemid)) {
		if (get_pcvar_num(cvar_vip_show_vip_items) > 0) {
		
			zp_items_menu_text_add("*VIP*")
			
			if (ATTRIB(id, AT_EXTRA_ITEMS)) {
				new maximum = get_pcvar_num(cvar_buys_per_round)
				if (maximum && p_bought_per_round[id] > maximum) {
					client_print_color(id, id, "^4[ZMVIP] ^1%L", id, "EXCEEDED_BUY_LIMIT", maximum)
					return ZP_ITEM_NOT_AVAILABLE;
				}
				else {
					return ZP_ITEM_AVAILABLE;
				}
			}
			else
				return get_pcvar_num(cvar_vip_show_vip_items)==2?ZP_ITEM_NOT_AVAILABLE:ZP_ITEM_DONT_SHOW;
		}
	}
	else if (p_views_extra_items_menu[id])
		return ZP_ITEM_DONT_SHOW;
#endif
	return ZP_ITEM_AVAILABLE;
}

public zp_fw_class_human_select_pre(id, classid) {
	
	if (!VipsItemHandle)
		return ZP_CLASS_AVAILABLE;
		
	if (VipsItemIs(CLASS_HUMAN, classid)) {
	
		zp_class_human_menu_text_add("*VIP*")
		return (ATTRIB(id, AT_VIP_CLASS))?ZP_CLASS_AVAILABLE:ZP_CLASS_NOT_AVAILABLE;
	}
	
	return ZP_CLASS_AVAILABLE;
}

public zp_fw_class_zombie_select_pre(id, classid) {
	
	if (!VipsItemHandle)
		return ZP_CLASS_AVAILABLE;
		
	if (VipsItemIs(CLASS_ZOMBIE, classid)) {
	
		zp_class_zombie_menu_text_add("*VIP*")
		return (ATTRIB(id, AT_VIP_CLASS))?ZP_CLASS_AVAILABLE:ZP_CLASS_NOT_AVAILABLE;
	}
	
	return ZP_CLASS_AVAILABLE;
}
#endif
#if MODIFICATION != NEW
public zp_user_infected_pre(id) {
	
	if(VipsItemHandle && !ATTRIB(id, AT_VIP_CLASS)) { 
		
		if(VipsItemIs(CLASS_ZOMBIE, zp_get_user_next_class(id))) {
			zp_set_user_zombie_class(id, 0)
			client_print(id, print_center, "%L", id, "VIPONLY_CLASS")
			client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "VIPONLY_CLASS_INFO")
		}
	}
}
public zp_extra_item_selected(id, itemid) {
	
	if (itemid == vip_buy_extra_item) {
		show_buy_menu(id)
		return ZP_PLUGIN_HANDLED;
	}
	return 1;
}
#endif
// Natives

public native_zv_get_user_flags(id) {
	return p_data[id][FLAGS];
}

public native_zv_set_user_flags(id, duration, flags) {
	
	new i, num, timestamp = get_systime(duration)
	
	if (id) {
		if (!is_user_connected(id))
			return false;
			
		goto skip_loop;
	}
	
	new players[32]
	get_players(players, num, "ch")
	
	for (i=0; i<num; i++) {
		id = players[i]
		
		skip_loop:
		
		if (!p_data[id][FLAGS] && duration == ZV_DURATION_IGNORE)
			return false;
		
		p_data[id][FLAGS] = flags==0?-1:flags;
		p_data[id][TIMESTAMP] = timestamp
		
		VipsDBSet(id)
		set_user_atribs(id)
	}
	
	return true;
}

public native_zv_remove_user_flags(id) {
	
	new i, num
	if (!VIPCNT(DAT) && !VIPCNT(INI) && !VIPCNT(AMX))
		return false;
	
	if (id) {
		
		if (!is_user_connected(id) || !p_data[id][FLAGS])
			return false;
		
		p_data[id][FLAGS] = 0
		p_data[id][TIMESTAMP] = 0
		arrayset(p_attribs[id], 0, player_attributes)
		
		return VipsDBRemove(id);
	}
	
	new players[32]
	get_players(players, num, "ch")
	
	for (i=0; i<num; i++) {
		id = players[i]
		
		p_data[id][FLAGS] = 0
		p_data[id][TIMESTAMP] = 0
		arrayset(p_attribs[id], 0, player_attributes)
		
		VipsDBRemove(id)
	}
	
	return true;
}

#if MODIFICATION == NEW
public native_zv_class_human_register(const name[], const description[], health, Float:speed, Float:gravity) {
	
	param_convert(1)
	param_convert(2)
	new class_id = zp_class_human_register(name, description, health, speed, gravity)
	
	VipsItemSet(CLASS_HUMAN, class_id)
	return class_id
}
public native_zv_class_zombie_register(const name[], const description[], health, Float:speed, Float:gravity) {

	param_convert(1)
	param_convert(2)
	new class_id = zp_class_zombie_register(name, description, health, speed, gravity)
	
	VipsItemSet(CLASS_ZOMBIE, class_id)
	return class_id
}
#if EXTRA_ITEMS == ON
public native_zv_items_register(const name[], cost) {
	
	param_convert(1)
	new item_id = zp_items_register(name, cost)
	
	VipsItemSet(EXTRA_ITEM, item_id)
	registered_extra_items_num++
	return item_id
}
#endif
#endif
#if MODIFICATION != NEW
public native_zv_register_zombie_class(const name[], const info[], const model[], const clawmodel[], hp, speed, Float:gravity, Float:knockback) {

	param_convert(1)
	param_convert(2)
	param_convert(3)
	param_convert(4)
	new class_id = zp_register_zombie_class(name, info, model, clawmodel, hp, speed, gravity, knockback)
	
	VipsItemSet(CLASS_ZOMBIE, class_id)
	return class_id
}
#if EXTRA_ITEMS == ON
public native_zv_register_extra_item2(const name[], cost, team) {

	param_convert(1)
	
	new item_data[item_struct]
	
	if(!array_vip_extra_items)
		array_vip_extra_items = ArrayCreate(item_struct)
	
	formatex(item_data[item_name], charsmax(item_data[item_name]), "*VIP* %s", name)
	item_data[item_cost] = cost
	item_data[item_team] = team
	
	if (chached_show_vip_items) {
	
		item_data[item_plid] = zp_register_extra_item(name, cost, team)
		
		VipsItemSet(EXTRA_ITEM, item_data[item_plid])
	}
	
	ArrayPushArray(array_vip_extra_items, item_data)
	registered_extra_items_num++
	
	return chached_show_vip_items?item_data[item_plid]:registered_extra_items_num
}
public native_zv_register_extra_item(const name[], const description[], cost, team) {
	
	param_convert(1)
	param_convert(2)
	
	new item_data[item_struct]
	
	if(!array_vip_extra_items)
		array_vip_extra_items = ArrayCreate(item_struct)
	
	formatex(item_data[item_name], charsmax(item_data[item_name]), "*VIP* %s \r[%s]", name, description)
	item_data[item_cost] = cost
	item_data[item_team] = team
	
	if (chached_show_vip_items) {
		
		item_data[item_plid] = zp_register_extra_item(name, cost, team)
		
		VipsItemSet(EXTRA_ITEM, item_data[item_plid])
	}
	
	ArrayPushArray(array_vip_extra_items, item_data)
	registered_extra_items_num++
	
	return chached_show_vip_items?item_data[item_plid]:registered_extra_items_num
}
public native_zv_force_buy_extra_item(id, itemid, ignorecost) {
	
	if (chached_show_vip_items) {
			
		zp_force_buy_extra_item(id, itemid, ignorecost)
		return;
	}
	
	new retval
	ExecuteForward(fw_extraitemselected, retval, id, itemid)
		
	if (retval >= ZP_PLUGIN_HANDLED && !ignorecost) {
		new item_data[item_struct]
		ArrayGetArray(array_vip_extra_items, itemid, item_data)
		zv_currency_set(id, zv_currency_get(id)+item_data[item_cost])
	}
}
public native_zv_get_extra_item_id(const name[]) {
	
	param_convert(1)
	
	if (chached_show_vip_items) {
		
		return zp_get_extra_item_id(name)
	}
	
	new item_data[item_struct]
	for (new i=0; i<registered_extra_items_num; i++) {
		
		ArrayGetArray(array_vip_extra_items, i, item_data)	
		if (equali(name, item_data[item_name]))
			return i;
	}
	
	return -1;
}
#endif
#endif
new dummy_record_count
public plugin_end() {
	if (dummy_record_count > 5)
		write_datafile()
	
/*	if (trie_vip_zombie_classes)
		TrieDestroy(trie_vip_zombie_classes)
#if MODIFICATION == NEW
	if (trie_vip_human_classes)
		TrieDestroy(trie_vip_human_classes)
#endif
#if EXTRA_ITEMS == ON
	if (trie_vip_extra_items)
		TrieDestroy(trie_vip_extra_items)
#if MODIFICATION != NEW
	if (array_vip_extra_items)
		ArrayDestroy(array_vip_extra_items)
#endif
#endif
	if (trie_vips_database)
		TrieDestroy(trie_vips_database)
	if (array_vips_database_nick)
		ArrayDestroy(array_vips_database_nick)
	*/
}
/*encode_date(d[]) { // TOOD: delete
	
	new ret
	d[4] = d[7] = EOS 
	ret += str_to_num(d)
	ret = (ret<<8)
	ret += str_to_num(d[5])
	ret = (ret<<8)
	ret += str_to_num(d[8])
	
	return ret
}

decode_date(d, ds[]) {

	num_to_str((d>>16), ds, 4)
	num_to_str((d>>8)&0xFF, ds[5], 4)
	num_to_str(d&0xFF, ds[8], 4)
	ds[4] = ds[7] = ':'
	ds[10] = EOS
}*/
stock zv_get_currency() {
#if MODIFICATION == NEW
	if (is_module_ammopacks_loaded)
		return CURRENCY_AMMO_PACKS;
	else
		return CURRENCY_MONEY;
#endif
	return CURRENCY_AMMO_PACKS;
}
stock zv_currency_give(id, amount) {
#if MODIFICATION == NEW
	if (is_module_ammopacks_loaded)
		zp_ammopacks_set(id, zp_ammopacks_get(id)+amount)
	else
		cs_set_user_money(id, cs_get_user_money(id)+amount)
#else
	zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id)+amount)
#endif
}
stock zv_currency_set(id, amount) {
#if MODIFICATION == NEW
	if (is_module_ammopacks_loaded)
		zp_ammopacks_set(id, amount)
	else
		cs_set_user_money(id, amount)
#else
	zp_set_user_ammo_packs(id, amount)
#endif
}
stock zv_currency_get(id) {
#if MODIFICATION == NEW
	if (is_module_ammopacks_loaded)
		return zp_ammopacks_get(id)
	else
		return cs_get_user_money(id)
	
	return 0;
#else
	return zp_get_user_ammo_packs(id)
#endif
}
#if VIPS_FILE_SYSTEM != OFF
load_ini_file() {

	new vipsfile[70]
	get_configsdir(vipsfile, charsmax(vipsfile))
	format(vipsfile, charsmax(vipsfile), "%s/%s", vipsfile, VIPS_FILE)
	new handle = fopen(vipsfile, "rt")
	
	new tempfilename[] = "temp.file";
	new temph = fopen(tempfilename, "wt")
	
	if(handle) {
		
		new vip_data[vips_database_type]

		new str_auth[50], data1[30], data2[30]
		new /*ret, */bool:comma_open, bool:line_removed = false
		new line[200], line_num, line_len;
		new i=0, s=0
		new datatype = 0
		new timestamp = get_systime()
		//new AuthType:authtype

		while(!feof(handle)) {

			comma_open = false
			line_len = fgets(handle, line, charsmax(line))
			line_num++
			
			i = 0
			datatype = 0
				
			if (line[i] == ';'
			|| line[i] == '/'
			|| line[i] == 'X'
			|| line[i] == EOS) {
				fputs(temph, line)
				continue;
			}
			
			vip_data[AUTH][0] = EOS
			vip_data[PASS][0] = EOS
			vip_data[SETTINGS] = 0
			vip_data[FLAGS] = 0
			vip_data[TIMESTAMP] = 0
			
			for(;;) {
				switch (line[i]) {
				case 'C': vip_data[SETTINGS] |= FLAG_C
				case 'N': vip_data[SETTINGS] |= FLAG_N
				case 'F': vip_data[SETTINGS] |= FLAG_F
				case 'K': vip_data[SETTINGS] |= FLAG_K
				default: goto loop_exit;
				}
				i++
			}
			
			loop_exit:
			
			for (;;) {
				
				if (i > charsmax(line)) {
					log_amx("ERROR: ^"%s^" Syntax error on line (%d:%d):^n^"%s^".^nLine too long.", VIPS_FILE, line_num, i+1, line)
					fputs(temph, line)
					goto global_continue;
				}
				if (line[i] == '"') {
					
					comma_open = !comma_open
					i++
					
					if (comma_open) datatype++
					else {
						switch (datatype) {
							
							case 1: str_auth[s] = EOS
							case 2: data1[s] = EOS
							case 3: data2[s] = EOS
							default: {
								log_amx("ERROR: ^"%s^" Syntax error on line (%d:%d):^n^"%s^". Too many parameters.", VIPS_FILE, line_num, i+1, line)
								fputs(temph, line)
								goto global_continue;
							}
						}
					}
					s = 0
					continue;
				}
				
				if (comma_open) {
					
					switch (datatype) {
						
						case 1: str_auth[s++] = line[i]
						case 2: data1[s++] = line[i]
						case 3: data2[s++] = line[i]
					}
				}
				else if (line[i] == '|') {
					
					new idx, fidx
					static frmt[] = "|//|:|"
					idx = i
					fidx = 0
					
					while (i < line_len) {
						
						if (frmt[fidx] == line[i]) {
							if (++fidx == charsmax(frmt))
								break;
						}
						else if (line[i] > '9' || line[i] < '0')
							break;
						i++
					}
					
					if (fidx == charsmax(frmt) && i < line_len) {
						vip_data[TIMESTAMP] = parse_time(line[idx], "|%Y/%m/%d|%H:%M|")
						break;
					}
					else {
						log_amx("ERROR: ^"%s^" Syntax error on line (%d:%d):^n^"%s^". Incorrect time.", VIPS_FILE, line_num, i+1, line)
						fputs(temph, line)
						goto global_continue;
					}
				}
				else if (line[i] == '^r' || line[i] == EOS || line[i] == '^n') {
					break;
				}
				else if (line[i] != ' ') {
					log_amx("ERROR: ^"%s^" Syntax error on line (%d:%d):^n^"%s^". Unknown symbol '%c'.", VIPS_FILE, line_num, i+1, line, line[i])
					fputs(temph, line)
					goto global_continue;
				}
				i++
			}
			
			switch (datatype) {
			case 1: {
				vip_data[FLAGS] = -1	
			}
			case 2: {
				vip_data[FLAGS] = read_flags(data1)
			}
			case 3: {
				copy(vip_data[PASS], charsmax(vip_data[PASS]), data1) 
				vip_data[FLAGS] = read_flags(data2)
			}
			}
			
			copy(vip_data[AUTH], charsmax(vip_data[AUTH]), str_auth)
			
			if (!(vip_data[SETTINGS] & (FLAG_C|FLAG_N|FLAG_F)))
				strtoupper(vip_data[AUTH])
				
			vip_data[SETTINGS] |= LOAD_FROM_INI
			VIPINC(INI)
			
			VipsDBInsert(vip_data)
			
			if (vip_data[TIMESTAMP] > 0 && timestamp > vip_data[TIMESTAMP]) {
				line_removed = true
				continue;
			}
			
			fputs(temph, line)
			
			global_continue:
		}
		
		
		fclose(handle)
		fclose(temph)
    
		if(line_removed) {
			
			delete_file(vipsfile)
			while (!rename_file(tempfilename, vipsfile, 1)) { }
		}
		else {
			delete_file(tempfilename)
		}
	}
	else log_amx("ERROR: Missing %s file in configs folder. Can't load zm_vip privileges.", VIPS_FILE)
}
remove_from_ini(data[vips_database_type]) {
	
	if (!VIPCNT(INI))
		return;
	
	new vipsfile[70]
	get_configsdir(vipsfile, charsmax(vipsfile))
	format(vipsfile, charsmax(vipsfile), "%s/%s", vipsfile, VIPS_FILE)
	new handle = fopen(vipsfile, "r+")
	
	if (handle) {
	
		new i, line[200], line_len, start

		while(!feof(handle)) {
			
			line_len = fgets(handle, line, charsmax(line))
			i = 0
			
			if (line[i] == ';'
			|| line[i] == '/'
			|| line[i] == 'X'
			|| line[i] == EOS) {
				continue;
			}
			
			start = 0
			while (start < line_len) {
				
				if (line[start++] == '"')
					break;
			}
			
			if (start >= line_len) continue;
			
			while (start < line_len) {
				
				if (line[start] == '"') {
					line[start] = EOS
					break;
				}
				start++
			}
			
			if (start >= line_len) continue;
			
			strtoupper(line[start])
			if (equal(line[start], data[AUTH])) {
				fseek(handle, -line_len, SEEK_CUR)
				fputc(handle, 'X')
				VIPDEC(INI)
				break;
			}
		}
		fclose(handle)
	}
	else
		log_amx("ERROR: Failed to read '%s' file.", vipsfile)
}
add_to_ini(data[vips_database_type]) {

	new vipsfile[70]
	get_configsdir(vipsfile, charsmax(vipsfile))
	format(vipsfile, charsmax(vipsfile), "%s/%s", vipsfile, VIPS_FILE)
	new handle = fopen(vipsfile, "at")
	
	if (handle) {
		new line[120], len
		len += formatex(line, charsmax(line), 
		"%s%s%s%s ^"%s^"",
		data[SETTINGS]&FLAG_C?"C":"",
		data[SETTINGS]&FLAG_N?"N":"",
		data[SETTINGS]&FLAG_F?"F":"",
		data[SETTINGS]&FLAG_K?"K":"",
		data[AUTH])
		
		if (!EMPTY(data[PASS]))
			len += formatex(line[len], charsmax(line)-len, " ^"%s^"", data[PASS])
		
		if (data[FLAGS] != -1) {
			new flags_str[30]
			get_flags(data[FLAGS], flags_str, charsmax(flags_str))
			len += formatex(line[len], charsmax(line)-len, " ^"%s^"", flags_str)
		}
		
		if (data[TIMESTAMP])
			len += format_time(line[len], charsmax(line)-len, " |%Y/%m/%d|%H:%M|", data[TIMESTAMP])
		
		VIPINC(INI)
		fputs(handle, line)
		fclose(handle)
	}
}
#endif
convert_duration_to_string(id, duration, string[], len) {
	
	if (duration == ZV_DURATION_TILL_MAP) {
		LookupLangKey(string, len, "TILL_MAPCHANGE", id)
		return;
	}
	else if (duration == ZV_DURATION_TILL_DISCONNECT) {
		LookupLangKey(string, len, "TILL_DISCONNECT", id)
		return;	
	}
	
	new index, time_unit[20] = {' '}, unit
	new week_word[][] = {"WEEK", "WEEKS", "WEEKSW"}
	new day_word[][] = {"DAY", "DAYS", "DAYSW"}
	new hour_word[][] = {"HOUR", "HOURS", "HOURSW"}
	new minute_word[][] = {"MINUTE", "MINUTES", "MINUTESW"}
	new second_word[][] = {"SECOND", "SECONDS", "SECONDSW"}
	
	if (duration >= 604800) {
		unit = duration/604800
		
		index += num_to_str(unit, string[index], len-index)
		LookupLangKey(time_unit[1], charsmax(time_unit), 
		week_word[(unit%10==1)?0:((unit%10==0||10<unit%100<20)?2:1)], id)
		index += add(string[index], len-index, time_unit)
		duration %= 604800
	}
	if (duration >= 86400) {
		if (index) { string[index] = ' '; string[++index] = EOS; }
		unit = duration/86400
		index += num_to_str(unit, string[index], len-index)
		LookupLangKey(time_unit[1], charsmax(time_unit),
		day_word[(unit%10==1)?0:((unit%10==0||10<unit%100<20)?2:1)], id)
		index += add(string[index], len-index, time_unit)
		duration %= 86400
	}
	if (duration >= 3600) {
		if (index) { string[index] = ' '; string[++index] = EOS; }
		unit = duration/3600
		index += num_to_str(unit, string[index], len-index)
		LookupLangKey(time_unit[1], charsmax(time_unit),
		hour_word[(unit%10==1)?0:((unit%10==0||10<unit%100<20)?2:1)], id)
		index += add(string[index], len-index, time_unit)
		duration %= 3600
	}
	if (duration >= 60) {
		if (index) { string[index] = ' '; string[++index] = EOS; }
		unit = duration/60
		index += num_to_str(unit, string[index], len-index)
		LookupLangKey(time_unit[1], charsmax(time_unit),
		minute_word[(unit%10==1)?0:((unit%10==0||10<unit%100<20)?2:1)], id)
		index += add(string[index], len-index, time_unit)
		duration %= 60
	}
	if (duration) {
		if (index) { string[index] = ' '; string[++index] = EOS; }
		index += num_to_str(duration, string[index], len-index)
		LookupLangKey(time_unit[1], charsmax(time_unit),
		second_word[(duration%10==1)?0:((duration%10==0||10<duration%100<20)?2:1)], id)
		index += add(string[index], len-index, time_unit)
	}
}

get_cvar_duration(cvar) {
	
	new dur[20], duration
	get_pcvar_string(cvar, dur, charsmax(dur))
	
	new len = strlen(dur)
	
	if (len) {
		
		switch (dur[len-1]) {

		case 'w': {
			dur[len-1] = EOS
			duration = str_to_num(dur)
			if (duration) {
				duration *= 7*24*3600
			}
		}
		case 'd': {
			dur[len-1] = EOS
			duration = str_to_num(dur)
			if (duration) {
				duration *= 24*3600
			}
		}
		case 'h': {
			dur[len-1] = EOS
			duration = str_to_num(dur)
			if (duration) {
				duration *= 3600
			}
		}
		case 's': {
			dur[len-1] = EOS
			duration = str_to_num(dur)
		}
		case 'm': {
			if (len-2 >= 0 && dur[len-2] == 't') {
				goto case_t
			}
			dur[len-1] = EOS
			duration = str_to_num(dur)
			if (duration) {
				duration *= 60
			}
		}
		case 't': {
			case_t:
			
			duration = ZV_DURATION_TILL_DISCONNECT
			if (dur[len-1] == 'm') {
				duration = ZV_DURATION_TILL_MAP
			}
		}
		default: {

			duration = str_to_num(dur)
			if (duration > 0) {
				duration *= 24*3600
			}
			else {
				log_amx("WARNING: Incorrect zm_vip_buy_duration cvar value ^"%s^".", dur)
				return -1;
			}
		}
		}
	}
	
	return duration
}
add_to_datafile(data[vips_database_type]) {
	
	new datafile[70]
	get_datadir(datafile, charsmax(datafile))
	add(datafile, charsmax(datafile), "/zm_vip.dat")
	
	new handle = fopen(datafile, "ab")
	
	if (handle) {
		
		fwrite_blocks(handle, data, 70, BLOCK_CHAR)
		fwrite_raw(handle, data[SETTINGS], 4, 3)
		fclose(handle)
		VIPINC(DAT)
	}
	else
		log_amx("ERROR: Failed to write '%s' file.", datafile)
}

remove_from_datafile(data[vips_database_type]) {
	
	if (!(data[SETTINGS] & LOAD_FROM_DAT))
		return;
	
	new datafile[70], bytes_in_file
	get_datadir(datafile, charsmax(datafile))
	add(datafile, charsmax(datafile), "/zm_vip.dat")
	
	bytes_in_file = file_size(datafile)
	
	new handle = fopen(datafile, "r+")
	
	if (handle) {
		
		new auth[sizeof(data[AUTH])]
		while (ftell(handle) < bytes_in_file) {
			
			fread_blocks(handle, auth, sizeof(data[AUTH]), BLOCK_CHAR)
			
			if (equal(auth, data[AUTH])) {
				fseek(handle, -sizeof(data[AUTH]), SEEK_CUR)
				fputc(handle, 0)
				VIPDEC(DAT)
				
				fseek(handle, sizeof(data[AUTH])+sizeof(data[PASS])+12-1, SEEK_CUR)
			}
			else {
				fseek(handle, sizeof(data[PASS])+12, SEEK_CUR)
			}
		}
		fclose(handle)
	}
	else
		log_amx("ERROR: Failed to read '%s' file.", datafile)
}
load_datafile() {
	
	new datafile[70]
	get_datadir(datafile, charsmax(datafile))
	add(datafile, charsmax(datafile), "/zm_vip.dat")
	
	if (!file_exists(datafile))
		return;
		
	new handle = fopen(datafile, "rb")
	
	if (handle) {
		
		new data[vips_database_type]
		while (!feof(handle)) {
			
			fread_blocks(handle, data, 70, BLOCK_CHAR)
			fread_raw(handle, data[SETTINGS], 4, 3)
			
			if (EMPTY(data[AUTH])) {
				dummy_record_count++
				continue;
			}
			data[SETTINGS] &= ~LOAD_MASK
			data[SETTINGS] |= LOAD_FROM_DAT
			VIPINC(DAT)
			
			VipsDBInsert(data)
		}
		fclose(handle)
	}
	else
		log_amx("ERROR: Failed to read '%s' file.", datafile)
}

write_datafile() {
	
	new datafile[70]
	get_datadir(datafile, charsmax(datafile))
	add(datafile, charsmax(datafile), "/zm_vip.dat")
	
	if (!VIPCNT(DAT) && file_exists(datafile)) {
		delete_file(datafile)
		return;
	}
	
	new handle = fopen(datafile, "wb")
	
	if (handle) {
		
		new key[40], i, size = ArraySize(array_vips_database)
		new data[vips_database_type]
		new timestamp = get_systime()
		
		for (i=0; i<size; i++) {
			
			ArrayGetString(array_vips_database, i, key, sizeof(key))
			
			if (EMPTY(key))
				continue;
			
			if (!TrieGetArray(trie_vips_database, key, data, vips_database_type))
				continue;
			
			if (!(data[SETTINGS] & LOAD_FROM_DAT))
				continue;
				
			if (data[TIMESTAMP] == ZV_DURATION_TILL_MAP)
				continue;
				
			if (data[TIMESTAMP] == ZV_DURATION_TILL_DISCONNECT) {
				
				if (data[PASS][charsmax(data[PASS])]+1 
				< floatround(get_gametime()*100, floatround_floor))
					continue;
				else
					data[PASS][charsmax(data[PASS])] = EOS
			}
			
			if (data[TIMESTAMP] <= timestamp)
				continue
			
			fwrite_blocks(handle, data, 70, BLOCK_CHAR)
			fwrite_raw(handle, data[SETTINGS], 4, 3)
		}
		
		if (array_vips_database_nick) {
			size = ArraySize(array_vips_database_nick)
			for (i=0; i<size; i++) {
				
				ArrayGetArray(array_vips_database_nick, i, data)
				
				if (EMPTY(data[AUTH]))
					continue;
					
				if (data[TIMESTAMP] == ZV_DURATION_TILL_MAP)
					continue;
					
				if (data[TIMESTAMP] == ZV_DURATION_TILL_DISCONNECT) {
					
					if (data[PASS][charsmax(data[PASS])]+1 
					< floatround(get_gametime()*100, floatround_floor))
						continue;
					else
						data[PASS][charsmax(data[PASS])] = EOS
				}
				
				if (data[TIMESTAMP] <= timestamp)
					continue
				
				data[SETTINGS] &= ~LOAD_MASK
				fwrite_blocks(handle, data, 70, BLOCK_CHAR)
				fwrite_raw(handle, data[SETTINGS], 4, 3)
			}
		}
		
		fclose(handle)
	}
	else
		log_amx("ERROR: Failed to write '%s' file.", datafile)
}

print_admin_contacts(id) {

	new contact[60]
	get_cvar_string("amx_contactinfo", contact, charsmax(contact))
	if(!EMPTY(contact))  {
		client_print_color(id, id, "^4%L: ^1%s.", id, "ADMIN_CONTACTS", contact)
	}
}

public show_vip_timeleft(id) {
	
	new timeleft[100]
	if (!p_data[id][TIMESTAMP])
		LookupLangKey(timeleft, charsmax(timeleft), "PERMANENT", id)
	else
		convert_duration_to_string(id, max(p_data[id][TIMESTAMP]-get_systime(), 0), timeleft, charsmax(timeleft))
	
	set_dhudmessage(51, 118, 4, 0.02, 0.52, 0, 6.0, 0.9, 0.1, 0.3)
	show_dhudmessage(id, "VIP: %s", timeleft)
}
stock timestamp_to_date(stamp, date_str[], dchars, time_str[], tchars) {
			
	new y=1970, m=1, d=1, cstamp = stamp
	new hours, mins
	
	while(cstamp >= 31536000) {
	
		cstamp -= (!(y%400)||((y%100)&&!(y%4)))?31622400:31536000
		y++;
	}
	
	while(cstamp >=	2419200) {
		
		switch(m) {
			case 2, 4, 6, 9: cstamp -= (!(y%400)||((y%100)&&!(y%4)))?2505600:2419200
			case 11:  cstamp -= 2592000
			case 1, 3, 5, 7, 8, 10, 12: cstamp -= 2678400
		}
		m++
	}

	while(cstamp >= 86400) {
	
		cstamp -= 86400
		d++
	}
	
	hours = cstamp/3600
	mins = (cstamp%3600)/60
	
	formatex(date_str, dchars, "%d/%d/%d%", y, m, d)
	formatex(time_str, tchars, "%d:%d", hours, mins)
}
/*stock date_to_timestamp(date_str[], time_str[]) {
		
	new y, m, d, i
	new hours, mins
	new temp_str[15], num[6]
	strtok(date_str, num, charsmax(num), temp_str, charsmax(temp_str), '/')
	y = str_to_num(num)
	strtok(temp_str, num, charsmax(num), temp_str, charsmax(temp_str), '/')
	m = str_to_num(num)
	d = str_to_num(temp_str)
	strtok(time_str, num, charsmax(num), temp_str, charsmax(temp_str), ':')
	hours = str_to_num(num)
	mins = str_to_num(temp_str)
	
	new stamp
	
	for (i=1970; y > i; i++)
		stamp += (!(i%400)||((i%100)&&!(i%4)))?31622400:31536000

	for (i=1; m > i; i++) {
		
		switch(i) {
			case 2, 4, 6, 9: stamp += (!(y%400)||((y%100)&&!(y%4)))?2505600:2419200
			case 11:  stamp += 2592000
			case 1, 3, 5, 7, 8, 10, 12: stamp += 2678400
		}
	}
	stamp += d*86400
	stamp += hours*3600
	stamp += mins*60
	return stamp;
}*/

stock findtag(msg[], tag[]) {
	
	static i, d
	i = 0
	while (msg[i] != EOS) {
		if (msg[i] == tag[0]) {
			
			d = 0
			while (tag[d]!=EOS&&msg[i+d]!=EOS) {
				if (tag[d]!=msg[i+d] && ((65<=tag[d]<=90) && (tag[d]+32)!=msg[i+d]))
					break;
				d++
			}
			if (tag[d] == EOS) {
				return i;
			}
		}
		i++
	}
	return -1;
}
stock read_config(cvar[], value[], len) {
	
	new directory[40]
	get_configsdir(directory, charsmax(directory))
	format(directory, charsmax(directory), "%s/%s", directory, CONFIGS_FILE)
	value[0] = EOS
	
	new handle = fopen(directory, "rt")
	if (handle) {
		
		new line[100], place
		while (!feof(handle)) {
			fgets(handle, line, charsmax(line))
			
			if ((place = contain(line, cvar)) != -1) {
				
				while (line[place] != '"' && line[place] != EOS) { place++; }
				
				if (line[place] == '"') {
					
					place++
					new index
					while (line[place] != '"' && line[place] != EOS && index < len) {
						
						value[index++] = line[place++] 
					}
					value[index] = EOS
					break;
				}
			}
		}
		fclose(handle)
	}
}
#if AMXX_VERSION_NUM < 183
stock client_print_color(id, sender, const message[], any:...) {	
#pragma unused sender
	static buffer[512], argscount
	argscount = numargs()
	
	if (!id) {
		
		static players[32], num, player, i, i2
		get_players(players, num , "ch")
			
		for (i = 0; i < num; i++) {
			
			player = players[i]
			
			static changed[5], changedcount
			changedcount = 0
			
			for (i2 = 2; i2 < argscount; i2++)
			{
				if (getarg(i2) == LANG_PLAYER)
				{
					setarg(i2, 0, player)
					changed[changedcount] = i2
					changedcount++
				}
			}
			
			vformat(buffer, charsmax(buffer), message, 3)
					
			message_begin(MSG_ONE_UNRELIABLE, msg_saytext, _, player)
			write_byte(player)
			write_string(buffer)
			message_end()
			
			for (i2 = 0; i2 < changedcount; i2++)
				setarg(changed[i2], 0, LANG_PLAYER)
		}
	}
	else {
		
		vformat(buffer, charsmax(buffer), message, 3)
				
		message_begin(MSG_ONE_UNRELIABLE, msg_saytext, _, id)
		write_byte(id)
		write_string(buffer)
		message_end()
	}
}
#else
//native client_print_color(index, sender, const message[], any:...);
#endif

#if AMXX_VERSION_NUM < 183
stock __dhud_color;
stock __dhud_x;
stock __dhud_y;
stock __dhud_effect;
stock __dhud_fxtime;
stock __dhud_holdtime;
stock __dhud_fadeintime;
stock __dhud_fadeouttime;
stock __dhud_reliable;
stock set_dhudmessage( red = 0, green = 160, blue = 0, Float:x = -1.0, Float:y = 0.65, effects = 2, Float:fxtime = 6.0, Float:holdtime = 3.0, Float:fadeintime = 0.1, Float:fadeouttime = 1.5, bool:reliable = false )
{
	#define clamp_byte(%1)       ( clamp( %1, 0, 255 ) )
	#define pack_color(%1,%2,%3) ( %3 + ( %2 << 8 ) + ( %1 << 16 ) )

	__dhud_color       = pack_color( clamp_byte( red ), clamp_byte( green ), clamp_byte( blue ) );
	__dhud_x           = _:x;
	__dhud_y           = _:y;
	__dhud_effect      = effects;
	__dhud_fxtime      = _:fxtime;
	__dhud_holdtime    = _:holdtime;
	__dhud_fadeintime  = _:fadeintime;
	__dhud_fadeouttime = _:fadeouttime;
	__dhud_reliable    = _:reliable;

	return 1;
}
#else
//native set_dhudmessage(red=200, green=100, blue=0, Float:x=-1.0, Float:y=0.35, effects=0, Float:fxtime=6.0, Float:holdtime=12.0, Float:fadeintime=0.1, Float:fadeouttime=0.2);
#endif

#if AMXX_VERSION_NUM < 183
stock show_dhudmessage(index, const message[], any:... )
{	
	new buffer[ 128 ];
	new numArguments = numargs();

	if( numArguments == 2 )
	{
		send_dhudMessage( index, message );
	}
	else if( index || numArguments == 3 )
	{
		vformat( buffer, charsmax( buffer ), message, 3 );
		send_dhudMessage( index, buffer );
	}
	else
	{
		new playersList[ 32 ], numPlayers;
		get_players( playersList, numPlayers, "ch" );

		if( !numPlayers )
		{
			return 0;
		}

		new Array:handleArrayML = ArrayCreate();

		for( new i = 2, j; i < numArguments; i++ )
		{
			if( getarg( i ) == LANG_PLAYER )
			{
				while( ( buffer[ j ] = getarg( i + 1, j++ ) ) ) {}
				j = 0;

				if( GetLangTransKey( buffer ) != TransKey_Bad )
				{
					ArrayPushCell( handleArrayML, i++ );
				}
			}
		}

		new size = ArraySize( handleArrayML );

		if( !size )
		{
			vformat( buffer, charsmax( buffer ), message, 3 );
			send_dhudMessage( index, buffer );
		}
		else
		{
			for( new i = 0, j; i < numPlayers; i++ )
			{
				index = playersList[ i ];

				for( j = 0; j < size; j++ )
				{
					setarg( ArrayGetCell( handleArrayML, j ), 0, index );
				}

				vformat( buffer, charsmax( buffer ), message, 3 );
				send_dhudMessage( index, buffer );
			}
		}

		ArrayDestroy( handleArrayML );
	}

	return 1;
}
stock send_dhudMessage( const index, const message[] )
{
	message_begin( __dhud_reliable ? ( index ? MSG_ONE : MSG_ALL ) : ( index ? MSG_ONE_UNRELIABLE : MSG_BROADCAST ), SVC_DIRECTOR, _, index );
	{
		write_byte( strlen( message ) + 31 );
		write_byte( DRC_CMD_MESSAGE );
		write_byte( __dhud_effect );
		write_long( __dhud_color );
		write_long( __dhud_x );
		write_long( __dhud_y );
		write_long( __dhud_fadeintime );
		write_long( __dhud_fadeouttime );
		write_long( __dhud_holdtime );
		write_long( __dhud_fxtime );
		write_string( message );
	}
	message_end();
}
#else
//native show_dhudmessage(index, const message[], any:...);
#endif

VipsItemIs(ClassType:type, itemid) {
	
	if (!trie_vip_items)
		return false;
		
	static strnum[6]
	num_to_str(itemid, strnum[1], charsmax(strnum)-1)
	strnum[0] = _:type
	
	return TrieKeyExists(trie_vip_items, strnum)
}
VipsItemSet(ClassType:type, itemid) {
	
	if (!trie_vip_items)
		trie_vip_items = TrieCreate()
		
	new strnum[6]
	num_to_str(itemid, strnum[1], charsmax(strnum)-1)
	strnum[0] = _:type
	
	return TrieSetCell(trie_vip_items, strnum, 1)
}

stock VipsDBGet(const id) {
	
	if (!(1 <= id < 33))
		return false;
		
	p_data[id][FLAGS] = 0
	p_data[id][SETTINGS] = 0
	
	if (!VIPCNT(DAT) && !VIPCNT(INI) && !VIPCNT(AMX))
		return false;
	
	static authid[30], ip[30], name[45]
	get_user_info(id, "name", name, charsmax(name))
	get_user_authid(id, authid, charsmax(authid))
	get_user_ip(id, ip, charsmax(ip), 1)
	
	static uppername[45], client_password[30]
	
	copy(uppername, charsmax(uppername), name)
	strtoupper(uppername)
	get_user_info(id, amx_password_field_string, client_password, charsmax(client_password))
	
	if (VIPCNT(MAIN) && TrieGetArray(trie_vips_database, authid, p_data[id], vips_database_type)) 
	{ p_data[id][SETTINGS] |= LOAD_FROM_MAIN; }
	else if(VIPCNT(MAIN) && TrieGetArray(trie_vips_database, ip, p_data[id], vips_database_type)) 
	{ p_data[id][SETTINGS] |= LOAD_FROM_MAIN; }
	else if(VIPCNT(MAIN) && TrieGetArray(trie_vips_database, uppername, p_data[id], vips_database_type)) 
	{ p_data[id][SETTINGS] |= LOAD_FROM_MAIN; }
	else if (VIPCNT(NAMES) && check_named_privileges(id, name, client_password) > 0) 
	{ p_data[id][SETTINGS] |= LOAD_FROM_NAMES; }
	
	if (!EMPTY(p_data[id][PASS]) && p_data[id][SETTINGS] & FLAG_K && !equal(p_data[id][PASS], client_password)) {
		p_data[id][SETTINGS] = 0
		p_data[id][FLAGS] = 0
		server_cmd("kick #%d ^"[ZMVIP] %L.^"", get_user_userid(id), id, "INVALID_PASS")
		return false;
	}
		
#if VIPS_FILE_SYSTEM != FORCED
	if(get_user_flags(id) & VIP_SYS_FLAG) {
		
		new flags = _get_pcvar_flags(cvar_amx_auth_flags)
		if (flags == 0)
			p_data[id][FLAGS] = -1
		else
			p_data[id][FLAGS] |= flags
		p_data[id][TIMESTAMP] = 0
		p_data[id][SETTINGS] |= LOAD_FROM_AMX
	}
#endif
	if (p_data[id][FLAGS]) {
		new flags = _get_pcvar_flags(cvar_amxmodx_flags)
		if (flags > 0)
		set_user_flags(id, flags)
	}
	
	if (!p_data[id][FLAGS]) {
		p_data[id][SETTINGS] = 0
		p_data[id][TIMESTAMP] = 0
		arrayset(p_attribs[id], 0, player_attributes)
		return false;
	}
	
	console_print(id, "* VIP Privileges set")
	return true;
}
	

stock VipsDBSet(const id) {
	
	if (!(1 <= id < 33))
		return false;
	
	if (p_data[id][SETTINGS]&LOAD_MASK) {
		
		if (p_data[id][SETTINGS]&(LOAD_FROM_MAIN)) {
			TrieSetArray(trie_vips_database, p_data[id][AUTH], p_data[id], vips_database_type)
		}
		else if (p_data[id][SETTINGS]&LOAD_FROM_NAMES) {
			ArraySetArray(array_vips_database_nick, p_data[id][INDEX], p_data[id])
		}
#if VIPS_FILE_SYSTEM != FORCED
		else if (p_data[id][SETTINGS]&LOAD_FROM_AMX) {
			
			p_data[id][SETTINGS] = 0
			VipsDBSet(id)
		}
#endif
#if VIPS_FILE_SYSTEM != OFF
		if (p_data[id][SETTINGS]&LOAD_FROM_INI) {
			remove_from_ini(p_data[id])
			add_to_ini(p_data[id])
		}
		else if (p_data[id][SETTINGS]&LOAD_FROM_DAT) {
			remove_from_datafile(p_data[id])
			add_to_datafile(p_data[id])
		}
#else
		remove_from_datafile(p_data[id])
		add_to_datafile(p_data[id])	
#endif
		return true;
	}
	
	get_user_authid(id, p_data[id][AUTH], charsmax(p_data[][AUTH]))
	if (p_data[id][AUTH][7] != ':')
		get_user_ip(id, p_data[id][AUTH], charsmax(p_data[][AUTH]), 1)
	
	p_data[id][PASS] = EOS
#if VIPS_FILE_SYSTEM != OFF
	if (get_pcvar_num(cvar_vip_store_ini)&&(p_data[id][TIMESTAMP]!=ZV_DURATION_TILL_MAP)){
		
		p_data[id][SETTINGS] = LOAD_FROM_INI
	}
	else {
		p_data[id][SETTINGS] = LOAD_FROM_DAT
	}
#else
	p_data[id][SETTINGS] = LOAD_FROM_DAT
#endif
	if (p_data[id][SETTINGS] & LOAD_FROM_DAT)
		add_to_datafile(p_data[id])
#if VIPS_FILE_SYSTEM != OFF
	if (p_data[id][SETTINGS] & LOAD_FROM_INI)
		add_to_ini(p_data[id])
#endif	
	return VipsDBInsert(p_data[id]);
}
stock VipsDBInsert(data[vips_database_type]) {
	
	if (data[SETTINGS] & ~(LOAD_MASK|FLAG_K)) {
		
		if(!array_vips_database_nick)
			array_vips_database_nick = ArrayCreate(vips_database_type, 10)
			
		data[SETTINGS] |= LOAD_FROM_NAMES
		data[INDEX] = ArraySize(array_vips_database_nick)
		ArrayPushArray(array_vips_database_nick, data)
		VIPINC(NAMES)
		
		return true;
	}
	
	data[INDEX] = ArraySize(array_vips_database)
	ArrayPushString(array_vips_database, data[AUTH])
	TrieSetArray(trie_vips_database, data[AUTH], data, vips_database_type)
	VIPINC(MAIN)
	
	return true;
}

stock VipsDBRemove(const id) {
	
	if (!(1 <= id < 33))
		return false;
	
	if (p_data[id][SETTINGS]&LOAD_MASK) {
		
		p_data[id][FLAGS] = 0
		p_data[id][TIMESTAMP] = 0
		if (p_data[id][SETTINGS]&(LOAD_FROM_MAIN)) {
			
			TrieDeleteKey(trie_vips_database, p_data[id][AUTH])
			ArraySetString(array_vips_database, p_data[id][INDEX], "")
			VIPDEC(MAIN)
			
			if (p_data[id][SETTINGS]&LOAD_FROM_MAIN)
				remove_from_datafile(p_data[id])
#if VIPS_FILE_SYSTEM != OFF
			if (p_data[id][SETTINGS]&LOAD_FROM_INI)
				remove_from_ini(p_data[id])
#endif
		}
		else if (p_data[id][SETTINGS]&LOAD_FROM_NAMES) {
			
			p_data[id][AUTH][0] = EOS
			ArraySetArray(array_vips_database_nick, p_data[id][INDEX], p_data[id])
			VIPDEC(NAMES)
		}
#if VIPS_FILE_SYSTEM != FORCED
		else if (p_data[id][SETTINGS]&LOAD_FROM_AMX) {
			
			remove_user_flags(id, VIP_SYS_FLAG)
			// VIPCNT(AMX) not decremented, because we don't delete from amxmodx dynamic
			// admin list. There is no efficient way to do this. Only by flushing all admins
		}
#endif
		new flags = _get_pcvar_flags(cvar_amxmodx_flags)
		if (flags > 0)
			remove_user_flags(id, flags)
		
		p_data[id][SETTINGS] = 0
		return true;
	}
	
	return false;
}
/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1063\\ f0\\ fs16 \n\\ par }
*/
Imagini: -
Last edited by [M]Maasym. on Sat Jun 25, 2022 7:30 pm, edited 1 time in total.
Reason: Link download editat
Image
Post Reply

Return to “Pluginuri”