• Регистрация на форуме отключена.
    Она будет открываться первого числа каждого месяца на 24 часа.

    Другие способы описаны>> тут <<

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

Сообщения
2,389
Реакции
2,459
Помог
56 раз(а)
Обсуждаем, выкладываем полезные стоки для скриптера. Делимся решением задач.

  1. Код позволяет "использовать" разные энтити объекты (где нет возм. по умолчанию)- Vaqtincha
  2. Макрос для проверки на наличие Steam клиента (необходимы Reunion и Reapi) - Subb98
  3. Детект броска и взрыва HEGRENADE - fantom
  4. ReAPI стоки (reapi_stocks.inc) - Vaqtincha
  5. Конвертация секунд (get_systime()) в дни\часы\минуты - wopox1337
  6. Правильное окончание слов после числительных (например 1 час 21 минута) - wopox1337
  7. Шаблон игроков в меню - Subb98
  8. Стоки is_plugin_running и get_plugin_state - Vaqtincha
  9. Макросы для работы с битсуммами- wopox1337
  10. Плагин логирования списка энтити на карте- wopox1337
  11. Добавление начала время в начале строке как в нативах логирования AMXX - wopox1337
  12. Получение из строки вида "123 -123 1234" массива с координатами iOrigin[3] - wopox1337
  13. Установка бомбы с "правильными" углами - voed
  14. Более кастомный худ, можно задавать цвет для эффекта и прозрачность - Black Rose
  15. Автоматическое дополнение-расширение регистрируемых команд до полного списка - wopox1337
  16. Проверка имеет ли файл расширение .mp3 - wopox1337
  17. Код для визуализации вектора в пространстве - wopox1337
  18. Сток для автоматической регистрации списка команд в зависимости от их типа (cmd, impulse) - wopox1337
  19. Код для плавного затемнения экрана игроку и такого же плавного возвращения яркости спустя определённое время - [email protected]
  20. Полоса загрузки из CS:CZ при Analyzing'е ботами карты- wopox1337
  21. Поддержка colorchat.inc для AMXX < 1.8.3 - AMXX Community & Lev
  22. Плагин блокировки звуков в начале раунда - REVO
  23. Плагин блокировки звуков и сообщений побед - REVO
  24. Сброс статистики определенного числа, через указанное кол-во месяцев - d3m37r4
  25. Макрос для получения строки в стоковых функциях с динамическим числом параметров - Kaido Ren
  26. Сообщение для отображения визуальных эффектов погоды (ReceiveW) - Xelson
  27. Проверка видимости при помощи 5 случайных трассировок(видимость зависит от случайности, 2 вызова стока могут вернуть разный результат на статичных обьектах в случае видимости очень маленького кусочка обьекта) из HLSDK(только без проверки waterlevel) - swank
  28. Код для генерации строки с набором случайных букв - Mistrick
  29. Сток подготовит кол-во секунд для отправки в message клиента write_short значения - wopox1337
  30. Проверка находится ли игрок в ослеплении, для ReAPI - wopox1337
  31. Код убирает всю отдачу (Recoil + Spray) для всех оружий - Vaqtincha
  32. Регулировка прозрачности игрока в зависимости от скорости - wopox1337
  33. Выставление свойств видимости объектов индивидуально для игрока (другие не видят) - wopox1337
  34. Код для определения времени суток - steelzzz
  35. Код для запуска hlds сервера в консольном режиме, с сворачиванием дочернего окна на Windows
  36. Fix (костыль) для исправления отображения Unicode-символов в подключаемых #include файлах - [email protected]
  37. Стоки для возвращения адреса переменной и для записи в память AMXX по указанному адресу - the_hunter
  38. Алгоритм поиска цвета между заданных двух в промежутке от 0 до range в заданной точке value - Garey
  39. Аналог native cs_get_user_buyzone(index) - проверка нахождения игрока в зоне закупки- d3m37r4
    • Это сокращенный вариант (один сток) варианта от Vaqtincha из номера 4
  40. Аналог Float:cs_get_user_lastactivity(index) - проверка последней активности игрока - d3m37r4
  41. Метод чтобы парсить переданные через натив структуры и избежать излишнего дублирования кода (принцип DRY) - BoecSpecOPs
  42. Парсинг времени для бана, парсинг цвета в формате HEX - fantom
  43. Создание времени - fantom
  44. Реверс строки - fantom
  45. Локализация плагинов на один язык - the_hunter
  46. Информация о реализации списков для плагинов - BoecSpecOPs
  47. Сток rg_give_item_ex - neygomon
  48. Копирование произвольного масива в другой массив - BoecSpecOPs
  49. Выдача оружия вместе с боеприпасом, аналог из ReGameDLL - wopox1337
  50. Аналоги DefaultDeploy и SendWeaponAnim с SDK - swank
  51. Cпособ использования ArrayFindString для массивов - Kaido Ren
  52. Вариант блокировки звуков выстрела по умолчанию - fl0wer
  53. Подсчет количества игроков в командах - d3m37r4
  54. Функция для конвертации steamid в steamid64, поддерживает не все типы аккаунтов - swank
  55. Рандомное деление игроков - w0w
  56. Отправка анимации оружия - fantom
  57. Замена каждой искомой подстроки в строке с использованием replace_stringex - Kaido Ren
  58. Отправка сообщения всем игрокам, кроме указанного в параметре index - d3m37r4
  59. Быстрый цикл по игрокам- Kaido Ren
  60. Получение параметров из bsp карт - the_hunter
  61. Функция для получения SteamID3 Steam аккаунта - wopox1337
  62. Использование switch и case как дефайн - Kaido Ren
  63. Функция WorldToScreen для Pawn — получение координат HUD текста (xy) из 3D пространства - Garey
  64. Зелёная иконка при смерти (DeathMsg) - PWNED // SISA
  65. Используя JSON заносить в массивы координаты - wopox1337
  66. Функция для поиска используемых звуков в моделях и добавление их в прекеш - the_hunter
  67. Макрос для проверки есть ли глушитель на оружии - ArKaNeMaN
  68. Сток для того чтобы только что выданное оружие сделать активным - fantom
  69. Пример открытия стандартного меню закупки - d3m37r4
  70. Вывод информации (цифры) в тысячах (k, M...) - Garey
  71. Создание дыма в указанной координате - wopox1337
  72. Проигрывание ближайшим игрокам дефолтного звука перезарядки оружия - Ruby
  73. Стоки для удобной регистрации целой пачки похожих команд- wopox1337
  74. Реализация дебага - wopox1337
  75. Просчет бади груп + сабмоделей - Shel
  76. Запатченный viewer, отображает всю строку(int32) body - Shel
  77. Нормализация спрайта и модели на поверхности - Shel
  78. Сток поиска оружия у игрока - fantom
  79. Функция для генерации версии билда в стиле Valve Software - Garey
  80. Преобразовывание ячейки в вид float'а без вызовов конструктора - Shel
  81. Преобразование float в int - Shel
  82. Эвенты смены команды игрока (API) - Shel
  83. Правильное закрытие меню вызывающееся несколько раз - Shel
  84. Функция для проверки пересекает ли линия облако дыма - Denzer порт из ReGameDLL
  85. Получение координат точки находящейся на определенном расстоянии от игрока относительно его взгляда - d3m37r4
  86. Аналог get_players на ReAPI - wopox1337
  87. Код для конвертации ближайшего тона HUE <-> RGB - Garey
  88. Способ сменить класснейм у ентити загруженой с карты - fantom
  89. Способ выдать кастом оружие (например weapon_bazuka) с помощю rg_give_item - fantom
 
