Перевод: DJ_WEST
Введение
AMX Mod X плагин может понимать четыре типа функций:
- public (публичная) - это значит, что данный тип функций виден и доступен движку AMX Mod X.
- native (внутренняя) - функция, которая объявлена или в модуле, или в ядре AMXX.
- регулярная - функция, которая объявлена без всяких атрибутов.
- forward - функция, которая вызывается после того, как произойдет какое-либо действие.
Любой плагин в AMX Mod X должен начинаться с инициализирующей функции:
- Код: Выделить всё
// include - включает native функции из файла includes\amxmodx.inc
#include <amxmodx>
// Определение трех строковых констант
#define PLUGIN "AMXX Demo"
#define AUTHOR "AMX-X.RU"
#define VERSION "1.0"
// Это публичная функция, которая необходимо для инициализации плагина под AMXX.
// У функции нет параметров и она запускается после загрузки карты.
public plugin_init()
{
// Регистрация функции в AMX Mod X и передача некоторой информации (название плагина, его автор и версия)
register_plugin(PLUGIN, VERSION, AUTHOR)
}
Создание админских команд
Существует простой способ добавления админских команд. Каждая команда "регистрируется", как консольная. При регистрации команды необходимо указать четыре опции: название команды; функция, которая эта команда вызывает; необходимый уровень доступа к этой команде и краткое описание команды.
К примеру, попробуем сделать плагин, который будет менять жизнь игроку через консольную команду "amx_hp". Следовательно, нам необходимо зарегистрировать консольную команду и написать функцию, которая будет выполняться после использования данной команды.
- Код: Выделить всё
#include <amxmodx>
#include <amxmisc> // Здесь содержится функция для проверки доступа игрока
#include <fun> // Здесь содержится функция для изменения количества жизни
#define PLUGIN "Change Health"
#define AUTHOR "AMX-X.RU"
#define VERSION "1.0"
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
register_concmd("amx_hp", "cmd_hp", ADMIN_SLAY, "<target>")
}
public cmd_hp(id, level, cid)
{
return PLUGIN_HANDLED
}
Попробуем понять, что же мы сделали. Через функцию "register_concmd" мы зарегистрировали новую консольную команду. Первый аргумент содержит название консольной команды. Второй - указать на public функцию. Третий аргумент - необходимый уровень доступа. Последний - описание для данной команды, которое можно посмотреть, например, через amx_help. Затем мы написали публичную функцию cmd_hp с тремя параметрами. Параметр id содержит id игрока, который запустил данную функцию, level - содержит флаг доступа к команде и cid содержит внутренний id команды.
Поговорим насчет PLUGIN_HANDLED. Есть два основных значения возврата функции, которых вы коснетесь. PLUGIN_CONTINUE - означает "продолжать дальнейшую операцию" и PLUGIN_HANDLED - "блокировать дальнейшую операцию". Различия маленькие, но важные. К примеру, при создании консольной команды вы не должны возвращать PLUGIN_CONTINUE. Но с другой стороны, если вы вернете PLUGIN_HANDLED при создании "say" команды, то это заблокирует сообщение игрока от отображения. Вы должны быть внимательны при использовании данных значений. На большинство вещей возврат никак не влияет (к примеру, task (задачи), events (события) и другие).
Теперь необходимо проверить, что у пользователя есть ADMIN_SLAY доступ:
- Код: Выделить всё
public cmd_hp(id, level, cid)
{
if (!cmd_access(id, level, cid, 3))
return PLUGIN_HANDLED
return PLUGIN_HANDLED
}
Функция cmd_access() проверяет информацию о команде (пользователь, доступ и id) и дает нам убедиться в том, что данный пользователь имеет нужный доступ и через команду передано необходимое количество аргументов. Мы указали 3, потому что команда имеет вид: amx_hp <цель> <количество>. Следовательно, состоит из трех частей (аргументов): amx_hp, цель, количество. Если cmd_access вернул ложный ответ, то мы прекращаем выполнение функции через возвращение PLUGIN_HANDLED.
Следующее, что нам необходимо сделать - это обработать два последних параметра. "Количество" нужно из строкового типа перевести в целочисленный. И параметр "цель", который указывает на игроков из трех типов:
- @CT или @T - CT или T команда
- @ALL - всем
- цель - часть имени игрока
- Код: Выделить всё
public cmd_hp(id, level, cid)
{
if (!cmd_access(id, level, cid, 3))
return PLUGIN_HANDLED
new Arg1[24]
new Arg2[4]
// Получаем аргументы команды из консоли
read_argv(1, Arg1, 23)
read_argv(2, Arg2, 3)
// Конвертируем жизнь из строки в число
new Health = str_to_num(Arg2)
// Проверяем, если первый символ @
if (Arg1[0] == '@')
{
new Team = 0
// Проверяем, какая команда была указана
// Начинаем с элемента [1], потому что символ @ нам не нужен
if (equali(Arg1[1], "CT"))
{
Team = 2
} else if (equali(Arg1[1], "T"))
{
Team = 1
}
new players[32], num
// Функция get_players заполянет переменную players[32]
// существующими id игроков. num - содержит количество существующих игроков.
get_players(players, num)
new i
for (i=0; i<num; i++)
{
if (!Team)
{
// Устанавливаем игроку количество жизни
set_user_health(players[i], Health)
} else {
if (get_user_team(players[i]) == Team)
{
set_user_health(players[i], Health)
}
}
}
} else {
// Находим id игрока, который соответствует указанному части имени
// Аргумент 1 означает, что мы не берем во внимание игроков с флагом иммунитета
new player = cmd_target(id, Arg1, 1)
if (!player)
{
// Показываем сообщение игроку, который выполнил админскую команду
// %s - означает строку
// %d или %i - означает число
// %f - означает число с плавающей точкой
// Например, для правильного отображения строки "Hello %s, I am %d years old"
// ей необходима строка и число
console_print(id, "Sorry, player %s could not be found or targetted!", Arg1)
return PLUGIN_HANDLED
} else {
set_user_health(player, Health)
}
}
return PLUGIN_HANDLED
}
В результате полноценный плагин будет выглядеть так:
- Код: Выделить всё
#include <amxmodx>
#include <amxmisc>
#include <fun>
#define PLUGIN "Change Health"
#define AUTHOR "AMX-X.RU"
#define VERSION "1.0"
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
register_concmd("amx_hp", "cmd_hp", ADMIN_SLAY, "<target> <hp>")
}
public cmd_hp(id, level, cid)
{
if (!cmd_access(id, level, cid, 3))
return PLUGIN_HANDLED
new Arg1[24]
new Arg2[4]
// Получаем аргументы команды из консоли
read_argv(1, Arg1, 23)
read_argv(2, Arg2, 3)
// Конвертируем жизнь из строки в число
new Health = str_to_num(Arg2)
// Проверяем, если первый символ @
if (Arg1[0] == '@')
{
new Team = 0
// Проверяем, какая команда была указана
// Начинаем с элемента [1], потому что символ @ нам не нужен
if (equali(Arg1[1], "CT"))
{
Team = 2
} else if (equali(Arg1[1], "T"))
{
Team = 1
}
new players[32], num
// Функция get_players заполянет переменную players[32]
// существующими id игроков. num - содержит количество существующих игроков.
get_players(players, num)
new i
for (i=0; i<num; i++)
{
if (!Team)
{
// Устанавливаем игроку количество жизни
set_user_health(players[i], Health)
} else {
if (get_user_team(players[i]) == Team)
{
set_user_health(players[i], Health)
}
}
}
} else {
// Находим id игрока, который соответствует указанному части имени
// Аргумент 1 означает, что мы не берем во внимание игроков с флагом иммунитета
new player = cmd_target(id, Arg1, 1)
if (!player)
{
// Показываем сообщение игроку, который выполнил админскую команду
// %s - означает строку
// %d или %i - означает число
// %f - означает число с плавающей точкой
// Например, для правильного отображения строки "Hello %s, I am %d years old"
// ей необходима строка и число
console_print(id, "Sorry, player %s could not be found or targetted!", Arg1)
return PLUGIN_HANDLED
} else {
set_user_health(player, Health)
}
}
return PLUGIN_HANDLED
}
Серверные команды (CVAR)
CVAR - это серверская комнада, к примеру, "mp_startmoney" - это Counter-Strike CVAR, который содержит количество денег, которые игроки будут получать в первом раунде. Вы можете сделать свои cvar, зарегистрировав их в plugin_init(). Давайте попробуем сделать аналог mp_startmoney.
- Код: Выделить всё
#include <amxmodx>
#include <cstrike>
public plugin_init()
{
register_plugin("CVAR Test", "1.0", "AMX-X.RU")
// 500 - это значение по умолчанию
register_cvar("amx_startmoney", "500")
}
// Вызывается после того, как игрок успешно зашел на сервер
public client_putinserver(id)
{
if (get_cvar_num("amx_startmoney") > 0)
{
cs_set_user_money(id, get_cvar_num("amx_startmoney"))
} else {
cs_set_user_money(id, get_cvar_num("mp_startmoney"))
}
}
Данный плагин может не работать, потому что это всего лишь пример. В качестве значений cvar можно использовать числа, числа с плавающей точкой и строки.