> > > >

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

Сообщения
260
Рейтинг
267
#21
Код для плавного затемнения экрана игроку и такого же плавного возвращения яркости спустя определённое время. Автор кода - [email protected]

Код:
// Пример использования
MessageScreenFade(pTarget, FADE_IN_TIME, FADE_HOLD_TIME, FADE_OUT_TIME, FADE_COLOR, FADE_ALPHA);

Код:
// Сам код:
#define FADE_IN_TIME 2.0
#define FADE_HOLD_TIME 6.0
#define FADE_OUT_TIME 4.0
#define FADE_TIME (FADE_IN_TIME + FADE_HOLD_TIME + FADE_OUT_TIME)
#define FADE_COLOR 0, 0, 0 // цвет экрана игрока в RGB формате (по умолчанию 0, 0, 0)
#define FADE_ALPHA 255 // уровень непрозрачности экрана игрока (по умолчанию 255)
#define MESSAGE_SCREEN_FADE 98
#define FFADE_OUT 0x0001
#define FFADE_IN 0x0000

enum _:DATA_SCREENFADE_SIZE
{
Float:DSS_OutTime,
DSS_Red,
DSS_Green,
DSS_Blue,
DSS_Alpha
}

MessageScreenFade(const id, const Float:fInTime, const Float:fHoldTime, const Float:fOutTime, const iRed, const iGreen, const iBlue, const iAlpha)
{
message_begin(MSG_ONE, MESSAGE_SCREEN_FADE, _, id);
write_short(min(floatround(fInTime * 4096), 65535)); // в данном случае, short - это word, максимум ~16 секунд (без 1/4096)
write_short(65535);
write_short(FFADE_OUT);
write_byte(iRed);
write_byte(iGreen);
write_byte(iBlue);
write_byte(iAlpha);
message_end();
new aData[DATA_SCREENFADE_SIZE];
aData[DSS_OutTime] = _:fOutTime;
aData[DSS_Red] = iRed;
aData[DSS_Green] = iGreen;
aData[DSS_Blue] = iBlue;
aData[DSS_Alpha] = iAlpha;
set_task(fInTime + fHoldTime, "MessageScreenFadeOut", id, aData, sizeof aData);
}

public MessageScreenFadeOut(const aData[DATA_SCREENFADE_SIZE], const id)
{
message_begin(MSG_ONE, MESSAGE_SCREEN_FADE, _, id);
write_short(min(floatround(aData[DSS_OutTime] * 4096), 65535)); // в данном случае, short - это word, максимум ~16 секунд (без 1/4096)
write_short(0);
write_short(FFADE_IN);
write_byte(aData[DSS_Red]);
write_byte(aData[DSS_Green]);
write_byte(aData[DSS_Blue]);
write_byte(aData[DSS_Alpha]);
message_end();
}
 
7  
Сообщения
1.869
Рейтинг
1645
#22
Полоса загрузки из CS:CZ при Analyzing'е ботами карты.
upload_2017-11-14_6-8-6.png
wopox1337 написал(а):
Это сообщение посылается клиентам, когда zBot появляются на новой для них карте и начинают её изучать. Он отображает прогресс-бар в центре экрана, с текстом заголовка. Бар не двигается, и ты ничего не можешь сделать, когда откроется бар. Это другой стиль бар прогресса, в отличии от BarTime события. Это действительно не адекватно отображается в CS.
Код:

#include <amxmodx>

new g_MsgId_ProgressBar;

enum { // From ReGameDLL
BOT_PROGGRESS_DRAW = 0, // draw status bar progress
BOT_PROGGRESS_START, // init status bar progress
BOT_PROGGRESS_HIDE, // hide status bar progress
};

public plugin_precache()
precache_generic("resource/ui/CSProgressBar.res");

public plugin_init() {
g_MsgId_ProgressBar = get_user_msgid("BotProgress");
register_clcmd("radio1", "test");
}

public test(pPlayer) {
Show_ProgressBar(pPlayer, .szHeader = "Hello World to Dev-CS.ru wopox1337");
return PLUGIN_HANDLED;
}

// https://github.com/s1lentq/ReGameDLL_CS/blob/9374fced908d64d8dbc90c878605925b151078fa/regamedll/dlls/bot/cs_bot_learn.cpp#L146-L168
stock Show_ProgressBar(pPlayer = 0, iState = BOT_PROGGRESS_DRAW, iProgress = 50, szHeader[] = "NULL") {
emessage_begin(pPlayer ? MSG_ONE_UNRELIABLE : MSG_BROADCAST, g_MsgId_ProgressBar, .player = pPlayer);
ewrite_byte(iState);
ewrite_byte(iProgress);
ewrite_string(szHeader);
emessage_end();
}

