Raised This Month: $318 Target: $400
 79%   Almost there!

Glow weapons


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Et3rnity
Member
Join Date: Sep 2018
Location: Romania
Old 09-27-2019 , 17:09   Glow weapons
Reply With Quote #1

Didnt show the glow weapons. Can someone tell me haw to fix that. Thanks
Code:
/******************************************************************/
/*                                                                */
/*                           entWatch                             */
/*                                                                */
/*                                                                */
/*  File:          entWatch.sp                                    */
/*  Description:   Notify players about entity interactions.      */
/*                                                                */
/*                                                                */
/*  Copyright (C) 2018  Kyle                                      */
/*  2018/05/08 20:13:14                                           */
/*                                                                */
/*  This code is licensed under the GPLv3 License.                */
/*                                                                */
/******************************************************************/


#pragma semicolon 1
#pragma newdecls required

#include <sourcemod>
#include <smutils>          //https://github.com/Kxnrl/sourcemod-utils
#include <cstrike>
#include <sdkhooks>
#include <clientprefs>
#include <entWatch>

#undef REQUIRE_EXTENSIONS
#include <dhooks>
#if SOURCEMOD_V_REV >= 6372
#include <topmenus>
#endif
#define REQUIRE_EXTENSIONS

#undef REQUIRE_PLUGIN
#include <ZombieEscape>
#include <zombiereloaded>
#if SOURCEMOD_V_REV >= 6372
#include <adminmenu>
#endif
#define REQUIRE_PLUGIN

#define USE_TRANSLATIONS  // if load translations

#define PI_NAME "[CSGO] entWatch"
#define PI_AUTH "Kyle"
#define PI_DESC "Notify players about entity interactions."
#define PI_VERS "1.4.0"
#define PI_URLS "https://kxnrl.com"

public Plugin myinfo = 
{
    name        = PI_NAME,
    author      = PI_AUTH,
    description = PI_DESC,
    version     = PI_VERS,
    url         = PI_URLS
};


#define MAXENT 128
#define MAXPLY  65
#define ZOMBIE   0
#define HUMANS   1
#define GLOBAL   0
#define COOLDN   1

#define Pre_Button 0
#define Pre_Weapon 1
#define Pre_Locked 2

enum Entity
{
    String:ent_name[32],
    String:ent_short[32],
    String:ent_buttonclass[32],
    String:ent_filtername[32],
    bool:ent_hasfiltername,
    ent_ownerid,
    ent_hammerid,
    ent_buttonid,
    ent_weaponref,
    ent_glowref,
    ent_mode,               // 0 = No button, 1 = Spam protection only, 2 = Cooldowns, 3 = Limited uses, 4 = Limited uses with cooldowns, 5 = Cooldowns after multiple uses.
    ent_uses,
    ent_maxuses,
    ent_startcd,
    ent_cooldown,
    ent_cooldowntime,
    ent_team,
    bool:ent_displayhud,
    bool:ent_weaponglow,
    bool:ent_pickedup,
    bool:ent_autotrasfer
}

enum Forward
{
    Handle:OnPick,
    Handle:OnPicked,
    Handle:OnDropped,
    Handle:OnUse,
    Handle:OnTransfered,
    Handle:OnBanned,
    Handle:OnUnban
}

enum Cookies
{
    Handle:Restricted,
    Handle:BanByAdmin,
    Handle:BanTLength,
    Handle:DisplayHud
}

static any g_EntArray[MAXENT][Entity];
static any g_Forward[Forward];
static any g_Cookies[Cookies];

static ArrayList g_aPreHammerId[3];

static Handle g_tRound         = null;
static Handle g_tKnife[MAXPLY] = null;
static Handle g_tCooldown      = null;

static int  g_iEntCounts      = MAXENT;
static int  g_iScores[MAXPLY] = {0, ...};
static int  g_iIconRef[MAXPLY] = {INVALID_ENT_REFERENCE, ...};

static bool g_bConfigLoaded    = false;
static bool g_bHasEnt[MAXPLY]  = false;
static bool g_bBanned[MAXPLY]  = false;
static bool g_bEntHud[MAXPLY]  = false;

static char g_szGlobalHud[2][2048];
static char g_szClantag[MAXPLY][32];

static float g_fPickup[MAXPLY] = {0.0, ...};

static bool g_pZombieEscape = false;
static bool g_pZombieReload = false;

static bool g_bLateload;

// DHook
static bool g_extDHook;
static Handle hAcceptInput;

static int g_iTeam[MAXPLY];
static int g_iEntTeam[2048];

public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
{
    RegPluginLibrary("entWatch");

    CreateNative("entWatch_HasbeenBanned", Native_HasBanned);
    CreateNative("entWatch_ClientHasItem", Native_HasItem);
    CreateNative("entWatch_EntityIsItem",  Native_IsItem);

    MarkNativeAsOptional("ZE_IsAvenger");
    MarkNativeAsOptional("ZE_IsInfector");
    MarkNativeAsOptional("ZR_IsClientHuman");
    MarkNativeAsOptional("ZR_IsClientZombie");
    
    g_bLateload = late;

    return APLRes_Success;
}

public int Native_HasBanned(Handle plugin, int numParams)
{
    return g_bBanned[GetNativeCell(1)];
}

public int Native_HasItem(Handle plugin, int numParams)
{
    return g_bHasEnt[GetNativeCell(1)];
}

public int Native_IsItem(Handle plugin, int numParams)
{
    if(!g_bConfigLoaded)
        return false;

    int entity = GetNativeCell(1);
    int entref = EntIndexToEntRef(entity);

    for(int i = 0; i < g_iEntCounts; ++i)
        if(g_EntArray[i][ent_weaponref] == entref)
            return true;

    return false;
}

public void OnPluginStart()
{
    if(GetEngineVersion() != Engine_CSGO)
        SetFailState("CSGO only!");

    SMUtils_SetChatPrefix("[\x04entWatch\x01]");
    SMUtils_SetChatSpaces("   ");
    SMUtils_SetChatConSnd(true);
    SMUtils_SetTextDest(HUD_PRINTCENTER);

    HookEventEx("round_start",    Event_RoundStart,   EventHookMode_Post);
    HookEventEx("round_end",      Event_RoundEnd,     EventHookMode_Post);
    HookEventEx("player_death",   Event_PlayerDeath,  EventHookMode_Post);
    HookEventEx("player_team",    Event_PlayerTeams,  EventHookMode_Post);

    g_Cookies[Restricted] = RegClientCookie("entwatch_restricted", "", CookieAccess_Private);
    g_Cookies[BanByAdmin] = RegClientCookie("entwatch_banbyadmin", "", CookieAccess_Private);
    g_Cookies[BanTLength] = RegClientCookie("entwatch_bantLength", "", CookieAccess_Private);
    g_Cookies[DisplayHud] = RegClientCookie("entwatch_displayhud", "", CookieAccess_Private);

    g_Forward[OnPick]       = CreateGlobalForward("entWatch_OnPickItem",        ET_Event,  Param_Cell, Param_String);
    g_Forward[OnPicked]     = CreateGlobalForward("entWatch_OnPickedItem",      ET_Ignore, Param_Cell, Param_String);
    g_Forward[OnDropped]    = CreateGlobalForward("entWatch_OnDroppedItem",     ET_Ignore, Param_Cell, Param_Cell, Param_String);
    g_Forward[OnUse]        = CreateGlobalForward("entWatch_OnItemUse",         ET_Event,  Param_Cell, Param_String);
    g_Forward[OnTransfered] = CreateGlobalForward("entWatch_OnItemTransfered",  ET_Ignore, Param_Cell, Param_Cell, Param_String);
    g_Forward[OnBanned]     = CreateGlobalForward("entWatch_OnClientBanned",    ET_Ignore, Param_Cell);
    g_Forward[OnUnban]      = CreateGlobalForward("entWatch_OnClientUnban",     ET_Ignore, Param_Cell);

    RegConsoleCmd("sm_entwatch", Command_entWatch);
    RegConsoleCmd("sm_estats",   Command_Stats);
    RegConsoleCmd("sm_ehud",     Command_DisplayHud);

    RegAdminCmd("sm_eban",       Command_Restrict,   ADMFLAG_BAN);
    RegAdminCmd("sm_eunban",     Command_Unrestrict, ADMFLAG_BAN);
    RegAdminCmd("sm_etransfer",  Command_Transfer,   ADMFLAG_BAN);

    RegServerCmd("sm_ereload",   Command_Reload);

    g_aPreHammerId[Pre_Button] = new ArrayList();
    g_aPreHammerId[Pre_Weapon] = new ArrayList();
    g_aPreHammerId[Pre_Locked] = new ArrayList();

#if defined USE_TRANSLATIONS
    LoadTranslations("entWatch.phrases");
#endif

    if(g_bLateload)
    {
        g_bLateload = false;
        
        for(int client = 1; client <= MaxClients; ++client)
        if(ClientIsValid(client))
        {
            OnClientConnected(client);
            OnClientPutInServer(client);
            if(AreClientCookiesCached(client))
                OnClientCookiesCached(client);
        }
        
        if(LibraryExists("dhooks"))
            OnLibraryAdded("dhooks");

#if SOURCEMOD_V_REV >= 6372
        if(LibraryExists("adminmenu"))
            OnLibraryAdded("adminmenu");
#endif
    }
}

public void OnLibraryAdded(const char[] name)
{
    if(strcmp(name, "dhooks") == 0)
    {
        Handle GameConf = LoadGameConfigFile("sdktools.games\\engine.csgo");

        if(GameConf == null)
        {
            SetFailState("Why not has gamedata?");
            return;
        }

        int offset = GameConfGetOffset(GameConf, "AcceptInput");
        hAcceptInput = DHookCreate(offset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, Event_AcceptInput);
        if(hAcceptInput == null)
        {
            LogError("Failed to DHook \"AcceptInput\".");
            return;
        }
        
        delete GameConf;

        DHookAddParam(hAcceptInput, HookParamType_CharPtr);
        DHookAddParam(hAcceptInput, HookParamType_CBaseEntity);
        DHookAddParam(hAcceptInput, HookParamType_CBaseEntity);
        DHookAddParam(hAcceptInput, HookParamType_Object, 20);
        DHookAddParam(hAcceptInput, HookParamType_Int);

        g_extDHook = true;
    }
#if SOURCEMOD_V_REV >= 6372
    else if(LibraryExists("adminmenu"))
    {
        TopMenu menu = GetAdminTopMenu();
        if(menu != null)
            OnAdminMenuReady(menu);
    }
#endif
}

