top round damage

  • Автор темы Автор темы hackerman
  • Дата начала Дата начала
Сообщения
10
Реакции
0
Баллы
1
Ошибка
-
AMX Mod X
1.9.0
Билд сервера
-
ReGameDLL
5.28
Metamod версия
1.3 R-версия
Metamod плагины
-
Список плагинов
-
Исходный код плагина
-
Доброго времени суток. Как сделать так чтобы данный плагин отображал за какую команду играет игрок
 
Решение
Код:
/*****************************************************************************
   Возможности:
1. Настроить сколько игроков выводить в список
2. Настроить минимальное количество игроков для вывода
3. Настроить с какого раунда выводить
4. Время показа
5. Мгновенное закрытие меню по нажатию на клавиши цифр
6. Отключение показа через команду /damage
7. Помимо урона рядом выводит также количество убийств
8. Префикс перед сообщением в чате
9. Настроить сколько денег давать лучшему игроку раунда
10. Возможность отключения выдачи награды
11. Добавлен вывод команды игрока [T/CT]

Только на реапи, без реапи делать не буду, не вижу смысла

Благодарности:
Vaqtincha - за куски кода, идею и помощь по коду
Ссылка на оригинал плагина...
@hackerman, возьми в привычку - заполнять все поля; не создавать две темы одинакового содержания; прикладывать исходник
 
Код:
/*****************************************************************************
   Возможности:
1. Настроить сколько игроков выводить в список
2. Настроить минимальное количество игроков для вывода
3. Настроить с какого раунда выводить
4. Время показа
5. Мгновенное закрытие меню по нажатию на клавиши цифр
6. Отключение показа через команду /damage
7. Помимо урона рядом выводит также количество убийств
8. Префикс перед сообщением в чате
9. Настроить сколько денег давать лучшему игроку раунда
10. Возможность отключения выдачи награды
11. Добавлен вывод команды игрока [T/CT]

Только на реапи, без реапи делать не буду, не вижу смысла

Благодарности:
Vaqtincha - за куски кода, идею и помощь по коду
Ссылка на оригинал плагина: [https://dev-cs.ru/threads/75/](https://dev-cs.ru/threads/75/)

Версии:
1.0.0 релиз
1.0.1 добавлена возможность выдавать денежную награду лучшему игроку
1.0.2 рефаторинг кода
1.0.3 перенес проверку на минимальное количество игроков с fnCompareDamage() в RoundEnd() и изменен подсчет наносимого урона
1.0.4 убрал вывод заголовка меню, если никто в раунде никого не ранил
1.0.5 добавлено отображение команды игрока [T] или [CT]

*****************************************************************************/

#include <amxmodx>
#include <reapi>

#if AMXX_VERSION_NUM < 183
    #include <colorchat>
#endif

#define PLUGIN "Top Round Damage"
#define VERSION "1.0.5 ReAPI"
#define AUTHOR "Dager* *.* -G-"

#if !defined MAX_PLAYERS
    #define MAX_PLAYERS 32
#endif

#if !defined MAX_NAME_LENGTH
    #define MAX_NAME_LENGTH 32
#endif

#define IsPlayer(%1)    (1 <= %1 <= g_iMaxPlayers)
#define ClearArr(%1)    arrayset(_:%1, _:0.0, sizeof(%1))
#define MENU_KEYS       (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)

/* настройки */
#define CHAT_PREFIX     "^4[Сервер]"  // префикс
#define TOP_PLAYERS     5             // количество выводимых игроков в топ по дамагу [больше 10 нет смысла указывать]
#define MIN_PLAYERS     2             // минимальное количество игроков для вывода топа
#define ROUND_NUMBER    1             // с какого раунда выводить
#define SHOW_TIME       5             // через сколько секунд закроется меню лучших игроков по дамагу за раунд [целое число]
#define GIVE_MONEY      500           // сколько денег давать лучшему игроку
#define GIVE_AWARD                    // закомментируйте если не хотите давать награду лучшему игроку

/* не трогать всё что ниже*/

enum _:ePlayerData
{
    PLAYER_ID,
    DAMAGE,
    KILLS,
    TEAM // Добавлено для хранения команды (хотя можно получать динамически)
};

