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

Сообщения
328
Реакции
93
Помог
2 раз(а)
Парсинг значений для hud (жёсткое, без any).
Код:
stock UTIL_ReadHudSettings(szHud[], &iRed = 255, &iGreen = 255, &iBlue = 255, &Float: x = 0.01, &Float: y = 0.3, &effects,
    &Float: flFxTime, &Float: flHoldTime, &Float: flFadeInTime, &Float: flFadeOut)
{
    new iStart, iEnd;
    iRed = strtol(szHud, iEnd); iStart += iEnd;
    iGreen = strtol(szHud[iStart], iEnd); iStart += iEnd;
    iBlue = strtol(szHud[iStart], iEnd); iStart += iEnd;
    x = strtof(szHud[iStart], iEnd); iStart += iEnd;
    y = strtof(szHud[iStart], iEnd); iStart += iEnd;
    effects = strtol(szHud[iStart], iEnd); iStart += iEnd;
    flFxTime = strtof(szHud[iStart], iEnd); iStart += iEnd;
    flHoldTime = strtof(szHud[iStart], iEnd); iStart += iEnd;
    flFadeInTime = strtof(szHud[iStart], iEnd); iStart += iEnd;
    flFadeOut = strtof(szHud[iStart]);
}
Код:
szHud[] = "255 255 255 0.01 0.3 0 0.0 2.0 0.1 0.2"
new iRed, iGreen, iBlue, Float: x, Float: y, effects, Float: flFxTime, Float: flHoldTime, Float: flFadeInTime, Float: flFadeOut;
UTIL_ReadHudSettings(szHud, iRed, iGreen, iBlue, x, y, effects, flFxTime, flHoldTime, flFadeInTime, flFadeOut);
set_hudmessage(iRed, iGreen, iBlue, x, y, effects, flFxTime, flHoldTime, flFadeInTime, flFadeOut, -1);

Проверка на время в указанном промежутке (unix).
(Не знаю, если ли здесь)
Код:
stock bool: UTIL_IsTimeWithin(iStart, iEnd)
{
    new iSysTime = get_systime();

    if (!(iEnd <= iSysTime <= iStart))
    {
        return true;
    }

    return false;
}

Сравнение 2-х бит флагов. Получает строковую разницу. Возращает бит флаг разницы.
Код:
stock UTIL_GetOtherFlags(bitFlagsOne, bitFlagsTwo, szOther[])
{
    bitFlagsTwo &= ~bitFlagsOne;
    get_flags(bitFlagsTwo, szOther, 31);
    return bitFlagsTwo;
}
Код:
new szOther[32];
set_user_flags(iPlayer, "alm");
new bitFlags = UTIL_GetOtherFlags(get_user_flags(iPlayer), read_flags("abit"), szOther);
// szOther == "bit"
// bitFlags == read_flags("bit")

Являются ли группа флагов игнором (Если перед флагами стоит точка, то проверяется каждый флаг, иначе наличия хотя бы одного из них. Разделение групп через пробел).
Код:
stock bool: UTIL_IsIgnorFlags(bitFlags, szIgnor[])
{
    new iPos, szFlags[32];

    while (iPos != -1)
    {
        iPos = argparse(szIgnor, iPos, szFlags, charsmax(szFlags));
      
        if (replace(szFlags, charsmax(szFlags), ".", ""))
        {
            if (bitFlags == (bitFlags | read_flags(szFlags))) return true;
        }
        else
        {
            if (bitFlags & read_flags(szFlags)) return true;
        }
    }

    return false;
}
Код:
UTIL_IsIgnorFlags(read_flags("abit"), ".am t"); // Вернёт true т.к. есть флаг 't'
UTIL_IsIgnorFlags(read_flags("abit"), "z .at"); // Вернёт true т.к. есть и флаг 'a', и флаг 't'
UTIL_IsIgnorFlags(read_flags("abit"), ".am");    // Вернёт false т.к. есть только флаг 'a'
UTIL_IsIgnorFlags(read_flags("abit"), "z lf .am vt"); // Вернёт true т.к. есть флаг 't'
 
Последнее редактирование:
  • Нравится
Реакции: uMk0
Сообщения
39
Реакции
7
Флуд
Обратите внимание, если вы хотите заключить сделку с этим пользователем, он заблокирован
Сообщения
2,750
Реакции
3,013
Помог
61 раз(а)
Following the example from https://docs.unity3d.com/ScriptReference/
C++:
/**
 * Linearly interpolates between two values.
 *
 * Linearly interpolates between a and b by t.
 * When t = 0 returns a.
 * When t = 1 return b.
 * When t = 0.5 returns the midpoint of a and b.
 *
 * @param a         Start value, returned when t = 0.
 * @param b         End value, returned when t = 1.
 * @param t         Value used to interpolate between a and b.
 *
 * @return          The interpolated float result between the two float values.
 */
stock Float: _xs_lerp(const Float: a, const Float: b, const Float: t) {
    return a + (b - a) * t;
}

/**
 * Determines where a value lies between two points.
 * The a and b values define the start and end of a linear numeric range.
 * The "value" parameter you supply represents a value which might lie somewhere within that range.
 * This method calculates where, within the specified range, the "value" parameter falls.
 * If the "value" parameter is within the range, _xs_inverse_lerp() returns a value between zero and one,
 * proportional to the value's position within the range.
 * If the "value" parameter falls outside of the range, _xs_inverse_lerp() returns either zero or one,
 * depending on whether it falls before the start of the range or after the end of the range.
 *
 * @param a         The a of the range.
 * @param b         The b of the range.
 * @param t         The point within the range you want to calculate.
 *
 * @return          A value between zero and one,
 *                  representing where the "value" parameter
 *                  falls within the range defined by `a` and `b`.
 */