Последнее редактирование модератором:
Сообщения
212
Реакции
241
Помог
4 раз(а)
Код позволяет "использовать" разные энтити объекты (где нет возм. по умолчанию)
Код:
public plugin_init()
{
RegisterHam(Ham_ObjectCaps, "weaponbox", "ObjectCaps", .Post = false)
RegisterHam(Ham_Use, "weaponbox", "Weaponbox_Use", .Post = true)
}

public ObjectCaps(pWeaponBox)
{
SetHamReturnInteger(FCAP_ONOFF_USE) // see FCAP_ cons hlsdk_const.inc
return HAM_OVERRIDE
}

public Weaponbox_Use(pWeaponBox, pOther)
{
if(is_user_connected(pOther)) // is player
{
client_print(pOther, print_center, "%i", pWeaponBox)
}
}



https://forums.alliedmods.net/showthread.php?t=225015
 
Сообщения
2,275
Реакции
2,523
Помог
58 раз(а)
Vaqtincha, можно пример где можно использовать это?
 
Последнее редактирование модератором:
Сообщения
261
Реакции
257
Помог
5 раз(а)

Макрос для проверки на наличие Steam клиента (необходимы Reunion и Reapi):
Код:
#define is_user_steam(%0) (REU_GetAuthtype(%0) == CA_TYPE_STEAM)
 