new g_arrData[MAX_PLAYERS + 1][ePlayerData];
new g_iPlayerDmg[MAX_PLAYERS + 1];
new g_iPlayerKills[MAX_PLAYERS + 1];
new g_iRoundCounter;
new g_iMaxPlayers;
new bool:g_bIsSwitch[MAX_PLAYERS + 1];
new g_iMenuID;

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR);
    
    register_clcmd("say /damage", "cmdTopDamageSwitch");
    register_clcmd("say_team /damage", "cmdTopDamageSwitch");
    
    RegisterHookChain(RG_CSGameRules_RestartRound, "CSGameRules_RestartRound_Pre", false);
    RegisterHookChain(RG_CBasePlayer_TakeDamage, "CBasePlayer_TakeDamage", true);
    RegisterHookChain(RG_CBasePlayer_Killed, "CBasePlayer_Killed", true);
    RegisterHookChain(RG_RoundEnd, "RoundEnd", true);
    
    g_iMenuID = register_menuid("TopDmg");
    register_menucmd(g_iMenuID, MENU_KEYS, "fnTopDmgHandler");
    
    g_iMaxPlayers = get_member_game(m_nMaxPlayers);
}

public client_putinserver(id)
{
    // начальные значения зашедшему игроку
    g_iPlayerDmg[id] = 0;
    g_iPlayerKills[id] = 0;
    g_bIsSwitch[id] = true;
}

public cmdTopDamageSwitch(id)
{
    g_bIsSwitch[id] = !g_bIsSwitch[id];
    
    new szSwitch[20];
    formatex(szSwitch, charsmax(szSwitch), "%s", g_bIsSwitch[id] ? "включили" : "отключили");
    
    client_print_color(id, print_team_default,
        "%s ^1Вы %s показ ^4[топ-%d по урону] ^1за раунд!",
        CHAT_PREFIX, szSwitch, TOP_PLAYERS
    );
    
    return PLUGIN_CONTINUE;
}

public CSGameRules_RestartRound_Pre()
{
    if(get_member_game(m_bCompleteReset))
        g_iRoundCounter = 0;
    
    g_iRoundCounter++;
    
    // чистка массивов с данными
    ClearArr(g_iPlayerDmg);
    ClearArr(g_iPlayerKills);
    
    for(new i = 1; i <= g_iMaxPlayers; i++)
        arrayset(g_arrData[i], 0, ePlayerData);
}

public CBasePlayer_TakeDamage(const pevVictim, pevInflictor, const pevAttacker, Float:flDamage, bitsDamageType)
{
    if(pevVictim == pevAttacker || !IsPlayer(pevAttacker) || (bitsDamageType & DMG_BLAST))
        return HC_CONTINUE;
    
    if(rg_is_player_can_takedamage(pevVictim, pevAttacker))
        g_iPlayerDmg[pevAttacker] += floatround(flDamage);
    
    return HC_CONTINUE;
}

public CBasePlayer_Killed(const Victim, Attacker)
{
    if(!is_user_connected(Victim) || Victim == Attacker || !IsPlayer(Attacker) || get_member(Victim, m_iTeam) == get_member(Attacker, m_iTeam))
        return HC_CONTINUE;
    
    g_iPlayerKills[Attacker]++;
    
    return HC_CONTINUE;
}

public fnCompareDamage()
{
    new iPlayers[MAX_PLAYERS], iNum, iPlayer;
#if defined GIVE_AWARD
    new szName[MAX_NAME_LENGTH], pBestPlayerId, pBestPlayerDamage;
#endif
    get_players(iPlayers, iNum, "h");
    
    // цикл сбора инфы по всем игрокам
    for(new i; i < iNum; i++)
    {
        iPlayer = iPlayers[i];
        
        g_arrData[i][PLAYER_ID] = iPlayer;
        g_arrData[i][DAMAGE] = _:g_iPlayerDmg[iPlayer];
        g_arrData[i][KILLS] = _:g_iPlayerKills[iPlayer];
    }
    
    // сортировка массива
    SortCustom2D(g_arrData, sizeof(g_arrData), "SortRoundDamage");
    
#if defined GIVE_AWARD
    // получение ид лучшего игрока после сортировки (1й элемент массива)
    pBestPlayerId = g_arrData[0][PLAYER_ID];
    // также получение урона лучшего игрока
    pBestPlayerDamage = g_arrData[0][DAMAGE];
    
    // проверки на валидность данного игрока и урон (если урон 0, то не давать награду)
    if(IsPlayer(pBestPlayerId) && is_user_connected(pBestPlayerId) && pBestPlayerDamage >= 1)
    {
        get_user_name(pBestPlayerId, szName, charsmax(szName));
        rg_add_account(pBestPlayerId, GIVE_MONEY, AS_ADD, true);
        
        client_print_color(0, print_team_default,
            "%s ^3%s ^1нанес больше всего урона [^4%d^1] и получает [^4%d^3$^1].",
            CHAT_PREFIX, szName, pBestPlayerDamage, GIVE_MONEY
        );
    }
#endif
    
    return PLUGIN_HANDLED;
}