public void OnLibraryRemoved(const char[] name)
{
    if(strcmp(name, "dhooks") == 0)
    {
        g_extDHook = false;
        LogError("Dhook library has been removed.");
    }
}

#if SOURCEMOD_V_REV >= 6372
enum struct AdminMenuType
{
    TopMenuObject sm_eban;
    TopMenuObject sm_eunban;
    TopMenuObject sm_etransfer;
}
static AdminMenuType g_TopItem;
static TopMenuObject entwatch_commands;
public void OnAdminMenuReady(Handle aTopMenu)
{
    TopMenu topmenu = TopMenu.FromHandle(aTopMenu);

    entwatch_commands = topmenu.AddCategory("entwatch", AdminMenuHandler, "ehud", ADMFLAG_BAN);

    if(entwatch_commands != INVALID_TOPMENUOBJECT)
    {
        g_TopItem.sm_eban      = topmenu.AddItem("sm_eban",      AdminMenuHandler, entwatch_commands, "sm_eban",      ADMFLAG_BAN);
        g_TopItem.sm_eunban    = topmenu.AddItem("sm_eunban",    AdminMenuHandler, entwatch_commands, "sm_eunban",    ADMFLAG_BAN);
        g_TopItem.sm_etransfer = topmenu.AddItem("sm_etransfer", AdminMenuHandler, entwatch_commands, "sm_etransfer", ADMFLAG_BAN);
    }
}

public void AdminMenuHandler(TopMenu topmenu, TopMenuAction action, TopMenuObject topobj_id, int param, char[] buffer, int maxlength)
{
    if(action == TopMenuAction_DisplayTitle)
    {
        if(topobj_id == entwatch_commands)
            FormatEx(buffer, maxlength, "entWatch: ");
    }
    else if(action == TopMenuAction_DisplayOption)
    {
        if(topobj_id == entwatch_commands)             FormatEx(buffer, maxlength, "entWatch");
        else if(topobj_id == g_TopItem.sm_eban)        FormatEx(buffer, maxlength, "Ban client");
        else if(topobj_id == g_TopItem.sm_eunban)      FormatEx(buffer, maxlength, "Unban client");
        else if(topobj_id == g_TopItem.sm_etransfer)   FormatEx(buffer, maxlength, "Transfer Item");
        else                                           FormatEx(buffer, maxlength, "entWatch");
    }
    else if(action == TopMenuAction_SelectOption)
    {
        if(topobj_id == entwatch_commands)             { }
        else if(topobj_id == g_TopItem.sm_eban)        DisplayMenu_Restrict(param);
        else if(topobj_id == g_TopItem.sm_eunban)      DisplayMenu_Unrestrict(param);
        else if(topobj_id == g_TopItem.sm_etransfer)   DisplayMenu_Transfer(param);
    }
}
#endif

public Action Command_Reload(int args)
{
    OnMapEnd();
    OnMapStart();
    OnConfigsExecuted();
}

public void OnMapStart()
{
    AddFileToDownloadsTable("materials/maoling/sprites/ze/entwatch_2017.vmt");
    AddFileToDownloadsTable("materials/maoling/sprites/ze/entwatch_2017.vtf");
    PrecacheModel("materials/maoling/sprites/ze/entwatch_2017.vmt", true);
}

public void OnConfigsExecuted()
{
    g_aPreHammerId[Pre_Weapon].Clear();
    g_aPreHammerId[Pre_Button].Clear();
    g_aPreHammerId[Pre_Locked].Clear();

    for(int index = 0; index < MAXENT; index++)
    {
        g_EntArray[index][ent_name][0]        = '\0';
        g_EntArray[index][ent_short][0]       = '\0';
        g_EntArray[index][ent_buttonclass][0] = '\0';
        g_EntArray[index][ent_filtername][0]  = '\0';
        g_EntArray[index][ent_hasfiltername]  = false;
        g_EntArray[index][ent_hammerid]       = -1;
        g_EntArray[index][ent_weaponref]      = -1;
        g_EntArray[index][ent_buttonid]       = -1;
        g_EntArray[index][ent_ownerid]        = -1;
        g_EntArray[index][ent_mode]           = 0;
        g_EntArray[index][ent_uses]           = 0;
        g_EntArray[index][ent_maxuses]        = 0;
        g_EntArray[index][ent_cooldown]       = 0;
        g_EntArray[index][ent_cooldowntime]   = -1;
        g_EntArray[index][ent_weaponglow]     = false;
        g_EntArray[index][ent_displayhud]     = false;
        g_EntArray[index][ent_team]           = -1;
        g_EntArray[index][ent_glowref]   = INVALID_ENT_REFERENCE;
    }

    LoadConfig();

#if defined __ZombieEscape__
    g_pZombieEscape = (LibraryExists("ZombieEscape") && GetFeatureStatus(FeatureType_Native, "ZE_IsAvenger") == FeatureStatus_Available);
#endif
#if defined __zombiereloaded__
    g_pZombieReload = (LibraryExists("zombiereloaded") && GetFeatureStatus(FeatureType_Native, "ZR_IsClientZombie") == FeatureStatus_Available);
#endif
}

public void OnMapEnd()
{
    StopTimer(g_tRound);
    StopTimer(g_tCooldown);
}

//public void OnEntityCreated(int entity, const char[] classname)
//{
//    if(g_extDHook && classname[0] == 'l' && strcmp(classname, "logic_compare", false) == 0)
//    {
//        PrintToServer("DHookEntity %s [%d]", classname, entity);
//        DHookEntity(hAcceptInput, true, entity);
//    }
//}

public void OnClientConnected(int client)
{
    g_bBanned[client] = false;
    g_bEntHud[client] = false;
}

public void OnClientCookiesCached(int client)
{
    char buffer_hud[32];
    GetClientCookie(client, g_Cookies[DisplayHud], buffer_hud, 32);
    if(StringToInt(buffer_hud) == 1)
        g_bEntHud[client] = true;

    char buffer_rej[32];
    GetClientCookie(client, g_Cookies[Restricted], buffer_rej, 32);
    if(StringToInt(buffer_rej) == 1)
        g_bBanned[client] = true;

    if(!g_bBanned[client])
        return;

    char buffer_ban[32];
    GetClientCookie(client, g_Cookies[BanTLength], buffer_ban, 32);
    int exp = StringToInt(buffer_ban);
    if(exp > 0 && exp < GetTime())
    {
        SetClientCookie(client, g_Cookies[Restricted], "0");
        SetClientCookie(client, g_Cookies[BanTLength], "-1");
        SetClientCookie(client, g_Cookies[BanByAdmin], "null");

        g_bBanned[client] = false;
    }
}

public void OnClientPutInServer(int client)
{
    if(!ClientIsValid(client))
        return;

    CS_GetClientClanTag(client, g_szClantag[client], 32);

    g_iScores[client] = 0;
    g_bHasEnt[client] = false;

    SDKHook(client, SDKHook_WeaponDropPost,  Event_WeaponDropPost);
    SDKHook(client, SDKHook_WeaponEquipPost, Event_WeaponEquipPost);
    SDKHook(client, SDKHook_WeaponCanUse,    Event_WeaponCanUse);
}

public void OnClientCommandKeyValues_Post(int client, KeyValues kv)
{
    char szCommmand[32];
    if(kv.GetSectionName(szCommmand, 32) && strcmp(szCommmand, "ClanTagChanged", false) == 0)
        kv.GetString("tag", g_szClantag[client], 32);
}

public void OnClientDisconnect(int client)
{
    if(!IsClientInGame(client))
        return;

    SDKUnhook(client, SDKHook_WeaponDropPost,  Event_WeaponDropPost);
    SDKUnhook(client, SDKHook_WeaponEquipPost, Event_WeaponEquipPost);
    SDKUnhook(client, SDKHook_WeaponCanUse,    Event_WeaponCanUse);

    StopTimer(g_tKnife[client]);

    if(g_bConfigLoaded && g_bHasEnt[client])
    {
        for(int index = 0; index < MAXENT; ++index)
            if(g_EntArray[index][ent_ownerid] == client)
            {
                if(g_EntArray[index][ent_autotrasfer])
                {
                    int target = AutoTarget(client);
                    if(target != -1)
                    {
                        TransferClientEnt(target, client, true);
                        continue;
                    }
                }

                int weapon = EntRefToEntIndex(g_EntArray[index][ent_weaponref]);

                g_EntArray[index][ent_ownerid] = -1;

                if(IsValidEdict(weapon))
                {
                    SDKHooks_DropWeapon(client, weapon);
                    RequestFrame(SetWeaponGlow, index);
                }

                ClearIcon(client);
                RefreshHud();

                Call_StartForward(g_Forward[OnDropped]);
                Call_PushCell(client);
                Call_PushCell(DR_OnDisconnect);
                Call_PushString(g_EntArray[index][ent_name]);
                Call_Finish();

#if defined USE_TRANSLATIONS
                tChatTeam(g_EntArray[index][ent_team], true, "%t", "disconnected with ent", client, g_EntArray[index][ent_name]);
#else
                ChatTeam(g_EntArray[index][ent_team], true, "\x0C%N\x01离开游戏时带着神器\x04%s", client, g_EntArray[index][ent_name]);
#endif
            }
    }

    if (IsPlayerAlive(client))
        StripWeapon(client, true);
}

static void ResetAllStats()
{
    for(int client = 1; client <= MaxClients; ++client)
        if(ClientIsValid(client))
            SetClientDefault(client);

    for(int index = 0; index < g_iEntCounts; index++)
    {
        if(g_EntArray[index][ent_buttonid] != -1)
            SDKUnhook(g_EntArray[index][ent_buttonid], SDKHook_Use, Event_ButtonUse);

        RemoveWeaponGlow(index);

        g_EntArray[index][ent_weaponref]      = -1;
        g_EntArray[index][ent_buttonid]       = -1;
        g_EntArray[index][ent_ownerid]        = -1;
        g_EntArray[index][ent_cooldowntime]   = -1;
        g_EntArray[index][ent_uses]           = 0;
        g_EntArray[index][ent_pickedup]       = false;
    }
}

