PDA

Просмотр полной версии : [Урок] Создание NPC бота



^_^
09.01.2014, 20:43
Доброго времени суток дорогие форумчане, в данном уроке вы подробно узнаете как создать своего собственного NPC бота.

Предисловие: За время моей практики я уже написал ещё один урок по созданию NPC бота, но к сожалению к тому времени у меня было мало опыта и допустил не мало ошибок. В данном уроке я попытаюсь исправить все мои допущенные ошибки, ну а также учту все нововведения появившийся с того момента.

Некоторые часто задаваемые вопросы:
Q:Что такое NPC?
A:NPC (Non-Playing Characters или 'боты') это нововведение в версии SA-MP 0.3. Данная нововведение позволяет вам добавить одного или несколько NPC на вашем сервере. Боты будут работать как "виртуальные игроки", при этом будут занимать 1 слот, также как нормальный игрок. (Подробнее: КЛАЦ (http://wiki.sa-mp.com/wiki/Category:NPC))
Q:Нужны ли определённые дополнения (плагин к примеру) для создания NPC?
A:Нет, всё нужное встроено в клиентах версии 0.3+. Если же, в папках .../pawno/include/ отсутствуют инлкюды a_npc или a_samp, вы можете их скопировать с официального сайта sa-mp.


I. Создание NPC


1) Заходим в корневую папку вашего сервера, находим файл server.cfg, открываем в Блокноте, и добавляем/изменяем после строчки "maxnpc" значение на *количество ботов которых вы хотите создать*.

http://breedpmnr.ru/i/b78a4baca10d74d23766eadd0a07.jpg


2) Открываем pawno, и создаём новый файл. Заменяем всё содержимое на:

#include <a_samp>
#tryinclude <dc_cmd>
#if defined DC_CMD
CMD:startrecrod(playerid, params[])
{
if(!strlen(params[0])) return SendClientMessage(playerid,0xFF0000FF,"Использвание: /startrecord {Название записи}");
if(!IsPlayerInAnyVehicle(playerid)) StartRecordingPlayerData(playerid,PLAYER_RECORDING_TYPE_DRIVER,params[0]);
else StartRecordingPlayerData(playerid,PLAYER_RECORDING_TYPE_ONFOOT,params[0]);
SendClientMessage(playerid,0xFF0000FF,"Запись началась.");
return 1;
}
CMD:stoprecord(playerid, params[])
{
StopRecordingPlayerData(playerid);
SendClientMessage(playerid,0xFF0000FF,"Запись остановлена.");
return 1;
}
#else
#include "../include/gl_common.inc"
public OnPlayerCommandText(playerid, cmdtext[])
{
new cmd[256];
new idx;
cmd = strtok(cmdtext, idx);
if(strcmp(cmd, "/startrecord", true) == 0){
new tmp[512];
tmp = strtok(cmdtext, idx);
if(!strlen(tmp)) return SendClientMessage(playerid,0xFF0000FF,"Использвание: /startrecord {Название записи}");
if(!IsPlayerInAnyVehicle(playerid)) StartRecordingPlayerData(playerid,PLAYER_RECORDING_TYPE_DRIVER,tmp);
else StartRecordingPlayerData(playerid,PLAYER_RECORDING_TYPE_ONFOOT,tmp);
SendClientMessage(playerid,0xFF0000FF,"Запись началась.");
return 1;
}
if(strcmp(cmd, "/stoprecord", true) == 0) {
StopRecordingPlayerData(playerid);
SendClientMessage(playerid,0xFF0000FF,"Запись остановлена.");
return 1;
}
return 0;
}
#endif
Компилируем под названием record в каталог(папку) filterscripts.

*Команды данного скрипта скомпилируются на DC_CMD (при наличии includa <dc_cmd>) либо на стандартный командный процессор.

http://breedpmnr.ru/i/39cf031f4377d4e72dc5e2f42d7f.jpg