stock Float: _xs_inverse_lerp(const Float: a, const Float: b, const Float: value) {
    return (value - a) / (b - a)
}

/**
 * Linearly interpolates between two vectors.
 *
 * @param a         Start value, returned when t = 0.
 * @param b         End value, returned when t = 1.
 * @param out       The output vector. Can be one of the input vectors.
 * @param t         Value used to interpolate between a and b.
 *
 * @noreturn
 */
stock _xs_vec_lerp(Float: a[], Float: b[], Float: out[], const Float: t, const size = sizeof(out)) {
    for (new i; i < size; i++) {
        out[i] = a[i] + (b[i] - a[i]) * t;
    }
}

/**
 * Linearly interpolates between two angles.
 * This method returns the shortest path between the specified angles.
 * This method wraps around values that are outside the range [-180, 180].
 * For example, _xs_vec_lerp_angle(1.0, 190.0, 1.0) returns -170.0.
 * To find the longest path use xs_lerp().
 *
 * @param a         The a angle. A float expressed in degrees.
 * @param b         The b angle. A float expressed in degrees.
 * @param t         Value used to interpolate between a and b.
 *
 * @return          Returns the interpolated float result between angle `a` and angle `b`,
 *                  based on the interpolation value `t`.
 */
stock Float: _xs_vec_lerp_angle(Float: a, Float: b, const Float: t) {
    while (a < -180.0)
        a += 360.0;
    while (a > 180.0)
        a -= 360.0;

    while (b < -180.0)
        b += 360.0;
    while (b > 180.0)
        b -= 360.0;

    new Float: angleDiff = b - a;

    if (angleDiff > 180.0)
        angleDiff -= 360.0;
    else if (angleDiff < -180.0)
        angleDiff += 360.0;

    new Float: result = a + t * angleDiff;

    while (result < -180.0)
        result += 360.0;
    while (result > 180.0)
        result -= 360.0;

    return result;
}

/**
 * Converts a vector represented as an array of floats to a formatted string.
 *
 * @param vec       The vector represented as an array of floats.
 * @param output    The output string where the formatted vector will be stored.
 * @param len       The maximum length of the output string.
 * @param precision The number of decimal places for each vector component.
 * @param size      The size of the vector array.
 *
 * @return          Returns the number of characters written to the output string.
 *                  It is the length of the formatted vector string.
 */
stock _xs_vec_to_string(const Float: vec[], output[], const len, const precision = 1, const size = sizeof(vec)) {
    new _len = copy(output, len, "(");

    for (new i = 0; i < size && _len < len; ++i) {
        _len += format(output[_len], (len - _len),
            fmt("%%.%if%s", precision, (i < size - 1) ? ", " : ")"),
            vec[i]
        );
    }

    return _len;
}

stock const XS_X = 0;
stock const XS_Y = 1;
stock const XS_Z = 2;
using _xs_vec_to_string() sample:
1695695077241.png
 
Последнее редактирование:
Сообщения
1,082
Реакции
58
Помог
11 раз(а)
Не знаю пригодится кому такое, но всёже. Получаем рандомное не повторяющее число из массива. Повторение чисел будет, но после того когда все числа перебраты
Код:
/*
* With this function, you can get a non-repeating random number
*
* @param iNumbers - Array of numbers
* @param iNonRepeatNum - He resulting number
*
* @return Will return true - if there was a coincidence, false - if there were no coincidencesNumber of cells written to buffer
*/

stock bool:non_repeatable_random(const iNumbers[], &iNonRepeatNum) {
    static
        iAction,
        iBuffer[32],
        iSizeNumbers;

    if(!iSizeNumbers)
        iSizeNumbers = strlen(iNumbers)

    new
        bool:bReplay,
        iRandomNum = iNumbers[random(iSizeNumbers)];

    for(new i; i <= iSizeNumbers; ++i) {
        if(iBuffer[i] == iRandomNum)
            bReplay = true;
    }

    if(!bReplay) {
        iNonRepeatNum = iBuffer[iAction] = iRandomNum;

        if(iAction++ == iSizeNumbers -1) {
            iAction = 0;
            arrayset(iBuffer, 0, iSizeNumbers);
        }

        return bReplay;
    }

    non_repeatable_random(iNumbers, iNonRepeatNum);
    return bReplay;
}
Не большой пример использования
Код:
#include <amxmodx>
#include <reapi>

public plugin_init() {
    register_plugin("Non Repeat Random Number", "rz 0.1", "(: [C][O][D][E] x");

    RegisterHookChain(RG_CBasePlayer_Spawn, "CBasePlayer_Spawn", 1);
}

public CBasePlayer_Spawn(const id) {
    if(!is_user_alive(id))
        return;

    new
        iNumbers[] = {4, 7, 19, 1, 2},
        iNonRepeatNum;

    non_repeatable_random(iNumbers, iNonRepeatNum);
    server_print("****** %i", iNonRepeatNum);
}