Структура: https://wiki.alliedmods.net/Half-life_1_game_events#BotProgress

Благодарность Adidasman за подсказку с .res файлом.

P.S: Проанимировать конечно, при сильном желании, можно и текст в заголовке поможет пользователям понять в чём дело :derisive:
И, будьте осторожны с использованием, игрок не сможет закрыть его сам, пока не перезайдёт. :negative:
 

Вложения

Последнее редактирование:
Сообщения
260
Рейтинг
301
#23
Поддержка colorchat.inc для AMXX < 1.8.3
Авторы: AMXX Community & Lev​
Код:
#if defined _colorchat_included
#endinput
#endif
#define _colorchat_included

/* ColorChat Support */
#define NORMAL DontChange
#define GREEN DontChange
#define RED Red
#define BLUE Blue
#define GREY Grey
#define ColorChat client_print_color

#define MAX_TRANSLATION_LENGTH 2048

enum {
DontChange = 0,
Grey = -1,
Red = -2,
Blue = -3
};

#define print_team_default DontChange
#define print_team_grey Grey
#define print_team_red Red
#define print_team_blue Blue

stock client_print_color(id, sender, const fmt[], any:...)
{
// check if id is different from 0
if (id && !is_user_connected(id))
{
return 0;
}

if (sender < Blue || sender > 32)
{
sender = DontChange;
}
else if (sender < DontChange)
{
sender = -sender + 32; // align indexes to the TeamInfo ones
}

static const szTeamName[][] =
{
"",
"TERRORIST",
"CT"
};

new szMessage[191];

new iParams = numargs();

// Specific player code
if (id)
{
if (iParams == 3)
{
copy(szMessage, charsmax(szMessage), fmt); // copy so message length doesn't exceed critical 192 value
}
else
{
vformat(szMessage, charsmax(szMessage), fmt, 4);
}

if (sender > (32 - Grey))
{
if (sender > (32 - Blue))
{
sender = id;
}
else
{
_CC_TeamInfo(id, sender, szTeamName[sender - (32 - Grey)]);
}
}
_CC_SayText(id, sender, szMessage);
}

// Send message to all players
else
{
// Figure out if at least 1 player is connected
// so we don't execute useless useless code if not
new iPlayers[32], iNum;
get_players(iPlayers, iNum, "ch");
if (!iNum)
{
return 0;
}

new iMlNumber, i, j;
new Array:aStoreML = ArrayCreate();
if (iParams >= 5) // ML can be used
{
for (j = 3; j < iParams; j++)
{
// retrieve original param value and check if it's LANG_PLAYER value
if (getarg(j) == LANG_PLAYER)
{
i = 0;
// as LANG_PLAYER == -1, check if next parm string is a registered language translation
while ((szMessage = getarg(j + 1, i++))) {}
if (GetLangTransKey(szMessage) != TransKey_Bad)
{
// Store that arg as LANG_PLAYER so we can alter it later
ArrayPushCell(aStoreML, j++);

// Update ML array saire so we'll know 1st if ML is used,
// 2nd how many args we have to alterate
iMlNumber++;
}
}
}
}

// If arraysize == 0, ML is not used
// we can only send 1 MSG_ALL message if sender != 0
if (!iMlNumber)
{
if (iParams == 3)
{
copy(szMessage, charsmax(szMessage), fmt);
}
else
{
vformat(szMessage, charsmax(szMessage), fmt, 4);
}
if (0 < sender < (32 - Blue)) // if 0 is passed, need to loop
{
if (sender > (32 - Grey))
{
_CC_TeamInfo(0, sender, szTeamName[sender - (32 - Grey)]);
}
_CC_SayText(0, sender, szMessage);
return 1;
}
}

if (sender > (32 - Blue))
{
sender = 0; // use receiver index
}

for (--iNum; iNum >= 0; iNum--)
{
id = iPlayers[iNum];

if (iMlNumber)
{
for (j = 0; j < iMlNumber; j++)
{
// Set all LANG_PLAYER args to player index ( = id )
// so we can format the text for that specific player
setarg(ArrayGetCell(aStoreML, j), _, id);
}

// format string for specific player
vformat(szMessage, charsmax(szMessage), fmt, 4);
}

if (sender > (32 - Grey))
{
_CC_TeamInfo(id, sender, szTeamName[sender - (32 - Grey)]);
}
_CC_SayText(id, sender, szMessage);
}

ArrayDestroy(aStoreML);
}
return 1;
}