Последнее редактирование модератором:
Сообщения
2,275
Реакции
2,523
Помог
58 раз(а)
Не актуально!

C++:
#include <amxmodx>
#include <engine>
#include <hamsandwich>
#include <reapi>

new g_HookGrenadeThink;

new g_FwdThrow, g_FwdExplode, g_Ret;

public plugin_init() {
register_plugin("HEGrenade API", "0.1", "[email protected]");

RegisterHam(Ham_Spawn, "grenade", "HookGrenadeSpawn", 1);
register_think("grenade", "HookGrenadeThinkExplode");

g_FwdThrow = CreateMultiForward("gapi_grenade_throw", ET_IGNORE, FP_CELL, FP_CELL);
g_FwdExplode = CreateMultiForward("gapi_grenade_explode", ET_IGNORE, FP_CELL, FP_CELL);
}

public HookGrenadeSpawn(ent) {
g_HookGrenadeThink = register_think("grenade", "HookGrenadeThink");
}

public HookGrenadeThink(ent) {
unregister_think(g_HookGrenadeThink);

if (Float:get_entvar(ent, var_dmg) > 40.0) {
ExecuteForward(g_FwdThrow, g_Ret, get_entvar(ent, var_owner), ent);
}
}

public HookGrenadeThinkExplode(ent) {
static dmgtime, gametime;

if (Float:get_entvar(ent, var_dmg) > 40.0) {
dmgtime = floatround(Float:get_entvar(ent, var_dmgtime) * 100.0, floatround_floor);
gametime = floatround(get_gametime() * 100.0, floatround_floor);
if (dmgtime == gametime) {
ExecuteForward(g_FwdExplode, g_Ret, get_entvar(ent, var_owner), ent);
}
}
}
 
Последнее редактирование модератором:
Сообщения
212
Реакции
241
Помог
4 раз(а)
Ну я начал написать сток (уж давно) для реапи. Да там есть полезные (или просто велосипеды) подойдет новичкам так и опытным скриптерам (улучшает читабельности кода и.т.д) Вот пока не хватает описание стоков.
Чтоб использовать подключаем
Код:
#include <reapi_stocks>

или копи-пастим на свой плагин (как делали с fakemeta_util)
 

Вложения

Сообщения
2,389
Реакции
2,459
Помог
56 раз(а)
Конвертация секунд (get_systime()) в дни\часы\минуты:
Код:

stock seconds_to_time(iSec, &iDays, &iHours, &iMinutes)
{
iDays = iSec / 60 / 60 / 24;
iHours = (iSec / 60 / 60) % 24;
iMinutes = (iSec / 60) % 60;
}


Правильное окончание слов после числительных (например 1 час 21 минута):
Код:

enum _:
{
Plural, // минут
Singular, // минуты
Nominative // минута
};


stock get_numerical_noun_form(iNum)
{
if (iNum > 10 && ((iNum % 100) / 10) == 1)
return Plural;

switch (iNum % 10)
{
case 1: return Nominative;
case 2, 3, 4: return Singular;
}

return Plural;
}

Автор: the_hunter
 
Сообщения
429
Реакции
397
Помог
14 раз(а)
C++:
#include <amxmodx>
#include <engine>
#include <hamsandwich>
#include <reapi>

new g_HookGrenadeThink;

new g_FwdThrow, g_FwdExplode, g_Ret;

public plugin_init() {
register_plugin("HEGrenade API", "0.1", "[email protected]");

RegisterHam(Ham_Spawn, "grenade", "HookGrenadeSpawn", 1);
register_think("grenade", "HookGrenadeThinkExplode");

g_FwdThrow = CreateMultiForward("gapi_grenade_throw", ET_IGNORE, FP_CELL, FP_CELL);
g_FwdExplode = CreateMultiForward("gapi_grenade_explode", ET_IGNORE, FP_CELL, FP_CELL);
}

public HookGrenadeSpawn(ent) {
g_HookGrenadeThink = register_think("grenade", "HookGrenadeThink");
}

public HookGrenadeThink(ent) {
unregister_think(g_HookGrenadeThink);

if (Float:get_entvar(ent, var_dmg) > 40.0) {
ExecuteForward(g_FwdThrow, g_Ret, get_entvar(ent, var_owner), ent);
}
}