3) Вводим в консоль команду "loadfs record"(без кавычек), либо в игре: /rcon loadfs record (сперва нужно авторизоваться как администратор).
http://breedpmnr.ru/i/dcc4ef069154f41597cdfa9b39f9.jpg


4) Заходим в игру и пишем /startrecrod "Название записи" с позиции старта/повтора записи бота.
После того как мы повторили точные движения бота, вводим /stoprecord.
-"Запись началась"
-"Запись остановлена."


5) Открываем каталог \scriptfiles и находим в нём файл с ранее указанным названием (расширение .rec).

6) Копируем/вырезаем файл в каталоге \npcmodes\recordings


7) Открываем компилятор, создаём новый файл, и заменяем всё содержимое на:

#define RECORDING "Название записи" //ковычки оставляем
#define RECORDING_TYPE 1// Заменяем на любое другое число если запись
#define RECORDING_REPLAY 1// Повтор записи, 1 - да, 0 - нет
#include <a_npc>
main(){}
#if RECORDING_REPLAY == 1
public OnRecordingPlaybackEnd() StartRecordingPlayback(RECORDING_TYPE, RECORDING);
#endif
#if RECORDING_TYPE == 1
public OnNPCEnterVehicle(vehicleid, seatid) StartRecordingPlayback(RECORDING_TYPE, RECORDING);
public OnNPCExitVehicle() StopRecordingPlayback();
#else
public OnNPCSpawn() StartRecordingPlayback(RECORDING_TYPE, RECORDING);
#endif
Компилируем в каталог \npcmodes с тем же названием что и у записи.

*Не забываем изменить директивы #define на нужные нам параметры.
*Вы также можете использовать в данный скрипт и другие NPC калбэки, полный список всех NPC калбэков: КЛАЦ (http://wiki.sa-mp.com/wiki/Category:NPC)



8) Подключаем бота при помощи функции ConnectNPC(name[], script[]) - желательно в OnGameModeInit*.

public OnGameModeInit()
{
ConnectNPC("Nick_Name","MyRec");
return 1;
}


*Так, у бота, без всякого риска останется свободный слот.



9) Если запись бота происходила а автомобиле, обязательно создавать его (при помощи функции CreateVehicle/AddStaticVehicle). Также, не обязательно указывать точные координаты спавна автомобиля, так как бот сам телепортирует её к месту старта записи, но не нужно забывать про PutPlayerInVehicle.
Пример:


new botcar;
public OnGameModeInit()
{
ConnectNPC("Nick_Name","MyRec");
botcar = CreateVehicle(*carid*, 0.0, 0.0, 5.0, 0.0,
*цвет1*, *цвет2*, 5000);
return 1;
}
public OnPlayerSpawn(playerid)
{
if(IsPlayerNPC(playerid))
{
new npcname[MAX_PLAYER_NAME+1];
GetPlayerName(playerid, npcname, sizeof(npcname));
if(!strcmp(npcname, "Nick_Name", true))
{
PutPlayerInVehicle(playerid, botcar, 0);
SetSpawnInfo(playerid,0,*skinid*,0.0,0.0,0.0,0.0,0,0,0,0,0,0);
}
return 1;
}
return 1;
}



10) ПРИМЕЧАНИЕ: После его подключение, бот ведёт себя как обычный игрок, и по мимо калбэков в NPC скрипте, он отвечает на обычных калбэков для игроков. Иногда это удобно, но при этом есть некоторые калбэки или функцие которые NPC не сможет пройти, к примеру вашу Реггистрацию, Анти-Чит телепорта и т.д. Следовательно, в данных калбэков нужно исключить NPC простой проверки:

if(IsPlayerNPC(playerid)) return 1;