stock _CC_TeamInfo(iReceiver, iSender, szTeam[])
{
static iTeamInfo = 0;
if (!iTeamInfo)
{
iTeamInfo = get_user_msgid("TeamInfo");
}
message_begin(iReceiver ? MSG_ONE : MSG_ALL, iTeamInfo, _, iReceiver);
write_byte(iSender);
write_string(szTeam);
message_end();
}

stock _CC_SayText(iReceiver, iSender, szMessage[])
{
static iSayText = 0;
if (!iSayText)
{
iSayText = get_user_msgid("SayText");
}

// Prevent sending format and localization strings via chat
for (new i = 0; i < 192; i++)
{
if (szMessage == 0) break;
if (szMessage == '%' ||
szMessage == '#')
szMessage = ' ';
}

message_begin(iReceiver ? MSG_ONE : MSG_ALL, iSayText, _, iReceiver);
write_byte(iSender ? iSender : iReceiver);
if (szMessage[0] > 4)
{
write_byte(1);
szMessage[192 - 2 - 1] = 0; // Two write_byte + string terminator
write_string(szMessage);
}
else
{
szMessage[192 - 1 - 1] = 0; // One write_byte + string terminator
write_string(szMessage);
}
message_end();
}

new _translation_szBuffer[MAX_TRANSLATION_LENGTH];

stock register_dictionary_colored(const filename[])
{
if (!register_dictionary(filename))
{
return 0;
}

new szFileName[256];
get_localinfo("amxx_datadir", szFileName, charsmax(szFileName));
format(szFileName, charsmax(szFileName), "%s/lang/%s", szFileName, filename);
new fp = fopen(szFileName, "rt");
if (!fp)
{
log_amx("Failed to open %s", szFileName);
return 0;
}

new szLang[3], szKey[64], TransKey:iKey;

while (!feof(fp))
{
fgets(fp, _translation_szBuffer, charsmax(_translation_szBuffer));
trim(_translation_szBuffer);

if (_translation_szBuffer[0] == '[')
{
strtok(_translation_szBuffer[1], szLang, charsmax(szLang), _translation_szBuffer, 1, ']');
}
else if (_translation_szBuffer[0])
{
strbreak(_translation_szBuffer, szKey, charsmax(szKey), _translation_szBuffer, charsmax(_translation_szBuffer));
iKey = GetLangTransKey(szKey);
if (iKey != TransKey_Bad)
{
replace_all(_translation_szBuffer, charsmax(_translation_szBuffer), "!g", "^4");
replace_all(_translation_szBuffer, charsmax(_translation_szBuffer), "!t", "^3");
replace_all(_translation_szBuffer, charsmax(_translation_szBuffer), "!n", "^1");
replace_all(_translation_szBuffer, charsmax(_translation_szBuffer), "^^4", "^4");
replace_all(_translation_szBuffer, charsmax(_translation_szBuffer), "^^3", "^3");
replace_all(_translation_szBuffer, charsmax(_translation_szBuffer), "^^1", "^1");
replace_all(_translation_szBuffer, charsmax(_translation_szBuffer), "^^n", "^n");
replace_all(_translation_szBuffer, charsmax(_translation_szBuffer), "^^t", "^t");
AddTranslation(szLang, iKey, _translation_szBuffer[2]);
}
}
}

fclose(fp);
return 1;
}

/* ML from AMXX 1.8.3 support */
#define register_dictionary register_dictionary_colored