public HookGrenadeThinkExplode(ent) {
static dmgtime, gametime;

if (Float:get_entvar(ent, var_dmg) > 40.0) {
dmgtime = floatround(Float:get_entvar(ent, var_dmgtime) * 100.0, floatround_floor);
gametime = floatround(get_gametime() * 100.0, floatround_floor);
if (dmgtime == gametime) {
ExecuteForward(g_FwdExplode, g_Ret, get_entvar(ent, var_owner), ent);
}
}
}
Способ не совсем корректный. dmgtime довольно сильно отличается от реального момента взрыва
 
Сообщения
212
Реакции
241
Помог
4 раз(а)
Последнее редактирование модератором:
Сообщения
639
Реакции
554
Помог
7 раз(а)
Простой шаблон игроков от Subb98, основным отличием которого является построения меню игроков с использованием уникального идентификатора UserID, который позволяет избежать недочет с неверным выбором игрока (случай носит исключающий характер, но тем не менее довольно встречающийся. При открытии меню игроков администратор может не надолго задержать его открытым или затратить некое время на поиск нужного игрока, тем временем данный игрок может выйти из сервера и на место его ID встать другой ID игрока, таким образом мы выбираем одного игрока для удаления, а удаляется другой игрок. По-своему опыту 1-3 случая за неделю точно).

И небольшая модификация от меня, которая требовалась под свои нужды.
  • Главный администратор (ADMIN_RCON) имеет право выбрать любого игрока, включая самого себя.
  • Простой администратор (ADMIN_BAN) имеет право выбрать любого игрока (включая иммунитированного), кроме главного администратора, самого себя и администраторов себе подобных (ADMIN_BAN).
  • Все иммунитированные игроки отмечаются с желтой звездочкой возле никнейма
  • Самого себя видно с красной звездочкой возле никнейма
  • Те игроки, которых выбрать невозможно выделяются серым цветом и желтой звездочкой возле никнейма, дабы тоже имеют своего рода "иммунитет" от выбора.
Код:
#include <amxmodx>

const PLAYERS_PER_PAGE = 8;

new g_MenuPosition[MAX_PLAYERS + 1];
new g_Players[MAX_PLAYERS + 1][MAX_PLAYERS];
new g_UserID[MAX_PLAYERS + 1][MAX_PLAYERS + 1];

public plugin_init() {
    register_clcmd("players_menu", "CmdPlayersMenu");
    register_menucmd(register_menuid("_players_menu"), 1023, "HandleMenu");
}

public CmdPlayersMenu(const id) {
    if(get_user_flags(id) & ADMIN_BAN) {
        return ShowMenu(id, g_MenuPosition[id] = 0);
    }
    console_print(id, "У вас недостаточно прав для использования этой команды");
    return PLUGIN_HANDLED;
}

ShowMenu(const id, Pos) {
    if(Pos < 0) return PLUGIN_CONTINUE;
  
    new PlayersNum, Start, End, PagesNum, Len, Menu[512], i, Name[32], b, Keys = MENU_KEY_0;
    new PlayerFlags, AdminFlags = get_user_flags(id);
  
    get_players(g_Players[id], PlayersNum, "ch");
  
    if((Start = Pos * PLAYERS_PER_PAGE) >= PlayersNum)
        Start = Pos = g_MenuPosition[id] = 0;
  
    if((End = Start + PLAYERS_PER_PAGE) > PlayersNum)
        End = PlayersNum;
  
    if((PagesNum = PlayersNum / PLAYERS_PER_PAGE + (PlayersNum % PLAYERS_PER_PAGE ? 1 : 0)) == 1)
        Len = copy(Menu, charsmax(Menu), "\yВыберите игрока^n^n");
    else
        Len = formatex(Menu, charsmax(Menu), "\yВыберите игрока \d(%d/%d)^n^n", Pos + 1, PagesNum);
  
    while(Start < End) {
        i = g_Players[id][Start++];
        g_UserID[id] = get_user_userid(i);
        get_user_name(i, Name, charsmax(Name));
        PlayerFlags = get_user_flags(i);
       
        if(AdminFlags & ADMIN_RCON) {
            Keys |= (1<<b);
            if(i != id)
                Len += formatex(Menu[Len], charsmax(Menu) - Len, "\y%d. \w%s%s^n", ++b, Name, (PlayerFlags & ADMIN_IMMUNITY) || (PlayerFlags & ADMIN_BAN) ? " \y*" : "");
            else {
                Len += formatex(Menu[Len], charsmax(Menu) - Len, "\y%d. \w%s \r*^n", ++b, Name);
            }
        } else if(AdminFlags & ADMIN_BAN) {
            if(i == id || PlayerFlags & ADMIN_BAN || PlayerFlags & ADMIN_RCON)
                Len += formatex(Menu[Len], charsmax(Menu) - Len, "\d%d. %s%s^n", ++b, Name, i == id ? " \r*" : " \y*");
            else {
                Keys |= (1<<b);
                Len += formatex(Menu[Len], charsmax(Menu) - Len, "\y%d. \w%s%s^n", ++b, Name, (PlayerFlags & ADMIN_IMMUNITY) ? " \y*" : "");
            }
        }
    }
   
    if(End < PlayersNum) {
        Keys |= MENU_KEY_9;
        formatex(Menu[Len], charsmax(Menu) - Len, "^n\y9. \wДалее^n\y0. \w%s", Pos ? "Назад" : "Выход");
    } else
        formatex(Menu[Len], charsmax(Menu) - Len, "^n\y0. \w%s", Pos ? "Назад" : "Выход");
   
    return show_menu(id, Keys, Menu, -1, "_players_menu");
}