stock bool:non_repeatable_random(const iNumbers[], &iNonRepeatNum) {
    static
        iAction,
        iBuffer[32],
        iSizeNumbers;

    if(!iSizeNumbers)
        iSizeNumbers = strlen(iNumbers)

    new
        bool:bReplay,
        iRandomNum = iNumbers[random(iSizeNumbers)];

    for(new i; i <= iSizeNumbers; ++i) {
        if(iBuffer[i] == iRandomNum)
            bReplay = true;
    }

    if(!bReplay) {
        iNonRepeatNum = iBuffer[iAction] = iRandomNum;

        if(iAction++ == iSizeNumbers -1) {
            iAction = 0;
            arrayset(iBuffer, 0, iSizeNumbers);
        }

        return bReplay;
    }

    non_repeatable_random(iNumbers, iNonRepeatNum);
    return bReplay;
}
 
Последнее редактирование модератором:
Сообщения
1,082
Реакции
58
Помог
11 раз(а)
Получаем количество русских и английских букв из строки.
Пример:
Код:
/*
* With this funktion we will get the number of Russian and English letters in the string
*
* @param szLine - The string being checked
* @param szBuffer - Array to write
* @param LenBuffer - Array size
*
* @return Will return true - Returns nothing
*/

stock get_count_letter(const szLine[], szBuffer[], const LenBuffer) {
    new
        En,
        Rus,
        Len = strlen(szLine);

    for(new i; i < Len; ++i) {
        if('A' <= szLine[i] <= 'Z' || 'a' <= szLine[i] <= 'z') {
            ++En;
            continue;
        }

        if(szLine[i] > 'z')
            ++Rus;
    }

    Rus = Rus/2;

    formatex(szBuffer, LenBuffer, "RUS - %i, EN - %i", Rus, En);
}
Не большой пример использования
Код:
#include <amxmodx>

public plugin_init() {
    register_plugin("Count letter", "rz 0.1", "(: [C][O][D][E] x");

    new szBuffer[191];
    get_count_letter("(: [C][O][D][E] x это и есть Виталик", szBuffer, charsmax(szBuffer));

    server_print("**** %s", szBuffer);
}

stock get_count_letter(const szLine[], szBuffer[], const LenBuffer) {
    new
        En,
        Rus,
        Len = strlen(szLine);

    for(new i; i < Len; ++i) {
        if('A' <= szLine[i] <= 'Z' || 'a' <= szLine[i] <= 'z') {
            ++En;
            continue;
        }

        if(szLine[i] > 'z')
            ++Rus;
    }

    Rus = Rus/2;

    formatex(szBuffer, LenBuffer, "RUS - %i, EN - %i", Rus, En);
}
 
Последнее редактирование модератором:
Сообщения
396
Реакции
112
Помог
2 раз(а)
В основном это для работы с IP-адресами (uint)... Но я использую и для запаковки STEAM_ID и других значений в nvault.

Код:
#define ACS_MAX_BASIS               64
#define ACS_MAX_INT_STR_LENGTH      12

stock acs_str_to_num(const str[], const basis = 10) {
    if (basis > 1 && basis <= ACS_MAX_BASIS) {
        for (new num, i_i; str[i_i]; i_i++)
            if (basis > 36 && str[i_i] >= 'a' && str[i_i] < ('a' + 28))
                num = num * basis + (str[i_i] - 'a' + 36);
            else if (basis > 10 && str[i_i] >= 'A' && str[i_i] < ('A' + 26))
                num = num * basis + (str[i_i] - 'A' + 10);
            else if (str[i_i] >= '0' && str[i_i] < ('0' + basis))
                num = num * basis + (str[i_i] - '0');
            else {
                //log_acs(ACS_LOG_DEBUG, "[ACS] acs_num_to_str(), string %s has over basis symbol %c (!!!!! ERROR !!!!!)", str, str{i_i});
                num = 0;
                break;
            }
    }/* else
        log_acs("[ACS] acs_str_to_num(), basis error: %d", basis); */
    return num;
}

stock acs_num_to_str(const num, const basis = 10, const null_text[] = "") {
    new i_i, i_num = num, i_div, s_str[ACS_MAX_INT_STR_LENGTH];
    if (basis > 1 && basis <= ACS_MAX_BASIS) {
        while (i_num != 0 && i_i < ACS_MAX_INT_STR_LENGTH) {
            i_div = i_num % basis;
            if (i_num < 0) {
                i_num = (basis & 0x1) ? (floatround((2.0 * float(0x40000000) + float(i_num & 0x7FFFFFFF)) / float(basis), floatround_floor)) : ((i_num >>> 1) / (basis >> 1));
            } else {
                i_num /= basis;
            }
            s_str[i_i] = (i_div >= 36) ? ('a' + i_div - 36) : (i_div >= 10) ? ('A' + i_div - 10) : ('0' + i_div);
            i_i++;
        }
        if (i_i >= ACS_MAX_INT_STR_LENGTH)
            i_i = 0;
        s_str[i_i] = 0;
        if (i_i)
            acs_reverse_str(s_str, i_i);
        else if (null_text[0])
            copy(s_str, charsmax(s_str), null_text);
        // CHECK
        //log_acs(ACS_LOG_DEBUG, "[ACS] acs_num_to_str(), original num = %u, basis = %d, txt = %s, verify = %u", num, basis, s_str, acs_str_to_num(s_str, basis));
    }/* else
        log_acs("[ACS] acs_str_to_num(), basis %d (!!!!! ERROR !!!!!)", basis); */
    return s_str;
}

stock acs_reverse_str(str[], const str_len = 0) {
    new i_end = str_len ? str_len : strlen(str);
    for (new i_i, s_tmp; i_i < i_end >> 1; i_i++) {
        s_tmp = str[i_i];
        str[i_i] = str[(i_end - i_i - 1)];
        str[(i_end - i_i - 1)] = s_tmp;
    }
}