Использование:
Для поддержки AMXX < 1.8.3 требуется в начало файла (после #include <amxmodx>) добавить данные строки кода.
Тогда, если натив client_print_color не был зарегистрирован ранее - он подхватится из внешнего инклуда.
Код:
#if !defined client_print_color
#include <colorchat>
#endif


Источник:
http://aghl.ru/webcompiler/include/colorchat.inc
 

Вложения

Последнее редактирование модератором:
6  
Сообщения
269
Рейтинг
87
#24
Блокирует звуки в начале раунда: LetsGo, Go Go Go, и т.д
Код:
#include <amxmodx>

new bool:bCanHear

public plugin_init()
{
register_plugin("", "", "")

register_event("HLTV", "OnNewRound", "a", "1=0", "2=0")
register_logevent("OnRoundStart",2, "1=Round_Start")

register_message(get_user_msgid("SendAudio"), "OnSendAudio")
}

public OnNewRound()
{
bCanHear = false
}

public OnRoundStart()
{
remove_task(6153)
set_task(1.0, "TaskEnableRadio", 6153)
}

public OnSendAudio()
{
if(!bCanHear) return PLUGIN_HANDLED;

return PLUGIN_CONTINUE;
}

public TaskEnableRadio()
{
bCanHear = true
}

Блокирует звуки и сообщения побед: Террористы победили, Контр-Террористы победили, и т.д
https://github.com/Jessyy/amxx-plugins-sma/blob/master/addons/amxmodx/scripting/block_t_ct_win.sma
Код:
#include <amxmodx>

public plugin_init()
{
register_plugin("Block T/CT Win Sounds/Msg", "1.0.0", "X");

register_message(get_user_msgid("TextMsg"), "message_textmsg");
register_message(get_user_msgid("SendAudio"), "message_sendaudio");
}

public message_textmsg(msg_id, msg_dest, msg_entity)
{
static message[3];
get_msg_arg_string(2,message,sizeof message - 1);

switch(message[1]) {
// -- #CTs_Win ; #Terrorists_Win ; #Round_Draw
case 'C', 'T', 'R' : return PLUGIN_HANDLED;
}

return PLUGIN_CONTINUE;
}

public message_sendaudio(msg_id, msg_dest, msg_entity)
{
static message[10];
get_msg_arg_string(2,message,sizeof message - 1);

switch(message[7]) {
// -- %!MRAD_terwin ; %!MRAD_ctwin ; %!MRAD_rounddraw
case 'c', 't', 'r' : return PLUGIN_HANDLED;
}

return PLUGIN_CONTINUE;
}
 
2  
Сообщения
198
Рейтинг
156
#25
REVO, нельзя блочить все SendAudio, там есть много чего помимо радио.
 
 
Сообщения
268
Рейтинг
248
#27
Сброс статистики определенного числа, через указанное кол-во месяцев.
Берется текущий месяц и проверяется остаток деления текущего месяца на AUTORESET_MONTH.

C++:
const AUTORESET_DAY   = 1;     // Какого числа делать сброс статистики
const AUTORESET_MONTH = 3;     // Через сколько месяцев делать сброс

AutoStatsReset()
{
    new szMonth[10];
    get_time("%m", szMonth, charsmax(szMonth));

    new iMonth = str_to_num(szMonth);

    new iResidue = iMonth % AUTORESET_MONTH;

    if(iResidue == 0)
    {
        new szDay[10], iDay;
        get_time("%d", szDay, charsmax(szDay));

        iDay = str_to_num(szDay);

        if(iDay == AUTORESET_DAY)
        {        
            new szData[10];
            szData[0] = 0;
            get_vaultdata("stats_clear", szData, charsmax(szData));

            if(!str_to_num(szData))
            {
                // для mysql статы жеталательно добавить проверку на соединение с бд
                set_vaultdata("stats_clear", "1");
                // Код для очистки статы
            }      
        } else {
            set_vaultdata("stats_clear","0");  
        }
    }
}
 
4  
Сообщения
32
Рейтинг
51
#28
C++:
//example: getarg_string(0/*arg*/, buffer, charsmax(buffer));
#define getarg_string(%0,%1,%2) \
    for (new i = 0; i <= %2; i++) \
        if ((%1[i] = getarg(%0, i)) == EOS) break
Макрос для получения строки в стоковых функциях с динамическим числом параметров.
P.S.: Для тех кто не в курсе, стоковые функции тоже могут иметь динамическое число параметров, как при регистрации нативов. Для этого в Pawn есть функции getarg и numargs, но getarg не отдает строку в виде готового массива, в этом как раз и поможет данный макрос.
 
2  
Сообщения
22
Рейтинг
28
#29
wopox1337, I think we can use like this;

Код:

#include <amxmodx>

new g_MsgId_ProgressBar;
new textg[100];


public plugin_precache()
precache_generic("resource/ui/CSProgressBar.res");

public plugin_init() {
g_MsgId_ProgressBar = get_user_msgid("BotProgress");
register_clcmd("say test", "test");
}

public test(pPlayer) {
formatex(textg,charsmax(textg),"Match is beginning...")
Show_ProgressBar(15);
set_task(5.0,"changetext1");
set_task(10.0,"changetext2");
set_task(13.0,"changetext3");
return PLUGIN_HANDLED;
}
public changetext1(){
formatex(textg,charsmax(textg),"Settings are updating for match.");
}
public changetext2(){
formatex(textg,charsmax(textg),"Settings are ready.");
}
public changetext3(){
formatex(textg,charsmax(textg),"Be ready.");
}
public Show_ProgressBar(ttime) {
static i;
if(ttime != i){
new bartime = 100/ttime*i
emessage_begin(MSG_BROADCAST, g_MsgId_ProgressBar, .player = 0);
ewrite_byte(0);
ewrite_byte(bartime);
ewrite_string(textg);
emessage_end();
i++
set_task(1.0,"Show_ProgressBar",ttime)
}
else{
Close_ProgressBar()
i=0;
//another commands
}
}
public Close_ProgressBar(){
emessage_begin(MSG_BROADCAST, g_MsgId_ProgressBar, .player = 0);
ewrite_byte(2);
emessage_end();
}
 
1  
Сообщения
5
Рейтинг
6
#30
Простой шаблон игроков от Subb98, основным отличием которого является построения меню игроков с использованием уникального идентификатора UserID, который позволяет избежать недочет с неверным выбором игрока (случай носит исключающий характер, но тем не менее довольно встречающийся. При открытии меню игроков администратор может не надолго задержать его открытым или затратить некое время на поиск нужного игрока, тем временем данный игрок может выйти из сервера и на место его ID встать другой ID игрока, таким образом мы выбираем одного игрока для удаления, а удаляется другой игрок. По-своему опыту 1-3 случая за неделю точно).

И небольшая модификация от меня, которая требовалась под свои нужды.
  • Главный администратор (ADMIN_RCON) имеет право выбрать любого игрока, включая самого себя.
  • Простой администратор (ADMIN_BAN) имеет право выбрать любого игрока (включая иммунитированного), кроме главного администратора, самого себя и администраторов себе подобных (ADMIN_BAN).
  • Все иммунитированные игроки отмечаются с желтой звездочкой возле никнейма
  • Самого себя видно с красной звездочкой возле никнейма
  • Те игроки, которых выбрать невозможно выделяются серым цветом и желтой звездочкой возле никнейма, дабы тоже имеют своего рода "иммунитет" от выбора.
C++:
#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, "Выбранный Вами игрок отключился от сервера");
}
}
}
Код:
g_UserID[id] = get_user_userid(i);
--->
Код:
g_UserID[id][i] = get_user_userid(i);
 