public HandleMenu(const id, const Key) {
    switch(Key) {
        case 8: ShowMenu(id, ++g_MenuPosition[id]);
        case 9: ShowMenu(id, --g_MenuPosition[id]);
        default: {
            new Target = g_Players[id][g_MenuPosition[id] * PLAYERS_PER_PAGE + Key];
            if(get_user_userid(Target) == g_UserID[id][Target]) {
                new Name[32];
                get_user_name(Target, Name, charsmax(Name));
                client_print(id, print_chat, "Вы выбрали игрока: %s", Name);
            } else
                client_print(id, print_chat, "Выбранный Вами игрок отключился от сервера");
        }
    }
}
 
Последнее редактирование модератором:
Сообщения
212
Реакции
241
Помог
4 раз(а)
Может велосипед
Код:

enum PluginState
{
PL_STATE_NOT_EXIST = 0,
PL_STATE_RUNNING,
PL_STATE_DEBUG,
PL_STATE_PAUSED,
PL_STATE_STOPPED,
PL_STATE_ERROR,
PL_STATE_BAD_LOAD
}

stock bool:is_plugin_running(const szName[], const bool:bUseFilename = false)
{
new PluginState:iPlState = get_plugin_state(szName, bUseFilename)
return bool:(iPlState == PL_STATE_RUNNING || iPlState == PL_STATE_DEBUG)
}

stock PluginState:get_plugin_state(const szName[], const bool:bUseFilename = false)
{
new szStatus[2], iPluginID

if((iPluginID = is_plugin_loaded(szPluginname, bUseFilename)) == INVALID_PLUGIN_ID) {
return PL_STATE_NOT_EXIST
}

if(get_plugin(iPluginID, .status = szStatus, .len5 = charsmax(szStatus)) != INVALID_PLUGIN_ID)
{
switch(szStatus[0])
{
case 'r': return PL_STATE_RUNNING // "running"
case 'd': return PL_STATE_DEBUG // "debug"
case 'p': return PL_STATE_PAUSED // "paused"
case 's': return PL_STATE_STOPPED // "stopped"
case 'e': return PL_STATE_ERROR // "error"
case 'b': return PL_STATE_BAD_LOAD // "bad load"
}
}

return PL_STATE_NOT_EXIST
}
 
Сообщения
2,389
Реакции
2,459
Помог
56 раз(а)
Макросы для работы с битсуммами
Код:

#define get_bit(%1,%2) (%1 & (1 << (%2 & 31)))
#define set_bit(%1,%2) (%1 |= (1 << (%2 & 31)))
#define reset_bit(%1,%2) (%1 &= ~(1 << (%2 & 31)))
#define invert_bit(%1,%2) (%1 ^= (1 << (%2 & 31)))

Например:
Код:
enum { FIRST_BIT, TWO_BIT }

new bitsummData;
...
if(get_bit(bitsummData, FIRST_BIT))
...

6 Авг 2017


Плагин логирует список entity на карте в файл amxmodx/logs/entities.log

Код:
#include <amxmodx>
#include <amxmisc>
#include <engine>

new g_Dir[128];

public plugin_precache(){
get_basedir(g_Dir, charsmax(g_Dir));
add(g_Dir, charsmax(g_Dir), "/logs/entities.log");
}

public pfn_keyvalue(pEntityId)
{
if(!is_valid_ent(pEntityId))
return;

static szClassName[64], szKeyName[64], szKeyValue[64];
copy_keyvalue(
szClassName,charsmax(szClassName),
szKeyName,charsmax(szKeyName),
szKeyValue,charsmax(szKeyValue)
);

Log_entity(g_Dir,
"> %i, %s,%s,%s",
pEntityId,
szClassName,
szKeyName,
szKeyValue
);
}

