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

wopox1337

😈 самый злой модератор
Сообщения
2.187
Реакции
2.196
Обсуждаем, выкладываем полезные стоки для скриптера. Делимся решением задач.
 
Сообщения
212
Реакции
235
Код позволяет "использовать" разные энтити объекты (где нет возм. по умолчанию)
Код:
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
 
Сообщения
1.569
Реакции
1.686
Vaqtincha, можно пример где можно использовать это?
 
Сообщения
260
Реакции
254
Последнее редактирование модератором:
Сообщения
1.569
Реакции
1.686
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
Реакции
235
Ну я начал написать сток (уж давно) для реапи. Да там есть полезные (или просто велосипеды) подойдет новичкам так и опытным скриптерам (улучшает читабельности кода и.т.д) Вот пока не хватает описание стоков.
Чтоб использовать подключаем
Код:
#include <reapi_stocks>

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

Вложения

wopox1337

😈 самый злой модератор
Сообщения
2.187
Реакции
2.196
Конвертация секунд (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
 
Сообщения
276
Реакции
213
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 довольно сильно отличается от реального момента взрыва
 
Сообщения
387
Реакции
428
Предупреждения
1
Простой шаблон игроков от 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, "Выбранный Вами игрок отключился от сервера");
}
}
}
 
Последнее редактирование:
Сообщения
212
Реакции
235
Может велосипед
Код:

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
}
 

wopox1337

😈 самый злой модератор
Сообщения
2.187
Реакции
2.196
Макросы для работы с битсуммами
Код:

#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
Реакции
235
Ну вообщем вариант
Код:
#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)
}
 

wopox1337

😈 самый злой модератор
Сообщения
2.187
Реакции
2.196
Получение из строки вида "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)
}
 
Сообщения
276
Реакции
213
Установка бомбы с "правильными" углами

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

Код:
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 за видео
 
Последнее редактирование:
Сообщения
168
Реакции
272
Более кастомный худ, можно задавать цвет для эффекта и прозрачность.
Скриншот 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
 

wopox1337

😈 самый злой модератор
Сообщения
2.187
Реакции
2.196
Автоматическое дополнение-расширение регистрируемых команд до полного списка.
Авто-расширение команд.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

 

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

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