COVID mode

Плагин АМХХ COVID mode 1.2.5

Нет прав для скачивания
C++:
/*
* - ----------

   Плагин - "COVID mode"

* - ----------

   Описание:

   Корона вирус (COVID) режим, добавляет атмосферу масок на сервере.

   Плагин может работать в двух режимах:

   1. Маски ставятся всем игрокам при спавне автоматически.
   2. Маски не ставятся автоматически.

* - ----------

   Благодарности:

   Предложения, помощь в проработке идеи: Nebo, Pokemoshka, present, ssx
   Перевод на разные языки: rian18, tarsisd2, Yek'-ta, sensej1021, asd
   Помощь по коду: Garey
   Другая помощь: f@ntom, urpok

* - ----------

   Поддержка плагина:

   Dev-Cs: @wellasgood
   vk: https://vk.com/d1mkin
   Telegram: @WellAsGood

* - ----------

   Ход разработки:

   ver 1.0.0:

   1. Изменены команды для открытия меню, спасибо: Pokemoshka.
   2. Переработано меню. (добавлен признак: ВКЛ ВЫКЛ, спасибо: present)
   3. Правки в части удаления ентити.
   4. Добавлен режим, при котором маски устанавливаются в положение ВКЛ по стандарту (при спавне игрока), далее игрок может сам ее отключить или включить через меню.)
   5. Учет дополнительных моментов, если нужно. (доп. режим, выдача масок только игрокам с флагом доступа к меню вкл/выкл)

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

/*
   Журнал изменений:

   ver 1.0.1:

   1. Подправлен LANG файл.
   2. Убрана лишняя кнопка в меню.

   ver 1.0.2:

   1. Изменена проверка на открытие меню по флагу.
   2. Добавлен немецкий перевод в LANG файл.

   ver 1.0.3:

   1. Добавлен португальский перевод в LANG файл.
   2. Добавлена возможность установить чуть меньше здоровья тем кто без маски. (настройка #define)
   3. В режим MASK_ALL_MODE добавлен (под режим), забирать жизни при спавне (если снята маска). Для этого дела добавлены квары и другое. Вся настройка кварами. Работает только если включен режим MASK_ALL_MODE. (Если режим MASK_ALL_MODE отключен, то никакие квары и ничего другое задействоваться не будет). Об отнимании жизней. Есть 3 квара: вкл/выкл, количество отнимаемых жизней, выводить ли сообщение при смене маски и непосредственно спавне. Настройте как Вам удобно.
   4. В LANG файл добавлены описание к кварам.
   5. Добавлено много изменений по коду с учетом новых обновлений.

   ver 1.0.4:

   1. Исправлено отображение модели на стандартных моделях игроков.
   2. Изменено наименование модели, что-бы игроки скачивали новую модель заного.

   ver 1.0.5:

   1. В LANG файл было добавлен новый турецкий перевод. (спасибо: Yek'-ta)
   2. В LANG файле был обновлен португальский и немецкий перевод на корректный.

   ver 1.0.6:

   1. Добавлен польский перевод в LANG файл. (спасибо: sensej1021)

   ver 1.0.7:

   1. Удален перевод COVID_ERROR_MSG в LANG файле и исходнике, оставлен по стандарту en.

   ver 1.0.8:

   1. Обнаружена ошибка во всех переводах LANG файла: было COVID_HEALTH_MSN_PRE, стало COVID_HEALTH_MSG_PRE

   ver 1.0.9:

   1. Добавлена проверка на значение квара cv_mask_health_msg ('HealthMsg(PlayerID, 1);' - отсылалось даже если в кваре значение выкл)

   ver 1.1.0:

   1. Дополнена модель маски (добавлены новые текстуры разных цветов)
   2. Добавлен выбор цвета в плагине для каждого игрока отдельно (в меню).
   3. Изменения по коду с учетом новых обновлений.
   4. Дополнен LANG файл.
   5. Изменено наименование модели.

   ver 1.1.1:

   1. В меню масок, при выборе цвета, добавлен пункт: "Рандом". Если игрок активирует это, то при спавне у него будет случайный цвет маски. (только для режима MASK_ALL_MODE)
   2. Изменения по коду с учетом новых обновлений.
   3. Дополнен LANG файл.

   ver 1.1.2:

   1. Поправлена версия плагина AMXX 1.8.2 в исходнике на более понятную.

   ver 1.1.3:

   1. Теперь есть возможность сохранить цвет маски который был выбран в игре. (если игрок выходит с сервера и заходит, а также после смены карты)
   2. Для сохранения задействован #include <nvault>
   3. Включить/отключить сохранение: откомментируйте или закомментируйте 'define SAVE_MASK_MODE'
   4. Правка кода с учетом новых обновлений.

   ver 1.1.4:

   1. Добавлена проверка #if defined SAVE_MASK_MODE в части кода функции plugin_init. (если режим сохранения был выкл, то эта часть бы работала)

   ver 1.1.5:

   1. Поправлен способ сохранения цвета маски в основной версии плагина.

   ver 1.1.6:

   1. Добавлена цветная модель, сделанная по другому (без применения многих текстур). Использование с помощью topcolor (colormap)
   2. Для основного плагина, сделан fix маски, для старых (без детализации) моделей. (если снять галочку HD в игре)
   3. Большие правки по коду, с учетом добавленного.
   4. Переработано меню, а также в него добавлены цвета для маски что-бы выбрать из предложенных, иначе ввести свой цвет в формате RGB (255 255 0), через пробел.
   5. Цвет маски теперь сохраняется в двух случаях, если игрок выбрал цвет из предложенных, а также если игрок выбрал свой цвет (RGB)

   ver 1.1.7:

   1. Вновь были неполадки с сохранением цвета после выхода и повторного захода игрока на сервере. Исправлено.

   ver 1.1.8:

   1. В версии плагина AMXX 1.8.2 добавлена функция закрытия файла nvault (plugin_end)

   ver 1.1.9:

   1. В версии плагина AMXX 1.8.2 добавлена проверка #if defined SAVE_MASK_MODE для функции plugin_end, так как, она выполнялась бы в любом случае.

   ver 1.2.0:

   1. Выявлен баг, что если закомментировать режим #define MASK_ALL_MODE, то плагин не компилировался. (поправлено, теперь работа плагина в режиме без #define MASK_ALL_MODE доступна), спасибо: urpok
   2. Добавлены доп. проверки по коду с учетом новых обновлений.
   3. В версии плагина AMXX 1.8.2 добавлена проверка на вызов функции (сообщение в чат), иначе оно отправлялось бы вне зависимости от положения квара.
   4. Дополнен LANG файл.

   ver 1.2.1:

   1. Добавлена возможность рекламировать в чат сообщения о командах открытия меню (вкл/выкл настройка #define CHAT_ADVERTISING, а также можно настроить временной интервал #define TIME).
   2. Добавлена возможность указать цвет который будет выставляться по умолчанию (настройка new const DEFAULT_COLOR[], работает только с режимом #define MASK_ALL_MODE)
   3. Добавлена функция обработчик, преобразующая строку c RGB данными в float массив, дабы не повторять лишний раз одно и тоже.
   4. Теперь если игрок сохранит маску (т.е просто выберет в меню настроек), после перезахода на сервер и повторного захода в меню, уже будет пункт цвета (сохраненный), это означает, что даже после выключения маски или обратного включения (листания цветов других), можно вернуться к сохраненному цвету. (дабы заного его не вводить, например если это был свой RGB цвет)
   5. Учтены и протестированы моменты, когда юзаются разные вариации режимов.
   6. Большие правки/добавления по коду, с учетом новых обновлений.
   7. В версию плагина AMXX 1.8.2 добавлен цветной чат (include colorchat.inc), теперь сообщения в чате цветные, как и в основной версии плагина.

   ver 1.2.2:

   1. В версии плагина AMXX 1.8.2 изменен ключ с %l на %L в client_print_color, так как, ключ %l не поддерживается.

   ver 1.2.3:

   1. Добавлено сохранение положения пункта РАНДОМ [ВКЛ/ВЫКЛ], после выхода и повторного захода на сервер, выбранное положение (вкл/выкл) сохранится.
   2. Добавлено сохранение положения пункта МАСКА [ВКЛ/ВЫКЛ], после выхода и повторного захода на сервер, выбранное положение (вкл/выкл) сохранится.
   3. Правка кода.

   ver 1.2.4:

   1. Поправлено наименование создаваемого конфига в основной версии плагина, так как, пробелы в наименование не читаются.

   ver 1.2.5:

   1. Правки немецкого перевода в LANG файле, спасибо: rian18
*/

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