2  
Сообщения
37
Рейтинг
54
#31
Сообщение для отображения визуальных эффектов погоды (ReceiveW).
C:
enum
{
    WEATHER_NONE = 0,
    WEATHER_RAIN,
    WEATHER_SNOW
}

stock UTIL_Weather(id, iMode, bool:bReliable = false)
{
    static iMsgReceiveW
    if(!iMsgReceiveW) iMsgReceiveW = get_user_msgid("ReceiveW")
    
    if(bReliable) message_begin(id ? MSG_ONE : MSG_ALL, iMsgReceiveW, _, id)
    else message_begin(id ? MSG_ONE_UNRELIABLE : MSG_BROADCAST, iMsgReceiveW, _, id)
    write_byte(iMode)
    message_end()
}
 
4  
Сообщения
84
Рейтинг
95
#32
Проверка видимости при помощи 5 случайных трассировок(видимость зависит от случайности, 2 вызова стока могут вернуть разный результат на статичных обьектах в случае видимости очень маленького кусочка обьекта) из HLSDK(только без проверки waterlevel)
Код:
stock bool:FBoxVisible(const looker, const target, Float:hit_origin[3], const Float:size = 0.0) {
    new tr = create_tr2()
    new Float:looker_origin[3], Float:looker_view_ofs[3]
    pev(looker, pev_origin, looker_origin)
    pev(looker, pev_view_ofs, looker_view_ofs)
    xs_vec_add(looker_origin, looker_view_ofs, looker_origin)

    for (new i; i < 5; i++) {
       new Float:target_origin[3], Float:target_mins[3], Float:target_maxs[3]
       pev(target, pev_origin, target_origin)
       pev(target, pev_mins, target_mins)
       pev(target, pev_maxs, target_maxs)
       target_origin[0] += random_float(target_mins[0] + size, target_maxs[0] + size)
       target_origin[1] += random_float(target_mins[1] + size, target_maxs[1] + size)
       target_origin[2] += random_float(target_mins[2] + size, target_maxs[2] + size)

       engfunc(EngFunc_TraceLine, looker_origin, target_origin, 1 | 0x100 /* ignore_monsters | ignoreGlass */, looker, tr)
       new Float:fraction
       get_tr2(tr, TR_flFraction, fraction)
       if (fraction == 1.0) {
           xs_vec_copy(target_origin, hit_origin)
           free_tr2(tr)
           return true
       }
    }

    free_tr2(tr)
    return false
}
А также небольшая функция из HLSDK
Код:
stock MakeAimVectors(const Float:in_angles[3]) {
    new Float:angles[3]
    xs_vec_copy(in_angles, angles)

    angles[0] = -angles[0]
    engfunc(EngFunc_MakeVectors, angles)
}
 
