Лимит на покупку Щита

Сообщения
2,491
Реакции
2,791
Помог
61 раз(а)
И как оказалось РеАПи все же крут, ибо вон сколько кода заменили 1 хуком и 1 мембером
 
Сообщения
453
Реакции
79
Помог
4 раз(а)
fantom, Из-за этого, хочу теперь познать ReAPI - От и До :good2:
18 Янв 2019
BlackSignature, Понял
18 Янв 2019
Теперь, я как в тумане
Код:
#include <amxmodx>
#include <reapi>

#define SHIELD_LIMIT 1                // Количество Щитов на каждую команду
#define ACCESS_IMMUNITY    ADMIN_RCON    // Иммунитет к функциям плагина. Для отключения, пропишите: ADMIN_ALL

new g_iShieldCount[3];
new bool:g_bUseShield[33];

public plugin_init()
{
    register_plugin("Shield Limitter", "1.5", "WILL BE");
    
    new sPref[][] = {"awp_", "aim_", "35hp", "fy_"};
    new map[32]; get_mapname(map, charsmax(map));
    for(new i; i < sizeof sPref; i++)
    {
        if(containi(map, sPref[i]) != -1)
        {
            pause("ad");
            return;
        }
    }
    
    RegisterHookChain(RG_CBasePlayer_HasRestrictItem, "HasRestrictItem_Pre");
    RegisterHookChain(RG_CSGameRules_RestartRound, "RestartRound_Pre");
    
    register_event("DeathMsg", "eDeathMsg", "a");
}

public HasRestrictItem_Pre(id, ItemID:iItem, ItemRestType:iRestType)
{
    if(iRestType != ITEM_TYPE_BUYING) return HC_CONTINUE;
    
    new team = get_user_team(id);

    if(iItem == ITEM_SHIELDGUN)
    {
        #if ACCESS_IMMUNITY != ADMIN_ALL       
        if(~get_user_flags(id) & ACCESS_IMMUNITY && g_iShieldCount[team] >= SHIELD_LIMIT)
#else
        if(g_iShieldCount[team] >= SHIELD_LIMIT)
#endif
        {
            client_print_color(id, print_team_default, "[^4Shield Limit^1] Достигнуто ^3максимальное ^1количество ^4Щитов ^1на команду [^3%d^1/^3%d^1]", g_iShieldCount[team], SHIELD_LIMIT);
            SetHookChainReturn(ATYPE_INTEGER, true);
            return HC_SUPERCEDE;
        }
        else
        {
            g_iShieldCount[team]++;
            g_bUseShield[id] = true;
        }
    }
    else
    {
        if(g_iShieldCount[team])
            g_iShieldCount[team]--;
        g_bUseShield[id] = false;
    }
    return HC_CONTINUE;
}

public eDeathMsg()
    FuncDiscDeath(read_data(2));

public client_disconnected(id)
    FuncDiscDeath(id);

FuncDiscDeath(id)
{
    if(!g_bUseShield[id]) return;
    
    new team = get_user_team(id);
    if(g_iShieldCount[team])
        g_iShieldCount[team]--;
    g_bUseShield[id] = false;
}

public RestartRound_Pre()
{
    new players[32], pnum, i;
    arrayset(g_iShieldCount, 0, 3);

    get_players(players, pnum, "ae", "TERRORIST");
    for(i = 0; i < pnum; i++)
    {
        if(get_member(players[i], m_bOwnsShield))
        {
            g_iShieldCount[1]++;
            g_bUseShield[players[i]] = true;
        } else g_bUseShield[players[i]] = false;
    }
    get_players(players, pnum, "ae", "CT");
    for(i = 0; i < pnum; i++)
    {
        if(get_member(players[i], m_bOwnsShield))
        {
            g_iShieldCount[2]++;
            g_bUseShield[players[i]] = true;
        } else g_bUseShield[players[i]] = false;
    }
}
Лимит то работает, то нет. Ощущение, что зависит от кол.-ва людей на сервере. Когда 2 CT, то лимит работает, ежели играем 9х9, то лимит странно себя ведет, то дает купить, то не дает. В голове не укладывается:cray:
 
Сообщения
2,491
Реакции
2,791
Помог
61 раз(а)
Код:
 new sPref[][] = {"awp_", "aim_", "35hp", "fy_"};
 new map[32]; get_mapname(map, charsmax(map));
 for(new i; i < sizeof sPref; i++)
 {
     if(containi(map, sPref[i]) != -1)
     {
         pause("ad");
         return;
     }
 }
Ну во-первых ватит лепить костыли на паузу плагинов методом перебора contain. Есть конфигурация плагинов для карт по префиксам и названии. Там и должно быть отключение

Во-вторых: при каких случаях идет не такое поведение которое нужно
18 Янв 2019
А вот третих не делайте магические числа
new bool:g_bUseShield[33]; -> new bool:g_bUseShield[MAX_PLAYERS + 1];
18 Янв 2019
Еще get_user_team может возвращать совсем не то что реально. Для этого получают через второй аргумент первый символ строкы кото}ый является наименованием команды. Замените на TeamNames:get_member(id, m_iTeam);
 