#define AUTO_CREATE_CONFIG //Авто-создание конфига. (включать только если включен режим MASK_ALL_MODE)

#define MULTI_LANGUAGE(%0) fmt("%L", LANG_SERVER, %0)

#define ACCESS_FLAG_MENU (ADMIN_BAN | ADMIN_USER) //Мульти флаг, доступ к меню включения/выключения масок и для режима MASK_ACCESS

#define MASK_ALL_MODE //Если включено, то маски всем выставляются при заходе.

//#define MASK_ACCESS //Работает с режимом MASK_ALL_MODE (Если включено, то выдает при спавне маски только игрокам с флагом ACCESS_FLAG_MENU, иначе всем)

#if defined MASK_ALL_MODE
#define SAVE_MASK_MODE //Сохранение цвета маски при выходе и повторном заходе игрока, а также при смене карты.

new DefColor;

#if defined SAVE_MASK_MODE
#include <nvault>
new Vault, SaveMaskColor[MAX_PLAYERS+1], DoubleSaveColor[MAX_PLAYERS+1];
new bool:DefCheck[MAX_PLAYERS+1];
#endif

new const DEFAULT_COLOR[] = "135 206 250" //указать цвет который будет выставляться по умолчанию (RGB формат)
#endif

#define CHAT_ADVERTISING //возможность рекламировать в чат сообщения о командах открытия меню (вкл/выкл откоммент/коммент).

#if defined CHAT_ADVERTISING
#define TIME 120.0 //время для показа рекламы в чате (интервал)
#endif

new const PLUGIN[] = "COVID_mode";
new const VERSION[] = "1.2.5";
new const AUTHOR[] = "wellasgood";

new const MEDICAL_MODEL[] = "models/medical-mask/med-mask_clr.mdl";
new const MEDICAL_MODEL_FIX[] = "models/medical-mask/med-mask_clr_fix.mdl";

new Entity[MAX_PLAYERS+1], MaskColor[MAX_PLAYERS+1];
new bool:HDModels[MAX_PLAYERS+1], Model[2];

#if defined MASK_ALL_MODE
new bool:Check[MAX_PLAYERS+1];

enum _:CVAR_DATA
{
    MASK_HEALTH_EN,
    MASK_HEALTH_NUM,
    MASK_HEALTH_MSG
};

new eCvarData[CVAR_DATA], bool:CheckHealth[MAX_PLAYERS+1], bool:CheckRandom[MAX_PLAYERS+1];
#endif

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR);
    register_dictionary("covid.txt");

    register_clcmd("say /covid", "cmdOpenMenu");
    register_clcmd("say /cv", "cmdOpenMenu");

    register_concmd("its_color", "func_its_color");

    register_menu("CovidMenu", 1023, "Handle_CovidMenu", 0);

    #if defined MASK_ALL_MODE
    RegisterHookChain(RG_CBasePlayer_Spawn, "EventSpawn", true);

    RegCvars();

    #if defined AUTO_CREATE_CONFIG
    AutoExecConfig(true, "COVID_mode");
    #endif

    new Float:Color[3];
    func_handler_row(DEFAULT_COLOR, Color);

    DefColor = RGBtoHUE(Color);
    #endif

    #if defined SAVE_MASK_MODE
    Vault = nvault_open("Covid_save");

    if(Vault == INVALID_HANDLE)
    {
        set_fail_state("Error opening nVault file!");
    }
    #endif

    RegisterQueryFile("models/player/militia/militia.mdl", "handler_QueryFile", RES_TYPE_HASH_ANY, -1);
    RegisterQueryFile("models/player/spetsnaz/spetsnaz.mdl", "handler_QueryFile", RES_TYPE_HASH_ANY, -1);

    #if defined CHAT_ADVERTISING
    set_task_ex(TIME, "Chat_Advertising", .flags = SetTask_Repeat);
    #endif
}

