Pawn. SA-MP. Взаимодействие с игроком

Взаимодействовать с игроком очень важно. Именно это придаёт интерес игровому процессу. Разработчик скрипта должен думать об игроках, с которыми этот скрипт будет взаимодействовать, поэтому скрипт нужно писать максимально простым для конечного пользователя.

Создание простой команды

Создать команду очень просто, для этого нам нужно использовать каллбэк OnPlayerCommandText и функцию strcmp.

OnPlayerCommandText, вызывается когда игрок вводит в строку ввода текст, начинающийся на /(слэш).
strcmp, функция, которая сравнивает две строки и возвращает 0, если строки одинаковы


Для примера сделаем команду «/hi», которая отправит всем игрокам сообщение «Hello World!»:

public OnPlayerCommandText(playerid, cmdtext[])
{
	// проверим на идентичность содержимого cmdtext и "/hi"
	if (!strcmp(cmdtext, "/hi", true))
	{
		// выводим сообщение
		SendClientMessageToAll(0xFFFFFFFF, "Hello World!");
		return 1;
	}
	return 0;
}

Создание команды с параметром

При вводе команд, иногда требуется ввести определённый параметр. Например в команде по передаче денег, нужно указать ID игрока, а иначе никак не понять какому игроку вы желаете передать деньги. Такие команды делают обычно с использованием функции strtok, но в предыдущей статье я опубликовал способ, который работает быстрее, чем strtok, поэтому будем использовать его.
Сама функция:

stock strcharsplit(const string[], &index, seperator=' ')
{
	new result[20], i = 0;
	if (index != 0 && string[index] != '\0') index++;
	while (string[index] && string[index] != seperator && string[index] != '\r' && string[index] != '\n')
	{
		result[i++] = string[index++];
	}
	return result;
}

Как её применить? Усовершенствуем нашу команду «/hi» так, чтобы игроку нужно было указывать в качестве параметра ID игрока, которому будет послано сообщение «Hello World!».

public OnPlayerCommandText(playerid, cmdtext[])
{
	// создадим необходимые переменные
	new cmd[128],
		idx = 0;
	// переменной cmd присвоим значение, вычлененное из cmdtext[] с нулевой позиции до первого пробела или окончания строки.
	cmd = strcharsplit(cmdtext,idx,' ');
 
	// проверим на идентичность содержимого cmd и "/hi"
	if (!strcmp(cmd, "/hi", true))
	{
		// создадим новую переменную, для хранения следующего значения
		new tmp[128];
		// то-же самое что и в первом случае, но теперь вычлениваем с позиции idx
		tmp = strcharsplit(cmdtext,idx,' ');
		// проверим, ввёл ли игрок параметр
		if (strlen(tmp) == 0)
			return SendClientMessage(id,0xFFFFFFFF, "Применение: /hi [id]");
		// преобразуем введённый параметр в число
		new id = strval(tmp);
		// если игрок введёт ID игрока, которого нет в онлайне, то сообщим ему об ошибке
		if (!IsPlayerConnected(id))
			return SendClientMessage(id,0xFFFFFFFF, "Ошибка [/hi]: Неверный ID игрока");
		// ну и наконец, если всё хорошо, то выводим сообщение
		SendClientMessage(id,0xFFFFFFFF, "Hello World!");
		return 1;
	}
	return 0;
}

Использование функций, влияющих на игровой процесс

SA-MP предоставляет обширные возможности по контролю параметров игрока. Изменение количества здоровья, брони, денег, перемещение игрока, изменение внешности и другое. Полный список функций вы можете посмотреть на википедии, а мы рассмотрим одну из них — GivePlayerMoney(изменение количества денег).

Создадим простенькую команду по передаче денег другому игроку:

public OnPlayerCommandText(playerid, cmdtext[])
{
	// создадим необходимые переменные
	new cmd[128],
		idx = 0;
	// переменной cmd присвоим значение, вычлененное из cmdtext[] с нулевой позиции до первого пробела или окончания строки.
	cmd = strcharsplit(cmdtext,idx,' ');
 
	// проверим на идентичность содержимого cmd и "/givemoney"
	if (!strcmp(cmd, "/givemoney", true))
	{
		// создадим новую переменную, для хранения следующего значения
		new tmp[128];
		// то-же самое что и в первом случае, но теперь вычлениваем с позиции idx
		tmp = strcharsplit(cmdtext,idx,' ');
		// проверим, ввёл ли игрок параметр
		if (strlen(tmp) == 0)
			return SendClientMessage(id,0xFFFFFFFF, "Применение: /hi [givemoney] [money]");
		// преобразуем введённый параметр в число
		new id = strval(tmp);
		// если игрок введёт ID игрока, которого нет в онлайне, то сообщим ему об ошибке
		if (!IsPlayerConnected(id))
			return SendClientMessage(id,0xFFFFFFFF, "Ошибка [/givemoney]: Неверный ID игрока");
 
		// то-же самое что и в предыдущем случае
		tmp = strcharsplit(cmdtext,idx,' ');
		// проверим, ввёл ли игрок параметр
		if (strlen(tmp) == 0)
			return SendClientMessage(id,0xFFFFFFFF, "Применение: /givemoney [id] [money]");
		// преобразуем введённый параметр в число
		new money = strval(tmp);
		// т.к. функция GivePlayerMoney может принимать и отрицательные значения, то сделаем такую проверку
		// чтобы игрок не мог забрать деньги у другого игрока
		if (money <= 0)
			return SendClientMessage(id,0xFFFFFFFF, "Ошибка [/givemoney]: Неверное количество денег");
 
		// ну и передаём игроку id количество денег, равное money
		GivePlayerMoney(id,money);
		return 1;
	}
	return 0;
}

Ну собственно это всё, что нужно, чтобы вы разобрались в этом вопросе, задать вопросы можете в комментариях, я обязательно отвечу;)

  • DiSE

    ЗКМД с сканфом куда лучше

    • ZiGGi

      В статье внимание акцентируется совсем не на это. Про различные способы создания команд напишу в будущем.

  • fabervox

    С if (index != 0) index++; в strcharsplit, при написании без параметра отсылало id0.
    А вот с if (index != 0 && string[index] != '') index++; из темы о сравнении с strtok, заработало как надо.

    • Спасибо, я забыл исправить эту функцию здесь.

      • fabervox

        А зачем проверять перенос, если его невозможно ввести в командную строку?Или \\n здесь что-то другое?

        • Это универсальная функция, она может использоваться не только в командах, но и в операциях с файлами и т.п..

Перейти к верхней панели