1  
Сообщения
1.869
Рейтинг
1645
#33
Код для генерации строки с набором случайных букв.
Автор: Mistrick
Код:
generate_string(str[], len)
{
  for(new i; i < len; i++)
  {
    switch(random(3))
    {
      case 0: str[i] = random_num('A', 'Z');
      case 1: str[i] = random_num('a', 'z');
      case 2: str[i] = random_num('0', '9');
    }
  }
  str[len] = 0;
}
 
Последнее редактирование:
5  
Сообщения
1.869
Рейтинг
1645
#34
Сток подготовит кол-во секунд для отправки в message клиента write_short значения.
Код:
stock FixedUnsigned16(Float:flValue, iScale = (1 << 12)) {
    return clamp(floatround(flValue * iScale), 0, 0xFFFF);
}
Из примеров использования можно привести:
1) реализация HUD сообщений в AMXX, время указываем в секундах при использовании натива.
2) в различных нормальных плагинах (к примеру ScrrenFade, ScreenShade и прочих).
10 Апр 2018
Проверка находится ли игрок в ослеплении, для ReAPI.
Код:
stock bool: IsBlind(pPlayer) {
    return bool:(Float: get_member(pPlayer, m_blindStartTime) + Float: get_member(pPlayer, m_blindFadeTime) >= get_gametime());
}
10 Апр 2018
Автор кода: Vaqtincha
Код убирает всю отдачу (Recoil + Spray) для всех оружий.

Код:
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>


const SECONDARY_WPN_BS = ((1<<CSW_P228)|(1<<CSW_ELITE)|(1<<CSW_FIVESEVEN)|(1<<CSW_USP)|(1<<CSW_GLOCK18)|(1<<CSW_DEAGLE))
const EXP_WPN_BS = ((1<<CSW_HEGRENADE)|(1<<CSW_SMOKEGRENADE)|(1<<CSW_FLASHBANG)|(1<<CSW_KNIFE)|(1<<CSW_C4))
const SNIPER_WPN_BS = ((1<<CSW_AWP)|(1<<CSW_SCOUT)|(1<<CSW_SG550)|(1<<CSW_G3SG1))

const m_pPlayer = 41
const m_iFOV = 363
const random_seed = 96
const m_flAccuracy = 62
const m_flLastFire = 63
const m_iShotsFired = 64
const m_iId = 43

const XO_WEAPON = 4

#define MAX_CLIENTS     32
new Float:g_vecPunchAngle[MAX_CLIENTS + 1][3], Float:g_vecVelocity[MAX_CLIENTS + 1][3]


public plugin_init()
{
    register_plugin("Patch Accuracy", "0.2", "Vaqtincha")

    for(new szWeaponName[17], iId = CSW_P228; iId <= CSW_P90; iId++)
    {
        if(!(EXP_WPN_BS & (1 << iId)) && get_weaponname(iId, szWeaponName, charsmax(szWeaponName)))
        {
            RegisterHam(Ham_Weapon_PrimaryAttack, szWeaponName, "CBasePlayerWeapon_PrimAttack", false)
            RegisterHam(Ham_Weapon_PrimaryAttack, szWeaponName, "CBasePlayerWeapon_PrimAttackP", true)
        }
    }
}

public CBasePlayerWeapon_PrimAttackP(const pWeapon)
{
    if(pWeapon <= 0)
        return

    new pPlayer = get_pdata_cbase(pWeapon, m_pPlayer, XO_WEAPON)
    if(pPlayer > 0)
    {
        set_pev(pPlayer, pev_punchangle, g_vecPunchAngle[pPlayer])

        if(g_vecVelocity[pPlayer][0] && g_vecVelocity[pPlayer][0] && g_vecVelocity[pPlayer][0])
        {
            set_pev(pPlayer, pev_velocity, g_vecVelocity[pPlayer])
            set_pev(pPlayer, pev_fov, float(get_pdata_int(pPlayer, m_iFOV)))
            set_pev(pPlayer, pev_flags, pev(pPlayer, pev_flags) & ~(FL_ONGROUND|FL_DUCKING))

            g_vecVelocity[pPlayer][0] = g_vecVelocity[pPlayer][1] = g_vecVelocity[pPlayer][2] = 0.0
        }
    }
}

