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

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

  1. Код позволяет "использовать" разные энтити объекты (где нет возм. по умолчанию)Vaqtincha
  2. Макрос для проверки на наличие Steam клиента (необходимы Reunion и Reapi)Subb98
  3. Детект броска и взрыва HEGRENADEfantom
  4. ReAPI стоки (reapi_stocks.inc)Vaqtincha
  5. Конвертация секунд (get_systime()) в дни\часы\минутыSergeyShorokhov
  6. Правильное окончание слов после числительных (например 1 час 21 минута)SergeyShorokhov
  7. Шаблон игроков в менюSubb98
  8. Стоки is_plugin_running и get_plugin_stateVaqtincha
  9. Макросы для работы с битсуммамиSergeyShorokhov
  10. Плагин логирования списка энтити на картеSergeyShorokhov
  11. Добавление начала время в начале строке как в нативах логирования AMXXSergeyShorokhov
  12. Получение из строки вида "123 -123 1234" массива с координатами iOrigin[3]SergeyShorokhov
  13. Установка бомбы с "правильными" угламиvoed
  14. Более кастомный худ, можно задавать цвет для эффекта и прозрачностьBlack Rose
  15. Автоматическое дополнение-расширение регистрируемых команд до полного спискаSergeyShorokhov
  16. Проверка имеет ли файл расширение .mp3SergeyShorokhov
  17. Код для визуализации вектора в пространствеSergeyShorokhov
  18. Сток для автоматической регистрации списка команд в зависимости от их типа (cmd, impulse)SergeyShorokhov
  19. Код для плавного затемнения экрана игроку и такого же плавного возвращения яркости спустя определённое время — PRoSToTeM@
  20. Полоса загрузки из CS:CZ при Analyzing'е ботами картыSergeyShorokhov
  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 значенияSergeyShorokhov
  30. Проверка находится ли игрок в ослеплении, для ReAPISergeyShorokhov
  31. Код убирает всю отдачу (Recoil + Spray) для всех оружийVaqtincha
  32. Регулировка прозрачности игрока в зависимости от скоростиSergeyShorokhov
  33. Выставление свойств видимости объектов индивидуально для игрока (другие не видят)SergeyShorokhov
  34. Код для определения времени сутокsteelzzz
  35. Код для запуска hlds сервера в консольном режиме, с сворачиванием дочернего окна на Windows
  36. Fix (костыль) для исправления отображения Unicode-символов в подключаемых #include файлах — PRoSToTeM@
  37. Стоки для возвращения адреса переменной и для записи в память AMXX по указанному адресуthe_hunter
  38. Алгоритм поиска цвета между заданных двух в промежутке от 0 до range в заданной точке valueGarey
  39. Аналог native cs_get_user_buyzone(index) — проверка нахождения игрока в зоне закупкиd3m37r4
    • Это сокращенный вариант (один сток) варианта от Vaqtincha из номера 4
  40. Аналог Float:cs_get_user_lastactivity(index) — проверка последней активности игрокаd3m37r4
  41. Метод чтобы парсить переданные через натив структуры и избежать излишнего дублирования кода (принцип DRY)BoecSpecOPs
  42. Парсинг времени для бана, парсинг цвета в формате HEXfantom
  43. Создание времениfantom
  44. Реверс строкиfantom
  45. Локализация плагинов на один языкthe_hunter
  46. Информация о реализации списков для плагиновBoecSpecOPs
  47. Сток rg_give_item_ex neygomon
  48. Копирование произвольного масива в другой массивBoecSpecOPs
  49. Выдача оружия вместе с боеприпасом, аналог из ReGameDLLSergeyShorokhov
  50. Аналоги DefaultDeploy и SendWeaponAnim с SDKswank
  51. Cпособ использования ArrayFindString для массивовKaido Ren
  52. Вариант блокировки звуков выстрела по умолчаниюfl0wer
  53. Подсчет количества игроков в командахd3m37r4
  54. Функция для конвертации steamid в steamid64, поддерживает не все типы аккаунтовswank
  55. Рандомное деление игроковtwisterniq
  56. Отправка анимации оружияfantom
  57. Замена каждой искомой подстроки в строке с использованием replace_stringexKaido Ren
  58. Отправка сообщения всем игрокам, кроме указанного в параметре indexd3m37r4
  59. Быстрый цикл по игрокамKaido Ren
  60. Получение параметров из bsp картthe_hunter
  61. Функция для получения SteamID3 Steam аккаунтаSergeyShorokhov
  62. Использование switch и case как дефайнKaido Ren
  63. Функция WorldToScreen для Pawn — получение координат HUD текста (xy) из 3D пространстваGarey
  64. Зелёная иконка при смерти (DeathMsg)PWNED // SISA
  65. Используя JSON заносить в массивы координатыSergeyShorokhov
  66. Функция для поиска используемых звуков в моделях и добавление их в прекешthe_hunter
  67. Макрос для проверки есть ли глушитель на оружииArKaNeMaN
  68. Сток для того чтобы только что выданное оружие сделать активнымfantom
  69. Пример открытия стандартного меню закупкиd3m37r4
  70. Вывод информации (цифры) в тысячах (k, M...)Garey
  71. Создание дыма в указанной координатеSergeyShorokhov
  72. Проигрывание ближайшим игрокам дефолтного звука перезарядки оружияRuby
  73. Стоки для удобной регистрации целой пачки похожих командSergeyShorokhov
  74. Реализация дебагаSergeyShorokhov
  75. Просчет бади груп + сабмоделейShel
  76. Запатченный viewer, отображает всю строку(int32) bodyShel
  77. Нормализация спрайта и модели на поверхностиShel
  78. Сток поиска оружия у игрокаfantom
  79. Функция для генерации версии билда в стиле Valve SoftwareGarey
  80. Преобразовывание ячейки в вид float'а без вызовов конструктораShel
  81. Преобразование float в intShel
  82. Эвенты смены команды игрока (API)Shel
  83. Правильное закрытие меню вызывающееся несколько разShel
  84. Функция для проверки пересекает ли линия облако дымаDenzer порт из ReGameDLL
  85. Получение координат точки находящейся на определенном расстоянии от игрока относительно его взглядаd3m37r4
  86. Аналог get_players на ReAPISergeyShorokhov
  87. Код для конвертации ближайшего тона HUE <-> RGBGarey
  88. Способ сменить класснейм у ентити загруженой с картыfantom
  89. Способ выдать кастом оружие (например weapon_bazuka) с помощю rg_give_itemfantom
  90. Удаление оружие по его названию из инвентаря игрокаRuby
  91. Queue на основе ArraySergeyShorokhov
  92. DamageDecal из ReGameDLLRuby
  93. Вывод строки в консоль с более чем 255 символамиSergeyShorokhov
  94. Получение цветов и массива цветов из JSON и пример использованияArKaNeMaN
  95. Получение из строки отдельных символов с поддержкой мнобайтовых символов.ArKaNeMaN
  96. Обёртка для цикла по игрокам, подходящим по указанному условиюSergeyShorokhov
  97. Получение массива индексов игроков, подходящих по указанному условиюSergeyShorokhov
  98. Получение указанного кол-ва индексов случайных игроков, подходящих по указанному условиюSergeyShorokhov
  99. Получение индекса случайного игрока, подходящего по указанному условиюSergeyShorokhov
  100. Сдвиг динамического массива Array на один элемент влевоShel
  101. Пример реализации VK Bot Long Poll API на павнеDenzer
  102. Спавн армори энтитиd3m37r4
  103. Дистанция между игроком/объектом и "потолком" карты либо помещенияAlbertio
  104. Удаление заложников на всех картах или одной конкретной картеMayroN
  105. Удаление дропнутых щипцовMayroN
  106. Добавление/определение ключа перевода (мультиязычности)SergeyShorokhov
  107. Возвращает противоположную игровую командуfl0wer
  108. UTIL_ShowScores() - форсивное отображение таблицы счёта игрокамSergeyShorokhov
  109. Пример реализации аргумента функции с динамическим типом тегом, а так же конвертируемым в нужный тег с помощью tagofSergeyShorokhov
  110. Задание функции определенного времени исполненияufame
  111. Получение количества прошедших дней с указанной даты по сегодняшний деньMayroN
  112. Получение количества прошедших дней с даты по датуMayroN
  113. Удаление комментариев после спец символовufame
  114. Получение длины строки с учётом многобайтовых символовArKaNeMaN
  115. Мигание денег игрока(подобное появляется, когда пытаетесь купить оружие, а денег не хватает)Albertio
  116. Возвращает строку времени до конца срока в днях, часаха, минутах, секундахg3cKpunTop
  117. Удобное решение с кулдаунами. Вернет true если кулдаун обновлен, false если время еще не истеклоg3cKpunTop
  118. Создание newmenus с готовым префиксом в меню и без fmt / formatexg3cKpunTop
  119. Сток меняет автоматически цвет линии в таблице при работе с Motdg3cKpunTop
  120. Получение отдельных разрядов числа и общего кол-ва разрядовAlbertio
  121. Получение всех цифр из строкиArKaNeMaN
  122. Время разговора в микрофон(именно разговора, а не использования микрофона)Albertio
  123. Пример блока шаговd3m37r4
  124. Код дыма от пуль из сурсов клиента cs 1.6t3rkecorejz
  125. Код расширяющего прицела при стрельбеt3rkecorejz
  126. Сток проверит если сейчас выходныеEmma Jule
  127. Макрос для очистки массива с enumNoob_with_cheats
  128. Функция проверяет, видит ли обьект координатыg3cKpunTop
  129. Сток ищет видимые объекты в поле зрения объектаg3cKpunTop
  130. Стоки для проверки находится ли сущность или точка на прицеле игрока, в определенном радиусеkaraulov
  131. Код и модель реалистичной лужи во время дождяMayroN
  132. Сток выполняет плавный блик света(день - ночь)g3cKpunTop
  133. Сток арифметических функцийAlbertio
  134. Сток/обертки над функциями ReAPIb0t.
  135. Cток обнаружения скольжения на сюрфsatanizmov
  136. Сток для установки анимации игроку которая есть в моделиt3rkecorejz
  137. Сток-аналог EngFunc_DropToFloor с возвращением нового значения в вашу переменнуюt3rkecorejz
  138. Сток преобразует число в текст и добавляет спецсимвол между тысячнымиt3rkecorejz
  139. Макросы для работы с векторами. Инициализация вектора, пустой ли векторt3rkecorejz
  140. Макрос проверяет пустая ли строкаt3rkecorejz
  141. Отправляет бартайм с дробным значениемAlbertio
  142. Cток для открытия всех дверейb0t.
  143. Получает индекс команды, которая выигрывает подряд n разAlbertio
  144. Получение оставшегося времени до конца раундаAlbertio
  145. Нумерация ent-объектов для их дальнейшей идентификацииBalbuR
  146. Преобразование угла в матрицу 3х4t3rkecorejz
  147. Кастомные функции обработки строкJavekson
  148. Перемешивание элементов в случайном порядке методом тасования Фишера — ЙетсаJavekson
  149. Функция LerpRuby
  150. Кастомный урон по радиусу с возможностью указывать разные функции зависимости уронаArKaNeMaN
  151. Исправленный сток hex2intNordic Warrior
  152. Стоки для удобного предварительного кеширования файловNordic Warrior
  153. Сток для сканирования директории и получения списка файлов по необходимым критериямJavekson
  154. Порт utf8codepoint из Cufame
  155. Макрос, чтобы определить, является ли символ ASCIIthe_hunter
  156. Разбиение чисел, включая отрицательные, на разряды тысячныхAlbertio
  157. Получения разряда чиселAlbertio
  158. Функции линейной интерполяции для значений и векторов, интерполяцию углов, а также конвертацию вектора в строкуSergeyShorokhov
 