*Можно экспериментировать калбэками (КЛАЦ (http://wiki.sa-mp.com/wiki/Category:Scripting_Callbacks)) и обычными функциями и создать весьма интересные системы ; ).


Данный урок посвящается порталу pro-pawn.ru, просьба не копировать на посторонних источниках.
Автор: ^_^

Тема будет дополнятся.

TWIX
09.01.2014, 20:48
Неплохо!

Dima_Turkow
09.01.2014, 21:12
+ дам

Daniel_Cortez
09.01.2014, 21:32
Not bad. За фишку с опциональным использованием dc_cmd уже можно + поставить.

P.S.: Если не сложно, уменьши ширину 1-го столбца в таблице. Жутко неудобно каждый раз прокручивать страницу вправо, чтобы увидеть содержимое 2-го столбца.

^_^
09.01.2014, 21:54
Not bad. За фишку с опциональным использованием dc_cmd уже можно + поставить.

P.S.: Если не сложно, уменьши ширину 1-го столбца в таблице. Жутко неудобно каждый раз прокручивать страницу вправо, чтобы увидеть содержимое 2-го столбца.
Благодарю, первый пост обновлён.

Dima_Turkow
09.01.2014, 21:56
Молодец )

Salvacore
10.01.2014, 09:01
Молодец.
Very good.

MR_BEN
11.01.2014, 16:21
Спасибо, пригодилось.

AndreyKa
12.01.2014, 00:28
Отлично,не каждый знает это!

^_^
12.01.2014, 16:25
Тема обновлена.

Osetin
19.01.2014, 23:27
Not bad.Good work

MaZaRHaKeR
27.09.2014, 21:58
Подниму тему своим вопросов)
Если мне требуется записать не просто какое-либо движение, а при этом ещё и задействовать анимацию (для бота в дальнейшем), это всё запишется автоматически рекордом или надо что-то ещё "прикручивать"?

$continue$
13.01.2015, 18:38
Круто!

sanyaretro
02.04.2018, 23:45
В сампе 0.3.7 будет работать ?

pawnoholic
03.04.2018, 00:15
В сампе 0.3.7 будет работать ?

А почему нет?

sanyaretro
03.04.2018, 01:51
А почему нет?
Я в этом не понимаю потому и спрашиваю . По коментариям людей ,встречались коды, которые функционировали на сампе 03 e - z а на 0.3.7 нет

sanyaretro
03.04.2018, 14:33
При компилировании файла record ошибка .Пробую на чистом сервере сампа 0.3.7

C:\SERVER\filterscripts\record.pwn(25) : warning 217: loose indentation
C:\SERVER\filterscripts\record.pwn(27) : warning 217: loose indentation
C:\SERVER\filterscripts\record.pwn(28) : warning 217: loose indentation
C:\SERVER\filterscripts\record.pwn(29) : error 017: undefined symbol "StartRecordingPlayerData"
C:\SERVER\filterscripts\record.pwn(30) : error 017: undefined symbol "StartRecordingPlayerData"
C:\SERVER\filterscripts\record.pwn(34) : warning 217: loose indentation
C:\SERVER\filterscripts\record.pwn(35) : error 017: undefined symbol "StopRecordingPlayerData"
Pawn compiler 3.2.3664 Copyright (c) 1997-2006, ITB CompuPhase


3 Errors.

pawnoholic
03.04.2018, 15:18
При компилировании файла record ошибка .Пробую на чистом сервере сампа 0.3.7

C:\SERVER\filterscripts\record.pwn(25) : warning 217: loose indentation
C:\SERVER\filterscripts\record.pwn(27) : warning 217: loose indentation
C:\SERVER\filterscripts\record.pwn(28) : warning 217: loose indentation
C:\SERVER\filterscripts\record.pwn(29) : error 017: undefined symbol "StartRecordingPlayerData"
C:\SERVER\filterscripts\record.pwn(30) : error 017: undefined symbol "StartRecordingPlayerData"
C:\SERVER\filterscripts\record.pwn(34) : warning 217: loose indentation
C:\SERVER\filterscripts\record.pwn(35) : error 017: undefined symbol "StopRecordingPlayerData"
Pawn compiler 3.2.3664 Copyright (c) 1997-2006, ITB CompuPhase