// функция сравнения для сортировки
public SortRoundDamage(const elem1[], const elem2[])
{
    // сравнение дамага
    return (elem1[DAMAGE] < elem2[DAMAGE]) ? 1 : (elem1[DAMAGE] > elem2[DAMAGE]) ? -1 : 0;
}

public RoundEnd()
{
    if(g_iRoundCounter >= ROUND_NUMBER)
    {
        new iPlayers[MAX_PLAYERS], iNum;
        get_players(iPlayers, iNum, "h");
        
        // если игроков меньше чем выставленное значение MIN_PLAYERS, то прерываем
        if(iNum >= MIN_PLAYERS)
        {
            // таск с задежкой для сравнения урона игроков (без него будет неточность последнего попадания)
            // при игре 1х1 и убийстве противника с одного патрона думаю станет ясно, что это значит и для чего таск
            set_task(0.1, "fnCompareDamage");
            // таск на отображение списка
            set_task(0.2, "fnShowStats");
        }
    }
}

public fnShowStats()
{
    new iPlayers[MAX_PLAYERS], iNum, szMenu[512], szName[MAX_NAME_LENGTH], iLen, iPlayer;
    new bool:bMenuDmgShow;
    new szTeamTag[8]; // Буфер для тега команды
    get_players(iPlayers, iNum, "h");
    
    iLen = formatex(szMenu, charsmax(szMenu), "\w#. \r[\yУрон\r] [\yФраги\r] \wза раунд:^n^n");
    
    // Определяем лимит цикла (либо TOP_PLAYERS, либо реальное кол-во игроков)
    new iLimit = (iNum < TOP_PLAYERS) ? iNum : TOP_PLAYERS;
    
    for(new i; i < iLimit; i++)
    {
        // для тех, кому надо выводить игроков с 0 уроном, закомментировать 2 строки ниже
        if(g_arrData[i][DAMAGE] <= 0)
            continue;
        
        new id = g_arrData[i][PLAYER_ID];
        
        // Получаем имя
        get_user_name(id, szName, charsmax(szName));
        
        // Получаем команду и формируем тег
        switch(get_member(id, m_iTeam))
        {
            case TEAM_TERRORIST: copy(szTeamTag, charsmax(szTeamTag), "\r[T]");
            case TEAM_CT:        copy(szTeamTag, charsmax(szTeamTag), "\b[CT]");
            default:             copy(szTeamTag, charsmax(szTeamTag), "\y[SPEC]");
        }
        
        // форматирование красивого меню в столбик с добавлением команды
        // Формат: 1. [099] [2] [T] Nickname
        if(0 <= g_arrData[i][DAMAGE] < 10)
            iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\w%d. \r[\y00%d\r] [\y%d\r] %s \w%s^n", i + 1, g_arrData[i][DAMAGE], g_arrData[i][KILLS], szTeamTag, szName);
        else if(10 <= g_arrData[i][DAMAGE] < 100)
            iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\w%d. \r[\y0%d\r] [\y%d\r] %s \w%s^n", i + 1, g_arrData[i][DAMAGE], g_arrData[i][KILLS], szTeamTag, szName);
        else
            iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\w%d. \r[\y%d\r] [\y%d\r] %s \w%s^n", i + 1, g_arrData[i][DAMAGE], g_arrData[i][KILLS], szTeamTag, szName);
        
        bMenuDmgShow = true;
    }
    
    // если есть игроки в раунде с уроном
    if(bMenuDmgShow)
    {
        // показ всем игрокам список лучших игроков
        for(new i; i < iNum; i++)
        {
            iPlayer = iPlayers[i];
            
            // если игрок не выключил показ, то показываем
            if(g_bIsSwitch[iPlayer] && !is_player_see_menu(iPlayer, g_iMenuID))
                show_menu(iPlayer, MENU_KEYS, szMenu, SHOW_TIME, "TopDmg");
        }
    }
    
    return PLUGIN_HANDLED;
}

stock bool:is_player_see_menu(pPlayer, iMenuIdToIgnore = 0) {
    new iMenuID, iKeys;
    get_user_menu(pPlayer, iMenuID, iKeys);
    return (iMenuID && iMenuID != iMenuIdToIgnore);
}

// обработчик нажатия цифр для закрытия меню моментально
public fnTopDmgHandler(id, iKey)
{
    if(iKey >= 0 || iKey <= 9)
        return PLUGIN_CONTINUE;
    
    return PLUGIN_HANDLED;
}
 
Решение

Кто просматривает тему

Назад
Верх