Последнее редактирование модератором:
Сообщения
657
Реакции
562
Предупреждения
8
Помог
9 раз(а)
Код позволяет "использовать" разные энтити объекты (где нет возм. по умолчанию)
Код:
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,491
Реакции
2,794
Помог
61 раз(а)
Vaqtincha, можно пример где можно использовать это?
 
Последнее редактирование модератором:
Сообщения
258
Реакции
262
Помог
5 раз(а)

Макрос для проверки на наличие Steam клиента (необходимы Reunion и Reapi):
Код:
#define is_user_steam(%0) (REU_GetAuthtype(%0) == CA_TYPE_STEAM)
 
Последнее редактирование модератором:
Сообщения
657
Реакции
562
Предупреждения
8
Помог
9 раз(а)
fantom,

Обновил
 

Download all Attachments

Последнее редактирование модератором:
Сообщения
2,491
Реакции
2,794
Помог
61 раз(а)
Не актуально!

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", "F@nt0M");

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);
}
}
}
 
Последнее редактирование модератором:
Сообщения
657
Реакции
562
Предупреждения
8
Помог
9 раз(а)
Ну я начал написать сток (уж давно) для реапи. Да там есть полезные (или просто велосипеды) подойдет новичкам так и опытным скриптерам (улучшает читабельности кода и.т.д) Вот пока не хватает описание стоков.
Чтоб использовать подключаем
Код:
#include <reapi_stocks>

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