public void Event_RoundStart(Event event, const char[] name, bool dontBroadcast)
{
    if(!g_bConfigLoaded)
    {
        for(int index = 0; index < g_aPreHammerId[Pre_Locked].Length; ++index)
            g_aPreHammerId[Pre_Locked].Set(index, -1.0);
        
        return;
    }

    g_szGlobalHud[ZOMBIE][0] = '\0';
    g_szGlobalHud[HUMANS][0] = '\0';
    ResetAllStats();

    if(g_tRound != null)
        KillTimer(g_tRound);
    g_tRound = CreateTimer(5.0, Timer_RoundStart);

    static ConVar mp_disconnect_kills_players = null;
    if(mp_disconnect_kills_players == null)
        mp_disconnect_kills_players = FindConVar("mp_disconnect_kills_players");

    mp_disconnect_kills_players.SetInt(0, true, true);

    static ConVar mp_weapons_glow_on_ground = null;
    if(mp_weapons_glow_on_ground == null)
        mp_weapons_glow_on_ground = FindConVar("mp_weapons_glow_on_ground");

    mp_weapons_glow_on_ground.SetInt(0, true, true);
}

public void Event_RoundEnd(Event event, const char[] name, bool dontBroadcast)
{
    if(!g_bConfigLoaded)
        return;

    StopTimer(g_tRound);
}

public Action Timer_RoundStart(Handle timer)
{
    g_tRound = null;

#if defined USE_TRANSLATIONS
    tChatAll("%t", "welcome message");
#else
    ChatAll("\x07当前服务器已启动entWatch \x0A::\x04Kyle Present\x0A::");
#endif

    return Plugin_Stop;
}

public void ZE_OnFirstInfected(int[] clients, int numClients, bool teleportOverride, bool teleport)
{
    for(int client = 0; client < numClients; ++client)
        DropClientEnt(client);
}

public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn)
{
    if(!motherInfect)
        return;
    
    DropClientEnt(client);
}

public void Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast)
{
    if(!g_bConfigLoaded)
        return;
    
    int client = GetClientOfUserId(event.GetInt("userid"));

    DropClientEnt(client);
}

static void DropClientEnt(int client)
{
    if(!g_bHasEnt[client])
        return;

    for(int index = 0; index < MAXENT; ++index)
        if(g_EntArray[index][ent_ownerid] == client)
        {
            int weaponid = EntRefToEntIndex(g_EntArray[index][ent_weaponref]);

            if(IsValidEdict(weaponid))
            {
                SDKHooks_DropWeapon(client, weaponid);
                RequestFrame(SetWeaponGlow, index);
            }

            g_EntArray[index][ent_ownerid] = -1;
            
            Call_StartForward(g_Forward[OnDropped]);
            Call_PushCell(client);
            Call_PushCell(DR_OnDeath);
            Call_PushString(g_EntArray[index][ent_name]);
            Call_Finish();

#if defined USE_TRANSLATIONS
            tChatTeam(g_EntArray[index][ent_team], true, "%t", "died with ent", client, g_EntArray[index][ent_name]);
#else
            ChatTeam(g_EntArray[index][ent_team], true, "\x0C%N\x01死亡时带着神器\x04%s", client, g_EntArray[index][ent_name]);
#endif
        }

    RefreshHud();
    SetClientDefault(client);
}

public void Event_PlayerTeams(Event e, const char[] name, bool dontBroadcast)
{
    g_iTeam[GetClientOfUserId(e.GetInt("userid"))] = e.GetInt("team");
}

public void OnEntityCreated(int entity, const char[] classname)
{
    if(StrContains(classname, "weapon_", false) != 0)
        return;

    SDKHook(entity, SDKHook_SpawnPost, Event_WeaponCreated);
}

public void Event_WeaponCreated(int entity)
{
    SDKUnhook(entity, SDKHook_SpawnPost, Event_WeaponCreated);

    if(!IsValidEdict(entity))
        return;

    RequestFrame(Event_CreatedPost, entity);
}

static void Event_CreatedPost(int entity)
{
    if(!IsValidEdict(entity))
        return;

    char classname[32];

    if(!GetEdictClassname(entity, classname, 32))
        return;

    int hammerid = GetEntityHammerID(entity);

    if(hammerid <= 0)
        return;

    for(int index = 0; index < g_iEntCounts; ++index)
        if(g_EntArray[index][ent_hammerid] == hammerid)
        {
            //PrintToServer("Event_WeaponCreated -> %d -> match -> %d", entity, hammerid);
            if(g_EntArray[index][ent_weaponref] == -1)
            {
                g_EntArray[index][ent_weaponref] = EntIndexToEntRef(entity);
                RequestFrame(SetWeaponGlow, index);
                //PrintToServer("Event_WeaponCreated -> %d -> Validate -> %d", entity, index);
                break;
            }
        }

    //PrintToServer("Event_WeaponCreated -> %d -> not found -> %d", entity, hammerid);
}

public void Event_WeaponEquipPost(int client, int weapon)
{
    if(!g_bConfigLoaded)
    {
        CheckPreConfigs(client, weapon);
        return;
    }

    int hamid = GetEntityHammerID(weapon);
    
    if(hamid <= 0)
        return;

    int iref = EntIndexToEntRef(weapon);
    
    int index = -1;
    for(int x = 0; x < g_iEntCounts; ++x)
        if(g_EntArray[x][ent_hammerid] == hamid)
            if(g_EntArray[x][ent_weaponref] == iref)
            {
                index = x;
                break;
            }

    if(index < 0)
        return;

    g_EntArray[index][ent_team] = g_iTeam[client];
    
    if(!g_EntArray[index][ent_pickedup])
        g_EntArray[index][ent_cooldowntime] = g_EntArray[index][ent_startcd];

    g_EntArray[index][ent_ownerid]   = client;
    g_EntArray[index][ent_pickedup]  = true;

    CreateIcon(client);
    RemoveWeaponGlow(index);

    g_bHasEnt[client] = true;
    g_iScores[client] = 999 - CS_GetClientContributionScore(client);
    g_fPickup[client] = GetGameTime();

    CS_SetClientContributionScore(client, 999);

    if(IsValidEdict(g_EntArray[index][ent_buttonid]))
        SDKHookEx(g_EntArray[index][ent_buttonid], SDKHook_Use, Event_ButtonUse);
    else if(g_EntArray[index][ent_buttonid] == -1 && g_EntArray[index][ent_mode] > 0 && strcmp(g_EntArray[index][ent_buttonclass], "func_button", false) == 0)
    {
        char buffer_targetname[32], buffer_parentname[32];
        GetEntityTargetName(weapon, buffer_targetname, 32);

        int button = -1;
        while((button = FindEntityByClassname(button, g_EntArray[index][ent_buttonclass])) != -1)
        {
            GetEntityParentName(button, buffer_parentname, 32);

            if(strcmp(buffer_targetname, buffer_parentname) == 0)
            {
                SDKHookEx(button, SDKHook_Use, Event_ButtonUse);
                g_EntArray[index][ent_buttonid] = button;
                //LogMessage("%N first picked %d:%d", client, weapon, button);
                break;
            }
        }
    }

    if(g_EntArray[index][ent_hasfiltername])
        DispatchKeyValue(client, "targetname", g_EntArray[index][ent_filtername]);

#if defined USE_TRANSLATIONS
    tChatTeam(g_EntArray[index][ent_team], true, "%t", "pickup ent", client, g_EntArray[index][ent_name]);
#else
    ChatTeam(g_EntArray[index][ent_team], true, "\x0C%N\x01捡起了神器\x04%s", client, g_EntArray[index][ent_name]);
#endif

    Call_StartForward(g_Forward[OnPicked]);
    Call_PushCell(client);
    Call_PushString(g_EntArray[index][ent_name]);
    Call_Finish();

    RefreshHud();
}

static void CheckPreConfigs(int client, int weapon)
{
    // Get HammerID
    int hammerid = GetEntityHammerID(weapon);
    if(hammerid <= 0) return;

    // if was stored.
    if(g_aPreHammerId[Pre_Weapon].FindValue(hammerid) != -1)
    {
        ChatAll("\x04PreConfigs \x01->\x10 Already record \x01[\x07%d\x01]", hammerid);
        return;
    }

    // Check targetname
    char targetname[128];
    GetEntityTargetName(weapon, targetname, 128);

    ChatAll("\x04PreConfigs \x01->\x05 targetname\x01[\x07%s\x01]", targetname);

    if(targetname[0] == '\0')
        return;

    // Find button
    int button = MaxClients+1;
    bool found = false;
    char parentname[128];
    while((button = FindEntityByClassname(button, "func_button")) != -1)
    {
        GetEntPropString(button, Prop_Data, "m_iParent", parentname, 128);

        // if match
        if(strcmp(targetname, parentname) == 0)
        {
            found = true;
            break;
        }
    }
    
    if(!found)
        button = -1;
    else ChatAll("\x04PreConfigs \x01->\x05 funcbutton\x01[\x07%d\x01]", button);

    DataPack pack;
    CreateDataTimer(0.2, Timer_CheckFilter, pack);
    pack.WriteCell(client);
    pack.WriteCell(weapon);
    pack.WriteCell(button);
    pack.WriteString(targetname);
    pack.WriteString(parentname);
}

static void SavePreConfigs(int weapon_hammerid, float cooldown)
{
    KeyValues kv = new KeyValues("entWatchPre");

    char path[256];
    GetCurrentMap(path, 256);
    BuildPath(Path_SM, path, 256, "configs/entWatchPre/%s.cfg", path);
    
    if(FileExists(path))
        kv.ImportFromFile(path);

    kv.Rewind();

    char buffer[32];
    IntToString(weapon_hammerid, buffer, 32);
    
    // check key exists
    if(!kv.JumpToKey(buffer, false))
    {
        delete kv;
        return;
    }

    kv.SetNum("cooldown", RoundToFloor(cooldown));

    // Save
    kv.Rewind();
    kv.ExportToFile(path);
    
    // close
    delete kv;
}

