Long-
Мастер
Команды DC_CMD + Sscanf2
Команды в SA:MP существуют для того, чтобы можно было взаимодействовать с сервером.
Покупать оружее и т.п
Пример обработки команд стандартным способом:
PHP:
public OnPlayerCommandText(playerid, cmdtext[])
{
if(strcmp(cmdtext, "/command") == 0)
{
SendClientMessage(playerid, -1, "Вызвана.");
return 1;
}
if(strcmp(cmdtext, "/command1") == 0)
{
SendClientMessage(playerid, -1, "Вызвана.");
return 1;
}
return 0;
}
Но есть другой способ обработки команд: командный процессор DC_CMD
Пример создания команд для DC_CMD:
PHP:
CMD:command (playerid, params[])
{
SendClientMessage(playerid, 0xFFFFFFFF, "Вызвана.");
return 1;
}
CMD:command 1(playerid, params[])
{
SendClientMessage(playerid, 0xFFFFFFFF, "Вызвана.");
return 1;
}
Преимущества DC_CMD:
- Более простой синтаксис команд.
- Команды можно расположить в любом участке скрипта (не только в OnPlayerCommandText).
- Не требуется вручную отделять параметры команд (уже отделённые параметры передаются в команду в строке params).
- Проще в освоении.
- Работает в разы быстрее других обработчиков, создавая меньшую нагрузку на сервер.
Теперь перейдём к обработке параметров.
Допустим, у нас есть команда "/ban", которая банит на сервере игрока с указанным ID (пример: "/ban 65").
PHP:
CMD:ban(playerid, params[])
{
// ...
}
Стандартным способом это делается с помощью функции strval, которая преобразует содержимое строки в число:
new target = strval(params);
Но в данном способе есть много минусов
- Если игрок ничего не ввёл, строка params будет пустой и функция strval вернёт 0, из-за чего можно нечаянно забанить игрока ID 0 (а если под ID 0 находитесь вы - забаните сами себя).
- Для обработки более чем 1 параметра, извлечения ID игроков и т.п. приходится вставлять в скрипт и много раз использовать пользовательские функции strtok, IsNumeric, ReturnUser и т.д.
Чтобы избежать этих ошибок, придётся сделать дополнительные проверки на пустоту и подсчёт количества параметров (сосчитать все пробелы в строке и прибавить 1). Такая задача может оказаться слишком трудной для начинающих скриптеров.
Однако, есть иное решение: плагин sscanf2.
Использование:
PHP:
sscanf(<исх. строка>, <форматная строка>, <переменные>);
<форматная строка> - строка, в которой указывается, какого типа данные должны быть считаны из исходной строки (пример: "ds[40]")
- d, i - целое число
- f - вещественное число (Float)
- u - игрок (ID или часть имени)
- s[размер] - строка с указанной макс. длиной
<переменные> - переменные, в которые будут записаны значения, полученные из исходной строки
Для получения ID игрока в команде /ban плагин sscanf2 можно использовать следующим образом
PHP:
CMD:ban(playerid, params[])
{
new target;
sscanf(params, "u", target);
}
Но что делать, если ID всё же не был введён игроком?
Здесь всё тоже предусмотрено: функция sscanf возвращает 1 в случае ошибки и 0 в случае успеха. Таким образом, проверку на неправильный ввод можно записать в виде ветвления if
PHP:
CMD:ban(playerid, params[])
{
new target;
if(sscanf(params, "u", target))
{
SendClientMessage(playerid, 0xFFFFFFFF,
"Использование: /ban [ID игрока/часть имени]");
return 1;
}
// ...
}
Теперь, когда ID игрока получен и все случаи неправильного ввода обработаны, можно доделать оставшуюся часть команды:
PHP:
CMD:ban(playerid, params[])
{
new target;
if(sscanf(params, "u", target))
{
SendClientMessage(playerid, 0xFFFFFFFF,
"Использование: /ban [ID игрока/часть имени]");
return 1;
}
Ban(target);
return 1;
}
Сделаем тестовую команду выдачу уровня:
PHP:
CMD:givelevel(playerid, params[])
{
new target, level;
if(sscanf(params, "ud", target, level))
return SendClientMessage(playerid, 0xFFFFFFFF, "Используйте: /givelevel [ID игрока/часть имени] [уровень]");
SetPlayerScore(target, GetPlayerScore(target) + level);
return 1;
}
И как вы успели заметить, тут мы используем 2 параметра это
- target - Сюда записываем id игрока.
- level - Записываем LVL который хотим дать игроку.
Разберем
PHP:
SetPlayerScore(target, GetPlayerScore(target) + level);
- SetPlayerScore - Функция отвечающая за число находящийся в TAB листе.
- targetid - переменная в которую мы записали ID игрока.
- GetPlayerScore(target) - Функция отвечающая за получения текущего числа в TAB листе.
- + level - Так как мы уже получили текущее число которое уже есть и приплюсовываем к этому числу которое уже есть, ту переменную в которую записали число(Уровень).
Давайте создадим еще одну тестовую команду, но уже будем записывать не число а текст вывода определенному игроку:
PHP:
CMD:sms(playerid, params[])
{
new target, text, sendername[MAX_PLAYER_NAME], str_[28-4+MAX_PLAYER_NAME+120];
if(sscanf(params, "us[145]", target, text))
return SendClientMessage(playerid, 0xFFFFFFFF, "Используйте: /sms [ID игрока/часть имени] [Text]");
GetPlayerName(playerid, sendername, sizeof(sendername));
format(str_ , sizeof(str_), "Игрок %s отправил вам текст: %s", sendername, text);
SendClientMessage(target, 0xFFFFFFFF, str_);
return 1;
}
Но на самом деле не чего тут страшного нет, и самые обычные функции.
Разберем первую строку
PHP:
new target, text, sendername[MAX_PLAYER_NAME], str_[28-4+MAX_PLAYER_NAME+120];
- target - записываем id игрока.
- text - записываем текст.
- sendername[MAX_PLAYER_NAME] - в нее будет записываться имя игрока.
- MAX_PLAYER_NAME - это макрос который определяет размер ячеек директивой #define по дефолту в a_samp.inc она имеет значение 24.
- А 24 это максимальное длина имени, можно написать за место MAX_PLAYER_NAME просто 24 разницы не будет.
- str_[28-4+MAX_PLAYER_NAME+120] - сюда как раз и будет записываться отформатированный текст.
- 28-4+MAX_PLAYER_NAME+120 - Это размер ячеек сколько можно будет поместить в эту переменную символов.
- Я сделал точный подсчет всего символов 28 не считая %s два раза. Именно поэтому я отнимаю 4 ибо % - 1 s - 2. и еще раз % - 1 s - 2.
- + MAX_PLAYER_NAME - Ну думаю понятно максимальное длина имени.
- + 120 - это и есть текст который будет передаваться в функцию SendClientMessage по дефолту в чат максимальная длина 144 + нуль символ 145.
Теперь расскажу подробнее про эту
PHP:
if(sscanf(params, "us[145]", target, text))
- u - ид игрока
- s[145] - сам текст и 145 ячеек.Так как всего максимальная длина 144 в чате + нуль символ 1 получается 145.
Получения имени игрока:
PHP:
GetPlayerName(<id игрока>, <строковая переменная>, <размер>)
PHP:
format(<строковая переменная>, <размер>, <форматная строка>, <список>)
PHP:
SendClientMessage(target, 0xFFFFFFFF, str_);
Всем спасибо это был урок для новичков #1.
Урок #2 - Временно не доступен
Урок #2 - Временно не доступен
