Ultimate Revive

Ultimate Revive 1.0.7

Нет прав для скачивания
C++:
/*
 * Official resource topic: https://dev-cs.ru/resources/447/
 */

#include <amxmodx>
#include <amxmisc>
#include <reapi>

#pragma semicolon 1

public stock const PluginName[] = "Ultimate Revive";
public stock const PluginVersion[] = "1.0.7";
public stock const PluginAuthor[] = "twisterniq";
public stock const PluginURL[] = "https://github.com/twisterniq/amxx-ultimate-revive";
public stock const PluginDescription[] = "Adds the ability to respawn a player/team/everyone through console command or menu with the option to set HP and armor";

new const CONFIG_NAME[] = "ultimate_revive";

// Console command to revive players
new const CONSOLE_COMMAND[] = "amx_revive";

// Console command to open the menu to revive players
new const CONSOLE_MENU_COMMAND[] = "amx_revivemenu";

// Players per page in menu. No more than six.
const PLAYERS_PER_PAGE = 6;

enum _:CVARS
{
    CVAR_ACCESS[32],
    CVAR_ARMOR_TYPE,
    CVAR_BOT_SUPPORT,
    CVAR_MESSAGES,
    CVAR_LOG
};

new g_eCvar[CVARS];

enum _:CVAR_MESSAGE_TYPES
{
    MESSAGE_SHOW_USER_TARGET = 1,
    MESSAGE_SHOW_ALL
};

new g_szLogFile[PLATFORM_MAX_PATH];

// Menu
new g_iMenuPlayers[MAX_PLAYERS+1][MAX_PLAYERS], g_iMenuPosition[MAX_PLAYERS+1];

new Float:g_flHealth[MAX_PLAYERS+1] = { 100.0, ... };
new g_iArmor[MAX_PLAYERS+1] = { 100, ... };