stock acs_pack_steam(const authid[]) {
    new s_s[3][ACS_MAX_INT_STR_LENGTH], s_tmp[MAX_AUTHID_LENGTH];
    if (strlen(authid) > 7) {
        strtok(authid[6], s_s[0], charsmax(s_s[]), s_tmp, charsmax(s_tmp), ':', 0);
        strtok(s_tmp, s_s[1], charsmax(s_s[]), s_s[2], charsmax(s_s[]), ':', 0);
        formatex(s_tmp, MAX_AUTHID_LENGTH, "%s:%s:%s", s_s[0], s_s[1], acs_num_to_str(acs_str_to_num(s_s[2]), ACS_MAX_BASIS, s_s[2]));
    }
    return s_tmp;
}
1 Дек 2023
Буферизированный вариант логов для отладки (примерно в 12 раз быстрее классического open/close):

Код:
stock log_acs(const message[], any:...) {
    static _PLUGIN_NAME[32];
    static _LOGPATH[PLATFORM_MAX_PATH];
    static s_log_data[1024];
    // FILL SYSTEM INFO
    if (!_PLUGIN_NAME[0]) {
        get_plugin(-1, _PLUGIN_NAME, charsmax(_PLUGIN_NAME));
        replace(_PLUGIN_NAME, charsmax(_PLUGIN_NAME), ".amxx", "");
    }
    if (!_LOGPATH[0]) {
        get_localinfo("amxx_logs", _LOGPATH, charsmax(_LOGPATH));
        format(_LOGPATH, charsmax(_LOGPATH), "%s/%s.log", _LOGPATH, _PLUGIN_NAME);
    }
    vformat(s_log_data, charsmax(s_log_data), message, 2);
    acs_log_to_file(_LOGPATH, s_log_data, true);
}

stock acs_log_to_file(const filename[], const message[], const bool:is_buffered = false) {
    static _MOD_NAME[32];
    static _AMXX_VERSION[32];
    static h_file, bool:b_file_exists, s_date[32];
    if (filename[0] && message[0]) {
        if (!_MOD_NAME[0])
            get_modname(_MOD_NAME, charsmax(_MOD_NAME));
        if (!_AMXX_VERSION[0])
            get_amxx_verstring(_AMXX_VERSION, charsmax(_AMXX_VERSION));
        format_time(s_date, charsmax(s_date), "%m/%d/%Y - %H:%M:%S");
        b_file_exists = h_file ? true : bool:file_exists(filename);
        if (!h_file)
            h_file = fopen(filename, "at");
        if (h_file) {
            if (!b_file_exists)
                fprintf(h_file, "L %s: Log file started (file ^"%s^") (game ^"%s^") (amx ^"%s^")^n", s_date, filename, _MOD_NAME, _AMXX_VERSION);
            fprintf(h_file, "L %s: %s^n", s_date, message);
        } else
            log_error(AMX_ERR_GENERAL, "[ACS] ERROR: acs_log_to_file(), can't open file %s", filename);
    }
    // WRITE BUFFER TO DISK
    if (h_file && !is_buffered) {
        fclose(h_file);
        h_file = 0;
    }
}

/*
public plugin_end() {
    // SAVE BUFFERED LOG DATA
    acs_log_to_file("", "");
}
*/
 
Последнее редактирование:
Сообщения
57
Реакции
5
Начальная стадия кода - Play Music in Server (YandexMusic)

Код:
Веб-приложение на Node.js:

const express = require('express');
const axios = require('axios');
const bodyParser = require('body-parser');

const app = express();
app.use(bodyParser.json());

const YA_MUSIC_API_URL = 'https://api.music.yandex.net';

// Обработка запроса на управление воспроизведением
app.post('/play', async (req, res) => {
    const trackId = req.body.trackId;
    try {
        const response = await axios.post(${YA_MUSIC_API_URL}/tracks/${trackId}/play, null, {
        headers: {
            Authorization: 'Bearer YOUR_ACCESS_TOKEN',
        },
    });
    res.json({ message: 'Трек начал воспроизводиться' });
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
});

app.listen(3000, () => {
    console.log('Сервер запущен на порту 3000');
});
Код:
Плагин на AMXX:

#define WEB_REQUEST_URL "http://your-web-app-url.com"

public PlayTrack(client, const trackId[])
{
    new url[256];
    format(url, sizeof(url), "%s/play", WEB_REQUEST_URL);
    new result[512];
    new post_data[256];

    format(post_data, sizeof(post_data), "trackId=%s", trackId);
    if (http_post(url, post_data, result, sizeof(result)))
    {
    // Обработка ответа от веб-приложения
        client_print(client, print_chat, result);
    } else {
        client_print(client, print_chat, "Ошибка при выполнении запроса");
    }
}
В этой начальной стадии куска кода, сделан скрипт веб-приложения на Node.js который принимает POST-запросы на /play для управления воспроизведением музыки с использованием API Яндекс.Музыки.
В другую очередь, плагин на AMXX отправляет запросы на веб-приложение для управления воспроизведением треков.

Не забудьте заменить YOUR_ACCESS_TOKEN на ваш реальный токен доступа к API Яндекс.Музыки и http://your-web-app-url.com на реальный URL вашего веб-приложения.

p.s может кому-нибудь под дальнейшую разработку понадобиться, строго за структуру кода не губите меня)
 
