> > > >

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

Сообщения
1.866
Рейтинг
1640
#1
Обсуждаем, выкладываем полезные стоки для скриптера. Делимся решением задач.
 
1  
Сообщения
212
Рейтинг
231
#2
Код позволяет "использовать" разные энтити объекты (где нет возм. по умолчанию)
Код:
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
 
3  
Сообщения
1.008
Рейтинг
954
#3
Vaqtincha, можно пример где можно использовать это?
 
 
Сообщения
260
Рейтинг
267
#5
Последнее редактирование модератором:
5  
Сообщения
1.008
Рейтинг
954
#7
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);
}
}
}
 
3  
Сообщения
212
Рейтинг
231
#8
Ну я начал написать сток (уж давно) для реапи. Да там есть полезные (или просто велосипеды) подойдет новичкам так и опытным скриптерам (улучшает читабельности кода и.т.д) Вот пока не хватает описание стоков.
Чтоб использовать подключаем
Код:
#include <reapi_stocks>

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

Вложения

8  
Сообщения
1.866
Рейтинг
1640
#9
Конвертация секунд (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
 
8  
Сообщения
198
Рейтинг
156
#10
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 довольно сильно отличается от реального момента взрыва
 
2  
Сообщения
280
Рейтинг
319
#12
Простой шаблон игроков от 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, "Выбранный Вами игрок отключился от сервера");
}
}
}
 
Последнее редактирование:
4  
Сообщения
212
Рейтинг
231
#13
Может велосипед
Код:

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
}
 
4  
Сообщения
1.866
Рейтинг
1640
#14
Макросы для работы с битсуммами
Код:

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


Возможно пригодится при разработке.
 
3  
Сообщения
212
Рейтинг
231
#16
Ну вообщем вариант
Код:
#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  
Сообщения
1.866
Рейтинг
1640
#17
Получение из строки вида "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)
}
 
2  
Сообщения
198
Рейтинг
156
#18
Установка бомбы с "правильными" углами

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

Код:
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 за видео
 
Последнее редактирование:
3  
Сообщения
143
Рейтинг
189
#19
Более кастомный худ, можно задавать цвет для эффекта и прозрачность.
Скриншот 24-08-2017 222649.jpg Скриншот 24-08-2017 222657.jpg
HTML:
/*
* 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
 
3  
Сообщения
1.866
Рейтинг
1640
#20
Автоматическое дополнение-расширение регистрируемых команд до полного списка.
Авто-расширение команд.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);
}


Пример использования:
Код:
 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

 
8  

Похожие темы

> > > >