Сообщения
1,177
Реакции
2,144
Помог
57 раз(а)
Чтобы лимитирование с использованием кеша (g_iShieldCount) работало, нужно учесть все ситуации. Навскидку: подъём с земли, покупка, выдача плагинами, отъём плагинами, естественный дроп, переход в другую команду без смерти (автобаланс, плагины), выход с сервера. Либо это всё нужно описать, либо отказаться от кеша, и пересчитывать реальное кол-во щитов на руках у конкретной команды при попытке покупки, при показе в меню(если нужно), и т.п. Т.е. пытаюсь я купить щит - кидаем get_players() с "a" (только живые) для моей команды, перебираем циклом, заносим в счётчик всех у кого есть щит. И уже от этого пляшем. Да, так тяжелее по моментальной нагрузке. Но для частого вызова вроде тача (подбор с земли) можно юзать "недолгий кеш". Плюс в том что кода в разы меньше, и проще в понимании. В любом случае, какой путь выбрать, решать вам.
 

Вложения

Сообщения
1,177
Реакции
2,144
Помог
57 раз(а)
fl0wer, шило на мыло, если я правильно понял. Актуальный индекс команды для каждого игрока всё равно нужно поддерживать. Иначе в любом случае придётся циклом аррей перебирать.
 
Сообщения
27
Реакции
-1
Вы уж меня простите, но мне это бред. Зачем ограничивать щиты, это же не чит, где к примеру аимщик бегает со скорострелкой.
 
Сообщения
1,668
Реакции
1,495
Помог
24 раз(а)
alexei1s, человек попросил помощи, а бред - не бред уже ему решать :)
 
Сообщения
453
Реакции
79
Помог
4 раз(а)
fantom, new team = TeamName:get_member(id, m_iTeam); и выкидывает warning 213, но с отступами все как полагается
18 Янв 2019
fl0wer, можешь поподробнее объяснить про ArrayFindValue
 
Сообщения
1,668
Реакции
1,495
Помог
24 раз(а)
WILL_BE, конечно, возвращает индекс в арие, если находит элемент из аргумента в нем, иначе -1.
 
Сообщения
453
Реакции
79
Помог
4 раз(а)
BlackSignature, в вашем вложении стал интересен пункт, ибо я не понимаю для чего он
Код:
bind_pcvar_float( create_cvar("awplimit_limit_ratio", "0.3", .description = "Кол-во слотов на команду = (игроки_онлайн / 2) * awplimit_limit_ratio",
        .has_min = true, .min_val = 0.01), Float:g_eCvar[CVAR__LIMIT_RATIO] );
18 Янв 2019
shadow, и так пробовал, начинают сыпаться Warning 213
18 Янв 2019
BlackSignature, так же стал интересен к познаниями, кусок кода
Код:
    switch(iRestType) {
        case ITEM_TYPE_TOUCHED: {
            if(get_member(id, m_bHasPrimary)) {
                return HC_CONTINUE
            }
            
            if(g_fLastFailTime[id] && get_gametime() - g_fLastFailTime[id] < CACHE_TIME) {
                SetHookChainReturn(ATYPE_INTEGER, true)
                return HC_SUPERCEDE
            }
        }
        case ITEM_TYPE_EQUIPPED: {
            return HC_CONTINUE
        }
    }
 
Сообщения
453
Реакции
79
Помог
4 раз(а)
Код:
    switch(iRestType) {
        case ITEM_TYPE_TOUCHED: {
            if(get_member(id, m_bOwnsShield)) {
                return HC_CONTINUE
            }
           
            if(g_fLastFailTime[id] && get_gametime() - g_fLastFailTime[id] < CACHE_TIME) {
                SetHookChainReturn(ATYPE_INTEGER, true)
                return HC_SUPERCEDE
            }
        }
        case ITEM_TYPE_EQUIPPED: {
            return HC_CONTINUE
        }
    }
Думаю, что-то неправильно
18 Янв 2019
На примере вложения от BlackSignature, хочу попробовать. Но, как я понял, там просто не даст взять если игроков меньше указанного кол.-ва.
 
Сообщения
1,177
Реакции
2,144
Помог
57 раз(а)
WILL_BE,
я не понимаю для чего он
там же описание есть, и оно как бы намекает. динамический просчёт кол-ва единиц предмета на команду. крутим значение в большую сторону - станет доступно больше при меньшем значении игроков. крутим в меньшую - наоборот. Форумула описана.

там просто не даст взять если игроков меньше указанного кол.-ва.
Ну так что мешает отпилить контроль минимального кол-ва игроков? Это квар awplimit_min_players и проверка iRealCount < g_eCvar[CVAR__MIN_PLAYERS]
 
Сообщения
453
Реакции
79
Помог
4 раз(а)
BlackSignature, уже исправил данный квар. Осталась загвоздка, лимит работает, но если ни у кого в руках щита нет (допустим 1 щит лежит на земле) можно покупать бесконечно, но взять все равно даст только 1.
18 Янв 2019
Если я правильно понимаю, мне нужно думать в сторону OnHasRestrictItem_Pre
И, могу ошибаться (только начал учиться ReAPI), if(type == ITEM_TYPE_BUYING)
 
Сообщения
1,177
Реакции
2,144
Помог
57 раз(а)
WILL_BE, Что требуется сделать?
 
Сообщения
453
Реакции
79
Помог
4 раз(а)
BlackSignature, Если g_eCvar[CVAR__LIMIT_PER_TEAM] >= Допустимого, то не даст даже закупить предмет
 
Сообщения
1,177
Реакции
2,144
Помог
57 раз(а)
WILL_BE, Мой плагин так и работает.
 

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу