#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
// plugin's main information
#define PLUGIN_NAME "VIP Alternative"
#define PLUGIN_VERSION "0.1b"
#define PLUGIN_AUTHOR "VEN"
// plugin's CVAR name
new CVAR_NAME[] = "amx_vip_armor"
// CVAR's default value
#define CVAR_DEFAULT "0"
// comment to avoid plugin autodisabling on maps without VIP spawn point
#define VIP_MAP_CHECK
// possible special VIP icon display styles
#define BIT_ICON_NORMAL (1<<0)
#define BIT_ICON_BLINK (1<<1)
// comment to disable special VIP icon displaying or change display style
#define BIT_ICON BIT_ICON_NORMAL
// special VIP icon colors in RGB format
#define ICON_R 0
#define ICON_G 0
#define ICON_B 255
#define EXTRA_OFFSET 5
// private data armor type offset
#define OFFSET_ARMORTYPE 112
// armor type offset bits
#define BIT_VEST (1<<0) // vest
#define BIT_VESTHELM (1<<1) // vest + helmet
// when CVAR amx_vip_armor > 0 VIP will gain specified armor type
#define BIT_ARMORTYPE BIT_VEST
// display helmet hud icon bit
#define BIT_HELMET_ICON (1<<0)
// private data VIP offset
#define OFFSET_VIP 209
// VIP offset bit
#define BIT_VIP (1<<8)
new g_cvar_pointer
new ICON_NAME[] = "vipsafety"
#define BIT_CENTER_TEXT (1<<2)
new MESSAGE_TEXT[] = "#Cannot_Switch_From_VIP"
new g_msgid_icon
new g_msgid_armortype
new g_msgid_text
new g_vip_id
public plugin_init() {
register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR)
g_cvar_pointer = register_cvar(CVAR_NAME, CVAR_DEFAULT)
#if defined VIP_MAP_CHECK
if (!engfunc(EngFunc_FindEntityByString, FM_NULLENT, "classname", "func_vip_safetyzone"))
return
#endif
register_event("HLTV", "event_new_round", "a", "1=0", "2=0")
register_event("StatusIcon", "event_vip_safety", "be", "1=1", "2=vipsafety")
RegisterHam(Ham_Spawn, "player", "Player_Spawn", 1)
#if defined BIT_ICON
register_event("DeathMsg", "event_death", "a", "2!0")
#endif
register_clcmd("chooseteam", "clcmd_role_switch")
register_clcmd("jointeam", "clcmd_role_switch")
g_msgid_icon = get_user_msgid("StatusIcon")
g_msgid_armortype = get_user_msgid("ArmorType")
g_msgid_text = get_user_msgid("TextMsg")
}
/* *************************************************** Base **************************************************** */
public event_new_round() {
if (!g_vip_id || !is_user_connected(g_vip_id))
return
new tchar[2]
get_user_team(g_vip_id, tchar, 1)
if (tchar[0] != 'C') {
g_vip_id = 0
return
}
set_player_vip(g_vip_id)
if (get_pcvar_num(g_cvar_pointer) < 0)
g_vip_id = 0
}
public Player_Spawn(id)
{
new armor = get_pcvar_num(g_cvar_pointer)
if (armor >= 0 && is_user_alive(id) && set_player_vip(id, false)) {
g_vip_id = id
set_player_armor(id, armor)
#if defined BIT_ICON
msg_vip_icon(id)
#endif
}
}
public client_disconnect(id) {
if (id == g_vip_id && !is_player_vip(id)) {
set_player_vip(id)
g_vip_id = 0
}
}
public event_vip_safety(id) {
if (id == g_vip_id)
set_player_vip(id)
}
public event_death() {
new id = read_data(2)
if (id == g_vip_id)
msg_vip_icon(id, false)
}
public clcmd_role_switch(id) {
if (id != g_vip_id)
return PLUGIN_CONTINUE
msg_cant_switch_roles(id)
return PLUGIN_HANDLED
}
/* ************************************************** Stocks *************************************************** */
stock is_player_vip(id) {
return (get_pdata_int(id, OFFSET_VIP, EXTRA_OFFSET) & BIT_VIP)
}
stock bool:set_player_vip(id, bool:vip = true) {
new oldbits = get_pdata_int(id, OFFSET_VIP, EXTRA_OFFSET)
if (!vip && !(oldbits & BIT_VIP))
return false
new newbits
switch (vip) {
case true : newbits = (oldbits | BIT_VIP)
case false: newbits = (oldbits & ~BIT_VIP)
}
set_pdata_int(id, OFFSET_VIP, newbits, EXTRA_OFFSET)
return true
}
stock set_player_armor(id, armor) {
set_pev(id, pev_armorvalue, float(armor))
set_pdata_int(id, OFFSET_ARMORTYPE, (armor ? BIT_ARMORTYPE : 0), EXTRA_OFFSET)
#if BIT_ARMORTYPE == BIT_VESTHELM
msg_helmet_icon(id, armor ? true : false)
#else
msg_helmet_icon(id, false)
#endif
}
stock msg_helmet_icon(id, bool:show = true) {
message_begin(MSG_ONE_UNRELIABLE, g_msgid_armortype, {0, 0, 0}, id)
write_byte((show ? BIT_HELMET_ICON : 0))
message_end()
}
stock msg_vip_icon(id, bool:show = true) {
message_begin(MSG_ONE_UNRELIABLE, g_msgid_icon, {0, 0, 0}, id)
write_byte((show ? BIT_ICON : 0))
write_string(ICON_NAME)
if (show) {
write_byte(ICON_R)
write_byte(ICON_G)
write_byte(ICON_B)
}
message_end()
}
stock msg_cant_switch_roles(id) {
message_begin(MSG_ONE_UNRELIABLE, g_msgid_text, {0, 0, 0}, id)
write_byte(BIT_CENTER_TEXT)
write_string(MESSAGE_TEXT)
message_end()
}