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

Сообщения
2,751
Реакции
3,016
Помог
61 раз(а)
Функция для конвертации steamid в steamid64
Функция для получения SteamID3 Steam аккаунта. Внимание! Работает не корректно с эмулированными SteamID (Non-Steam RevEmu и прочее) - получаются отрицательные значения.
1555940169565.png

Код:
stock _GetSteamId3(client)
{
    new szAuthId[MAX_AUTHID_LENGTH];
    get_user_authid(client, szAuthId, sizeof(szAuthId));
    enum any:SteamId_s { /*arg_universe,*/ arg_id = 1, arg_accountnumber };
    new data[SteamId_s][10];
    explode_string(szAuthId, ":", data, sizeof(data), sizeof(data[]));

    return strtol(data[arg_id]) + (strtol(data[arg_accountnumber]) << 1);
}
В итоге: из STEAM_0:0:56777063 получаем 113554126
 
Последнее редактирование:
Сообщения
147
Реакции
29
wopox1337 for what is SteamID3 being used ? Like SteamID64 is good for getting user's steamprofile for example
 
Последнее редактирование модератором:
Сообщения
2,751
Реакции
3,016
Помог
61 раз(а)
jocasrb, for steam only servers it's good way to store some data by integer unique num
 
Последнее редактирование модератором:
Сообщения
48
Реакции
151
Немножко удобной наркомании.
Код:
new any: __switchVar;
#define Switch(%0) __switchVar = %0;
#define FirstCase(%0) if (__switchVar == %0)
#define SubCase(%0) else if (__switchVar == %0)
#define Default() else
Пример из моего шоп апи (пример из примера, ага):

Код:
Switch(item) {
    FirstCase(g_sItemData[ShopItem_Gravity][ItemID]) {
        set_pev(player, pev_gravity, g_sItemData[ShopItem_Gravity][ItemAmount]);
    }

    SubCase(g_sItemData[ShopItem_Speed][ItemID]) {
        set_pev(player, pev_maxspeed, g_sItemData[ShopItem_Speed][ItemAmount]);
    }

    SubCase(g_sItemData[ShopItem_HP][ItemID]) {
        set_pev(player, pev_health, float(g_sItemData[ShopItem_HP][ItemAmount]));
    }

    SubCase(g_sItemData[ShopItem_HE][ItemID]) {
        give_item(player, "weapon_hegrenade");
    }
}
Увы, родной switch требует константные значения в кейсах.
 
Сообщения
1,291
Реакции
2,288
Помог
57 раз(а)
Kaido Ren, Особенно "удобно" подобное раскуривать потребителю, желающему внести правки. Практическая польза то какая? Её нет. Только запутывает.
 
Последнее редактирование модератором:
Сообщения
48
Реакции
151
BlackSignature, что касается пользы, последнюю строку еще раз прочитай. И первую, кстати, тоже, где русским языком сказано, что это наркомания. А если "потребитель" глуп и не понимает, что такое макросы или не знает принцип работы switch (а здесь ровно тоже самое, только названия "операторов" другие), то это полностью его проблемы, меня они никак не волнуют. То есть, благодаря тупым потребителям, судя по твоей логике, родной switch юзать тоже не стоит, они же запутаются, бедняжки. Ага, конечно.
 
Последнее редактирование модератором:
Сообщения
1,291
Реакции
2,288
Помог
57 раз(а)
https://web-creator.ru/articles/kiss
https://ru.wikipedia.org/wiki/Don’t_repeat_yourself

Kaido Ren, При чём тут "глуп, не глуп"? Это заставляет держать в голове лишний логический набор (не один макрос, именно набор), наряду с остальной логикой плагина. И чем плагин больше, тем это проблематичнее. Не деле то какой профит? Его нет, повторюсь. Топик называется "склад полезного кода". Здесь люди берут на заметку юзфул-стоки и "хаки" для скриптинга. И боже упаси, кто-то возьмёт на вооружение вот эти ваши идеи описывать всё велоспипедными макросами. Вполне представляю себя в роли новичка. Мне идея показалась бы достаточно интересной (люблю извращения). И представляю, как бы потом меня Фантом лупил книжкой по лицу за подобные реализации в коде.