public Action Timer_CheckFilter(Handle timer, DataPack pack)
{
    pack.Reset();
    int client = pack.ReadCell();
    int weapon = pack.ReadCell();
    int button = pack.ReadCell();
    char targetname[128], parentname[128];
    pack.ReadString(targetname, 128);
    pack.ReadString(parentname, 128);

    if(!IsClientInGame(client) || !IsPlayerAlive(client) || !IsValidEdict(client))
        return Plugin_Stop;
    
    int hammerid = GetEntityHammerID(weapon);
    
    char filtername[128], clientname[128];
    GetEntityTargetName(client, clientname, 128);

    ChatAll("\x04PreConfigs \x01->\x05 clientname\x01[\x07%s\x01]", clientname);
    
    int iFilter = -1;
    bool found = false;
    while((iFilter = FindEntityByClassname(iFilter, "filter_activator_name")) != -1)
    {
        GetEntPropString(iFilter, Prop_Data, "m_iFilterName", filtername, 128);
        
        if(strcmp(clientname, filtername) == 0)
        {
            found = true;
            break;
        }
    }
    
    if(!found)
        strcopy(filtername, 128, "null");

    ChatAll("\x04PreConfigs \x01->\x05 filtername\x01[\x07%s\x01]", filtername);

    KeyValues kv = new KeyValues("entWatchPre");

    char path[256];
    GetCurrentMap(path, 256);
    BuildPath(Path_SM, path, 256, "configs/entWatchPre/%s.cfg", path);

    if(FileExists(path))
        kv.ImportFromFile(path);

    kv.Rewind();

    char kvstringid[16];
    IntToString(hammerid, kvstringid, 16);
    
    // store in array
    g_aPreHammerId[Pre_Weapon].Push(hammerid);
    g_aPreHammerId[Pre_Button].Push(button == -1 ? -1 : GetEntityHammerID(button));
    g_aPreHammerId[Pre_Locked].Push(-1.0);

    if(kv.JumpToKey(kvstringid, false))
    {
        int cooldown = kv.GetNum("cooldown");
        if(cooldown > 0)
        {
            g_aPreHammerId[Pre_Button].Set(g_aPreHammerId[Pre_Button].Length-1, -1);
            g_aPreHammerId[Pre_Locked].Set(g_aPreHammerId[Pre_Locked].Length-1, cooldown);
        }
        return Plugin_Stop;
    }

    // create key
    kv.JumpToKey(kvstringid, true);

    // set name
    kv.SetString("name",      targetname);
    kv.SetString("shortname", targetname);
 
    // set button
    kv.SetString("buttonclass", button == -1 ? "" : "func_button");
    
    // filtername
    kv.SetString("filtername",    found ? filtername : "null");
    kv.SetString("hasfiltername", found ? "true"     : "false");
    
    // hammerid
    kv.SetString("hammerid", kvstringid);

    // set default
    kv.SetString("mode",      "0");
    kv.SetString("maxuses",   "0");
    kv.SetString("cooldown",  "0");
    kv.SetString("maxamount", "1");
    kv.SetString("glow",      "true");
    kv.SetString("team",      IsInfector(client) ? "zombie" : "human");
    kv.SetString("hud",       "true");

    // Save
    kv.Rewind();
    kv.ExportToFile(path);
    
    // close
    delete kv;

    if(button != -1 && g_extDHook)
    {
        //PrintToServer("DHookEntity func_button [%d]", button);
        DHookEntity(hAcceptInput, true, button);
    }

    ChatAll("\x04PreConfigs \x01->\x10 Record the data successfully", filtername);

    return Plugin_Stop;
}

public void Event_WeaponDropPost(int client, int weapon)
{
    if(!IsValidEdict(weapon))
        return;

    if(g_bConfigLoaded)
    {
        int index = FindIndexByEntityRef(EntIndexToEntRef(weapon));

        if(index >= 0)
        {
            SetClientDefault(client);
            RequestFrame(SetWeaponGlow, index);

            g_EntArray[index][ent_ownerid] = -1;
            
            if(g_EntArray[index][ent_buttonid] != -1)
                SDKUnhook(g_EntArray[index][ent_buttonid], SDKHook_Use, Event_ButtonUse);

#if defined USE_TRANSLATIONS
            tChatTeam(g_EntArray[index][ent_team], true, "%t", "droped ent", client, g_EntArray[index][ent_name]);
#else
            ChatTeam(g_EntArray[index][ent_team], true, "\x0C%N\x01丟掉了神器\x04%s", client, g_EntArray[index][ent_name]);
#endif

            RefreshHud();
            
            Call_StartForward(g_Forward[OnDropped]);
            Call_PushCell(client);
            Call_PushCell(DR_NormalDrop);
            Call_PushString(g_EntArray[index][ent_name]);
            Call_Finish();

            return;
        }
    }

    char targetname[32];
    GetEntityTargetName(weapon, targetname, 32);
    if(targetname[0] != '\0')
        return;

    if(GetEntPropEnt(weapon, Prop_Data, "m_hMoveChild") != -1)
        return;

    AcceptEntityInput(weapon, "KillHierarchy");
    //if(!SelfKillEntityEx(weapon, 15.0)) AcceptEntityInput(weapon, "KillHierarchy");
}

public Action Event_SetTransmit(int entity, int client)
{
    if(g_iEntTeam[entity] <= 1 || g_iTeam[client] <= 1)
        return Plugin_Continue;

    return g_iEntTeam[entity] == g_iTeam[client] ? Plugin_Continue : Plugin_Handled;
}

static void SetClientDefault(int client)
{
    ClearIcon(client);

    g_bHasEnt[client] = false;

    CS_SetClientContributionScore(client, CS_GetClientContributionScore(client) - g_iScores[client]);
    CS_SetClientClanTag(client, g_szClantag[client]);
}

static bool IsWeaponKnife(int weapon)
{
    char classname[32];
    GetEdictClassname(weapon, classname, 32);
    return (strcmp(classname, "weapon_knife") == 0);
}

public Action Event_WeaponCanUse(int client, int weapon)
{
    if(!IsValidEdict(weapon))
        return Plugin_Handled;

    if(!IsPlayerAlive(client))
        return Plugin_Handled;
    
    bool knife = IsWeaponKnife(weapon);

    if(IsInfector(client) && !knife)
        return Plugin_Handled;

    if(!g_bConfigLoaded)
        return Plugin_Continue;

    if(GetEntPropEnt(weapon, Prop_Data, "m_hMoveChild") == -1)
        return Plugin_Continue;

    int index = FindIndexByHammerId(GetEntityHammerID(weapon));

    if(index < 0)
        return Plugin_Continue;

    bool allow = true;
    Call_StartForward(g_Forward[OnPick]);
    Call_PushCell(client);
    Call_PushString(g_EntArray[index][ent_name]);
    Call_Finish(allow);

    if(allow && CanClientUseEnt(client))
    {
        // allow to pick up
        return Plugin_Continue;
    }

    if(knife)
    {
        // knife stripper?
        CheckClientKnife(client);
    }

    return Plugin_Handled;
}

static bool CanClientUseEnt(int client)
{
    if(g_bBanned[client])
    {
#if defined USE_TRANSLATIONS
        Text(client, "%t", "has been banned centertext");
#else
        Text(client, "你神器被BAN了,\n请到论坛申诉!");
#endif
        return false;
    }

    return true;
}