stock Log_entity(szLogsDir[], Message[], any:...) {
static szMsg[512], pFile;

vformat(szMsg, charsmax(szMsg), Message, 3);
pFile = fopen(szLogsDir, "at");
fprintf(pFile, "%s^n", szMsg);
fclose(pFile);
}


Возможно пригодится при разработке.
 
Сообщения
212
Реакции
241
Помог
4 раз(а)
Ну вообщем вариант
Код:
#include <amxmodx>
#include <engine>

new const LOG_FILE_NAME[] = "entities.log"

new g_pFilePointer

public plugin_precache()
{
new g_szLogFile[128], szMapName[32], iLen
iLen = get_localinfo("amxx_logs", g_szLogFile, charsmax(g_szLogFile))
get_mapname(szMapName, charsmax(szMapName))
formatex(g_szLogFile[iLen], charsmax(g_szLogFile) - iLen, "%s/%s_%s", g_szLogFile[iLen], szMapName, LOG_FILE_NAME)

if(!(g_pFilePointer = fopen(g_szLogFile, "wt"))) {
set_fail_state("Can't create the file")
}
}

public plugin_init()
{
if(g_pFilePointer > 0) {
fclose(g_pFilePointer)
}
}

public pfn_keyvalue(pEntityId)
{
if(!is_valid_ent(pEntityId))
return

new szClassName[64], szKeyName[64], szKeyValue[64]

copy_keyvalue(szClassName,charsmax(szClassName), szKeyName,charsmax(szKeyName), szKeyValue,charsmax(szKeyValue))

fprintf(g_pFilePointer, "> %i, %s, %s, %s^n", pEntityId, szClassName, szKeyName, szKeyValue)
}
 
Сообщения
2,389
Реакции
2,459
Помог
56 раз(а)
Получение из строки вида "123 -123 1234" массива с координатами iOrigin[3]
Код:
get_coords(string[], iOrigin[3], const delimiter[] = " ")
{
new i;
new ePos, stPos, rawPoint[32];

do
{
ePos = strfind(string[stPos],delimiter);
formatex(rawPoint, ePos, string[stPos]);
stPos += ePos + 1;

trim(rawPoint);

if(rawPoint[0])
{
iOrigin = str_to_num(rawPoint);

}
}
while(ePos != -1)
}
 
Сообщения
429
Реакции
397
Помог
14 раз(а)
Установка бомбы с "правильными" углами

Когда-то давно, года три назад, долгим зимним вечером мне было скучно и я игрался со свойствами бомбы. Мне не нравилось, что бомба всегда устанавливалась под одним и тем же углом, независимо от того, куда смотрит игрок. Ну и я набыдлокодил что-то вот такое:

Код:
new Float:angles[3]

public bomb_planted(id) //csx
{
pev(id, pev_v_angle, angles)
new bomb = engfunc( EngFunc_FindEntityByString, 0, "model", "models/w_c4.mdl" );
if ( !pev_valid( bomb ) )
return PLUGIN_CONTINUE

angles[0]=0.0 // В этой оси бомба должна стоять ровно.
angles[1]+=90.0 // В этой оси нужно повернуть на 90 градусов
set_pev(bomb, pev_angles, angles)
return PLUGIN_CONTINUE
}


Теперь бомба устанавливается под "правильными" углами. Тестил на нескольких картах, вроде данные манипуляции не позволяют спрятать бомбу так, чтоб ее не было видно.

Спасибо perforator за видео
 
Последнее редактирование:
Сообщения
170
Реакции
276
Помог
1 раз(а)
Более кастомный худ, можно задавать цвет для эффекта и прозрачность.
Скриншот 24-08-2017 222649.jpg Скриншот 24-08-2017 222657.jpg
Код:
/*
* id
* Player to send the message to.
*   0 = everyone
*
* text[]
*   Text to send.
*
* Float:X
*   X position on screen.
*
* Float:Y
*   Y position on screen.
*
* R
*   Red color.
*
* G
*   Green color.
*
* B
*   Blue color.
*
* A
*   Alpha.
*   Default value: 255
*
* Float:holdtime
*   Float:fadeintime
*   Time to fade in message
*   Default value: 0.1
*
* Float:fadeouttime
*   Time to fade out message
*   Default value: 0.1
*
* channel
*   Textchannel
*   -1 = auto choose.
*   Default value: -1
*
* effect
*   Effect of message.
*   1 = Flicker with 2nd color.
*   2 = Print out as 2nd color, fade into 1st color.
*     effecttime decides fade time between colors.
*     fadeintime decides how fast the letters should be printed out.
*   Default value: 0
*
* effect_R
*   Red color of effect.
*   Default value: 0
*
* effect_G
*   Green color of effect.
*   Default value: 0
*
* effect_B
*   Blue color of effect.
*   Default value: 0
*
* effect_A
*   Alpha of effect.
*   Default value: 255
*
* Float:effecttime
*   Only for effect 2.
*   Default value: 0.0
*/