Вложения

Сообщения
2,751
Реакции
3,016
Помог
61 раз(а)
Конвертация секунд (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
 
Сообщения
432
Реакции
410
Помог
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", "F@nt0M");

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 довольно сильно отличается от реального момента взрыва
 
Сообщения
657
Реакции
562
Предупреждения
8
Помог
9 раз(а)
Последнее редактирование модератором:
Сообщения
1,032
Реакции
828
Помог
10 раз(а)
Простой шаблон игроков от 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, "Выбранный Вами игрок отключился от сервера");
        }
    }
}
 
Последнее редактирование модератором:
Сообщения
657
Реакции
562
Предупреждения
8
Помог
9 раз(а)
Может велосипед
Код:

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,751
Реакции
3,016
Помог
61 раз(а)
Макросы для работы с битсуммами
Код:

#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);
}


Возможно пригодится при разработке.
 
Сообщения
2,751
Реакции
3,016
Помог
61 раз(а)
Последнее редактирование:
Сообщения
657
Реакции
562
Предупреждения
8
Помог
9 раз(а)
Ну вообщем вариант
Код:
#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,751
Реакции
3,016
Помог
61 раз(а)
Получение из строки вида "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)
}
 
Сообщения
432
Реакции
410
Помог
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 за видео
 
Последнее редактирование:
Сообщения
187
Реакции
319
Помог
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,751
Реакции
3,016
Помог
61 раз(а)
Автоматическое дополнение-расширение регистрируемых команд до полного списка.
Авто-расширение команд.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
 
Последнее редактирование модератором:

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

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