public Action Event_ButtonUse(int button, int activator, int caller, UseType type, float value)
{
    if(!g_bConfigLoaded || !IsValidEdict(button) || !ClientIsAlive(activator))
        return Plugin_Continue;
    
    //LogMessage("%N pressing %d : %d", activator, button, GetEntityHammerID(button));
    //LogMessage("%d parent is %d", button, GetEntPropEnt(button, Prop_Data, "m_pParent"));

    int index = FindIndexByButton(button);

    if(index < 0)
    {
        //LogMessage("Event_ButtonUse -> %N -> FindIndexByButton -> %d : %d", activator, button, GetEntityHammerID(button));
        return Plugin_Handled;
    }

    if(g_EntArray[index][ent_ownerid] != activator)
    {
        //LogMessage("Event_ButtonUse -> %N -> activator", activator);
        return Plugin_Handled;
    }

    if(g_fPickup[activator]+1.5 > GetGameTime())
    {
        //LogMessage("Event_ButtonUse -> %N -> g_fPickup", activator);
        return Plugin_Handled;
    }

    int iOffset = FindDataMapInfo(button, "m_bLocked");

    if(iOffset != -1 && GetEntData(button, iOffset, 1))
    {
        //LogMessage("Event_ButtonUse -> %N -> iOffset", activator);
        return Plugin_Handled;
    }

    if(g_EntArray[index][ent_team] != g_iTeam[activator])
    {
        //LogMessage("Event_ButtonUse -> %N -> GetClientTeam");
        return Plugin_Handled;
    }

    if(g_EntArray[index][ent_hasfiltername])
        DispatchKeyValue(activator, "targetname", g_EntArray[index][ent_filtername]);
    
    bool allow = true;
    Call_StartForward(g_Forward[OnUse]);
    Call_PushCell(activator);
    Call_PushString(g_EntArray[index][ent_name]);
    Call_Finish(allow);

    if(!allow)
        return Plugin_Handled;

    if(g_EntArray[index][ent_mode] == 1)
    {
        AddClientScore(activator, 1);
        return Plugin_Continue;
    }
    else if(g_EntArray[index][ent_mode] == 2 && g_EntArray[index][ent_cooldowntime] <= 0)
    {
        g_EntArray[index][ent_cooldowntime] = g_EntArray[index][ent_cooldown];

#if defined USE_TRANSLATIONS
        tChatTeam(g_EntArray[index][ent_team], true, "%t", "used ent and cooldown", activator, g_EntArray[index][ent_name], g_EntArray[index][ent_cooldown]);
#else
        ChatTeam(g_EntArray[index][ent_team], true, "\x0C%N\x01使用了神器\x04%s\x01[\x04CD\x01:\x07%d\x04秒\x01]", activator, g_EntArray[index][ent_name], g_EntArray[index][ent_cooldown]);
#endif

        RefreshHud();
        AddClientScore(activator, 3);

        return Plugin_Continue;
    }
    else if(g_EntArray[index][ent_mode] == 3 && g_EntArray[index][ent_uses] < g_EntArray[index][ent_maxuses], activator, g_EntArray[index][ent_name], g_EntArray[index][ent_maxuses]-g_EntArray[index][ent_uses])
    {
        g_EntArray[index][ent_uses]++;

#if defined USE_TRANSLATIONS
        tChatTeam(g_EntArray[index][ent_team], true, "%t", "used ent and maxuses", activator, g_EntArray[index][ent_name], g_EntArray[index][ent_maxuses]-g_EntArray[index][ent_uses]);
#else       
        ChatTeam(g_EntArray[index][ent_team], true, "\x0C%N\x01使用了神器\x04%s\x01[\x04剩余\x01:\x07%d\x04次\x01]", activator, g_EntArray[index][ent_name], g_EntArray[index][ent_maxuses]-g_EntArray[index][ent_uses]);
#endif

        RefreshHud();
        AddClientScore(activator, 3);
        
        return Plugin_Continue;
    }
    else if(g_EntArray[index][ent_mode] == 4 && g_EntArray[index][ent_uses] < g_EntArray[index][ent_maxuses] && g_EntArray[index][ent_cooldowntime] <= 0)
    {
        g_EntArray[index][ent_cooldowntime] = g_EntArray[index][ent_cooldown];
        g_EntArray[index][ent_uses]++;

#if defined USE_TRANSLATIONS
        tChatTeam(g_EntArray[index][ent_team], true, "%t", "used ent and cd maxuses", activator, g_EntArray[index][ent_name], g_EntArray[index][ent_cooldown], g_EntArray[index][ent_maxuses]-g_EntArray[index][ent_uses]);
#else
        ChatTeam(g_EntArray[index][ent_team], true, "\x0C%N\x01使用了神器\x04%s\x01[\x04CD\x01:\x07%ds\x01|\x04剩余\x01:\x07%d\x04次\x01]", activator, g_EntArray[index][ent_name], g_EntArray[index][ent_cooldown], g_EntArray[index][ent_maxuses]-g_EntArray[index][ent_uses]);
#endif
        
        RefreshHud();
        AddClientScore(activator, 5);

        return Plugin_Continue;
    }
    else if(g_EntArray[index][ent_mode] == 5 && g_EntArray[index][ent_cooldowntime] <= 0)
    {
#if defined USE_TRANSLATIONS
        tChatTeam(g_EntArray[index][ent_team], true, "%t", "used ent and times cd", activator, g_EntArray[index][ent_name], g_EntArray[index][ent_maxuses]-g_EntArray[index][ent_uses]);
#else
        ChatTeam(g_EntArray[index][ent_team], true, "\x0C%N\x01使用了神器\x04%s\x01[\x04使用%d次后冷却\x01]", activator, g_EntArray[index][ent_name], g_EntArray[index][ent_maxuses]-g_EntArray[index][ent_uses]);
#endif

        g_EntArray[index][ent_uses]++;
        
        if(g_EntArray[index][ent_uses] >= g_EntArray[index][ent_maxuses])
        {
#if defined USE_TRANSLATIONS
            tChatTeam(g_EntArray[index][ent_team], true, "%t", "used ent and used times into cd", g_EntArray[index][ent_name], g_EntArray[index][ent_cooldown]);
#else
            ChatTeam(g_EntArray[index][ent_team], true, "神器\x04%s\x01[\x04CD\x01:\x07%d\x04秒\x01]", g_EntArray[index][ent_name], g_EntArray[index][ent_cooldown]);
#endif

            g_EntArray[index][ent_cooldowntime] = g_EntArray[index][ent_cooldown];
            g_EntArray[index][ent_uses] = 0;
        }

        RefreshHud();
        AddClientScore(activator, 3);
        
        return Plugin_Continue;
    }

    return Plugin_Handled;
}

public MRESReturn Event_AcceptInput(int pThis, Handle hReturn, Handle hParams)
{
    if(!IsValidEntity(pThis))
        return MRES_Ignored;
    
    char classname[32];
    GetEntityClassname(pThis, classname, 32);

    char command[128];
    DHookGetParamString(hParams, 1, command, 128);
    //PrintToServer("Event_AcceptInput pThis -> %d.%s -> %s", pThis, classname, command);

    // Tested on ze_sandstorm_go_v1_3
    if(strcmp(classname, "func_button") == 0)
    {
        if(strcmp(command, "Lock", false) == 0)
        {
            int index = g_aPreHammerId[Pre_Button].FindValue(GetEntityHammerID(pThis));
            if(index > -1)
                g_aPreHammerId[Pre_Locked].Set(index, GetGameTime());
        }
        else if(strcmp(command, "Unlock", false) == 0)
        {
            int index = g_aPreHammerId[Pre_Button].FindValue(GetEntityHammerID(pThis));
            if(index > -1)
            {
                float locked = g_aPreHammerId[Pre_Locked].Get(index);
                if(locked > 0.0)
                {
                    float cooldown = GetGameTime() - locked;
                    SavePreConfigs(g_aPreHammerId[Pre_Weapon].Get(index), cooldown);
                    g_aPreHammerId[Pre_Button].Set(index, -1);
                }
            }
        }
    }
    // Tested on ze_FFVII_Mako_Reactor_v5_3_v5 ? bug
    //else if(strcmp(classname, "logic_compare") == 0)
    //{
    //    int type = -1;
    //    float fVal = 0.0;
    //    type = DHookGetParamObjectPtrVar(hParams, 4, 16, ObjectValueType_Int);
    //
    //    if(type == 1) 
    //        fVal = DHookGetParamObjectPtrVar(hParams, 4, 0, ObjectValueType_Float);
    //    else if(type == 2)
    //    {
    //        char val[32];
    //        DHookGetParamObjectPtrString(hParams, 4, 0, ObjectValueType_String, val, 128);
    //        StringToFloatEx(val, fVal);
    //    }
    //
    //    if(strcmp(command, "SetCompareValue", false) == 0)
    //    {
    //        int index = g_aPreHammerId[Pre_Button].FindValue(GetEntityHammerID(pThis));
    //        if(index > -1)
    //        {
    //            float locked = g_aPreHammerId[Pre_Locked].Get(index);
    //            if(locked == -1.0)
    //            {
    //                g_aPreHammerId[Pre_Locked].Set(index, GetGameTime());
    //            }
    //            else
    //            {
    //                float cooldown = GetGameTime() - locked;
    //                SavePreConfigs(g_aPreHammerId[Pre_Weapon].Get(index), cooldown);
    //                g_aPreHammerId[Pre_Button].Set(index, -1);
    //            }
    //        }
    //    }
    //}

    return MRES_Ignored;
}

public Action Timer_Cooldowns(Handle timer)
{
    if(!g_bConfigLoaded)
    {
        g_tCooldown = null;
        return Plugin_Stop;
    }
    
    for(int index = 0; index < g_iEntCounts; index++)
        if(g_EntArray[index][ent_cooldowntime] > 0)
            g_EntArray[index][ent_cooldowntime]--;

    RefreshHud();

    return Plugin_Continue;
}

static void RefreshHud()
{
    strcopy(g_szGlobalHud[ZOMBIE], 2048, "[!ehud] Zombie entWatch: ");
    strcopy(g_szGlobalHud[HUMANS], 2048, "[!ehud] Humans entWatch: ");

    for(int index = 0; index < g_iEntCounts; index++)
    {
        CountdownMessage(index);
        BuildHUDandScoreboard(index);
    }

    if(strcmp(g_szGlobalHud[ZOMBIE], "[!ehud] Zombie entWatch: ") == 0)
        g_szGlobalHud[ZOMBIE][0] = '\0';
        //Format(g_szGlobalHud[ZOMBIE], 2048, "%s\n", g_szGlobalHud[ZOMBIE]);

    if(strcmp(g_szGlobalHud[HUMANS], "[!ehud] Humans entWatch: ") == 0)
        g_szGlobalHud[HUMANS][0] = '\0';
        //Format(g_szGlobalHud[HUMANS], 2048, "%s\n", g_szGlobalHud[HUMANS]);

    SetHudTextParams(0.160500, 0.099000, 2.0, 57, 197, 187, 255, 0, 30.0, 0.0, 0.0);

    for(int client = 1; client <= MaxClients; ++client)
        if(IsClientInGame(client) && !g_bEntHud[client])
            ShowHudText(client, 5, IsInfector(client) ? g_szGlobalHud[ZOMBIE] : g_szGlobalHud[HUMANS]);
}

static void CountdownMessage(int index)
{
    if(g_EntArray[index][ent_mode] == 4 || g_EntArray[index][ent_mode] == 2 || g_EntArray[index][ent_mode] == 5)
    {
        if(ClientIsAlive(g_EntArray[index][ent_ownerid]))
        {
            if(!g_bEntHud[g_EntArray[index][ent_ownerid]])
            {
                if(g_EntArray[index][ent_cooldowntime] > 0)
                {
                    SetHudTextParams(-1.0, 0.05, 2.0, 205, 173, 0, 255, 0, 30.0, 0.0, 0.0);
                    ShowHudText(g_EntArray[index][ent_ownerid], 6, ">>> [%s] :  %ds <<< ", g_EntArray[index][ent_name], g_EntArray[index][ent_cooldowntime]);
                }
                else
                {
                    SetHudTextParams(-1.0, 0.05, 2.0, 0, 255, 0, 255, 0, 30.0, 0.0, 0.0);
#if defined USE_TRANSLATIONS
                    ShowHudText(g_EntArray[index][ent_ownerid], 6, "%t[%s]%t", "Item", g_EntArray[index][ent_name], "Ready");
#else
                    ShowHudText(g_EntArray[index][ent_ownerid], 6, "神器[%s]就绪", g_EntArray[index][ent_name]);
#endif
                }
            }
        }
        else if(g_EntArray[index][ent_cooldowntime] == 1)
        {
            SMUtils_SkipNextChatCS();
#if defined USE_TRANSLATIONS
            tChatTeam(g_EntArray[index][ent_team], true, "%t", "cooldown end no owner", g_EntArray[index][ent_name]);
#else        
            ChatTeam(g_EntArray[index][ent_team], true, "\x07%s\x04冷却时间已结束\x01[\x07无人使用\x01]", g_EntArray[index][ent_name]);
#endif
            CreateTimer(1.1, Timer_RefreshGlow, index);
        }
    }
    else if(ClientIsValid(g_EntArray[index][ent_ownerid]))
    {
        if(g_EntArray[index][ent_mode] == 3 && g_EntArray[index][ent_uses] >= g_EntArray[index][ent_maxuses])
        {
            if(!g_bEntHud[g_EntArray[index][ent_ownerid]])
            {
                SetHudTextParams(-1.0, 0.05, 2.0, 255, 0, 0, 233, 0, 30.0, 0.0, 0.0);
#if defined USE_TRANSLATIONS
                ShowHudText(g_EntArray[index][ent_ownerid], 6, "%t[%s]%t", "Item", g_EntArray[index][ent_name], "Deplete");
#else
                ShowHudText(g_EntArray[index][ent_ownerid], 6, "神器[%s]耗尽", g_EntArray[index][ent_name]);
#endif
            }
        }
        else
        {
            if(!g_bEntHud[g_EntArray[index][ent_ownerid]])
            {
                SetHudTextParams(-1.0, 0.05, 2.0, 0, 255, 0, 255, 0, 30.0, 0.0, 0.0);
#if defined USE_TRANSLATIONS
                ShowHudText(g_EntArray[index][ent_ownerid], 6, "%t[%s]%t", "Item", g_EntArray[index][ent_name], "Ready");
#else
                ShowHudText(g_EntArray[index][ent_ownerid], 6, "神器[%s]就绪", g_EntArray[index][ent_name]);
#endif
            }
        }
    }
}