stock send_hudmessage(id,text[],Float:X,Float:Y,R,G,B,A=255,Float:holdtime=5.0,Float:fadeintime=0.1,Float:fadeouttime=0.1,channel=-1,effect=0,effect_R=0,effect_G=0,effect_B=0,effect_A=255,Float:effecttime=0.0) {
   
    if ( id )
        message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, {0,0,0}, id);
    else
        message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
    write_byte(TE_TEXTMESSAGE)
    write_byte(channel)
    write_short(coord_to_hudmsgshort(X))
    write_short(coord_to_hudmsgshort(Y))
    write_byte(effect)
    write_byte(R)  
    write_byte(G)
    write_byte(B)
    write_byte(A)
    write_byte(effect_R)
    write_byte(effect_G)
    write_byte(effect_B)
    write_byte(effect_A)
    write_short(seconds_to_hudmsgshort(fadeintime))
    write_short(seconds_to_hudmsgshort(fadeouttime))
    write_short(seconds_to_hudmsgshort(holdtime))
    if ( effect == 2 )
        write_short(seconds_to_hudmsgshort(effecttime));
    write_string(text)
    message_end()
}

/* 0.0 - 255.99609375 seconds */
stock seconds_to_hudmsgshort(Float:sec) {
    new output = floatround(sec * 256);
    return output < 0 ? 0 : output > 65535 ? 65535 : output;
}

stock coord_to_hudmsgshort(Float:coord) {
    new output = floatround(coord * 8192);
    return output < -32768 ? -32768 : output > 32767 ? 32767 : output;
}
Взято отсюда
https://forums.alliedmods.net/showthread.php?t=69263
 
Последнее редактирование модератором:
Сообщения
2,389
Реакции
2,459
Помог
56 раз(а)
Автоматическое дополнение-расширение регистрируемых команд до полного списка.
Авто-расширение команд.png
Код:
const MAX_CMD_LEN = 32;