Сообщения
458
Реакции
263
Помог
9 раз(а)
press2p, axios -> fetch, исключает необходимость установки доп библиотеки.
если вы хотите воспроизводить музыку на сервер, удобнее будет юзать ytdl для скачки музыки, на жс сервере у вас получится что-то вроде ftp сервера откуда можно будет скачать файл с помощью easyhttp, но помимо скачки на сервер, нужно еще и клиенту это прекешить. В целом удобнее просто скачать что нужно, обрезать как нужно, а так-же изменять битрейт и канал.
 
Сообщения
336
Реакции
414
Помог
7 раз(а)
Функция SumStringNums позволяет складывать большие и отрицательные целые числа в строках. Нет пределов числа от -2147483647 до 2147483647.
Спасибо the_hunter
Код:
// Функция складывает большие и отрицательные целые числа в строках
stock SumStringNums(const szFirstNum[], const szSecondNum[], szResult[]) {
    szResult[0] = EOS;

    if(szFirstNum[0] == EOS || szSecondNum[0] == EOS)
        return 0;

    new iFirstNumLen = strlen(szFirstNum);
    new iSecondNumLen = strlen(szSecondNum);
    new bool:bFirstNumNegative = (szFirstNum[0] == '-');
    new bool:bSecondNumNegative = (szSecondNum[0] == '-');
    new iLargerNum = CompareNumStringsWithoutMinusSign(szFirstNum, szSecondNum);
    new iCarryOver, iFirstDigit, iSecondDigit, szSumDigits[4];

    for(new i = (iFirstNumLen - 1), j = (iSecondNumLen - 1), k;
    ((i >= 0) || (j >= 0) || (iCarryOver && !bFirstNumNegative && !bSecondNumNegative));
    i--, j--, k++) {
        if(((j <= 0) && (szFirstNum[i] == '-')) || ((i <= 0) && (szSecondNum[j] == '-'))) {
            szResult[k] = '-';
            break;
        }

        iFirstDigit = (i >= 0 && szFirstNum[i] != '-') ? szFirstNum[i] - '0' : 0;
        iSecondDigit = (j >= 0 && szSecondNum[j] != '-') ? szSecondNum[j] - '0' : 0;

        iCarryOver = szSumDigits[1] != EOS ? (szSumDigits[0] - '0') : 0;

        if(iCarryOver && ((bFirstNumNegative && iFirstDigit && !iSecondDigit) || (bSecondNumNegative && !iFirstDigit && iSecondDigit))) {
            k--;
            continue;
        }

        if((!bFirstNumNegative && !bSecondNumNegative) || (bFirstNumNegative && bSecondNumNegative))
            AddStringDigits(iFirstDigit, iSecondDigit, iCarryOver, szSumDigits);
        else if(bFirstNumNegative || bSecondNumNegative)
            SubtractStringDigits(iFirstDigit, iSecondDigit, iCarryOver, szSumDigits, iLargerNum);

        szResult[k] = (szSumDigits[1] != EOS) ? szSumDigits[1] : szSumDigits[0];
    }

    new iResLen = strlen(szResult);

    if((szResult[iResLen - 1] == '-') && (szResult[iResLen - 2] == '0')) {
        szResult[0] = '0';
        szResult[1] = EOS;

        return 1;
    }

    if(szResult[iResLen - 1] == '0')
        szResult[iResLen - 1] = EOS;

    return ReverseString(szResult);
}

// Функция записывает сумму чисел в строку
stock AddStringDigits(iFirstDigit, iSecondDigit, iCarryOver, szSumDigits[4]) {
    num_to_str(iFirstDigit + iSecondDigit + iCarryOver, szSumDigits, charsmax(szSumDigits));
}

// Функция записывает разницу чисел в строку
stock SubtractStringDigits(iFirstDigit, iSecondDigit, iCarryOver, szSumDigits[4], iLargerNum) {
    if(iLargerNum <= 0)
        num_to_str(iFirstDigit - iSecondDigit - iCarryOver + (((iFirstDigit - iSecondDigit - iCarryOver) < 0) ? 20 : 0),
        szSumDigits, charsmax(szSumDigits));
    else
        num_to_str(iSecondDigit - iFirstDigit - iCarryOver + (((iSecondDigit - iFirstDigit - iCarryOver) < 0) ? 20 : 0),
        szSumDigits, charsmax(szSumDigits));
}

// Функция сравнивает две числовые строки без знака минус
stock CompareNumStringsWithoutMinusSign(const szFirstNum[], const szSecondNum[]) {
    new iFirstNumNegative = (szFirstNum[0] == '-');
    new iSecondNumNegative = (szSecondNum[0] == '-');
    new iFirstNumLen = strlen(szFirstNum) - iFirstNumNegative;
    new iSecondNumLen = strlen(szSecondNum) - iSecondNumNegative;

    if(iFirstNumLen > iSecondNumLen)
        return -1;
    else if(iFirstNumLen < iSecondNumLen)
        return 1;

    for(new i = iFirstNumNegative, j = iSecondNumNegative; i < iFirstNumLen; i++, j++) {
        if(szFirstNum[i] > szSecondNum[j])
            return -1;
        else if(szFirstNum[i] < szSecondNum[j])
            return 1;
    }

    return 0;
}

// Функция переворачивает строку
stock ReverseString(szStr[]) {
    new iLen = strlen(szStr), iHalfLen = iLen / 2;

    for(new i, iTemp; i < iHalfLen; i++) {
        iTemp = szStr[i];
        szStr[i] = szStr[iLen - i - 1];
        szStr[iLen - i - 1] = iTemp;
    }

    return iLen;
}
1706815568647.png
Код:
#include <amxmodx>

new sSumNums[][][] = {
    {"-1111", "777"},
    {"777", "-1111"},
    {"99999", "1"},
    {"1", "99999"},
    {"100000", "-1"},
    {"-1", "100000"},
    {"10000", "-10000"},
    {"-10000", "10000"},
    {"12345", "12345"},
    {"-12345", "-12345"},
    {"-12345", "12345"},
    {"12345", "-12345"},
    {"1234567890987654321", "1234567890987654321"},
    {"1234567890987654321", "12345"},
    {"-1234567890987654321", "-12345"},
    {"12345", "1234567890987654321"},
    {"-1234567890987654321", "12345"},
    {"12345", "-1234567890987654321"},
    {"1234567890987654321", "-12345"},
    {"-12345", "1234567890987654321"}
};

public plugin_init() {
    register_plugin("Test", "Albertio", "0.0.1");

    for(new i; i < sizeof(sSumNums); i++) {
        new szResult[64];
        SumStringNums(sSumNums[i][0][0], sSumNums[i][1][0], szResult);
        log_amx("%s + %s | %s", sSumNums[i][0][0], sSumNums[i][1][0], szResult);
    }
}

// Функция складывает большие и отрицательные целые числа в строках
stock SumStringNums(const szFirstNum[], const szSecondNum[], szResult[]) {
    szResult[0] = EOS;

    if(szFirstNum[0] == EOS || szSecondNum[0] == EOS)
        return 0;

    new iFirstNumLen = strlen(szFirstNum);
    new iSecondNumLen = strlen(szSecondNum);
    new bool:bFirstNumNegative = (szFirstNum[0] == '-');
    new bool:bSecondNumNegative = (szSecondNum[0] == '-');
    new iLargerNum = CompareNumStringsWithoutMinusSign(szFirstNum, szSecondNum);
    new iCarryOver, iFirstDigit, iSecondDigit, szSumDigits[4];

    for(new i = (iFirstNumLen - 1), j = (iSecondNumLen - 1), k;
    ((i >= 0) || (j >= 0) || (iCarryOver && !bFirstNumNegative && !bSecondNumNegative));
    i--, j--, k++) {
        if(((j <= 0) && (szFirstNum[i] == '-')) || ((i <= 0) && (szSecondNum[j] == '-'))) {
            szResult[k] = '-';
            break;
        }

        iFirstDigit = (i >= 0 && szFirstNum[i] != '-') ? szFirstNum[i] - '0' : 0;
        iSecondDigit = (j >= 0 && szSecondNum[j] != '-') ? szSecondNum[j] - '0' : 0;

        iCarryOver = szSumDigits[1] != EOS ? (szSumDigits[0] - '0') : 0;

        if(iCarryOver && ((bFirstNumNegative && iFirstDigit && !iSecondDigit) || (bSecondNumNegative && !iFirstDigit && iSecondDigit))) {
            k--;
            continue;
        }

        if((!bFirstNumNegative && !bSecondNumNegative) || (bFirstNumNegative && bSecondNumNegative))
            AddStringDigits(iFirstDigit, iSecondDigit, iCarryOver, szSumDigits);
        else if(bFirstNumNegative || bSecondNumNegative)
            SubtractStringDigits(iFirstDigit, iSecondDigit, iCarryOver, szSumDigits, iLargerNum);

        szResult[k] = (szSumDigits[1] != EOS) ? szSumDigits[1] : szSumDigits[0];
    }

    new iResLen = strlen(szResult);

    if((szResult[iResLen - 1] == '-') && (szResult[iResLen - 2] == '0')) {
        szResult[0] = '0';
        szResult[1] = EOS;

        return 1;
    }

    if(szResult[iResLen - 1] == '0')
        szResult[iResLen - 1] = EOS;

    return ReverseString(szResult);
}

// Функция записывает сумму чисел в строку
stock AddStringDigits(iFirstDigit, iSecondDigit, iCarryOver, szSumDigits[4]) {
    num_to_str(iFirstDigit + iSecondDigit + iCarryOver, szSumDigits, charsmax(szSumDigits));
}

// Функция записывает разницу чисел в строку
stock SubtractStringDigits(iFirstDigit, iSecondDigit, iCarryOver, szSumDigits[4], iLargerNum) {
    if(iLargerNum <= 0)
        num_to_str(iFirstDigit - iSecondDigit - iCarryOver + (((iFirstDigit - iSecondDigit - iCarryOver) < 0) ? 20 : 0),
        szSumDigits, charsmax(szSumDigits));
    else
        num_to_str(iSecondDigit - iFirstDigit - iCarryOver + (((iSecondDigit - iFirstDigit - iCarryOver) < 0) ? 20 : 0),
        szSumDigits, charsmax(szSumDigits));
}

// Функция сравнивает две числовые строки без знака минус
stock CompareNumStringsWithoutMinusSign(const szFirstNum[], const szSecondNum[]) {
    new iFirstNumNegative = (szFirstNum[0] == '-');
    new iSecondNumNegative = (szSecondNum[0] == '-');
    new iFirstNumLen = strlen(szFirstNum) - iFirstNumNegative;
    new iSecondNumLen = strlen(szSecondNum) - iSecondNumNegative;

    if(iFirstNumLen > iSecondNumLen)
        return -1;
    else if(iFirstNumLen < iSecondNumLen)
        return 1;

    for(new i = iFirstNumNegative, j = iSecondNumNegative; i < iFirstNumLen; i++, j++) {
        if(szFirstNum[i] > szSecondNum[j])
            return -1;
        else if(szFirstNum[i] < szSecondNum[j])
            return 1;
    }

    return 0;
}

// Функция переворачивает строку
stock ReverseString(szStr[]) {
    new iLen = strlen(szStr), iHalfLen = iLen / 2;

    for(new i, iTemp; i < iHalfLen; i++) {
        iTemp = szStr[i];
        szStr[i] = szStr[iLen - i - 1];
        szStr[iLen - i - 1] = iTemp;
    }

    return iLen;
}
 
Последнее редактирование:
Сообщения
336
Реакции
414
Помог
7 раз(а)
Функция NumberToRoman преобразовывает целые числа в римские. Поддерживаются числа от 0 до 3999.
Код:
#include <amxmodx>

new sNums[] = {
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
    11, 21, 31, 41, 51, 71, 81, 91, 101,
    1101, 1202, 1303, 1404, 1505, 1606,
    1707, 1808, 1909, 2020, 3999
};

public plugin_init() {
    register_plugin("Test", "0.0.1", "Albertio");

    for(new i; i < sizeof(sNums); i++) {
        new szResult[12];
        NumberToRoman(sNums[i], szResult, charsmax(szResult));
        log_amx("%d -> %s", sNums[i], szResult);
    }
}

stock NumberToRoman(const iNumber, szResult[], iResLen) {
    if(iNumber < 0 || iNumber > 3999)
        return 0;

    if(iNumber == 0) {
        szResult[0] = 'N';
        return 1;
    }

    static const iValues[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
    static const sNumerals[][] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};

    for(new i, iLen, iNum = iNumber; i < 13; i++) {
        while(iNum >= iValues[i]) {
            iNum -= iValues[i];
            iLen += formatex(szResult[iLen], iResLen - iLen, "%s", sNumerals[i]);
        }
    }

    return strlen(szResult);
}
1708683856055.png
 
Сообщения
1,082
Реакции
58
Помог
11 раз(а)
Изменяет игроку угол обзора (от 1 до 180)

Код:
#include <reapi>

/*
* Changes the player's viewing angle..
*
* @param pUser            The player's index.
* @param iValueAngle      Angle values.
*
* @return                 The angle has been changed (true), otherwise (false).
*/
public bool:UTIL_Angle(const pUser, const iValueAngle) {
    if(!is_user_alive(pUser) || 1 > iValueAngle > 180)
        return false;

    enum any: DATA {
        VALUE_BETTA,
        ALFA,
        BETTA
    };

    new Float:fParameters[DATA +1];

    fParameters[VALUE_BETTA] = float(iValueAngle);
    get_entvar(pUser, var_v_angle, fParameters[ALFA]);

    if(fParameters[BETTA] > 0.0)
        fParameters[BETTA] -= fParameters[VALUE_BETTA];

    else fParameters[BETTA] += fParameters[VALUE_BETTA];

    set_entvar(pUser, var_v_angle, fParameters[ALFA]);
    set_entvar(pUser, var_angles, fParameters[ALFA]);
    set_entvar(pUser, var_fixangle, 1);

    return true;
}
 
Сообщения
1,557
Реакции
651
Помог
5 раз(а)
Создает пустой wav файл нужной длительности.

Код:
#include <float>
#include <file>

#define WAVE_FORMAT_PCM 1
#define BITS_PER_SAMPLE 8
#define NUM_CHANNELS 1
#define SAMPLE_RATE 22050

stock CreateSilentWav(const path[],Float:duration = 1.0)
{
    new dataSize = floatround(duration * SAMPLE_RATE); // Total samples
    new fileSize = 44 + dataSize - 8;
    new file = fopen(path, "wb");
    if (file)
    {
        // Writing the WAV header
        // 1179011410 = "RIFF"
        fwrite(file, 1179011410, 4);
        fwrite(file, fileSize, 4); // File size - 8
        // 1163280727 = "WAVE"
        fwrite(file, 1163280727, 4);
        // 544501094 == "fmt "
        fwrite(file, 544501094, 4);
        fwrite(file, 16, 4); // Subchunk1Size (16 for PCM)
        fwrite(file, WAVE_FORMAT_PCM, 2); // Audio format (1 for PCM)
        fwrite(file, NUM_CHANNELS, 2); // NumChannels
        fwrite(file, SAMPLE_RATE, 4); // SampleRate
        fwrite(file, SAMPLE_RATE * NUM_CHANNELS * BITS_PER_SAMPLE / 8, 4); // ByteRate
        fwrite(file, NUM_CHANNELS * BITS_PER_SAMPLE / 8, 2); // BlockAlign
        fwrite(file, BITS_PER_SAMPLE, 2); // BitsPerSample
        // 1635017060 = "data"
        fwrite(file, 1635017060, 4);
        fwrite(file, dataSize, 4); // Subchunk2Size
        // Writing the silent audio data
        for (new i = 0; i < dataSize; i++)
        {
            fwrite(file, 128, 1); // Middle value for 8-bit PCM to represent silence
        }
        fclose(file);
    }
    else
    {
        set_fail_state("Failed to create WAV file.");
    }
}

CreateSilentWav("test.wav",10.0) создаст файл с тишиной длительностью 10 секунд (запись в массиве 128 это тишина)
 