Господа модераторы, перенесите в болталку, пожалуйста.
 
Последнее редактирование модератором:
Сообщения
48
Реакции
151
BlackSignature, вас никто насильно не заставляет что-то здесь использовать. Пользу я описал выше, если до вас она не доходит - проблемы ваши. Заставлять никого не собираюсь. Нет пользы для вас - я вас поздравляю, возьмите пирожок с полочки. А навязывать мне свое мнение не стоит.
 
Последнее редактирование модератором:
Сообщения
169
Реакции
462
Помог
2 раз(а)
Kaido Ren,
C++:
-new any: __switchVar;
+stock any: __switchVar;
Увы, родной switch требует константные значения в кейсах.
Компилятор из оператора switch делает некий data mapping. Что-то вроде ключ-значение. За счет чего улучшается производительность, по сравнению с оператором if. Разумеется, это не может работать с динамическими значениями (переменными).
 
Последнее редактирование модератором:
Сообщения
48
Реакции
151
the_hunter, кто ж спорит-то. Сам факт, что это невозможно - огромное неудобство.
 
Последнее редактирование модератором:
Сообщения
1,698
Реакции
1,510
Помог
26 раз(а)
the_hunter, ну вообще-то павн с недавних пор поддерживает такой синтаксис:
Код:
when (g_iEntityOjbect[iPlayer])
{
    g_iPlayerMuzzle[iPlayer] ->
    {
        // code
        return true
    }
    g_iPlayerIcon[iPlayer] ->
    {
        // code
        return true
    }
}
false
 
Последнее редактирование модератором:
Сообщения
594
Реакции
350
Предупреждения
1
Помог
9 раз(а)
fl0wer, что за магия вне Хогвартса
 
Последнее редактирование модератором:
Сообщения
1,698
Реакции
1,510
Помог
26 раз(а)
steelzzz, котлин)
 
Последнее редактирование модератором:

Garey

ninjaCow
Сообщения
422
Реакции
1,056
Помог
10 раз(а)
Функция WorldToScreen для Pawn - получает координаты HUD текста (xy) из 3д пространства.

C-like:
#include <fakemeta>
#include <xs>

Matrix4x4_CreateModelview( Float:out[4][4] )
{
    out[0][0] = out[1][1] = out[2][2] = 0.0;
    out[3][0] = out[0][3] = 0.0;
    out[3][1] = out[1][3] = 0.0;
    out[3][2] = out[2][3] = 0.0;
    out[3][3] = 1.0;
    out[1][0] = out[0][2] = out[2][1] = 0.0;
    out[2][0] = out[0][1] = -1.0;
    out[1][2] = 1.0;
}



Matrix4x4_Copy(Float:out[4][4], Float:in[4][4])
{
    for(new i = 0;i < 4;i++)
        for(new j = 0 ; j < 4; j++)
            out[i][j] = in[i][j];  
}

Matrix4x4_CreateRotate( Float:out[4][4], Float: angle, Float: x, Float: y, Float: z )
{
    new Float: len, Float:c, Float:s;

    len = x * x + y * y + z * z;
    if( len != 0.0 ) len = 1.0 / floatsqroot( len );
    x *= len;
    y *= len;
    z *= len;

    angle *= (-M_PI / 180.0);
    s = floatsin(angle);
    c = floatcos(angle);

    out[0][0]=x * x + c * (1 - x * x);
    out[0][1]=x * y * (1 - c) + z * s;
    out[0][2]=z * x * (1 - c) - y * s;
    out[0][3]=0.0;
    out[1][0]=x * y * (1 - c) - z * s;
    out[1][1]=y * y + c * (1 - y * y);
    out[1][2]=y * z * (1 - c) + x * s;
    out[1][3]=0.0;
    out[2][0]=z * x * (1 - c) + y * s;
    out[2][1]=y * z * (1 - c) - x * s;
    out[2][2]=z * z + c * (1 - z * z);
    out[2][3]=0.0;
    out[3][0]=0.0;
    out[3][1]=0.0;
    out[3][2]=0.0;
    out[3][3]=1.0;
}