public Action Timer_RefreshGlow(Handle timer, int index)
{
    if(ClientIsAlive(g_EntArray[index][ent_ownerid]))
        return Plugin_Stop;

    RemoveWeaponGlow(index);
    //PrintToServer("[Timer_RefreshGlow] -> %d", index);
    RequestFrame(SetWeaponGlow, index);

    return Plugin_Stop;
}

static void BuildHUDandScoreboard(int index)
{
    if(!g_EntArray[index][ent_displayhud])
        return;

    char szClantag[32], szGameText[128];
    strcopy(szClantag, 32, g_EntArray[index][ent_short]);

    if(ClientIsAlive(g_EntArray[index][ent_ownerid]))
    {   
        switch(g_EntArray[index][ent_mode])
        {
            case 1: FormatEx(szGameText, 128, "%s[R]: %N", g_EntArray[index][ent_name], g_EntArray[index][ent_ownerid]);
            case 2:
            {
                if(g_EntArray[index][ent_cooldowntime] <= 0)
                    FormatEx(szGameText, 128, "%s[R]: %N", g_EntArray[index][ent_name], g_EntArray[index][ent_ownerid]);
                else
                    FormatEx(szGameText, 128, "%s[%d]: %N", g_EntArray[index][ent_name], g_EntArray[index][ent_cooldowntime], g_EntArray[index][ent_ownerid]);
            }
            case 3:
            {
                if(g_EntArray[index][ent_maxuses] > g_EntArray[index][ent_uses])
                    FormatEx(szGameText, 128, "%s[R]: %N", g_EntArray[index][ent_name], g_EntArray[index][ent_ownerid]);
                else
                    FormatEx(szGameText, 128, "%s[N]: %N", g_EntArray[index][ent_name], g_EntArray[index][ent_ownerid]);
            }
            case 4:
            {
                if(g_EntArray[index][ent_cooldowntime] <= 0)
                {
                    if(g_EntArray[index][ent_maxuses] > g_EntArray[index][ent_uses])
                        FormatEx(szGameText, 128, "%s[R]: %N", g_EntArray[index][ent_name], g_EntArray[index][ent_ownerid]);
                    else
                        FormatEx(szGameText, 128, "%s[N]: %N", g_EntArray[index][ent_name], g_EntArray[index][ent_ownerid]);
                }
                else
                    FormatEx(szGameText, 128, "%s[%d]: %N", g_EntArray[index][ent_name], g_EntArray[index][ent_cooldowntime], g_EntArray[index][ent_ownerid]);
            }
            case 5:
            {
                if(g_EntArray[index][ent_cooldowntime] <= 0)
                    FormatEx(szGameText, 128, "%s[R]: %N", g_EntArray[index][ent_name], g_EntArray[index][ent_ownerid]);
                else
                    FormatEx(szGameText, 128, "%s[%d]: %N", g_EntArray[index][ent_name], g_EntArray[index][ent_cooldowntime], g_EntArray[index][ent_ownerid]);
            }
            default: FormatEx(szGameText, 128, "%s[R]: %N", g_EntArray[index][ent_name], g_EntArray[index][ent_ownerid]);
        }

        CS_SetClientClanTag(g_EntArray[index][ent_ownerid], szClantag);
        Format(g_szGlobalHud[g_EntArray[index][ent_team] - 2], 2048, "%s\n%s", g_szGlobalHud[g_EntArray[index][ent_team] - 2], szGameText);
    }
}

public Action Command_entWatch(int client, int args)
{
    // ....
    // Todo
    // ....
    Command_Stats(client, 0);
    return Plugin_Handled;
}

public Action Command_Stats(int client, int args)
{
    if(!AreClientCookiesCached(client))
    {
#if defined USE_TRANSLATIONS
        Chat(client, "%T", "ent data not cached", client);
#else
        Chat(client, "请等待你的数据加载完毕...");
#endif
        return Plugin_Handled;
    }

    if(!g_bBanned[client])
    {
#if defined USE_TRANSLATIONS
        Chat(client, "%T", "ent not ban", client);
#else
        Chat(client, "你的神器信用等级\x04良好\x01...");
#endif
        return Plugin_Handled;
    }

    char buffer_admin[32], buffer_timer[32];
    GetClientCookie(client, g_Cookies[BanByAdmin], buffer_admin, 32);
    GetClientCookie(client, g_Cookies[BanTLength], buffer_timer, 32);
    
    int exp = StringToInt(buffer_timer);
    FormatTime(buffer_timer, 32, "%Y/%m/%d - %H:%M:%S", exp);

#if defined USE_TRANSLATIONS
    Chat(client, "%T", "ent ban info", client, buffer_admin, buffer_timer);
#else
    Chat(client, "你的神器被 \x0C%N\x01 封禁了 [到期时间 \x07%s\x01]", buffer_admin, buffer_timer);
#endif

    return Plugin_Handled;
}

public Action Command_DisplayHud(int client, int args)
{
    if(!AreClientCookiesCached(client))
    {
#if defined USE_TRANSLATIONS
        Chat(client, "%T", "ent data not cached", client);
#else
        Chat(client, "请等待你的数据加载完毕...");
#endif
        return Plugin_Handled;
    }

    g_bEntHud[client] = !g_bEntHud[client];
    SetClientCookie(client, g_Cookies[DisplayHud], g_bEntHud[client] ? "1" : "0");

    Chat(client, "entWatch HUD is \x02%s\x01!", g_bEntHud[client] ? "\x07Off\x01" : "\x04On\x01");

    return Plugin_Handled;
}

public Action Command_Restrict(int client, int args)
{
    if(!client)
        return Plugin_Handled;
    
    DisplayMenu_Restrict(client);

    return Plugin_Handled;
}

static void DisplayMenu_Restrict(int client)
{
    Menu menu = new Menu(MenuHandler_Ban);
    
    menu.SetTitle("[entWatch]  Ban Menu\n ");

    char m_szId[8], m_szName[64];
    
    for(int x = 1; x <= MaxClients; ++x)
    {
        if(!IsClientInGame(x) || g_bBanned[x])
            continue;

        FormatEx(m_szId,    8, "%d", GetClientUserId(x));
        FormatEx(m_szName, 64, "  %N (%s)", x, m_szId);

        menu.AddItem(m_szId, m_szName);
    }

    if(menu.ItemCount < 1)
    {
        Chat(client, "No player in target list");
        delete menu;
        return;
    }

    menu.Display(client, 30);
}

public int MenuHandler_Ban(Menu menu, MenuAction action, int client, int itemNum) 
{
    if(action == MenuAction_Select) 
    {
        char info[32];
        menu.GetItem(itemNum, info, 32);
        BuildBanLengthMenu(client, info);
    }
    else if(action == MenuAction_End)
        delete menu;
}

static void BuildBanLengthMenu(int client, const char[] target)
{
    int m = GetClientOfUserId(StringToInt(target));
    if(!m)
    {
        Chat(client, "Target client disconnected.");
        return;
    }

    Menu menu = new Menu(MenuHandler_Time);
    
    menu.SetTitle("[entWatch]  Select Time\n Target: %N\n ", m);

    menu.AddItem(target, "", ITEMDRAW_IGNORE);

    menu.AddItem("1",   "1 Hour");
    menu.AddItem("2",   "1 Day");
    menu.AddItem("168", "1 Week");
    menu.AddItem("0",   "Permanent");

    menu.Display(client, 30);
}

public int MenuHandler_Time(Menu menu, MenuAction action, int client, int itemNum) 
{
    if(action == MenuAction_Select) 
    {
        char info[32];
        menu.GetItem(0, info, 32);
        int target = StringToInt(info);

        menu.GetItem(itemNum, info, 32);
        BanClientEnt(client, GetClientOfUserId(target), StringToInt(info));
    }
    else if(action == MenuAction_End)
        delete menu;
}

static void BanClientEnt(int client, int target, int time)
{
    if(!ClientIsValid(target))
    {
        Chat(client, "Target is not in server");
        return;
    }

    if(g_bHasEnt[target])
    {
        for(int index = 0; index < MAXENT; ++index)
            if(g_EntArray[index][ent_ownerid] == client)
            {
                g_EntArray[index][ent_ownerid] = -1;

                int weapon_index_1 = GetPlayerWeaponSlot(target, 1);
                int weapon_index_2 = GetPlayerWeaponSlot(target, 2);
                
                int weapon = EntRefToEntIndex(g_EntArray[index][ent_weaponref]);
                
                if(IsValidEdict(weapon))
                {
                    if(weapon_index_1 == weapon || weapon_index_2 == weapon)
                    {
                        SDKHooks_DropWeapon(target, weapon);
                        RequestFrame(SetWeaponGlow, index);

#if defined USE_TRANSLATIONS
                        tChatTeam(g_EntArray[index][ent_team], true, "%t", "ent dropped", g_EntArray[index][ent_name]);
#else
                        ChatTeam(g_EntArray[index][ent_team], true, "\x04%s\x0C已掉落", g_EntArray[index][ent_name]);
#endif

                        Call_StartForward(g_Forward[OnDropped]);
                        Call_PushCell(client);
                        Call_PushCell(DR_OnBanned);
                        Call_PushString(g_EntArray[index][ent_name]);
                        Call_Finish();
                    }
                }
            }

        SetClientDefault(client);
    }
    
    char szTime[32];
    if(time == 0)
        strcopy(szTime, 32, "0");
    else
        FormatEx(szTime, 32, "%d", GetTime()+60*time);
    
    char szAdmin[32];
    GetClientName(client, szAdmin, 32);

    g_bBanned[target] = true;
    SetClientCookie(target, g_Cookies[Restricted], "1");
    SetClientCookie(target, g_Cookies[BanByAdmin], szAdmin);
    SetClientCookie(target, g_Cookies[BanTLength], szTime);

#if defined USE_TRANSLATIONS
    switch(time)
    {
        case   0: FormatEx(szTime, 32, "%T", "permanent", client);
        case   1: FormatEx(szTime, 32, "%T", "1 hour",    client);
        case  24: FormatEx(szTime, 32, "%T", "1 day",     client);
        case 168: FormatEx(szTime, 32, "%T", "1 week",    client);
    }
#else
    switch(time)
    {
        case   0: strcopy(szTime, 32, "永久");
        case   1: strcopy(szTime, 32, "1时");
        case  24: strcopy(szTime, 32, "1天");
        case 168: strcopy(szTime, 32, "1周");
    }
#endif

    Call_StartForward(g_Forward[OnBanned]);
    Call_PushCell(target);
    Call_Finish();

#if defined USE_TRANSLATIONS
    tChatAll("%t", "ban ent", target, client, szTime);
#else
    ChatAll("小朋友\x07%N\x01因为乱玩神器,被dalao\x04%N\x07ban神器[%s]", target, client, szTime);
#endif

    LogAction(client, -1, "%L ban %L => %s [entWatch]", client, target, szTime);
}

public Action Command_Unrestrict(int client, int args)
{
    if(!client)
        return Plugin_Handled;
    
    DisplayMenu_Unrestrict(client);

    return Plugin_Handled;
}

static void DisplayMenu_Unrestrict(int client)
{
    Menu menu = new Menu(MenuHandler_Unban);

    menu.SetTitle("[entWatch]  UnBan\n ");

    char m_szId[8], m_szName[64];

    for(int x = 1; x <= MaxClients; ++x)
    {
        if(!IsClientInGame(x))
            continue;
        
        if(!g_bBanned[x])
            continue;

        FormatEx(m_szId,    8, "%d", GetClientUserId(x));
        FormatEx(m_szName, 64, "  %N (%s)", x, m_szId);
        
        menu.AddItem(m_szId, m_szName);
    }

    if(menu.ItemCount < 1)
    {
        Chat(client, "No player in target list");
        delete menu;
        return;
    }

    menu.Display(client, 30);
}

public int MenuHandler_Unban(Menu menu, MenuAction action, int client, int itemNum) 
{
    if(action == MenuAction_Select) 
    {
        char info[32];
        menu.GetItem(itemNum, info, 32);

        int target = GetClientOfUserId(StringToInt(info));

        UnestrictClientEnt(client, target);
    }
    else if(action == MenuAction_End)
        delete menu;
}

static void UnestrictClientEnt(int client, int target)
{
    if(!IsClientInGame(client))
        return;
    
    if(!ClientIsValid(target))
    {
        Chat(client, "Target is not in server.");
        return;
    }

    g_bBanned[target] = false;
    SetClientCookie(target, g_Cookies[Restricted], "0");
    SetClientCookie(target, g_Cookies[BanTLength], "-1");
    SetClientCookie(target, g_Cookies[BanByAdmin], "null");

#if defined USE_TRANSLATIONS
    tChatAll("%t", "unban ent", target, client);
#else
    ChatAll("小朋友\x07%N\x01的\x07ban神器\x01被dalao\x04%N\x01解开了", target, client);
#endif

    LogAction(client, -1, "%L unban %L [entWatch]", client, target);

    Call_StartForward(g_Forward[OnUnban]);
    Call_PushCell(target);
    Call_Finish();
}

public Action Command_Transfer(int client, int args)
{
    if(!g_bConfigLoaded || !client)
        return Plugin_Handled;

    DisplayMenu_Transfer(client);
    
    return Plugin_Handled;
}

static void DisplayMenu_Transfer(int client)
{
    Menu menu = new Menu(MenuHandler_Transfer);
    
    menu.SetTitle("[entWatch]  Transfer\n ");

    char m_szId[8], m_szName[64];
    
    for(int x = 1; x <= MaxClients; ++x)
    {
        if(!IsClientInGame(x))
            continue;
        
        if(!g_bHasEnt[x])
            continue;

        if(g_iTeam[client] != g_iTeam[x])
            continue;

        FormatEx(m_szId,    8, "%d", GetClientUserId(x));
        FormatEx(m_szName, 64, "  %N (%s)", x, m_szId);
        
        menu.AddItem(m_szId, m_szName);
    }

    if(menu.ItemCount < 1)
    {
        Chat(client, "No one pickup item.");
        delete menu;
        return;
    }

    menu.Display(client, 30);
}

public int MenuHandler_Transfer(Menu menu, MenuAction action, int client, int itemNum) 
{
    if(action == MenuAction_Select) 
    {
        char info[32];
        menu.GetItem(itemNum, info, 32);
        
        int target = GetClientOfUserId(StringToInt(info));
        
        TransferClientEnt(client, target);
    }
    else if(action == MenuAction_End)
    {
        delete menu;
    }
}

static void TransferClientEnt(int client, int target, bool autoTransfer = false)
{
    if(!ClientIsAlive(target))
    {
        Chat(client, "Target is invalid.");
        return;
    }

    for(int index = 0; index < MAXENT; ++index)
        if(g_EntArray[index][ent_ownerid] == target)
        {
            int weapon = EntRefToEntIndex(g_EntArray[index][ent_weaponref]);
            
            char buffer_classname[64];
            GetEdictClassname(weapon, buffer_classname, 64);
            
            SDKHooks_DropWeapon(target, weapon);
            GivePlayerItem(target, buffer_classname);
            EquipPlayerWeapon(client, weapon);

            if(!autoTransfer)
            {

#if defined USE_TRANSLATIONS
                tChatAll("%t", "transfer ent", client, target, g_EntArray[index][ent_name]);
#else
                ChatAll("\x0C%N\x01拿走了\x0C%N\x01手上的神器[\x04%s\x01]", client, target, g_EntArray[index][ent_name]);
#endif
                LogAction(client, -1, "%L transfer %L item %s [entWatch]", client, target, g_EntArray[index][ent_name]);
            }
            else
            {
#if defined USE_TRANSLATIONS
                tChatAll("%t", "autotransfer ent", client, target, g_EntArray[index][ent_name]);
#else
                ChatAll("\x0C%N\x01的遗志由\x0C%N\x01来继承: [\x04%s\x01]", client, target, g_EntArray[index][ent_name]);
#endif
            }

            RemoveWeaponGlow(index);

            Call_StartForward(g_Forward[OnDropped]);
            Call_PushCell(target);
            Call_PushCell(DR_OnTransfer);
            Call_PushString(g_EntArray[index][ent_name]);
            Call_Finish();

            Call_StartForward(g_Forward[OnPicked]);
            Call_PushCell(client);
            Call_PushString(g_EntArray[index][ent_name]);
            Call_Finish();

            Call_StartForward(g_Forward[OnTransfered]);
            Call_PushCell(client);
            Call_PushCell(target);
            Call_PushString(g_EntArray[index][ent_name]);
            Call_Finish();
        }

    g_bHasEnt[client] = true;
    g_bHasEnt[target] = false;

    RefreshHud();
}

static int AutoTarget(int source)
{
    for(int client = 0; client <= MaxClients; ++client)
    {
        if(!ClientIsAlive(client) || g_iTeam[source] != g_iTeam[client] || g_bHasEnt[client])
            continue;

        if (GetUserAdmin(client) == INVALID_ADMIN_ID)
            continue;

        return client;
    }
    return -1;
}

static void LoadConfig()
{
    StopTimer(g_tCooldown);
    
    g_iEntCounts = 0;
    g_bConfigLoaded = false;

    char path[128];
    GetCurrentMap(path, 128);
    Format(path, 128, "cfg/sourcemod/map-entwatch/%s.cfg", path);

    if(!FileExists(path))
    {
        LogMessage("Loading %s but does not exists", path);
        return;
    }

    KeyValues kv = new KeyValues("entities");

    kv.ImportFromFile(path);
    kv.Rewind();
    
    ImportKeyValies(kv);

    delete kv;

    if(g_iEntCounts)
    {
        g_bConfigLoaded = true;
        LogMessage("Load %s successful", path);
        g_tCooldown = CreateTimer(1.0, Timer_Cooldowns, _, TIMER_REPEAT);
    }
    else
        LogError("Loaded %s but not found any data", path);
}

