Склад полезного кода [GoldSrc]

Сообщения
48
Реакции
151
Это не кусок кода, но способ использования ArrayFindString для массивов. Натива задумывалась для динамических массивов содержащих только строки, но ее можно использовать для поиска строки в динамических массивах содержащих массивы. Масло масленое, лучше покажу на примере.

Предположим у нас есть структура нашего массива, в котором три свойства — целочисленное, целочисленное и какая-то строка.
C++:
enum Props {
    TestProp,
    TestProp1,
    TestProp2[32]
};
И есть динамический массив.
C++:
new Array: g_pItems = ArrayCreate(Props);
В котором, опять же предположим, есть куча записей и нам нужно найти одну запись по его свойству TestProp2. В том виде структуры (перечисления, если быть точнее, но давайте представим, что Pawn нормальный язык и будем называть это структурой), который есть у нас сейчас, натива ArrayFindString всегда будет возвращать -1, даже если искомая строка в одной из записей есть. Но если мы поставим наше свойство TestProp2 выше всех остальных:
C++:
enum Props {
    TestProp2[32],
    TestProp,
    TestProp1
};
то поиск будет работать.
 
Последнее редактирование:
Сообщения
2,491
Реакции
2,794
Помог
61 раз(а)
Метод много где расписан по разному. Но спасибо fl0wer за рабочий вариант блокировки звуков выстрела по умолчанию. Основная проблема что клиент сам его воспроизводит
Код:
#include <amxmodx>
#include <fakemeta>

public plugin_init() {
    register_forward(FM_UpdateClientData, "UpdateClientData_Post", true);
}

public UpdateClientData_Post(const id, const SendWeapons, const cd) {
    if (!is_user_alive(id) || !cd) {
        return FMRES_IGNORED;
    }

    set_cd(cd, CD_flNextAttack, get_gametime() + 0.001);
    return FMRES_IGNORED;
}
 
Последнее редактирование модератором:

d3m37r4

111111
Сообщения
1,451
Реакции
1,177
Помог
10 раз(а)
Подсчет кол-ва игроков в командах
Код:
stock rg_get_players_num(&terrorist = 0, &ct = 0, &spec = 0, &unassigned = 0) {
    for(new id = 1; id <= MaxClients; id++) {
        if(!is_user_connected(id))
            continue;
       
        switch(get_member(id, m_iTeam)) {
            case TEAM_TERRORIST: terrorist++;
            case TEAM_CT: ct++;
            case TEAM_SPECTATOR: spec++;
            case TEAM_UNASSIGNED: unassigned++;
        }
    }
}
 
Последнее редактирование:
  • Нравится
Реакции: ifx
Сообщения
1,698
Реакции
1,510
Помог
26 раз(а)
d3m37r4, зачем считать другие команды, если используется одна?
 
Последнее редактирование модератором:

d3m37r4

111111
Сообщения
1,451
Реакции
1,177
Помог
10 раз(а)
fl0wer, не продумал момент.
Спасибо fantom за подсказку. Пост обновлен.
 
Последнее редактирование модератором:
Сообщения
1,698
Реакции
1,510
Помог
26 раз(а)
d3m37r4, можно массивом было сделать, всё равно все считаешь))
 
Последнее редактирование модератором:
Сообщения
2,751
Реакции
3,016
Помог
61 раз(а)
Последнее редактирование модератором:
Сообщения
90
Реакции
126
Помог
3 раз(а)
Функция для конвертации steamid в steamid64, поддерживает не все типы аккаунтов
Код:
steamid_get_steamid64(const steamid[], buffer[], const len) {
    new steamid_exploded[3][11]
    explode_string(steamid, ":", steamid_exploded, sizeof(steamid_exploded), sizeof(steamid_exploded[]))
    new carry = str_to_num(steamid_exploded[1])
    new account = (str_to_num(steamid_exploded[2]) * 2) + 60265728 + carry
    new upper = 765611979
    new div = account / 100000000
    new index = 9 - (div ? div / 10 + 1 : 0)
    upper += div
    formatex(buffer[index], len - index, "%d", account)
    index = buffer[9]
    formatex(buffer, len, "%d", upper)
    buffer[9] = index
}
 
Сообщения
1,420
Реакции
2,511
Помог
58 раз(а)
Рандомное деление игроков (в данном случае террористов) на команды устанавливая им субмодель. Пример: реализация деления на цвета в jailbreak mod.

Код:
func_DivideTeam(iTeam)
{
    new iPlayers[MAX_PLAYERS], iPlayerCount;
    get_players_ex(iPlayers, iPlayerCount, GetPlayers_ExcludeDead|GetPlayers_MatchTeam, "TERRORIST");
    SortIntegers(iPlayers, iPlayerCount, Sort_Random);

    for(new i, iCount; i < iPlayerCount; i++)
    {
        set_entvar(iPlayers[i], var_body, iCount % iTeam);
        iCount++;
    }
}
Вызывается функция в формате func_DivideTeam(количество команд)
4 Янв 2019
Поправил код, нужно было вместо sizeof iPlayers в SortIntegers() указывать количество игроков - iPlayerCount
 