Matrix4x4_Concat( Float:out[4][4], const Float:in1[4][4], const Float:in2[4][4] )
{
    out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0] + in1[0][3] * in2[3][0];
    out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1] + in1[0][3] * in2[3][1];
    out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2] + in1[0][3] * in2[3][2];
    out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + in1[0][2] * in2[2][3] + in1[0][3] * in2[3][3];
    out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0] + in1[1][3] * in2[3][0];
    out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1] + in1[1][3] * in2[3][1];
    out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2] + in1[1][3] * in2[3][2];
    out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + in1[1][2] * in2[2][3] + in1[1][3] * in2[3][3];
    out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0] + in1[2][3] * in2[3][0];
    out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1] + in1[2][3] * in2[3][1];
    out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2] + in1[2][3] * in2[3][2];
    out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3] * in2[3][3];
    out[3][0] = in1[3][0] * in2[0][0] + in1[3][1] * in2[1][0] + in1[3][2] * in2[2][0] + in1[3][3] * in2[3][0];
    out[3][1] = in1[3][0] * in2[0][1] + in1[3][1] * in2[1][1] + in1[3][2] * in2[2][1] + in1[3][3] * in2[3][1];
    out[3][2] = in1[3][0] * in2[0][2] + in1[3][1] * in2[1][2] + in1[3][2] * in2[2][2] + in1[3][3] * in2[3][2];
    out[3][3] = in1[3][0] * in2[0][3] + in1[3][1] * in2[1][3] + in1[3][2] * in2[2][3] + in1[3][3] * in2[3][3];
}

Matrix4x4_ConcatRotate( Float:out[4][4], Float:angle,Float: x, Float: y, Float: z )
{
    new Float:base[4][4], Float:temp[4][4];

    Matrix4x4_Copy( base, out );
    Matrix4x4_CreateRotate( temp, angle, x, y, z );
    Matrix4x4_Concat( out, base, temp );
}

Matrix4x4_CreateTranslate( Float:out[4][4], Float:x, Float:y, Float: z )
{
    out[0][0] = 1.0;
    out[0][1] = 0.0;
    out[0][2] = 0.0;
    out[0][3] = x;
    out[1][0] = 0.0;
    out[1][1] = 1.0;
    out[1][2] = 0.0;
    out[1][3] = y;
    out[2][0] = 0.0;
    out[2][1] = 0.0;
    out[2][2] = 1.0;
    out[2][3] = z;
    out[3][0] = 0.0;
    out[3][1] = 0.0;
    out[3][2] = 0.0;
    out[3][3] = 1.0;
}

Matrix4x4_ConcatTranslate( Float:out[4][4], Float:x, Float:y, Float:z )
{
    new Float: base[4][4], Float: temp[4][4];

    Matrix4x4_Copy( base, out );
    Matrix4x4_CreateTranslate( temp, x, y, z );
    Matrix4x4_Concat( out, base, temp );
}

Matrix4x4_CreateProjection( Float:out[4][4], Float:xMax, Float: xMin, Float: yMax, Float: yMin, Float: zNear, Float:zFar )
{
    out[0][0] = ( 2.0 * zNear ) / ( xMax - xMin );
    out[1][1] = ( 2.0 * zNear ) / ( yMax - yMin );
    out[2][2] = -( zFar + zNear ) / ( zFar - zNear );
    out[3][3] = out[0][1] = out[1][0] = out[3][0] = out[0][3] = out[3][1] = out[1][3] = 0.0;

    out[2][0] = 0.0;
    out[2][1] = 0.0;
    out[0][2] = ( xMax + xMin ) / ( xMax - xMin );
    out[1][2] = ( yMax + yMin ) / ( yMax - yMin );
    out[3][2] = -1.0;
    out[2][3] = -( 2.0 * zFar * zNear ) / ( zFar - zNear );
}