static void ImportKeyValies(KeyValues kv)
{
    if(!kv.GotoFirstSubKey())
        return;
    
    char temp[32];
    int buffer_amount;

    do
    {
        kv.GetString("maxamount", temp, 32);
        buffer_amount = StringToInt(temp);

        if(buffer_amount == 0)
            buffer_amount = 1;

        for(int i = 0; i < buffer_amount; i++)
        {
            kv.GetString("name", temp, 32);
            strcopy(g_EntArray[g_iEntCounts][ent_name], 32, temp);

            kv.GetString("shortname", temp, 32);
            strcopy(g_EntArray[g_iEntCounts][ent_short], 32, temp);
            
            kv.GetString("buttonclass", temp, 32);
            strcopy(g_EntArray[g_iEntCounts][ent_buttonclass], 32, temp);

            kv.GetString("filtername", temp, 32);
            strcopy(g_EntArray[g_iEntCounts][ent_filtername], 32, temp);
            
            kv.GetString("hasfiltername", temp, 32);
            g_EntArray[g_iEntCounts][ent_hasfiltername] = (strcmp(temp, "true", false) == 0);
            
            kv.GetString("hammerid", temp, 32);
            g_EntArray[g_iEntCounts][ent_hammerid] = StringToInt(temp);

            kv.GetString("mode", temp, 32);
            g_EntArray[g_iEntCounts][ent_mode] = StringToInt(temp);

            kv.GetString("maxuses", temp, 32);
            g_EntArray[g_iEntCounts][ent_maxuses] = StringToInt(temp);
            
            kv.GetString("startcd", temp, 32);
            g_EntArray[g_iEntCounts][ent_startcd] = StringToInt(temp);

            kv.GetString("cooldown", temp, 32);
            g_EntArray[g_iEntCounts][ent_cooldown] = StringToInt(temp);

            kv.GetString("glow", temp, 32, "true");
            g_EntArray[g_iEntCounts][ent_weaponglow] = (strcmp(temp, "true", false) == 0);

            kv.GetString("hud", temp, 32, "true");
            g_EntArray[g_iEntCounts][ent_displayhud] = (strcmp(temp, "true", false) == 0);

            kv.GetString("autotrasfer", temp, 32, "true");
            g_EntArray[g_iEntCounts][ent_autotrasfer] = (strcmp(temp, "true", false) == 0);

            g_iEntCounts++;
            
            if(g_iEntCounts == MAXENT)
            {
                LogError("Entities array is full. current: %d  limit: %d", g_iEntCounts, MAXENT);
                return;
            }
        }
    }
    while(kv.GotoNextKey());
}

static void CheckClientKnife(int client)
{
    if(g_tKnife[client] == null)
        g_tKnife[client] = CreateTimer(0.3, Timer_CheckKnife, client);
    //KillTimer(g_tKnife[client]);
}

public Action Timer_CheckKnife(Handle timer, int client)
{
    g_tKnife[client] = INVALID_HANDLE;

    if(!ClientIsAlive(client))
        return Plugin_Stop;

    if(GetPlayerWeaponSlot(client, 2) == -1) 
        GivePlayerItem(client, "weapon_knife");

    return Plugin_Stop;
}

static int GetEntityHammerID(int entity)
{
    return GetEntProp(entity, Prop_Data, "m_iHammerID");
}

static int GetEntityTargetName(int entity, char[] buffer, int size)
{
    return GetEntPropString(entity, Prop_Data, "m_iName", buffer, size);
}

static int GetEntityParentName(int entity, char[] buffer, int size)
{
    return GetEntPropString(entity, Prop_Data, "m_iParent", buffer, size);
}

static int FindIndexByHammerId(int hammerid)
{
    for(int index = 0; index < g_iEntCounts; index++)
        if(g_EntArray[index][ent_hammerid] == hammerid)
            return index;

    return -1;
}

static int FindIndexByEntityRef(int ref)
{
    for(int index = 0; index < g_iEntCounts; index++)
        if(g_EntArray[index][ent_weaponref] == ref)
            return index;

    return -1;
}

static int FindIndexByButton(int button)
{
    for(int index = 0; index < g_iEntCounts; index++)
        if(g_EntArray[index][ent_buttonid] != -1 && g_EntArray[index][ent_buttonid] == button)
            return index;

    return -1;
}

static int GetGlowType(int index)
{
    if(!g_EntArray[index][ent_pickedup])
        return 0;

    switch(g_EntArray[index][ent_mode])
    {
        case 0: return 1;
        case 1: return 1;
        case 2: return (g_EntArray[index][ent_cooldowntime] <= 0) ? 1 : 2;
        case 3: return (g_EntArray[index][ent_uses] < g_EntArray[index][ent_maxuses]) ? 1 : 3;
        case 4: return (g_EntArray[index][ent_uses] < g_EntArray[index][ent_maxuses] && g_EntArray[index][ent_cooldowntime] <= 0) ? 1 : ((g_EntArray[index][ent_uses] >= g_EntArray[index][ent_maxuses]) ? 3 : 2);
        case 5: return (g_EntArray[index][ent_cooldowntime] <= 0) ? 1 : 2;
    }

    return 1;
}

static void SetWeaponGlow(int index)
{
    if(!g_EntArray[index][ent_weaponglow])
        return;

    if(IsValidEdict(EntRefToEntIndex(g_EntArray[index][ent_glowref])))
    {
        //PrintToServer("[SetWeaponGlow] Blocked -> %d -> by Ref", index);
        return;
    }

    float origin[3];
    float angle[3];
    char model[256];

    int weapon = EntRefToEntIndex(g_EntArray[index][ent_weaponref]);
    
    if(!IsValidEdict(weapon))
    {
        //PrintToServer("[SetWeaponGlow] Blocked -> %d -> by weapon", index);
        return;
    }

    GetEntPropVector(weapon, Prop_Send, "m_vecOrigin", origin);
    GetEntPropVector(weapon, Prop_Send, "m_angRotation", angle);

    float fForward[3];
    float fRight[3];
    float fUp[3];
    float fOffset[3] = {0.0, -5.0, 0.0};
    GetAngleVectors(angle, fForward, fRight, fUp);
    origin[0] += fRight[0]*fOffset[0]+fForward[0]*fOffset[1]+fUp[0]*fOffset[2];
    origin[1] += fRight[1]*fOffset[0]+fForward[1]*fOffset[1]+fUp[1]*fOffset[2];
    origin[2] += fRight[2]*fOffset[0]+fForward[2]*fOffset[1]+fUp[2]*fOffset[2];

    GetEntPropString(weapon, Prop_Data, "m_ModelName", model, 256);
    ReplaceString(model, 256, "_dropped", "", false);

    int glow = CreateEntityByName("prop_dynamic_glow");

    if(glow == -1)
        return;

    DispatchKeyValue(glow, "model",                 model);
    DispatchKeyValue(glow, "disablereceiveshadows", "1");
    DispatchKeyValue(glow, "disableshadows",        "1");
    DispatchKeyValue(glow, "solid",                 "0");
    DispatchKeyValue(glow, "spawnflags",            "256");

    DispatchSpawn(glow);

    SetEntProp(glow, Prop_Send, "m_CollisionGroup", 11);
    SetEntProp(glow, Prop_Send, "m_bShouldGlow",    true, true);

    SetEntPropFloat(glow, Prop_Send, "m_flGlowMaxDist", 100000.0);

    SetEntityRenderMode(glow,  RENDER_TRANSCOLOR);
    SetEntityRenderColor(glow, 255, 50, 150, 0);

    switch(GetGlowType(index))
    {
        case 0 : SetGlowColor(glow, 57,  197, 187);
        case 1 : SetGlowColor(glow, 0,   255, 0);
        case 2 : SetGlowColor(glow, 255,  50, 150);
        case 3 : SetGlowColor(glow, 255,   0, 0);
        default: SetGlowColor(glow, 255,  50, 150);
    }

    TeleportEntity(glow, origin, angle, NULL_VECTOR);

    SetEntityParent(glow, weapon);
    
    g_iEntTeam[glow] = g_EntArray[index][ent_team];

    g_EntArray[index][ent_glowref] = EntIndexToEntRef(glow);

    SDKHookEx(glow, SDKHook_SetTransmit, Event_SetTransmit);
}

static void RemoveWeaponGlow(int index)
{
    if(!g_EntArray[index][ent_weaponglow])
        return;

    if(g_EntArray[index][ent_glowref] != INVALID_ENT_REFERENCE)
    {
        int entity = EntRefToEntIndex(g_EntArray[index][ent_glowref]);

        if(IsValidEdict(entity))
            AcceptEntityInput(entity, "KillHierarchy");

        g_EntArray[index][ent_glowref] = INVALID_ENT_REFERENCE;
    }
}

static void SetGlowColor(int entity, int r, int g, int b)
{
    int colors[4];
    colors[0] = r;
    colors[1] = g;
    colors[2] = b;
    colors[3] = 255;
    SetVariantColor(colors);
    AcceptEntityInput(entity, "SetGlowColor");
}

static void AddClientScore(int client, int score)
{
    CS_SetClientContributionScore(client, CS_GetClientContributionScore(client) + score);
}

static void CreateIcon(int client)
{
    if(!ClientIsAlive(client))
        return;

    ClearIcon(client);

    float fOrigin[3];
    GetClientAbsOrigin(client, fOrigin);                
    fOrigin[2] = fOrigin[2] + 88.5;

    int iEnt = CreateEntityByName("env_sprite");
 
    DispatchKeyValue(iEnt, "model",         "materials/maoling/sprites/ze/entwatch_2017.vmt");
    DispatchKeyValue(iEnt, "classname",     "env_sprite");
    DispatchKeyValue(iEnt, "spawnflags",    "1");
    DispatchKeyValue(iEnt, "scale",         "0.01");
    DispatchKeyValue(iEnt, "rendermode",    "1");
    DispatchKeyValue(iEnt, "rendercolor",   "255 255 255");
    
    DispatchSpawn(iEnt);
    
    TeleportEntity(iEnt, fOrigin, NULL_VECTOR, NULL_VECTOR);

    SetEntityParent(iEnt, client);
    
    g_iEntTeam[iEnt] = g_iTeam[client];

    g_iIconRef[client] = EntIndexToEntRef(iEnt);

    SDKHookEx(iEnt, SDKHook_SetTransmit, Event_SetTransmit);
}

static void ClearIcon(int client)
{
    if(g_iIconRef[client] != INVALID_ENT_REFERENCE)
    {
        int iEnt = EntRefToEntIndex(g_iIconRef[client]);
        if(IsValidEdict(iEnt))
            AcceptEntityInput(iEnt, "KillHierarchy");
    }

    g_iIconRef[client] = INVALID_ENT_REFERENCE;
}

static bool IsInfector(int client)
{
    if(!IsPlayerAlive(client))
        return true;

    if(g_pZombieEscape)
        return (ZE_IsInfector(client) || ZE_IsAvenger(client));

    if(g_pZombieReload)
        return ZR_IsClientZombie(client);

    return (g_iTeam[client] == 2);
}
Et3rnity is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 11:30.


Powered by vBulletin®
Copyright ©2000 - 2022, vBulletin Solutions, Inc.
Theme made by Freecode