3 Errors.

Потому что, нужно a_samp.inc подключить в самом начале файла.


#include <a_samp>

sanyaretro
03.04.2018, 16:56
Потому что, нужно a_samp.inc подключить в самом начале файла.


#include <a_samp>

Спасибо, что отвечаете ! Так в файла record в самом начале это все прописано

#include <a_samp>
#tryinclude <dc_cmd>
#if defined DC_CMD

И все эти файлы :инлкюды - a_npc и a_samp ,и даже dc_cmd , у меня имеются в папке pawno\include
И почему то выдает ошибку error 017: undefined symbol "StartRecordingPlayerData"
Может быть код устаревший и для sampa 0.3.7 не подходит ?

pawnoholic
03.04.2018, 17:22
Спасибо, что отвечаете ! Так в файла record в самом начале это все прописано

#include <a_samp>
#tryinclude <dc_cmd>
#if defined DC_CMD

И все эти файлы :инлкюды - a_npc и a_samp ,и даже dc_cmd , у меня имеются в папке pawno\include
И почему то выдает ошибку error 017: undefined symbol "StartRecordingPlayerData"
Может быть код устаревший и для sampa 0.3.7 не подходит ?

Значит, что то с вашей библиотекой <a_samp>, скачайте с оф. сайта сборку с сервером, у переместите от туда все библиотеки в директорию к вашему компилятору.

StopRecordingPlayerData (http://wiki.sa-mp.com/wiki/StopRecordingPlayerData)

sanyaretro
03.04.2018, 17:24
Доброго вечера ! Скачал с официального сайта ,SA-MP 0.3.7-R2 Windows Server !

Теперь при открытии через pawno,что находиться в самом сервере :

C:\SERVER\filterscripts\record.pwn(25) : warning 217: loose indentation
C:\SERVER\filterscripts\record.pwn(27) : warning 217: loose indentation
C:\SERVER\filterscripts\record.pwn(28) : warning 217: loose indentation
C:\SERVER\filterscripts\record.pwn(34) : warning 217: loose indentation
Pawn compiler 3.2.3664 Copyright (c) 1997-2006, ITB CompuPhase


4 Warnings.

При вводе команды :/rcon loadfs record - ошибка загрузки (load failed)

А при открытии руссифицированного pawno !

C:\SERVER\filterscripts\record.pwn(25) : warning 217: loose indentation
C:\SERVER\filterscripts\record.pwn(27) : warning 217: loose indentation
C:\SERVER\filterscripts\record.pwn(28) : warning 217: loose indentation
C:\SERVER\filterscripts\record.pwn(29) : error 017: undefined symbol "StartRecordingPlayerData"
C:\SERVER\filterscripts\record.pwn(30) : error 017: undefined symbol "StartRecordingPlayerData"
C:\SERVER\filterscripts\record.pwn(34) : warning 217: loose indentation
C:\SERVER\filterscripts\record.pwn(35) : error 017: undefined symbol "StopRecordingPlayerData"
Pawn compiler 3.2.3664 Copyright (c) 1997-2006, ITB CompuPhase


3 Errors.

И тоже самое, при вводе команды :/rcon loadfs record - ошибка загрузки (load failed)

#Moore
25.07.2018, 11:59
if(!IsPlayerInAnyVehicle(playerid)) StartRecordingPlayerData(playerid,PLAYER_RECORDING_TYPE_DRIVER,params[0]);
Ничего не смущает? Начал разбираться в NPC, нашел данный мануал, записал маршрут автобусника, около часа голову ломал, почему же не работает.


if(IsPlayerInAnyVehicle(playerid)) StartRecordingPlayerData(playerid,PLAYER_RECORDING_TYPE_DRIVER,params[0]);