R_SetupProjectionMatrix( Float:m[4][4] )
{
    new Float:xMin, Float:xMax, Float:yMin, Float:yMax, Float:zNear, Float:zFar;

    zNear = 4.0

    zFar = floatmax( 256.0, 8192.0 );

    yMax = zNear * floattan( 74.0 * M_PI / 360.0 );
    yMin = -yMax;

    xMax = zNear * floattan( 90.0 * M_PI / 360.0 );
    xMin = -xMax;

    Matrix4x4_CreateProjection( m, xMax, xMin, yMax, yMin, zNear, zFar );
}

R_SetupModelviewMatrix( Float: m[4][4], Float:viewangles[3], Float:vieworg[3])
{
    Matrix4x4_CreateModelview( m );
    Matrix4x4_ConcatRotate( m, -viewangles[2], 1.0, 0.0, 0.0 );
    Matrix4x4_ConcatRotate( m, -viewangles[0], 0.0, 1.0, 0.0 );
    Matrix4x4_ConcatRotate( m, -viewangles[1], 0.0, 0.0, 1.0 );
    Matrix4x4_ConcatTranslate( m, -vieworg[0], -vieworg[1], -vieworg[2] );
}

stock bool:WorldToScreen( id, Float:point[3], Float:screen[2] )
{
    new bool:behind;
    new Float:w;
    new Float:worldToScreen[4][4];
    new Float:worldviewMatrix[4][4];
    new Float:projectionMatrix[4][4];
   
    new Float:viewangles[3];
    new Float:viewofs[3];
    new Float:vieworigin[3];
   
    pev(id, pev_origin, vieworigin);
    pev(id, pev_v_angle, viewangles);
    pev(id, pev_view_ofs, viewofs);
    xs_vec_add(vieworigin, viewofs, vieworigin);
    R_SetupModelviewMatrix(worldviewMatrix, viewangles, vieworigin);
    R_SetupProjectionMatrix( projectionMatrix );
    Matrix4x4_Concat( worldToScreen, projectionMatrix, worldviewMatrix );
   
    screen[0] = worldToScreen[0][0] * point[0] + worldToScreen[0][1] * point[1] + worldToScreen[0][2] * point[2] + worldToScreen[0][3];
    screen[1] = worldToScreen[1][0] * point[0] + worldToScreen[1][1] * point[1] + worldToScreen[1][2] * point[2] + worldToScreen[1][3];
    w = worldToScreen[3][0] * point[0] + worldToScreen[3][1] * point[1] + worldToScreen[3][2] * point[2] + worldToScreen[3][3];

    if( w < 0.001 )
    {
        screen[0] *= 100000;
        screen[1] *= 100000;
        behind = true;
    }
    else
    {
        new Float:invw = 1.0 / w;
        screen[0] *= invw;
        screen[1] *= invw;
        behind = false;
    }
    screen[0] =  0.5 * screen[0] * 1.0;
    screen[1] = -0.5 * screen[1] * 1.0;
    screen[0] += 0.5 * 1.0;
    screen[1] += 0.5 * 1.0;
   
    return behind;
}
17182
 
Последнее редактирование модератором:
Сообщения
147
Реакции
29
Garey is it less consuming for the server than Admin ESP's method? If it can be compared
 
Последнее редактирование модератором:
Сообщения
9
Реакции
9
DeathMsg like SISA

Ищем:
Код:
// Send Death Message for infections
SendDeathMsg(attacker, victim)
{
    message_begin(MSG_BROADCAST, g_msgDeathMsg)
    write_byte(attacker) // killer
    write_byte(victim) // victim
    write_byte(1) // headshot flag
    write_string("infected") // killer's weapon
    message_end()
}
Заменяем на:
Код:
// Send Death Message for infections
SendDeathMsg(attacker, victim)
{
    message_begin(MSG_BROADCAST, g_msgDeathMsg)
    write_byte(attacker) // killer
    write_byte(victim) // victim
    write_byte(0) // headshot flag
    write_string("teammate") // killer's weapon
    message_end()
}
17475
 
Сообщения
2,751
Реакции
3,016
Помог
61 раз(а)
Воможно, кому-то понадобится при пользовании JSON заносить в массивы координаты. Даю простенький пример, как можно вносить и Float и Int массивы.
#ТипоПерегрузка