#if defined MASK_ALL_MODE
RegCvars()
{
    bind_pcvar_num(create_cvar(
        .name = "cv_mask_health_en",
        .string = "1",
        .description = MULTI_LANGUAGE("DESCRIPTION_CVAR_HEALTH_EN"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0),
        eCvarData[MASK_HEALTH_EN]
    );

    bind_pcvar_num(create_cvar(
        .name = "cv_mask_health_num",
        .string = "5",
        .description = MULTI_LANGUAGE("DESCRIPTION_CVAR_HEALTH_NUM"),
        .has_min = false,
        .min_val = 0.0,
        .has_max = false,
        .max_val = 0.0),
        eCvarData[MASK_HEALTH_NUM]
    );

    bind_pcvar_num(create_cvar(
        .name = "cv_mask_health_msg",
        .string = "1",
        .description = MULTI_LANGUAGE("DESCRIPTION_CVAR_HEALTH_MSG"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0),
        eCvarData[MASK_HEALTH_MSG]
    );
}
#endif

public plugin_precache()
{
    CheckModels(MEDICAL_MODEL, 0);
    CheckModels(MEDICAL_MODEL_FIX, 1);
}

CheckModels(const model[], num)
{
    if(!file_exists(fmt("\%s", model)))
    {
        set_fail_state("Error! Model '%s' not found", model);
    }
    else
    {
        Model[num] = precache_model(model);
    }
}

public handler_QueryFile(const PlayerID, const hash, const uniqueId)
{
    HDModels[PlayerID] = true;
}

#if defined MASK_ALL_MODE
public client_putinserver(PlayerID)
{
    if(is_user_bot(PlayerID) || is_user_hltv(PlayerID))
    {
        return;
    }

    Check[PlayerID] = false;

    if(eCvarData[MASK_HEALTH_EN])
    {
        CheckHealth[PlayerID] = false;
    }

    #if defined SAVE_MASK_MODE
    new AuthID[MAX_AUTHID_LENGTH], Data[12];
    get_user_authid(PlayerID, AuthID, charsmax(AuthID));

    new timestamp, AccessResult = nvault_lookup(Vault, AuthID, Data, charsmax(Data), timestamp);

    if(AccessResult)
    {
        SaveMaskColor[PlayerID] = str_to_num(Data);

        if(SaveMaskColor[PlayerID] > 255)
        {
            switch(SaveMaskColor[PlayerID])
            {
                case 666:
                {
                    CheckRandom[PlayerID] = true;
                }
                case 777:
                {
                    CheckRandom[PlayerID] = false;
                }
                case 888:
                {
                    if(eCvarData[MASK_HEALTH_EN])
                    {
                        CheckHealth[PlayerID] = true;
                    }
                }
            }
        }
        else
        {
            DoubleSaveColor[PlayerID] = SaveMaskColor[PlayerID];
            DefCheck[PlayerID] = true;
        }
    }
    #endif

    #if defined MASK_ACCESS
    if(get_user_flags(PlayerID) & ACCESS_FLAG_MENU)
    {
        #if defined SAVE_MASK_MODE
        if(SaveMaskColor[PlayerID] != 888)
        {
            CreateEnt(PlayerID);
        }
        #else
        CreateEnt(PlayerID);
        #endif
    }
    #else
    #if defined SAVE_MASK_MODE
    if(SaveMaskColor[PlayerID] != 888)
    {
        CreateEnt(PlayerID);
    }
    #else
    CreateEnt(PlayerID);
    #endif
    #endif
}

public EventSpawn(PlayerID)
{
    if(!is_user_alive(PlayerID))
    {
        return;
    }

    if(eCvarData[MASK_HEALTH_EN])
    {
        if(CheckHealth[PlayerID])
        {
            new Float:HP = get_entvar(PlayerID, var_health);
            set_entvar(PlayerID, var_health, HP - eCvarData[MASK_HEALTH_NUM]);

            if(eCvarData[MASK_HEALTH_MSG])
            {
                HealthMsg(PlayerID, 2);
            }
        }
    }

    if(Entity[PlayerID] && is_entity(Entity[PlayerID]))
    {
        if(!Check[PlayerID])
        {
            SetMask(PlayerID);

            #if defined SAVE_MASK_MODE
            if(!CheckRandom[PlayerID])
            {
                if(DefCheck[PlayerID])
                {
                    set_entvar(Entity[PlayerID], var_colormap, SaveMaskColor[PlayerID]);
                }
                else
                {
                    set_entvar(Entity[PlayerID], var_colormap, DefColor);
                }
            }
            #else
            set_entvar(Entity[PlayerID], var_colormap, DefColor);
            #endif
        }

        if(CheckRandom[PlayerID])
        {
            new RandomNum = random_num(0, 255);
            set_entvar(Entity[PlayerID], var_colormap, RandomNum);
        }
    }
}
#endif

public client_disconnected(PlayerID)
{
    RemoveMask(PlayerID);

    MaskColor[PlayerID] = 0;

    #if defined SAVE_MASK_MODE
    SaveMaskColor[PlayerID] = 0;
    DefCheck[PlayerID] = false;
    #endif

    HDModels[PlayerID] = false;
}

public cmdOpenMenu(PlayerID)
{
    if(get_user_flags(PlayerID) & ACCESS_FLAG_MENU)
    {
        CovidMenu(PlayerID);
    }

    return PLUGIN_HANDLED;
}

CovidMenu(PlayerID)
{
    new Menu[MAX_MENU_LENGTH], Keys = MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4|MENU_KEY_0;
    new Len = formatex(Menu, charsmax(Menu), "%L^n^n", PlayerID, "COVID_MENU_TITLE");

    Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[1] \y# \w%L \y[\r%L\y]^n^n", PlayerID, "COVID_MENU_ITEM_INFO", PlayerID, Entity[PlayerID] == 0 ? "COVID_MENU_ITEM_OFF" : "COVID_MENU_ITEM_ON");

    #if defined MASK_ALL_MODE
    if(Entity[PlayerID] == 0)
    {
        Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[2] \y# \w%L \y[\d%L\y]^n", PlayerID, "COVID_MENU_ITEM_COLOR_RANDOM_INFO", PlayerID, "COVID_MENU_ITEM_COLOR_OFF");
    }
    else
    {
        Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[2] \y# \w%L \y[\r%L\y]^n", PlayerID, "COVID_MENU_ITEM_COLOR_RANDOM_INFO", PlayerID, !CheckRandom[PlayerID] ? "COVID_MENU_ITEM_OFF" : "COVID_MENU_ITEM_ON");
    }
    #else
        Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[2] \y# \w%L \y[\r%L\y]^n", PlayerID, "COVID_MENU_ITEM_COLOR_RANDOM_INFO", PlayerID, "COVID_MENU_ITEM_DISABLED");
    #endif

    if(Entity[PlayerID] == 0)
    {
        Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[3] \y# \w%L \y[\d%L\y]^n", PlayerID, "COVID_MENU_ITEM_COLOR_INFO", PlayerID, "COVID_MENU_ITEM_COLOR_OFF");
    }
    #if defined MASK_ALL_MODE
    else if(CheckRandom[PlayerID])
    {
        Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[3] \y# \w%L \y[\d%L\y]^n", PlayerID, "COVID_MENU_ITEM_COLOR_INFO", PlayerID, "COVID_MENU_ITEM_COLOR_RANDOM_ACTIVATE");
    }
    #endif
    else
    {
        #if defined SAVE_MASK_MODE
        if(MaskColor[PlayerID] == 0)
        {
            Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[3] \y# \w%L \y[\r%L\y]^n", PlayerID, "COVID_MENU_ITEM_COLOR_INFO", PlayerID, fmt(!DefCheck[PlayerID] ? "COVID_MENU_ITEM_COLOR_%d" : "COVID_MENU_ITEM_AUTOSAVE_%d", MaskColor[PlayerID]));
        }
        else
        {
            Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[3] \y# \w%L \y[\r%L\y]^n", PlayerID, "COVID_MENU_ITEM_COLOR_INFO", PlayerID, fmt("COVID_MENU_ITEM_COLOR_%d", MaskColor[PlayerID]));
        }
        #else
            #if !defined MASK_ALL_MODE
            Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[3] \y# \w%L \y[\r%L\y]^n", PlayerID, "COVID_MENU_ITEM_COLOR_INFO", PlayerID, fmt("COVID_MENU_ITEM_COLOR_%d", MaskColor[PlayerID] + 50));
            #else
            Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[3] \y# \w%L \y[\r%L\y]^n", PlayerID, "COVID_MENU_ITEM_COLOR_INFO", PlayerID, fmt("COVID_MENU_ITEM_COLOR_%d", MaskColor[PlayerID]));
            #endif
        #endif
    }

    if(Entity[PlayerID] == 0)
    {
        Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[4] \y# \w%L \y[\d%L\y]^n^n", PlayerID, "COVID_MENU_ITEM_ITS_COLOR", PlayerID, "COVID_MENU_ITEM_COLOR_OFF");
    }
    else
    {
        Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[4] \y# \w%L \y[\d%L\y]^n^n", PlayerID, "COVID_MENU_ITEM_ITS_COLOR", PlayerID, "COVID_MENU_ITEM_ITS_COLOR_RGB");
    }

    formatex(Menu[Len], charsmax(Menu) - Len, "\r[0] \y# \w%L", PlayerID, "COVID_MENU_EXIT");
    return show_menu(PlayerID, Keys, Menu, -1, "CovidMenu");
}

public Handle_CovidMenu(PlayerID, Keys)
{
    switch(Keys)
    {
        case 0:
            {
                if(Entity[PlayerID] && is_entity(Entity[PlayerID]))
                {
                    RemoveMask(PlayerID);

                    MaskColor[PlayerID] = 0;

                    #if defined MASK_ALL_MODE
                    Check[PlayerID] = false;

                    if(eCvarData[MASK_HEALTH_EN])
                    {
                        CheckHealth[PlayerID] = true;

                        if(eCvarData[MASK_HEALTH_MSG])
                        {
                            HealthMsg(PlayerID, 1);
                        }
                    }

                    #if defined SAVE_MASK_MODE
                    SaveMaskColor[PlayerID] = 888;
                    SaveMask(PlayerID);
                    #endif
                    #endif
                }
                else
                {
                    CreateEnt(PlayerID);
                    SetMask(PlayerID);

                    #if defined MASK_ALL_MODE
                    Check[PlayerID] = true;

                    if(eCvarData[MASK_HEALTH_EN])
                    {
                        CheckHealth[PlayerID] = false;

                        if(eCvarData[MASK_HEALTH_MSG])
                        {
                            HealthMsg(PlayerID, 1);
                        }
                    }

                    #if defined SAVE_MASK_MODE
                    SaveMaskColor[PlayerID] = DefColor;
                    SaveMask(PlayerID);
                    #endif
                    #endif
                }
            }
        case 1:
            {
                #if defined MASK_ALL_MODE
                if(Entity[PlayerID] != 0)
                {
                    CheckRandom[PlayerID] = !CheckRandom[PlayerID];

                    #if defined SAVE_MASK_MODE
                    SaveMaskColor[PlayerID] = CheckRandom[PlayerID] ? 666 : 777;
                    SaveMask(PlayerID);
                    #endif
                }
                #endif
            }
        case 2:
            {
                if(Entity[PlayerID] != 0)
                {
                    #if defined MASK_ALL_MODE
                    if(!CheckRandom[PlayerID])
                    {
                        MaskColor[PlayerID] = (MaskColor[PlayerID] + 50) % 300;

                        if(MaskColor[PlayerID] < 50)
                        {
                            #if defined SAVE_MASK_MODE
                            set_entvar(Entity[PlayerID], var_colormap, !DefCheck[PlayerID] ? DefColor : DoubleSaveColor[PlayerID]);
                            #else
                            set_entvar(Entity[PlayerID], var_colormap, DefColor);
                            #endif
                        }
                        else
                        {
                            set_entvar(Entity[PlayerID], var_colormap, MaskColor[PlayerID] - 50);
                        }
                    }
                    #else
                    MaskColor[PlayerID] = (MaskColor[PlayerID] + 50) % 250;
                    set_entvar(Entity[PlayerID], var_colormap, MaskColor[PlayerID]);
                    #endif

                    #if defined SAVE_MASK_MODE
                    if(MaskColor[PlayerID] < 50)
                    {
                        SaveMaskColor[PlayerID] = !DefCheck[PlayerID] ? MaskColor[PlayerID] - 50 : DoubleSaveColor[PlayerID];
                    }
                    else
                    {
                        SaveMaskColor[PlayerID] = MaskColor[PlayerID] - 50;
                    }

                    SaveMask(PlayerID);
                    #endif
                }
            }
        case 3:
            {
                if(Entity[PlayerID] != 0)
                {
                    client_cmd(PlayerID, "messagemode ^"its_color^"");
                }
            }
        case 9:
            {
                return PLUGIN_HANDLED;
            }
    }

    CovidMenu(PlayerID);
    return PLUGIN_HANDLED;
}

public func_its_color(PlayerID)
{
    new String[13];
    read_argv(1, String, charsmax(String));

    new Float:Color[3];
    func_handler_row(String, Color);

    new TopColorNum = RGBtoHUE(Color);

    set_entvar(Entity[PlayerID], var_colormap, TopColorNum);

    #if defined SAVE_MASK_MODE
    SaveMaskColor[PlayerID] = TopColorNum;
    SaveMask(PlayerID);
    #endif

    return PLUGIN_HANDLED;
}

func_handler_row(const String[], Float:Color[3])
{
    new R[4], G[4], B[4];
    parse(String, R, charsmax(R), G, charsmax(G), B, charsmax(B));

    Color[0] = str_to_float(R);
    Color[1] = str_to_float(G);
    Color[2] = str_to_float(B);
}

#if defined CHAT_ADVERTISING
public Chat_Advertising()
{
    client_print_color(0, print_team_default, "%l", "COVID_CHAT_INFO");
}
#endif

SetMask(PlayerID)
{
    set_entvar(Entity[PlayerID], var_body, 0);

    #if defined MASK_ALL_MODE
    #if defined SAVE_MASK_MODE
    set_entvar(Entity[PlayerID], var_colormap, !DefCheck[PlayerID] ? DefColor : DoubleSaveColor[PlayerID]);
    #else
    set_entvar(Entity[PlayerID], var_colormap, DefColor);
    #endif
    #endif
}

RemoveMask(PlayerID)
{
    if(Entity[PlayerID] && is_entity(Entity[PlayerID]))
    {
        set_entvar(Entity[PlayerID], var_flags, FL_KILLME);
        set_entvar(Entity[PlayerID], var_nextthink, get_gametime());
        Entity[PlayerID] = 0;
    }
}

CreateEnt(PlayerID)
{
    if((Entity[PlayerID] = rg_create_entity("info_target")))
    {
        set_entvar(Entity[PlayerID], var_classname, "_covid_medical_mask");
        set_entvar(Entity[PlayerID], var_model, HDModels[PlayerID] ? MEDICAL_MODEL : MEDICAL_MODEL_FIX);
        set_entvar(Entity[PlayerID], var_modelindex, HDModels[PlayerID] ? Model[0] : Model[1]);
        set_entvar(Entity[PlayerID], var_movetype, MOVETYPE_FOLLOW);
        set_entvar(Entity[PlayerID], var_aiment, PlayerID);
    }
}

#if defined MASK_ALL_MODE
HealthMsg(PlayerID, num)
{
    client_print_color(PlayerID, print_team_default, "%l", num == 1 ? "COVID_HEALTH_MSG_PRE" : "COVID_HEALTH_MSG_POST", eCvarData[MASK_HEALTH_NUM]);
}
#endif

#if defined SAVE_MASK_MODE
SaveMask(PlayerID)
{
    new AuthID[MAX_AUTHID_LENGTH], Data[12];

    get_user_authid(PlayerID, AuthID, charsmax(AuthID));
    formatex(Data, charsmax(Data), "%d", SaveMaskColor[PlayerID]);

    nvault_set(Vault, AuthID, Data);
}
#endif

//Thanks Garey
stock RGBtoHUE(Float:rgb[3])
{
    new Float:r = rgb[0] / 255.0;
    new Float:g = rgb[1] / 255.0;
    new Float:b = rgb[2] / 255.0;
    new Float:cmax = floatmax(r, floatmax(g, b));
    new Float:cmin = floatmin(r, floatmin(g, b));
    new Float:delta = cmax - cmin;
    new Float:H = 1.0;
    if (!delta)
    {
        // undefined color seams like white or black which dont exists
        return 0;
    }
    if (r == cmax)
    {
        H = (g - b) / delta;
    }
    else if (g == cmax)
    {
        H = 2.0 + (b - r) / delta;
    }
    else
    {
        H = 4.0 + (r - g) / delta;
    }

    H /= 6.0;

    if (H < 0.0)
    {
        H += 1;
    }

    return floatround(H * 255);
}
C++:
/*
* - ----------

Плагин - "COVID mode" [SPECIAL AMXX 1.8.2 VERSION]

Сделано для поддержки тех пользователей, которые еще на старом AMXX 1.8.2)

Функционал этого плагина дублирует основной плагин.

* - ----------

Благодарности:

Предложения, помощь в проработке идеи: Nebo, Pokemoshka, present, ssx
Перевод на разные языки: rian18, tarsisd2, Yek'-ta, sensej1021, asd
Помощь по коду: Garey
Другая помощь: f@ntom, urpok

* - ----------

Поддержка плагина:

Dev-Cs: @wellasgood
vk: https://vk.com/d1mkin
Telegram: @WellAsGood

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

/*
Журнал изменений:

ver 1.0.1:

1. Подправлен LANG файл.
2. Убрана лишняя кнопка в меню.

ver 1.0.2:

1. Изменена проверка на открытие меню по флагу.
2. Добавлен немецкий перевод в LANG файл.

ver 1.0.3:

1. Добавлен португальский перевод в LANG файл.
2. Добавлена возможность установить чуть меньше здоровья тем кто без маски. (настройка #define)
3. В режим MASK_ALL_MODE добавлен (под режим), забирать жизни при спавне (если снята маска).
4. В LANG файл добавлены описание к кварам.
5. Добавлено много изменений по коду с учетом новых обновлений.

ver 1.0.4:

1. Исправлено отображение модели на стандартных моделях игроков.
2. Изменено наименование модели, что-бы игроки скачивали новую модель заного.

ver 1.0.5:

1. В LANG файл было добавлен новый турецкий перевод. (спасибо: Yek'-ta)
2. В LANG файле был обновлен португальский и немецкий перевод на корректный.

ver 1.0.6:

1. Добавлен польский перевод в LANG файл. (спасибо: sensej1021)

ver 1.0.7:

1. Удален перевод COVID_ERROR_MSG в LANG файле и исходнике, оставлен по стандарту en.

ver 1.0.8:

1. Обнаружена ошибка во всех переводах LANG файла: было COVID_HEALTH_MSN_PRE, стало COVID_HEALTH_MSG_PRE

ver 1.0.9:

1. Добавлена проверка на значение квара cv_mask_health_msg ('HealthMsg(PlayerID, 1);' - отсылалось даже если в кваре значение выкл)

ver 1.1.0:

1. Дополнена модель маски (добавлены новые текстуры разных цветов)
2. Добавлен выбор цвета в плагине для каждого игрока отдельно (в меню).
3. Изменения по коду с учетом новых обновлений.
4. Дополнен LANG файл.
5. Изменено наименование модели.

ver 1.1.1:

1. В меню масок, при выборе цвета, добавлен пункт: "Рандом". Если игрок активирует это, то при спавне у него будет случайный цвет маски. (только для режима MASK_ALL_MODE)
2. Изменения по коду с учетом новых обновлений.
3. Дополнен LANG файл.

ver 1.1.2:

1. Поправлена версия плагина AMXX 1.8.2 в исходнике на более понятную.

ver 1.1.3:

1. Теперь есть возможность сохранить цвет маски который был выбран в игре. (если игрок выходит с сервера и заходит, а также после смены карты)
2. Для сохранения задействован #include <nvault>
3. Включить/отключить сохранение: откомментируйте или закомментируйте 'define SAVE_MASK_MODE'
4. Правка кода с учетом новых обновлений.

ver 1.1.4:

1. Добавлена проверка #if defined SAVE_MASK_MODE в части кода функции plugin_init. (если режим сохранения был выкл, то эта часть бы работала)

ver 1.1.5:

1. Поправлен способ сохранения цвета маски в основной версии плагина.

ver 1.1.6:

1. Добавлена цветная модель, сделанная по другому (без применения многих текстур). Использование с помощью topcolor (colormap)
2. Для версии AMXX 1.8.2, fix маски для старых моделей игрока (без детализации) осуществлен не был, по техническим проблемам. (вот вам и минус старых версий amxx)
3. Большие правки по коду, с учетом добавленного.
4. Переработано меню, а также в него добавлены цвета для маски что-бы выбрать из предложенных, иначе ввести свой цвет в формате RGB (255 255 0), через пробел.
5. Цвет маски теперь сохраняется в двух случаях, если игрок выбрал цвет из предложенных, а также если игрок выбрал свой цвет (RGB)

ver 1.1.7:

1. Вновь были неполадки с сохранением цвета после выхода и повторного захода игрока на сервере. Исправлено.

ver 1.1.8:

1. В версии плагина AMXX 1.8.2 добавлена функция закрытия файла nvault (plugin_end)

ver 1.1.9:

1. Добавлена проверка #if defined SAVE_MASK_MODE для функции plugin_end, так как, она выполнялась бы в любом случае.

ver 1.2.0:

1. Выявлен баг, что если закомментировать режим #define MASK_ALL_MODE, то плагин не компилировался. (поправлено, теперь работа плагина в режиме без #define MASK_ALL_MODE доступна), спасибо: urpok
2. Добавлены доп. проверки по коду с учетом новых обновлений.
3. В версии плагина AMXX 1.8.2 добавлена проверка на вызов функции (сообщение в чат), иначе оно отправлялось бы вне зависимости от положения квара.
4. Дополнен LANG файл.

ver 1.2.1:

1. Добавлена возможность рекламировать в чат сообщения о командах открытия меню (вкл/выкл настройка #define CHAT_ADVERTISING, а также можно настроить временной интервал #define TIME).
2. Добавлена возможность указать цвет который будет выставляться по умолчанию (настройка new const DEFAULT_COLOR[], работает только с режимом #define MASK_ALL_MODE)
3. Добавлена функция обработчик, преобразующая строку c RGB данными в float массив, дабы не повторять лишний раз одно и тоже.
4. Теперь если игрок сохранит маску (т.е просто выберет в меню настроек), после перезахода на сервер и повторного захода в меню, уже будет пункт цвета (сохраненный).
4.1. Это означает, что даже после выключения маски или обратного включения (листания цветов других), можно вернуться к сохраненному цвету. (дабы заного его не вводить, например если это был свой RGB цвет)
5. Учтены и протестированы моменты, когда юзаются разные вариации режимов.
6. Большие правки/добавления по коду, с учетом новых обновлений.
7. В версию плагина AMXX 1.8.2 добавлен цветной чат (include colorchat.inc), теперь сообщения в чате цветные, как и в основной версии плагина.

ver 1.2.2:

1. В версии плагина AMXX 1.8.2 изменен ключ с %l на %L в client_print_color, так как, ключ %l не поддерживается.

ver 1.2.3:

1. Добавлено сохранение положения пункта РАНДОМ [ВКЛ/ВЫКЛ], после выхода и повторного захода на сервер, выбранное положение (вкл/выкл) сохранится.
2. Добавлено сохранение положения пункта МАСКА [ВКЛ/ВЫКЛ], после выхода и повторного захода на сервер, выбранное положение (вкл/выкл) сохранится.
3. Правка кода.

ver 1.2.4:

1. Поправлено наименование создаваемого конфига в основной версии плагина, так как, пробелы в наменование не читаются.

ver 1.2.5:

1. Правки немецкого перевода в LANG файле, спасибо: rian18
*/

#include <amxmodx>
#include <amxmisc>
#include <engine>
#include <fakemeta>
#include <colorchat>

#define MAX_RESOURCE_PATH_LENGTH 64
#define MAX_PLAYERS 32
#define MAX_MENU_LENGTH 512
#define MAX_AUTHID_LENGTH 64

#define ACCESS_FLAG_MENU (ADMIN_BAN|ADMIN_USER) //Мульти флаг, доступ к меню включения/выключения масок и для режима MASK_ACCESS

#define MASK_ALL_MODE //Если включено, то маски всем выставляются при заходе.

#if defined MASK_ALL_MODE
#include <hamsandwich>

#define SAVE_MASK_MODE //Сохранение цвета маски при выходе и повторном заходе игрока, а также при смене карты.

new DefColor;

#if defined SAVE_MASK_MODE
#include <nvault>
new Vault, SaveMaskColor[MAX_PLAYERS+1], DoubleSaveColor[MAX_PLAYERS+1];
new bool:DefCheck[MAX_PLAYERS+1];
#endif

new const DEFAULT_COLOR[] = "135 206 250" //указать цвет который будет выставляться по умолчанию (RGB формат)
#endif

//#define MASK_ACCESS //Работает с режимом MASK_ALL_MODE (Если включено, то выдает при спавне маски только игрокам с флагом ACCESS_FLAG_MENU, иначе всем)

#define CHAT_ADVERTISING //возможность рекламировать в чат сообщения о командах открытия меню (вкл/выкл откоммент/коммент).

#if defined CHAT_ADVERTISING
#define TIME 120.0 //время для показа рекламы в чате (интервал)
#endif

new const PLUGIN[] = "COVID mode";
new const VERSION[] = "[182] 1.2.5";
new const AUTHOR[] = "wellasgood";

new const MEDICAL_MODEL[] = "models/medical-mask/med-mask_clr.mdl";

new const COVID_DIR[] = "COVID_mode" //папка плагина
new const COVID_CFG[] = "covid" //файл конфигурации

new Entity[MAX_PLAYERS+1], MaskColor[MAX_PLAYERS+1];

#if defined MASK_ALL_MODE
new bool:Check[MAX_PLAYERS+1];

new MASK_HEALTH_EN, MASK_HEALTH_NUM, MASK_HEALTH_MSG;

new bool:CheckHealth[MAX_PLAYERS+1], bool:CheckRandom[MAX_PLAYERS+1];
#endif

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR);
    register_dictionary("covid.txt");

    register_clcmd("say /covid", "cmdOpenMenu");
    register_clcmd("say /cv", "cmdOpenMenu");

    register_concmd("its_color", "func_its_color");

    register_menu("CovidMenu", 1023, "Handle_CovidMenu", 0);

    #if defined MASK_ALL_MODE
    RegisterHam(Ham_Spawn, "player", "EventSpawn", true);

    MASK_HEALTH_EN = register_cvar("cv_mask_health_en", "1");
    MASK_HEALTH_NUM = register_cvar("cv_mask_health_num", "5");
    MASK_HEALTH_MSG = register_cvar("cv_mask_health_msg", "1");

    new Float:Color[3];
    func_handler_row(DEFAULT_COLOR, Color);

    DefColor = RGBtoHUE(Color);
    #endif

    #if defined SAVE_MASK_MODE
    Vault = nvault_open("Covid_save");

    if(Vault == INVALID_HANDLE){
        set_fail_state("Error opening nVault file!");
    }
    #endif

    #if defined CHAT_ADVERTISING
    set_task(TIME, "Chat_Advertising", .flags = "b");
    #endif
}