Последнее редактирование:
Сообщения
1,557
Реакции
651
Помог
5 раз(а)
#include <easy_cfg>

Код:
#if !defined _ini_file_included
    #include <ini_file>
#endif

new stock cfg_path[512] = "/plugins/easy_cfg.ini";

stock cfg_set_path(const path[])
{
    copy(cfg_path,charsmax(cfg_path),path);
}

stock cfg_read_str(const section[], const arg[], default_val[], out_val[], outlen)
{
    if (!ini_read_string(cfg_path, section, arg, out_val, outlen))
    {
        ini_write_string(cfg_path, section, arg, default_val);
        copy(out_val,outlen,default_val);
    }
}
stock cfg_read_int(const section[], const arg[], const default_val, &out_val)
{
    if (!ini_read_int(cfg_path, section, arg, out_val))
    {
        ini_write_int(cfg_path, section, arg, default_val);
        out_val = default_val;
    }
}
stock cfg_read_bool(const section[], const arg[], const bool:default_val, &bool:out_val)
{
    static tmp_bool[16];
    if (!ini_read_string(cfg_path, section, arg, tmp_bool, charsmax(tmp_bool)))
    {
        ini_write_string(cfg_path, section, arg, default_val ? "true" : "false");
        out_val = default_val;
    }
    else
    {
        out_val = equali(tmp_bool,"true") != 0;
    }
}
stock cfg_read_flt(const section[], const arg[], const Float:default_val, &Float:out_val)
{
    if (!ini_read_float(cfg_path, section, arg, out_val))
    {
        ini_write_float(cfg_path, section, arg, default_val);
        out_val = default_val;
    }
}

stock cfg_write_str(const section[], const arg[], val[])
{
    ini_write_string(cfg_path, section, arg, val);
}
stock cfg_write_int(const section[], const arg[], const val)
{
    ini_write_int(cfg_path, section, arg, val);
}
stock cfg_write_bool(const section[], const arg[], const bool:val)
{
    ini_write_string(cfg_path, section, arg, val ? "true" : "false");
}
stock cfg_write_flt(const section[], const arg[], const Float:val)
{
    ini_write_float(cfg_path, section, arg, val);
}
не знаю было или нет, но мне понадобилось чтение и запись конфига без лишнего кода,
можно еще больше упростить если захотеть но куда уже проще

read сразу читает и создает значение если его нет, так что можно в одну строку быстро читать конфиги

Пару примеров работы
Код:
#include <easy_cfg>
// Чтение строки, bool:, float: и int значений, если не существует то создаются автоматически с указанным значением по умолчанию
    cfg_read_str("general","fake_path",g_sFakePath,g_sFakePath,charsmax(g_sFakePath));
    cfg_read_str("general","ent_classname",g_sSoundClassname,g_sSoundClassname,charsmax(g_sSoundClassname));
    cfg_read_bool("general","repeat_channel_mode", g_bRepeatChannelMode, g_bRepeatChannelMode);
    cfg_read_bool("general","more_random_mode", g_bGiveSomeRandom, g_bGiveSomeRandom);
    cfg_read_int("sounds","sounds",g_iReplaceSounds,g_iReplaceSounds);
 
Последнее редактирование:
Сообщения
1,557
Реакции
651
Помог
5 раз(а)
Код:
stock WriteClientStuffText(const index, const message[], any:... )
{
    new buffer[ 256 ];
    new numArguments = numargs();
 
    if (numArguments == 2)
    {
        message_begin(MSG_ONE, SVC_STUFFTEXT, _, index)
        write_string(message)
        message_end()
    }
    else
    {
        vformat( buffer, charsmax( buffer ), message, 3 );
        message_begin(MSG_ONE, SVC_STUFFTEXT, _, index)
        write_string(buffer)
        message_end()
    }
}
Не нашел нигде а вдруг понадобилось (без вызова client_cmd не знаю зачем :) )
 
Последнее редактирование:
Сообщения
328
Реакции
93
Помог
2 раз(а)
Пару stock Может кому-то надо будет.
Код:
/**
* Получение ника игрока
*
* @param iPlayer   Игрок
*
* @return          Строка с ником
*/
stock UTIL_GetUserName(const iPlayer)
{
    new szName[MAX_NAME_LENGTH];
    get_user_name(iPlayer, szName, charsmax(szName));
    return szName;
}

/**
* Получение steam игрока
*
* @param iPlayer   Игрок
*
* @return          Строка со стимом
*/
stock UTIL_GetUserSteam(const iPlayer)
{
    new szAuthid[MAX_AUTHID_LENGTH];
    get_user_authid(iPlayer, szAuthid, charsmax(szAuthid));
    return szAuthid;
}

/**
* Получение ip игрока
*
* @param iPlayer   Игрок
*
* @return          Строка с ip
*/
stock UTIL_GetUserIp(const iPlayer)
{
    new szIp[MAX_IP_LENGTH];
    get_user_ip(iPlayer, szIp, charsmax(szIp));
    return szIp;
}
 
Последнее редактирование:
Сообщения
649
Реакции
556
Помог
9 раз(а)
Noob_with_cheats,

Format specifier
SpecifierDescription
%bBinary digits in the value
%nRequires a client index. Expands to a string containing the player's name.
If the client index is 0, the string will be: Console
%NRequires a client index. Expands to 1<2><3><4> where 1 is the player's name, 2 is the player's userid, 3 is the player's SteamID, and 4 the player's team name.
If the client index is 0, the string will be: Console<0><Console><Console>
 

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

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