public CBasePlayerWeapon_PrimAttack(const pWeapon)
{
    if(pWeapon <= 0)
        return

    new pPlayer = get_pdata_cbase(pWeapon, m_pPlayer, XO_WEAPON)
    if(pPlayer > 0)
    {
        pev(pPlayer, pev_punchangle, g_vecPunchAngle[pPlayer])
        set_pdata_int(pPlayer, random_seed, 0)

        new iId = get_pdata_int(pWeapon, m_iId, XO_WEAPON)
        if(SECONDARY_WPN_BS & (1 << iId))
        {
            set_pdata_float(pWeapon, m_flLastFire, 0.0, XO_WEAPON)
            set_pdata_float(pWeapon, m_flAccuracy, 1.0, XO_WEAPON)
        }
        else if(SNIPER_WPN_BS & (1 << iId))
        {
            pev(pPlayer, pev_velocity, g_vecVelocity[pPlayer])

            set_pev(pPlayer, pev_flags, pev(pPlayer, pev_flags) | (FL_ONGROUND|FL_DUCKING))
            set_pev(pPlayer, pev_velocity, Float:{0.0, 0.0, 0.0})
            set_pev(pPlayer, pev_fov, 40.0)

            if(iId == CSW_SG550 || iId == CSW_G3SG1)
            {
                set_pdata_float(pWeapon, m_flLastFire, 0.0, XO_WEAPON)
                set_pdata_float(pWeapon, m_flAccuracy, 1.0, XO_WEAPON)
            }
        }
        else
        {
            set_pdata_int(pWeapon, m_iShotsFired, 0, XO_WEAPON)
            set_pdata_float(pWeapon, m_flAccuracy, 0.0, XO_WEAPON)
        }
    }
}
 
Последнее редактирование:
4  
Сообщения
1.869
Рейтинг
1645
#35
Регулировка прозрачности игрока в зависимости от скорости.
Зачастую такого рода эффект наблюдал в плагинах для ZombieMod и FurienMod.
Простой код с примерами использования: (какие нативы использовать, и где именно - решать уж вам)
Код:
#include <amxmodx>
#include <engine>

new MIN_TRANS;
new Float: SPEED_SENSETIVE;
new Float: INVISIBLE_FACTOR;
new Float: TRANSPARENCY;

public plugin_init()
{
    register_plugin("Transparency by Speed", "0.0.1", "wopox1337");

    new pCvar;
    pCvar = create_cvar("ToS_SpeedSens", "250.0");
    bind_pcvar_float(pCvar, SPEED_SENSETIVE);

    pCvar = create_cvar("ToS_InvisFactor", "2.0");
    bind_pcvar_float(pCvar, INVISIBLE_FACTOR);

    pCvar = create_cvar("ToS_Trans", "255.0");
    bind_pcvar_float(pCvar, TRANSPARENCY);

    pCvar = create_cvar("ToS_Min","25");
    bind_pcvar_num(pCvar, MIN_TRANS);
}

public client_PreThink(pPlayer)
{
    if(!is_user_alive(pPlayer))
        return;

    static Float: fVecVelocity[3];
    entity_get_vector(pPlayer, EV_VEC_velocity, fVecVelocity);
   
    static Float: fSpeed;
    fSpeed = vector_length(fVecVelocity);

    set_rendering(
        .index      = pPlayer,
        .fx         = kRenderFxNone,
        .render     = kRenderTransAlpha,
        .amount     = get_transparency_by_speed(fSpeed)
    );
}

stock get_transparency_by_speed(Float: fSpeed)
{
    return max(MIN_TRANS, floatround( (fSpeed < SPEED_SENSETIVE) ? fSpeed / INVISIBLE_FACTOR : TRANSPARENCY ));
}
Допускается и такой, упрощённый вариант:

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

public client_PreThink(pPlayer)
{
    if(!is_user_alive(pPlayer))
        return;

    static Float: fVecVelocity[3];
    entity_get_vector(pPlayer, EV_VEC_velocity, fVecVelocity);

    set_rendering(
        .index      = pPlayer,
        .fx         = kRenderFxNone,
        .render     = kRenderTransAlpha,
        .amount     = max( 20, floatround(vector_length(fVecVelocity)))
    );
}
 