public plugin_precache()
{
    new Path[MAX_RESOURCE_PATH_LENGTH];
    formatex(Path, charsmax(Path), "\%s", MEDICAL_MODEL);

    if(!file_exists(Path))
    {
        set_fail_state("Error! Model not found");
    }
    else
    {
        precache_model(MEDICAL_MODEL);
    }
}

public plugin_cfg()
{
    new Dir[MAX_RESOURCE_PATH_LENGTH];
    get_localinfo("amxx_configsdir", Dir, charsmax(Dir));

    new Path[MAX_RESOURCE_PATH_LENGTH * 2];
    formatex(Path, charsmax(Path), "%s/%s/%s.cfg", Dir, COVID_DIR, COVID_CFG);

    if(!file_exists(Path)){
        return;
    }

    server_cmd("exec %s", Path);
}

#if defined SAVE_MASK_MODE
public plugin_end()
{
    nvault_close(Vault);
}
#endif

#if defined MASK_ALL_MODE
public client_putinserver(PlayerID)
{
    if(is_user_bot(PlayerID) || is_user_hltv(PlayerID))
    {
        return;
    }

    Check[PlayerID] = false;

    if(get_pcvar_num(MASK_HEALTH_EN) == 1)
    {
        CheckHealth[PlayerID] = false;
    }

    #if defined SAVE_MASK_MODE
    new AuthID[MAX_AUTHID_LENGTH], Data[12];
    get_user_authid(PlayerID, AuthID, charsmax(AuthID));

    new timestamp, AccessResult = nvault_lookup(Vault, AuthID, Data, charsmax(Data), timestamp);

    if(AccessResult)
    {
        SaveMaskColor[PlayerID] = str_to_num(Data);

        if(SaveMaskColor[PlayerID] > 255)
        {
            switch(SaveMaskColor[PlayerID])
            {
                case 666:
                {
                    CheckRandom[PlayerID] = true;
                }
                case 777:
                {
                    CheckRandom[PlayerID] = false;
                }
                case 888:
                {
                    if(get_pcvar_num(MASK_HEALTH_EN) == 1)
                    {
                        CheckHealth[PlayerID] = true;
                    }
                }
            }
        }
        else
        {
            DoubleSaveColor[PlayerID] = SaveMaskColor[PlayerID];
            DefCheck[PlayerID] = true;
        }
    }
    #endif

    #if defined MASK_ACCESS
    if(get_user_flags(PlayerID) & ACCESS_FLAG_MENU)
    {
        #if defined SAVE_MASK_MODE
        if(SaveMaskColor[PlayerID] != 888)
        {
            CreateEnt(PlayerID);
        }
        #else
        CreateEnt(PlayerID);
        #endif
    }
    #else
    #if defined SAVE_MASK_MODE
    if(SaveMaskColor[PlayerID] != 888)
    {
        CreateEnt(PlayerID);
    }
    #else
    CreateEnt(PlayerID);
    #endif
    #endif
}

public EventSpawn(PlayerID)
{
    if(!is_user_alive(PlayerID))
    {
        return;
    }

    if(get_pcvar_num(MASK_HEALTH_EN) == 1)
    {
        if(CheckHealth[PlayerID])
        {
            new HP = pev(PlayerID, pev_health);
            set_pev(PlayerID, pev_health, float(HP) - get_pcvar_num(MASK_HEALTH_NUM));

            if(get_pcvar_num(MASK_HEALTH_MSG) == 1)
            {
                HealthMsg(PlayerID, 2);
            }
        }
    }

    if(Entity[PlayerID] && is_valid_ent(Entity[PlayerID]))
    {
        if(!Check[PlayerID])
        {
            SetMask(PlayerID);

            #if defined SAVE_MASK_MODE
            if(!CheckRandom[PlayerID])
            {
                if(DefCheck[PlayerID])
                {
                    set_pev(Entity[PlayerID], pev_colormap, SaveMaskColor[PlayerID]);
                }
                else
                {
                    set_pev(Entity[PlayerID], pev_colormap, DefColor);
                }
            }
            #else
            set_pev(Entity[PlayerID], pev_colormap, DefColor);
            #endif
        }

        if(CheckRandom[PlayerID])
        {
            new RandomNum = random_num(0, 255);
            set_pev(Entity[PlayerID], pev_colormap, RandomNum);
        }
    }
}
#endif