public plugin_init()
{
#if AMXX_VERSION_NUM == 190
    register_plugin(
        .plugin_name = PluginName,
        .version = PluginVersion,
        .author = PluginAuthor);
#endif

    register_dictionary("ultimate_revive.txt");

    register_clcmd(CONSOLE_COMMAND, "@func_ConsoleCmdRevive");

    // Menu cmd
    register_clcmd(CONSOLE_MENU_COMMAND, "@func_ClCmdReviveMenu");
    register_menucmd(register_menuid("func_ReviveMenu"), 1023, "@func_ReviveMenu_Handler");

    register_clcmd("ur_set_health", "@func_MessageModeSetHealth");
    register_clcmd("ur_set_armor", "@func_MessageModeSetArmor");

    bind_pcvar_string(create_cvar(
        .name = "ur_access",
        .string = "m",
        .flags = FCVAR_NONE,
        .description = fmt("%L", LANG_SERVER, "UR_CVAR_ACCESS")),
        g_eCvar[CVAR_ACCESS], charsmax(g_eCvar[CVAR_ACCESS]));

    bind_pcvar_num(create_cvar(
        .name = "ur_bot_support",
        .string = "0",
        .flags = FCVAR_NONE,
        .description = fmt("%L", LANG_SERVER, "UR_CVAR_BOT_SUPPORT"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0), g_eCvar[CVAR_BOT_SUPPORT]);

    bind_pcvar_num(create_cvar(
        .name = "ur_messages",
        .string = "1",
        .flags = FCVAR_NONE,
        .description = fmt("%L", LANG_SERVER, "UR_CVAR_MESSAGES"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 2.0), g_eCvar[CVAR_MESSAGES]);

    bind_pcvar_num(create_cvar(
        .name = "ur_log",
        .string = "0",
        .flags = FCVAR_NONE,
        .description = fmt("%L", LANG_SERVER, "UR_CVAR_LOG"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0), g_eCvar[CVAR_LOG]);

    AutoExecConfig(true, CONFIG_NAME);

    new szPath[PLATFORM_MAX_PATH];

    get_localinfo("amxx_configsdir", szPath, charsmax(szPath));
    server_cmd("exec %s/plugins/%s.cfg", szPath, CONFIG_NAME);
    server_exec();

    get_localinfo("amxx_logs", szPath, charsmax(szPath));
    formatex(g_szLogFile, charsmax(g_szLogFile), "%s/%s.log", szPath, CONFIG_NAME);
}

public client_putinserver(id)
{
    g_flHealth[id] = 100.0;
    g_iArmor[id] = 100;
}

@func_ConsoleCmdRevive(const id)
{
    if (!has_flag(id, g_eCvar[CVAR_ACCESS]))
    {
        console_print(id, "%l", "UR_ERROR_HAVE_NO_ACCESS");
        return PLUGIN_HANDLED;
    }

    enum { arg_name = 1, arg_health = 2, arg_armor };

    new szArgName[MAX_NAME_LENGTH];
    read_argv(arg_name, szArgName, charsmax(szArgName));

    if (!szArgName[0])
    {
        console_print(id, "%l", "UR_ERROR_USAGE", CONSOLE_MENU_COMMAND);
        return PLUGIN_HANDLED;
    }

    new szArgHealth[10], szArgArmor[10];
    read_argv(arg_health, szArgHealth, charsmax(szArgHealth));
    read_argv(arg_armor, szArgArmor, charsmax(szArgArmor));

    new Float:flHealth, iArmor;
    new bool:bNeedSetHealth, bool:bNeedSetArmor, ArmorType:iArmorType;

    if (szArgHealth[0])
    {
        if (!is_digit_arg(szArgHealth))
        {
            console_print(id, "%l", "UR_ERROR_USAGE", CONSOLE_MENU_COMMAND);
            return PLUGIN_HANDLED;
        }

        bNeedSetHealth = true;
        flHealth = floatclamp(str_to_float(szArgHealth), 1.0, 2147483520.0);
    }

    if (szArgArmor[0] > 0)
    {
        if (!is_digit_arg(szArgArmor))
        {
            console_print(id, "%l", "UR_ERROR_USAGE", CONSOLE_MENU_COMMAND);
            return PLUGIN_HANDLED;
        }

        bNeedSetArmor = true;
        iArmor = clamp(str_to_num(szArgArmor), 0, 999);
        // ARMOR_KEVLAR or ARMOR_VESTHELM
        iArmorType = ArmorType:(g_eCvar[CVAR_ARMOR_TYPE] + 1);
    }

    new iSelected;

    enum { SELECTED_T, SELECTED_CT, SELECTED_ALL, SELECTED_TARGET };

    if (!strcmp(szArgName, "T"))
    {
        iSelected = SELECTED_T;
    }
    else if (!strcmp(szArgName, "CT"))
    {
        iSelected = SELECTED_CT;
    }
    else if (!strcmp(szArgName, "ALL"))
    {
        iSelected = SELECTED_ALL;
    }
    else
    {
        iSelected = SELECTED_TARGET;
    }

    if (SELECTED_T <= iSelected <= SELECTED_ALL)
    {
        new iPlayers[MAX_PLAYERS], iPlayerCount, i, iPlayer;
        get_players_ex(iPlayers, iPlayerCount, !g_eCvar[CVAR_BOT_SUPPORT] ? (GetPlayers_ExcludeAlive|GetPlayers_ExcludeBots|GetPlayers_ExcludeHLTV) : (GetPlayers_ExcludeAlive|GetPlayers_ExcludeHLTV));

        new iCount;

        for (i = 0; i < iPlayerCount; i++)
        {
            iPlayer = iPlayers[i];

            switch(iSelected)
            {
                case SELECTED_T:
                {
                    if (get_member(iPlayer, m_iTeam) != TEAM_TERRORIST)
                    {
                        continue;
                    }
                }
                case SELECTED_CT:
                {
                    if (get_member(iPlayer, m_iTeam) != TEAM_CT)
                    {
                        continue;
                    }
                }
                case SELECTED_ALL:
                {
                    if (!(TEAM_TERRORIST <= get_member(iPlayer, m_iTeam) <= TEAM_CT))
                    {
                        continue;
                    }
                }
            }

            iCount++;
            rg_round_respawn(iPlayer);

            if (bNeedSetHealth)
            {
                set_entvar(iPlayer, var_health, flHealth);
            }

            if (bNeedSetArmor)
            {
                rg_set_user_armor(iPlayer, iArmor, iArmorType);
            }

            if (g_eCvar[CVAR_MESSAGES] == MESSAGE_SHOW_USER_TARGET)
            {
                client_print_color(iPlayer, print_team_default, "%l", "UR_REVIVED_PLAYER_TARGET", id);
            }
        }

        if (!iCount)
        {
            return PLUGIN_HANDLED;
        }

        if (!g_eCvar[CVAR_MESSAGES] && !g_eCvar[CVAR_LOG])
        {
            return PLUGIN_HANDLED;
        }

        new szTeam[64];

        switch(iSelected)
        {
            case SELECTED_T:
            {
                formatex(szTeam, charsmax(szTeam), "%L", id, "UR_MSG_T");
            }
            case SELECTED_CT:
            {
                formatex(szTeam, charsmax(szTeam), "%L", id, "UR_MSG_CT");
            }
            case SELECTED_ALL:
            {
                formatex(szTeam, charsmax(szTeam), "%L", id, "UR_MSG_ALL");
            }
        }

        switch(g_eCvar[CVAR_MESSAGES])
        {
            case MESSAGE_SHOW_USER_TARGET:
            {
                client_print_color(id, print_team_red, "%l", "UR_REVIVED_MSG", szTeam);
            }
            case MESSAGE_SHOW_ALL:
            {
                client_print_color(0, print_team_red, "%l", "UR_REVIVED_MSG_ALL", id, szTeam);
            }
        }

        if (g_eCvar[CVAR_LOG])
        {
            new szAuthID[MAX_AUTHID_LENGTH], szIP[MAX_IP_LENGTH];
            get_user_authid(id, szAuthID, charsmax(szAuthID));
            get_user_ip(id, szIP, charsmax(szIP), 1);

            log_to_file(g_szLogFile, "%l", "UR_REVIVED_TEAM_LOG", id, szAuthID, szIP, szTeam);
        }

        return PLUGIN_HANDLED;
    }
    else
    {
        new iTarget = cmd_target(id, szArgName, CMDTARGET_ALLOW_SELF);

        if (!iTarget)
        {
            return PLUGIN_HANDLED;
        }

        if (is_user_alive(iTarget))
        {
            console_print(id, "%l", "UR_ERROR_ALIVE");
            return PLUGIN_HANDLED;
        }

        if (get_member(iTarget, m_iTeam) != TEAM_TERRORIST && get_member(iTarget, m_iTeam) != TEAM_CT)
        {
            console_print(id, "%l", "UR_ERROR_TEAM");
            return PLUGIN_HANDLED;
        }

        rg_round_respawn(iTarget);

        if (bNeedSetHealth)
        {
            set_entvar(iTarget, var_health, flHealth);
        }

        if (bNeedSetArmor)
        {
            rg_set_user_armor(iTarget, iArmor, iArmorType);
        }

        func_AfterReviveAction(id, iTarget);
    }

    return PLUGIN_HANDLED;
}

@func_ClCmdReviveMenu(const id)
{
    if (!has_flag(id, g_eCvar[CVAR_ACCESS]))
    {
        console_print(id, "%l", "UR_ERROR_HAVE_NO_ACCESS");
        return PLUGIN_HANDLED;
    }

    func_ReviveMenu(id, 0, true);
    return PLUGIN_HANDLED;
}

func_ReviveMenu(const id, iPage, bool:bChat = false)
{
    if (iPage < 0)
    {
        return PLUGIN_HANDLED;
    }

    new iPlayerCount;

    for (new i = 1; i <= MaxClients; i++)
    {
        if (!is_user_connected(i) || is_user_alive(i) || get_member(i, m_iTeam) != TEAM_TERRORIST && get_member(i, m_iTeam) != TEAM_CT || !g_eCvar[CVAR_BOT_SUPPORT] && is_user_bot(i))
        {
            continue;
        }

        g_iMenuPlayers[id][iPlayerCount++] = i;
    }

    SetGlobalTransTarget(id);

    new i = min(iPage * PLAYERS_PER_PAGE, iPlayerCount);
    new iStart = i - (i % PLAYERS_PER_PAGE);
    new iEnd = min(iStart + PLAYERS_PER_PAGE, iPlayerCount);
    g_iMenuPosition[id] = iPage = iStart / PLAYERS_PER_PAGE;

    new szMenu[MAX_MENU_LENGTH], iMenuItem, iKeys = (MENU_KEY_0);
    new iPagesNum = (iPlayerCount / PLAYERS_PER_PAGE + ((iPlayerCount % PLAYERS_PER_PAGE) ? 1 : 0));
    new iLen = formatex(szMenu, charsmax(szMenu), "\y%l \d\R%d/%d^n^n", "UR_MENU_TITLE", iPage + 1, iPagesNum);

    for (new a = iStart, iPlayer; a < iEnd; ++a)
    {
        iPlayer = g_iMenuPlayers[id][a];

        iKeys |= (1<<iMenuItem);
        iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\y%d. \w%n^n", ++iMenuItem, iPlayer);
    }

    if (!iMenuItem)
    {
        if (bChat)
        {
            client_print_color(id, print_team_red, "%l", "UR_ERROR_MENU_PLAYERS");
        }

        return PLUGIN_HANDLED;
    }

    iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "^n\y7. \w%l^n", "UR_MENU_HEALTH", g_flHealth[id]);
    iKeys |= (MENU_KEY_7);

    iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\y8. \w%l^n", "UR_MENU_ARMOR", g_iArmor[id]);
    iKeys |= (MENU_KEY_8);

    if (iEnd != iPlayerCount)
    {
        formatex(szMenu[iLen], charsmax(szMenu) - iLen, "^n\y9. \w%l^n\y0. \w%l", "UR_NEXT", iPage ? "UR_BACK" : "UR_EXIT");
        iKeys |= (MENU_KEY_9);
    }
    else
    {
        formatex(szMenu[iLen], charsmax(szMenu) - iLen, "^n\y0. \w%l", iPage ? "UR_BACK" : "UR_EXIT");
    }

    show_menu(id, iKeys, szMenu, -1, "func_ReviveMenu");
    return PLUGIN_HANDLED;
}

@func_ReviveMenu_Handler(const id, iKey)
{
    switch(iKey)
    {
        case 6:
        {
            client_cmd(id, "messagemode ur_set_health");
            func_ReviveMenu(id, g_iMenuPosition[id]);
        }
        case 7:
        {
            client_cmd(id, "messagemode ur_set_armor");
            func_ReviveMenu(id, g_iMenuPosition[id]);
        }
        case 8:
        {
            func_ReviveMenu(id, ++g_iMenuPosition[id]);
        }
        case 9:
        {
            func_ReviveMenu(id, --g_iMenuPosition[id]);
        }
        default:
        {
            new iTarget = g_iMenuPlayers[id][(g_iMenuPosition[id] * PLAYERS_PER_PAGE) + iKey];
            new TeamName:iTargetTeam = get_member(iTarget, m_iTeam);

            if (is_user_alive(iTarget) || iTargetTeam != TEAM_TERRORIST && iTargetTeam != TEAM_CT)
            {
                func_ReviveMenu(id, g_iMenuPosition[id]);
                return PLUGIN_HANDLED;
            }

            // ARMOR_KEVLAR or ARMOR_VESTHELM
            new ArmorType:iArmorType = ArmorType:(g_eCvar[CVAR_ARMOR_TYPE] + 1);

            rg_round_respawn(iTarget);
            set_entvar(iTarget, var_health, g_flHealth[id]);
            rg_set_user_armor(iTarget, g_iArmor[id], iArmorType);

            func_AfterReviveAction(id, iTarget);
            func_ReviveMenu(id, g_iMenuPosition[id]);
        }
    }

    return PLUGIN_HANDLED;
}

func_AfterReviveAction(const id, const iTarget)
{
    switch(g_eCvar[CVAR_MESSAGES])
    {
        case MESSAGE_SHOW_USER_TARGET:
        {
            client_print_color(id, iTarget, "%l", "UR_REVIVED_MSG", iTarget);
            client_print_color(iTarget, print_team_default, "%l", "UR_REVIVED_PLAYER_TARGET", id);
        }
        case MESSAGE_SHOW_ALL:
        {
            client_print_color(0, iTarget, "%l", "UR_REVIVED_MSG_ALL", id, iTarget);
        }
    }

    if (g_eCvar[CVAR_LOG])
    {
        new szAuthID[MAX_AUTHID_LENGTH], szIP[MAX_IP_LENGTH];
        get_user_authid(id, szAuthID, charsmax(szAuthID));
        get_user_ip(id, szIP, charsmax(szIP), 1);

        new szTargetAuthID[MAX_AUTHID_LENGTH], szTargetIP[MAX_IP_LENGTH];
        get_user_authid(iTarget, szTargetAuthID, charsmax(szTargetAuthID));
        get_user_ip(iTarget, szTargetIP, charsmax(szTargetIP), 1);

        log_to_file(g_szLogFile, "%L", LANG_SERVER, "UR_REVIVED_ONE_LOG",
            id, szAuthID, szIP,
            iTarget, szTargetAuthID, szTargetIP);
    }
}

@func_MessageModeSetHealth(const id)
{
    enum { arg_health = 1 };

    new szArgHealth[10];
    read_argv(arg_health, szArgHealth, charsmax(szArgHealth));

    if (!szArgHealth[0])
    {
        client_print_color(id, print_team_red, "%l", "UR_ERROR_MENU_USAGE_ZERO");
        return PLUGIN_HANDLED;
    }

    if (szArgHealth[0])
    {
        if (!is_digit_arg(szArgHealth))
        {
            client_print_color(id, print_team_red, "%l", "UR_ERROR_MENU_USAGE_DIGIT");
            return PLUGIN_HANDLED;
        }

        g_flHealth[id] = floatclamp(str_to_float(szArgHealth), 1.0, 2147483520.0);

        func_ReviveMenu(id, g_iMenuPosition[id]);
    }

    return PLUGIN_HANDLED;
}

@func_MessageModeSetArmor(const id)
{
    enum { arg_armor = 1 };

    new szArgArmor[10];
    read_argv(arg_armor, szArgArmor, charsmax(szArgArmor));

    if (!szArgArmor[0])
    {
        client_print_color(id, print_team_red, "%l", "UR_ERROR_MENU_USAGE_ZERO");
        return PLUGIN_HANDLED;
    }

    if (szArgArmor[0])
    {
        if (!is_digit_arg(szArgArmor))
        {
            client_print_color(id, print_team_red, "%l", "UR_ERROR_MENU_USAGE_DIGIT");
            return PLUGIN_HANDLED;
        }

        g_iArmor[id] = clamp(str_to_num(szArgArmor), 0, 999);

        func_ReviveMenu(id, g_iMenuPosition[id]);
    }

    return PLUGIN_HANDLED;
}

stock is_digit_arg(szArg[])
{
    new bool:bIsDigit = true;

    for (new iCharacter, iLen = strlen(szArg); iCharacter < iLen; iCharacter++)
    {
        if (!isdigit(szArg[iCharacter]))
        {
            bIsDigit = false;
            break;
        }
    }

    return bIsDigit;
}
Назад
Верх