new const g_szCmds[] = "menu, vipmenu";
new const szPreCmd[][] = {"say ", "say_team ", ""};
new const szCtrlChar[][] = {"!", "/", "\", "." , ""};
new const FUNC_NAME[] = "Show_Menu";

Init_Cmds()
{
    if(strlen(g_szCmds))
    {
        for(new i; i < sizeof(szPreCmd); i++)
        {
            for(new k; k < sizeof(szCtrlChar); k++)
            {
                new szCmd[MAX_CMD_LEN], ePos, stPos, rawPoint[32];

                do
                {
                    ePos = strfind(g_szCmds[stPos],",");
                    formatex(rawPoint, ePos, g_szCmds[stPos]);
                    stPos += ePos + 1;
 
                    trim(rawPoint);
 
                    if(rawPoint[0])
                    {
                        formatex(szCmd, charsmax(szCmd),
                            "%s%s%s",
                            szPreCmd,
                            szCtrlChar[k],
                            rawPoint
                        );
                          
                        register_clcmd(szCmd, FUNC_NAME);
                    }
                }
                while(ePos != -1)
            }
        }
    }
}
27 Авг 2017

Проверка имеет ли файл расширение .mp3
Код:
#define IsMp3Format(%1)    equali( %1[strlen( %1 ) - 4 ], ".mp3" )
27 Авг 2017
Код для визуализации вектора в пространстве.
Код:
#include <amxmodx>
#include <engine>

// #define DEBUG_
// #define _THINK
#define _FASTVIS

const TASK_POINT = 1337;

#if defined DEBUG_

#if !defined _THINK
    public plugin_init()
    register_clcmd("radio1", "test");
    public test(pPlayer)
    #else
    public client_PostThink(pPlayer)
    #endif
    {
        static vOrigin_end[3], vOrigin_start[3];
        get_user_origin(pPlayer, vOrigin_start);            // Start point
        get_user_origin(pPlayer, vOrigin_end, .mode = 3);    // End point

        UTIL_VisualizeVector(
            .vStart = vOrigin_start,
            .vEnd = vOrigin_end,
            .time = 0.1,
            .width = 10
        );

        // return PLUGIN_HANDLED;
    }
#endif    // DEBUG_

new g_pBeamSprite;
new const SPRITE_BEAM[] = "sprites/arrow1.spr";
new const SPRITE_POINT[] = "sprites/3dmflared.spr";

public plugin_precache()
{
    g_pBeamSprite = precache_model(SPRITE_BEAM);
    precache_model(SPRITE_POINT);
}

public UTIL_VisualizeVector(vStart[3], vEnd[3], Float: time, width)
{
    message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
    write_byte(TE_BEAMPOINTS);
    write_coord(vEnd[0]);
    write_coord(vEnd[1]);
    write_coord(vEnd[2]);
    write_coord(vStart[0]);
    write_coord(vStart[1]);
    write_coord(vStart[2]);
    write_short(g_pBeamSprite);
    write_byte(1);            //Стартовый кадр
    write_byte(1);            //Скорость анимации
    write_byte(floatround(time * 10));    //Время существования
    write_byte(width);        //Толщина луча
    write_byte(0);            //Искажение
    write_byte(255);            //Цвет красный
    write_byte(0);            //Цвет зеленый
    write_byte(0);            //Цвет синий
    write_byte(1000);        //Яркость
    write_byte(10);
    message_end();

#if !defined _FASTVIS
    CreatePoint(vStart, .time = time);
    CreatePoint(vEnd, .time = time);
#else
    // Create_Sparks(vStart);
    Create_Sparks(vEnd);
#endif
}

stock CreatePoint(vOrigin[3], Float: time)
{
    static pEnt, Float: fOrigin[3];
    pEnt = create_entity("info_target");
    IVecFVec(vOrigin, fOrigin);

    if(is_valid_ent(pEnt))
    {
        // entity_set_string(pEnt, EV_SZ_classname, "points");
        entity_set_model(pEnt, SPRITE_POINT);
        entity_set_origin(pEnt, fOrigin);
        entity_set_int(pEnt, EV_INT_solid, SOLID_NOT);
        entity_set_int(pEnt, EV_INT_movetype, MOVETYPE_NONE);
        entity_set_float(pEnt, EV_FL_scale, 0.1);
        entity_set_float(pEnt, EV_FL_nextthink, get_gametime());
        entity_set_int(pEnt, EV_INT_rendermode, kRenderTransAdd);
        entity_set_float(pEnt, EV_FL_renderamt, 100.0);
    
        set_task(time, "DeleteEnt", TASK_POINT + pEnt);
    }
}

stock Create_Sparks(vOrigin[3])
{
    message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
    write_byte(TE_SPARKS);
    write_coord(vOrigin[0]);
    write_coord(vOrigin[1]);
    write_coord(vOrigin[2]);
    message_end();
}


public DeleteEnt(pEnt)
{
    pEnt -= TASK_POINT;
    if(is_valid_ent(pEnt))
        remove_entity(pEnt);
}[/SRC]

Пример использования:
[SRC] public client_PostThink(pPlayer)
{
    static vOrigin_end[3], vOrigin_start[3];
    get_user_origin(pPlayer, vOrigin_start);            // Start point
    get_user_origin(pPlayer, vOrigin_end, .mode = 3);    // End point

    UTIL_VisualizeVector(
        .vStart = vOrigin_start,
        .vEnd = vOrigin_end,
        .time = 0.1,
        .width = 10
    );
}
30 Авг 2017


Сток для автоматической регистрации списка команд в зависимости от их типа (cmd, impulse)
Код:
#include <amxmodx>
#include <engine>

new g_szCmds[][] = {
    "radio1",
    "impulse 201",
    "nightvision"
}

new const MENU_CMD[] = "CMD_MenuOpen";

public plugin_init()
{
    RegisterCmds(g_szCmds, sizeof g_szCmds, MENU_CMD);
}

RegisterCmds(szCmds[][], iLen, const szFunction[])
{
    for(new i; i < iLen; i++)
    {
        if(containi(szCmds, "impulse") != -1)
            register_impulse(str_to_num(szCmds[8]), szFunction);
        else
            register_clcmd(szCmds, szFunction);
    }
}

public MyMenu(pPlayer)
    // Hooked
 
Последнее редактирование модератором:

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

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