public client_disconnect(PlayerID)
{
    RemoveMask(PlayerID);

    MaskColor[PlayerID] = 0;

    #if defined SAVE_MASK_MODE
    SaveMaskColor[PlayerID] = 0;
    DefCheck[PlayerID] = false;
    #endif
}

public cmdOpenMenu(PlayerID)
{
    if(get_user_flags(PlayerID) & ACCESS_FLAG_MENU)
    {
        CovidMenu(PlayerID);
    }

    return PLUGIN_HANDLED;
}

CovidMenu(PlayerID)
{
    new Menu[MAX_MENU_LENGTH], Keys = MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4|MENU_KEY_0;
    new Len = formatex(Menu, charsmax(Menu), "%L^n^n", PlayerID, "COVID_MENU_TITLE");

    Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[1] \y# \w%L \y[\r%L\y]^n^n", PlayerID, "COVID_MENU_ITEM_INFO", PlayerID, Entity[PlayerID] == 0 ? "COVID_MENU_ITEM_OFF" : "COVID_MENU_ITEM_ON");

    #if defined MASK_ALL_MODE
    if(Entity[PlayerID] == 0)
    {
        Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[2] \y# \w%L \y[\d%L\y]^n", PlayerID, "COVID_MENU_ITEM_COLOR_RANDOM_INFO", PlayerID, "COVID_MENU_ITEM_COLOR_OFF");
    }
    else
    {
        Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[2] \y# \w%L \y[\r%L\y]^n", PlayerID, "COVID_MENU_ITEM_COLOR_RANDOM_INFO", PlayerID, !CheckRandom[PlayerID] ? "COVID_MENU_ITEM_OFF" : "COVID_MENU_ITEM_ON");
    }
    #else
        Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[2] \y# \w%L \y[\r%L\y]^n", PlayerID, "COVID_MENU_ITEM_COLOR_RANDOM_INFO", PlayerID, "COVID_MENU_ITEM_DISABLED");
    #endif

    if(Entity[PlayerID] == 0)
    {
        Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[3] \y# \w%L \y[\d%L\y]^n", PlayerID, "COVID_MENU_ITEM_COLOR_INFO", PlayerID, "COVID_MENU_ITEM_COLOR_OFF");
    }
    #if defined MASK_ALL_MODE
    else if(CheckRandom[PlayerID])
    {
        Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[3] \y# \w%L \y[\d%L\y]^n", PlayerID, "COVID_MENU_ITEM_COLOR_INFO", PlayerID, "COVID_MENU_ITEM_COLOR_RANDOM_ACTIVATE");
    }
    #endif
    else
    {
        new FormatLang[64];

        #if defined SAVE_MASK_MODE
        if(MaskColor[PlayerID] == 0)
        {
            formatex(FormatLang, charsmax(FormatLang), !DefCheck[PlayerID] ? "COVID_MENU_ITEM_COLOR_%d" : "COVID_MENU_ITEM_AUTOSAVE_%d", MaskColor[PlayerID]);

            Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[3] \y# \w%L \y[\r%L\y]^n", PlayerID, "COVID_MENU_ITEM_COLOR_INFO", PlayerID, FormatLang);
        }
        else
        {
            formatex(FormatLang, charsmax(FormatLang), "COVID_MENU_ITEM_COLOR_%d", MaskColor[PlayerID]);
            Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[3] \y# \w%L \y[\r%L\y]^n", PlayerID, "COVID_MENU_ITEM_COLOR_INFO", PlayerID, FormatLang);
        }
        #else
            #if !defined MASK_ALL_MODE
            formatex(FormatLang, charsmax(FormatLang), "COVID_MENU_ITEM_COLOR_%d", MaskColor[PlayerID] + 50);
            Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[3] \y# \w%L \y[\r%L\y]^n", PlayerID, "COVID_MENU_ITEM_COLOR_INFO", PlayerID, FormatLang);
            #else
            formatex(FormatLang, charsmax(FormatLang), "COVID_MENU_ITEM_COLOR_%d", MaskColor[PlayerID]);
            Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[3] \y# \w%L \y[\r%L\y]^n", PlayerID, "COVID_MENU_ITEM_COLOR_INFO", PlayerID, FormatLang);
            #endif
        #endif
    }

    if(Entity[PlayerID] == 0)
    {
        Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[4] \y# \w%L \y[\d%L\y]^n^n", PlayerID, "COVID_MENU_ITEM_ITS_COLOR", PlayerID, "COVID_MENU_ITEM_COLOR_OFF");
    }
    else
    {
        Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[4] \y# \w%L \y[\d%L\y]^n^n", PlayerID, "COVID_MENU_ITEM_ITS_COLOR", PlayerID, "COVID_MENU_ITEM_ITS_COLOR_RGB");
    }

    formatex(Menu[Len], charsmax(Menu) - Len, "\r[0] \y# \w%L", PlayerID, "COVID_MENU_EXIT");
    return show_menu(PlayerID, Keys, Menu, -1, "CovidMenu");
}

public Handle_CovidMenu(PlayerID, Keys)
{
    switch(Keys)
    {
        case 0:
            {
                if(Entity[PlayerID] && is_valid_ent(Entity[PlayerID]))
                {
                    RemoveMask(PlayerID);

                    MaskColor[PlayerID] = 0;

                    #if defined MASK_ALL_MODE
                    Check[PlayerID] = false;

                    if(get_pcvar_num(MASK_HEALTH_EN) == 1)
                    {
                        CheckHealth[PlayerID] = true;

                        if(get_pcvar_num(MASK_HEALTH_MSG) == 1)
                        {
                            HealthMsg(PlayerID, 1);
                        }
                    }

                    #if defined SAVE_MASK_MODE
                    SaveMaskColor[PlayerID] = 888;
                    SaveMask(PlayerID);
                    #endif
                    #endif
                }
                else
                {
                    CreateEnt(PlayerID);
                    SetMask(PlayerID);

                    #if defined MASK_ALL_MODE
                    Check[PlayerID] = true;

                    if(get_pcvar_num(MASK_HEALTH_EN) == 1)
                    {
                        CheckHealth[PlayerID] = false;

                        if(get_pcvar_num(MASK_HEALTH_MSG) == 1)
                        {
                            HealthMsg(PlayerID, 1);
                        }
                    }

                    #if defined SAVE_MASK_MODE
                    SaveMaskColor[PlayerID] = DefColor;
                    SaveMask(PlayerID);
                    #endif
                    #endif
                }
            }
        case 1:
            {
                #if defined MASK_ALL_MODE
                if(Entity[PlayerID] != 0)
                {
                    CheckRandom[PlayerID] = !CheckRandom[PlayerID];

                    #if defined SAVE_MASK_MODE
                    SaveMaskColor[PlayerID] = CheckRandom[PlayerID] ? 666 : 777;
                    SaveMask(PlayerID);
                    #endif
                }
                #endif
            }
        case 2:
            {
                if(Entity[PlayerID] != 0)
                {
                    #if defined MASK_ALL_MODE
                    if(!CheckRandom[PlayerID])
                    {
                        MaskColor[PlayerID] = (MaskColor[PlayerID] + 50) % 300;

                        if(MaskColor[PlayerID] < 50)
                        {
                            #if defined SAVE_MASK_MODE
                            set_pev(Entity[PlayerID], pev_colormap, !DefCheck[PlayerID] ? DefColor : DoubleSaveColor[PlayerID]);
                            #else
                            set_pev(Entity[PlayerID], pev_colormap, DefColor);
                            #endif
                        }
                        else
                        {
                            set_pev(Entity[PlayerID], pev_colormap, MaskColor[PlayerID] - 50);
                        }
                    }
                    #else
                    MaskColor[PlayerID] = (MaskColor[PlayerID] + 50) % 250;
                    set_pev(Entity[PlayerID], pev_colormap, MaskColor[PlayerID]);
                    #endif

                    #if defined SAVE_MASK_MODE
                    if(MaskColor[PlayerID] < 50)
                    {
                        SaveMaskColor[PlayerID] = !DefCheck[PlayerID] ? MaskColor[PlayerID] - 50 : DoubleSaveColor[PlayerID];
                    }
                    else
                    {
                        SaveMaskColor[PlayerID] = MaskColor[PlayerID] - 50;
                    }

                    SaveMask(PlayerID);
                    #endif
                }
            }
        case 3:
            {
                if(Entity[PlayerID] != 0)
                {
                    client_cmd(PlayerID, "messagemode ^"its_color^"");
                }
            }
        case 9:
            {
                return PLUGIN_HANDLED;
            }
    }

    CovidMenu(PlayerID);
    return PLUGIN_HANDLED;
}

public func_its_color(PlayerID)
{
    new String[13];
    read_argv(1, String, charsmax(String));

    new Float:Color[3];
    func_handler_row(String, Color);

    new TopColorNum = RGBtoHUE(Color);

    set_pev(Entity[PlayerID], pev_colormap, TopColorNum);

    #if defined SAVE_MASK_MODE
    SaveMaskColor[PlayerID] = TopColorNum;
    SaveMask(PlayerID);
    #endif

    return PLUGIN_HANDLED;
}

func_handler_row(const String[], Float:Color[3])
{
    new R[4], G[4], B[4];
    parse(String, R, charsmax(R), G, charsmax(G), B, charsmax(B));

    Color[0] = str_to_float(R);
    Color[1] = str_to_float(G);
    Color[2] = str_to_float(B);
}

#if defined CHAT_ADVERTISING
public Chat_Advertising()
{
    client_print_color(0, print_team_default, "%L", LANG_PLAYER, "COVID_CHAT_INFO");
}
#endif

SetMask(PlayerID)
{
    entity_set_int(Entity[PlayerID], EV_INT_body, 0);

    #if defined MASK_ALL_MODE
    #if defined SAVE_MASK_MODE
    set_pev(Entity[PlayerID], pev_colormap, !DefCheck[PlayerID] ? DefColor : DoubleSaveColor[PlayerID]);
    #else
    set_pev(Entity[PlayerID], pev_colormap, DefColor);
    #endif
    #endif
}

RemoveMask(PlayerID)
{
    if(Entity[PlayerID] && is_valid_ent(Entity[PlayerID]))
    {
        entity_set_int(Entity[PlayerID], EV_INT_flags, FL_KILLME);
        entity_set_float(Entity[PlayerID], EV_FL_nextthink, get_gametime());
        Entity[PlayerID] = 0;
    }
}

CreateEnt(PlayerID)
{
    if((Entity[PlayerID] = create_entity("info_target")))
    {
        entity_set_string(Entity[PlayerID], EV_SZ_classname, "_covid_medical_mask");
        entity_set_model(Entity[PlayerID], MEDICAL_MODEL);
        entity_set_int(Entity[PlayerID], EV_INT_movetype, MOVETYPE_FOLLOW);
        entity_set_edict(Entity[PlayerID], EV_ENT_aiment, PlayerID);
    }
}

#if defined MASK_ALL_MODE
HealthMsg(PlayerID, num)
{
    client_print_color(PlayerID, print_team_default, "%L", PlayerID, num == 1 ? "COVID_HEALTH_MSG_PRE" : "COVID_HEALTH_MSG_POST", get_pcvar_num(MASK_HEALTH_NUM));
}
#endif

#if defined SAVE_MASK_MODE
SaveMask(PlayerID)
{
    new AuthID[MAX_AUTHID_LENGTH], Data[12];

    get_user_authid(PlayerID, AuthID, charsmax(AuthID));
    formatex(Data, charsmax(Data), "%d", SaveMaskColor[PlayerID]);

    nvault_set(Vault, AuthID, Data);
}
#endif

//Thanks Garey
stock RGBtoHUE(Float:rgb[3])
{
    new Float:r = rgb[0] / 255.0;
    new Float:g = rgb[1] / 255.0;
    new Float:b = rgb[2] / 255.0;
    new Float:cmax = floatmax(r, floatmax(g, b));
    new Float:cmin = floatmin(r, floatmin(g, b));
    new Float:delta = cmax - cmin;
    new Float:H = 1.0;
    if (!delta)
    {
        // undefined color seams like white or black which dont exists
        return 0;
    }
    if (r == cmax)
    {
        H = (g - b) / delta;
    }
    else if (g == cmax)
    {
        H = 2.0 + (b - r) / delta;
    }
    else
    {
        H = 4.0 + (r - g) / delta;
    }

    H /= 6.0;

    if (H < 0.0)
    {
        H += 1;
    }

    return floatround(H * 255);
}
Назад
Сверху