Последнее редактирование:
Сообщения
2,491
Реакции
2,794
Помог
61 раз(а)
Ничего сверхестественного, просто отправка анимации оружия
Код:
stock sendWeaponAnimation(const id, const weapon, const anim, const szAnim[], const Float:time) {
    set_entvar(id, var_weaponanim, anim);

    message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = id);
    write_byte(anim);        // sequence number
    write_byte(get_entvar(weapon, var_body));    // weaponmodel bodygroup.
    message_end();

    set_member(id, m_szAnimExtention, szAnim);
    set_member(weapon, m_Weapon_flTimeWeaponIdle, time);
    set_member(weapon, m_Weapon_flNextPrimaryAttack, time);
    set_member(weapon, m_Weapon_flNextSecondaryAttack, time);
}
Пример для надевания глушителя M4A1
Код:
sendWeaponAnimation(id, weapon, M4A1_ATTACH_SILENCER, "rifle", 2.0);
Пример для надевания глушителя USP
Код:
sendWeaponAnimation(id, weapon, USP_ATTACH_SILENCER, "onehanded", 3.0);
 
Последнее редактирование модератором:
Сообщения
48
Реакции
151
Функция выполняет замену каждой искомой подстроки в строке с использованием replace_stringex. Думаю не нужно объяснять, чем лучше replace_stringex, который появился в AMXX 1.8.3+, все написано в описании к функции.

C++:
stock replace_allex(text[], maxlength, const search[], const replace[], searchLen = -1, replaceLen = -1, bool:caseSensitive = true)
{
    enum { NO_REPLACEMENTS_WERE = -1 };

replaceLabel:
    if (replace_stringex(text, maxlength, search, replace, searchLen, replaceLen, caseSensitive) != NO_REPLACEMENTS_WERE) {
        goto replaceLabel;
    }
}
UPD.: Для тех, кому не нравится goto, можно пустой while цикл юзать. Лично меня это всегда смущает.
 
Последнее редактирование модератором:

d3m37r4

111111
Сообщения
1,451
Реакции
1,177
Помог
10 раз(а)
Отправка сообщения всем игрокам, кроме указанного в параметре index.
Код:
/**
*    Sends colored chat messages to all players except one.
*
*    @param index     Index of player who does not receive message
*    @param sender    Client index used as the message sender
**/
stock SendMsgAllExceptOnePlayer(const index, const sender, const message[], any:...) {
    new str[190]; vformat(str, charsmax(str), message, 4);
    for(new playerId = 1; playerId <= MaxClients; playerId++) {
        if(playerId != index) {
            client_print_color(playerId, sender, str);
        }
    }
}
Upd: убрана лишняя проверка на коннект, спасибо wopox1337
Upd2: добавлен формат строки, спасибо Mistrick за замечание
 
Последнее редактирование:
Сообщения
48
Реакции
151
Быстрый цикл по игрокам (без указания флагов и указания команды).
C++:
stock dummyFunc(cell) {
    #pragma unused cell
}
#define GETPLAYERS(%0,%1) new __players[MAX_PLAYERS], %0, %1; \
    dummyFunc(%1); \
    get_players(__players, %0, "ch"); \
    for (new i, %1 = __players[i]; i < %0; %1 = __players[++i])
Тоже самое, только с флагами (без указания команды).
C++:
stock dummyFunc(cell) {
    #pragma unused cell
}
#define GETPLAYERS(%0,%1,%2) new __players[MAX_PLAYERS], %0, %1; \
    dummyFunc(%1); \
    get_players(__players, %0, %2); \
    for (new i, %1 = __players[i]; i < %0; %1 = __players[++i])
Меня этот макрос очень выручает, ибо я ленивая жопа и мне с ним очень удобно:

Код:
@CSGameRules_RestartRound()
{
    GETPLAYERS(iPlayers, iPlayer, "ch") {
        // some code
    }
}
Если в одной функции этот макрос используется несколько раз, то лучше использовать его в отдельной зоне видимости, то есть в отдельном блоке { } или дать переменным НЕ одинаковые названия. Это нужно, чтобы не было ошибки, говорящей нам о том, что такая переменная уже была создана ранее.
 
Последнее редактирование:
Сообщения
432
Реакции
410
Помог
14 раз(а)
Kaido Ren, тогда уместнее было бы назвать макрос FOREACH_PLAYER и get_players_ex юзать
 
Последнее редактирование модератором:
Сообщения
48
Реакции
151
voed, называй его как хочешь, хоть LUNNAYAPRIZMADAYMNEIGROKOV.
и get_players_ex юзать
Тут да, но подтягивать amxmisc или нет - выбор каждого, не хочу делать зависимость от подключения пусть и родного, но необязательного инклуда.
 
Последнее редактирование модератором:
Сообщения
169
Реакции
462
Помог
2 раз(а)
Недавно, вроде бы здесь на форуме видел тему, о получении каких-то параметров из bsp карты...
Прикрепленный инклуд умеет искать строки в LUMP_ENTITIES (это тот блок данных, который редактирует BSPEdit), подсчитывать количество найденных строк (например, для поиска строки "info_player_start", что бы узнать количество точек респауна), считает количество зон для закладки бомб на de_* картах.
Описанную выше инфу легко узнать и штатными способами, однако, мне это понадобилось сделать в прекеше, а в это время энтити карты недоступны. Кроме того, инклуд позволяет узнать эти параметры еще до загрузки карты.
При желании, можно доработать что бы вытащить другую полезную инфу из BSP, которую нельзя получить штатными способами.
 

Вложения

Сообщения
42
Реакции
7
fantom, если использовать модели с боди будет ли отображаться спектрам?
 
Последнее редактирование модератором:
Сообщения
2,491
Реакции
2,794
Помог
61 раз(а)
laucerZ, нет. Отправка идет одному игроку. Но сделать отправку спектрам не так уж и сложно
 
Последнее редактирование модератором:

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

Сверху Снизу