AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Plugin/Gameplay Ideas and Requests (https://forums.alliedmods.net/forumdisplay.php?f=60)
-   -   Glow weapons (https://forums.alliedmods.net/showthread.php?t=318897)

Et3rnity 09-27-2019 17:09

Glow weapons
 
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);
}



All times are GMT -4. The time now is 17:57.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.