Код:
#include <amxmodx>
#include <json>

public plugin_init()
{
    new JSON:pArr_Origin = json_init_array();
    {
        new szBuffer[1024];

        _OriginToArray(pArr_Origin, {123, 456, 789});
        _OriginToArray(pArr_Origin, Float:{123.123, 456.456, 789.789});

        json_serial_to_string(pArr_Origin, szBuffer, charsmax(szBuffer), .pretty = false);
        server_print("JSONArray='%s'", szBuffer);

        json_free(pArr_Origin);
    }
}

stock _OriginToArray(&JSON:pArr_Origin, {_, Float}:vOrigin[3], arg_type = tagof(vOrigin))
{
    for(new i; i < sizeof(vOrigin); i++)
    {
        json_array_append_number(pArr_Origin, (arg_type == tagof(Float:)) ? floatround( (Float:vOrigin[i]) ) : vOrigin[i]);
    }
}
На выходе: JSONArray='[123,456,789,123,456,790]'

P.S: округления сами выберите =)
 
Сообщения
147
Реакции
29
Garey can you show any example of using WorldToScreen stock?
 
Последнее редактирование модератором:
Сообщения
169
Реакции
462
Помог
2 раз(а)
Функция ищет используемые звуки в моделях и добавляет их в прекеш. Делает то же самое, что квар sv_auto_precache_sounds_in_models 1 в ReHLDS.
C++:
stock precache_model_sounds(const szModel[])
{
    const OFFSET_NUMSEQ = 0xA4;
    const SIZE_SEQUENCE = 0xB0;
    const OFFSET_NUMEVENTS = 0x30;
    const SIZE_EVENT = 0x4C;
    const OFFSET_EVENT = 0x4;
    const OFFSET_OPTIONS = 0xC;

    new model = fopen(szModel, "rb");
    if (model == 0) return;

    new numSeq;
    new offsetSeqIndex;

    if (fseek(model, OFFSET_NUMSEQ, SEEK_SET) || !FileReadInt32(model, numSeq))
    {
        fclose(model);
        return;
    }

    if (!FileReadInt32(model, offsetSeqIndex))
    {
        fclose(model);
        return;
    }

    new event = 0;
    new numEvents = 0;
    new offsetEventIndex = 0;
    new szSound[MAX_RESOURCE_PATH_LENGTH];

    for (new i = 0; i < numSeq; i++, offsetSeqIndex += SIZE_SEQUENCE)
    {
        if (fseek(model, offsetSeqIndex, SEEK_SET))
            continue;

        if (fseek(model, offsetSeqIndex + OFFSET_NUMEVENTS, SEEK_SET) || !FileReadInt32(model, numEvents))
            continue;

        if (!FileReadInt32(model, offsetEventIndex))
            continue;

        for (new j = 0; j < numEvents; j++, offsetEventIndex += SIZE_EVENT)
        {
            if (fseek(model, offsetEventIndex + OFFSET_EVENT, SEEK_SET))
                continue;

            if (!FileReadInt32(model, event) || event != 5004)
                continue;

            if (fseek(model, offsetEventIndex + OFFSET_OPTIONS, SEEK_SET))
                continue;

            fread_blocks(model, szSound, charsmax(szSound), BLOCK_CHAR);

            if (szSound[0] != EOS)
                precache_sound(szSound);
        }
    }

    fclose(model);
}
Использовать так:

C++:
public plugin_precache()
{
    precache_model("models/some_model.mdl");

    if (get_cvar_num("sv_auto_precache_sounds_in_models") == 0)
        precache_model_sounds("models/some_model.mdl");
}
 

ArKaNeMaN

Квалифицированный специалист по VipModular
Сообщения
433
Реакции
293
Помог
5 раз(а)
Надет ли глушитель
Код:
#define IsWeaponSilenced(%0) bool:((WPNSTATE_M4A1_SILENCED | WPNSTATE_USP_SILENCED) & get_member(%0, m_Weapon_iWeaponState))
 
Последнее редактирование модератором:

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

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