Последнее редактирование:
4  
Сообщения
1.869
Рейтинг
1645
#37
fl0wer, спс, поправил.
11 Апр 2018
Выставление свойств видимости объектов индивидуально для игрока (другие не видят).
Код подойдёт, к примеру, для Deathrun серверов, где необходимо некоторые типы entity, такие как ловушки, кнопки и пр. подсвечивать игрокам, купившим услугу с магазина.
Код:
#include <amxmodx>
#include <fakemeta>

stock const CLASSES[][] = {
    "func_door_rotating",
    "func_door",
    "func_breakable",
    "func_button"
}

new Trie: g_tClasses;

public plugin_init() {
    register_forward(FM_AddToFullPack, "AddToFullPack", ._post = true);

    g_tClasses = TrieCreate();

    for(new i; i < sizeof CLASSES; i++)
        TrieSetCell(g_tClasses, CLASSES[i], 0);

// for tests
    register_clcmd("radio2", "toggle");
}

public plugin_end()
    TrieDestroy(g_tClasses);

new bool: gBool[33];
public toggle(pPlayer) {
    gBool[pPlayer] = !gBool[pPlayer];

    return PLUGIN_HANDLED;
}

public AddToFullPack(es, e, ent, host, hostflags, player, pSet) {
    if(!is_user_alive(host) || !gBool[host]) return;

    static szString[19];
    pev(e, pev_classname, szString, charsmax(szString));

    if(TrieKeyExists(g_tClasses, szString))
    {
        set_es_rendering(
            .es = es,
            .fx = kRenderFxGlowShell,
            .color = {255, 0, 0},
            .render = kRenderTransColor,
            .amount = 100
        );
    }
}

stock set_es_rendering(es = 0, fx = kRenderFxNone, color[3] = {255, 255, 255}, render = kRenderNormal, amount = 16) {
    set_es(es, ES_RenderFx, fx);
    set_es(es, ES_RenderColor, color);
    set_es(es, ES_RenderMode, render);
    set_es(es, ES_RenderAmt, amount);
}
 
7  
Сообщения
57
Рейтинг
51
#38
Код для определения времени суток.
Screenshot_1.png
Код:
GetTime()
{
    new szText[24]
    new szTime[32]; get_time("%H", szTime, charsmax(szTime))
    new iTime = str_to_num(szTime)

    switch(iTime)
    {
        case 0..4: szText = "Доброй ночи"
        case 5..11: szText = "Доброе утро"
        case 12..16: szText = "Добрый день"
        case 17..23: szText = "Добрый вечер"
    }
    return szText
}
Пример
Код:
#include <amxmodx>

public plugin_init()
{
    register_clcmd("say 2", "radio1test")
}

public radio1test(iPlayer)
{
    new szTime[32]; get_time("%H", szTime, charsmax(szTime))
    new szText[24]; formatex(szText, charsmax(szText), "%s", GetTime())
    client_print(iPlayer, print_chat, "%s | %d", szText, str_to_num(szTime))

}
    
GetTime()
{
    new szText[24]
    new szTime[32]; get_time("%H", szTime, charsmax(szTime))
    new iTime = str_to_num(szTime)

    switch(iTime)
    {
        case 0..4: szText = "Доброй ночи"
        case 5..11: szText = "Доброе утро"
        case 12..16: szText = "Добрый день"
        case 17..23: szText = "Добрый вечер"
    }
    return szText
}
 
4  
Сообщения
1.869
Рейтинг
1645
#39
Код для запуска hlds сервера в консольном режиме, с сворачиванием дочернего окна на Windows.
SCSS:
START /HIGH  hlds.exe -game cstrike +port 27016 +map de_dust2 +maxplayers 32 -noipx -console
P.S: кто видел лучше варианты - делитесь. Я видел более удобные скрипты, но сейчас не получается их найти...
 

Вложения

4  
Сообщения
1.869
Рейтинг
1645
#40
Fix (костыль) для исправления отображения Unicode-символов в подключаемых #include файлах
iS9v21R[1].png
Автор находки-решения: [email protected].
Де-факто способ решения ошибки компилятора с обработкой Unicode символов в подключаемых инклудах.
NOTE: Данную ошибку уже решили в одном из Pull Request'ов в официальном репозитории AmxModX 1.8.3.
Fix broken UTF8 support. #329 , однако, принимать правки - не спешат.

Как пользоваться? В начале каждого #include файла добавляете комментарий с заведомо не валидным Unicode-символом.
Должно получиться такое:
Код:
// ￿ <- тот самый символ
TestUTF8() {
    client_print(0, print_chat, "Трололо");
}
 

Вложения

Последнее редактирование:
5  

Похожие темы

> > > >