Русское сообщество по скриптингу

Создание продвинутого NPC

Статьи или фрагменты кода для новичков и уже опытных скриптеров по AMXX.

Модератор: Chuvi

Правила форума
1. Запрещено материться и оскорблять других участников форума.
2. Запрещен флуд, оффтоп, дабл постинг во всех разделах форума, кроме раздела "Болтовня".
3. Запрещено взламывать сайт/форум или наносить любой вред проекту.
4. Запрещено рекламировать другие ресурсы.
5. Запрещено создавать темы без информативного названия. Название темы должно отображать ее смысл.

В данном разделе форума разрешено создавать темы, касающие только обучающему материалу по AMX Mod X.

Создание продвинутого NPC

Сообщение crash94 » 11 авг 2013, 15:32

Всем доброго времени суток

В данной статье я постараюсь рассказать - как создать NPC(бота на amxx), которого вы сможете запрограммировать на любые действия - если конечно присутствует серое вещество, а не опилки..

В статье мы разберем непосредственное создание npc, перемещение по карте и его смерть

Приступаем!
Я не буду расписывать каждую строку отдельно, а буду приводить отдельные функции со всеми комментариями и пометками.

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

Ну собственно код выглядит так. Я надеюсь ни у кого не составит труда понять что к чему

Код: Выделить всё
#include <amxmodx>
#include <engine>
#include <fakemeta>
#include <hamsandwich>
 
#define PLUGIN  "TestNPC"
#define VERSION         "1.0"
#define AUTHOR  "CrAsH"
 
new g_Cvar[5//квары
 
new const gModel[] = "models/player/vip/vip.mdl" //Модель NPC
new const gClassname[] = "TestNPC" //Класснейм NPC
 
//Флагменты костей(разрыв npc на части хД)
enum _:GIBS
{
        HEAD,
        LEG,
        BONE,
        LUNG,
        GIB
}
 
new gModelGibs[GIBS//Прекаши костей
new gSpriteBlood //прекаш спрайта
 
new iNPC_ID //Идентификатор созданного NPC
new iPlayer_ID //Идентификатор игрока, который создал NPC
 
new Float:fNPCOrigin[3//Координаты точки появление NPC
 
public plugin_init()
{
        register_plugin(PLUGINVERSIONAUTHOR//Ну думаю тут ясно
    
        register_think
(gClassname"NPCThink"//Событие действий NPC
 
        g_Cvar
[1] = register_cvar("testnpc_health""100"//жизни npc
        g_Cvar[2] = register_cvar("testnpc_speed""100"//Скорость noc
        g_Cvar[3] = register_cvar("testnpc_distance""100"//Минимальная дистанция при которой он побежит за вами
 
        register_clcmd
("say /npc_origin""NPCOrigin"//Команда создание координат появление
        register_clcmd("say /npc_create""NPCCreate"//Команда непосредственного создания
}
 
public plugin_precache()
{
        precache_modelgModel //Прекаш модели NPC
 
        
//Костей
        gModelGibs[HEAD] = precache_model("models/gib_skull.mdl")
        gModelGibs[LEG] = precache_model("models/gib_legbone.mdl")
        gModelGibs[BONE] = precache_model("models/gib_b_bone.mdl")
        gModelGibs[LUNG] = precache_model("models/gib_lung.mdl")
        gModelGibs[GIB] = precache_model("models/gib_b_gib.mdl")
 
        
//Крови
        gSpriteBlood precache_model("sprites/blood.spr")
 

Думаю здесь всё понятно. Как видите у меня зарегистрировано 2 команды для создание координат и создания самого npc.

Давайте рассмотрим создание координат

Код: Выделить всё
public NPCOrigin(id)
{
        entity_get_vector(idEV_VEC_originfNPCOrigin//Записываем координаты
        client_print(idprint_chat"[NPC]Origin create"//выводим сообщение

Как видите здесь ничего сложного нет. В уже подготовленный массив fNPCOrigin мы записываем координаты своего положения, чтобы на это место поставить NPC.

Давайте рассмотрим создание NPC

Код: Выделить всё
public NPCCreate(id)
  
        iPlayer_ID 
id //Записываем идентификатор игрока, запустившего создание NPC
 
        
if(iNPC_ID//Если npc уже был создан
        {
                remove_entity(iNPC_ID//Убираем его
                iNPC_ID //Сбрасываем идентификатор
        }
 
        iNPC_ID 
create_entity("info_target"//Создаем объект
 
        
if(pev_validiNPC_ID )) //Проверяем, создан ли объект
        {
                client_print(idprint_chat"[NPC]Create"//Если да, пишем, что создан
        }else{
                client_print(idprint_chat"[NPC]Error create"//Иначе выводим
                return PLUGIN_HANDLED //Прекращаем дальшейнее выполнение функции
        }
 
        entity_set_origin
(iNPC_IDfNPCOrigin//Ставим на координаты, созданные нами ранее
 
        entity_set_float
(iNPC_IDEV_FL_takedamage,1.0//Делаем смертным
 
        
new Float:fHealth floatget_pcvar_numg_Cvar[1] )) //Получаем значение квара и конвертируем в дробное число
        entity_set_float(iNPC_IDEV_FL_healthfHealth//Присваиваем количество жизней
 
        entity_set_model
(iNPC_IDgModel//Присваем модель
        entity_set_string(iNPC_IDEV_SZ_classnamegClassname//Присваиваем класс
    
        entity_set_int
(iNPC_IDEV_INT_solidSOLID_BBOX//Делаем его материальным
        entity_set_int(iNPC_IDEV_INT_movetypeMOVETYPE_PUSHSTEP//NPC может передвигаться по карте
 
        entity_set_size
(iNPC_IDFloat:{-16.0, -16.0, -36.0}, Float:{16.016.036.0}) //Задаем размеры( не путать с размером модели )
 
        entity_set_float
(iNPC_IDEV_FL_nextthinkhalflife_time() + 0.01//Заводим think
 
        
//Задаем свойства
        set_pev(iNPC_IDpev_enemy0)
        entity_set_int(iNPC_IDEV_INT_gamestate,1)
 
        entity_set_int
(iNPC_IDEV_INT_sequence1//Задаем начальную анимацию
        entity_set_float(iNPC_IDEV_FL_animtimeget_gametime()) //Задаем время анимации
        entity_set_float(iNPC_IDEV_FL_framerate 1.0//Задаем скорость анимации
        entity_set_float(iNPC_IDEV_FL_frame0.0//Задаем начальный кадр
 
        RegisterHamFromEntity
(Ham_KillediNPC_ID"NPCKilled"//Задаем событие смерти
 
        
//Создаем в руках оружие
        new iWeapon create_entity("info_target")
 
        entity_set_int
(iWeaponEV_INT_solidSOLID_NOT//Не задаем никаких физичиских свойств
        entity_set_int(iWeaponEV_INT_movetypeMOVETYPE_FOLLOW//Задаем свойство следования объекта за игроком
        entity_set_edict(iWeaponEV_ENT_aimentiNPC_ID//Непосредственно прикрепление объекта к NPC
        entity_set_model(iWeapon"models/p_ak47.mdl"//Задаем модель( можете хоть гранатомет ему давать )
 
        
return PLUGIN_HANDLED //конец

Как вы наверное поняли мы создадим NPC, который будет в моделе vip и дадим в руки модель ak47.Это придаст достаточно видимости, что перед нами реальный игрок и отличить от настоящего игрока будет не совсем просто.

Следующим шагом будет создание think`а npc. Это самая важная часть плагина, которая отвечает за передвижение игрока.Без него он тупо будет стоять и ворон считать. Не будем стоять на месте и создаем

Код: Выделить всё
public NPCThinkiEntity )
{
        if(!is_valid_entiEntity )) //Если NPC не существует
                return FMRES_IGNORED //Прекращаем дальшейнее выполнение функции
 
        
if(!is_user_aliveiPlayer_ID ) || !is_user_connectediPlayer_ID )) //Если игрок мертв или отсоеденился
        {
                remove_entityiEntity //Убираем NPC
                iNPC_ID //Сбрасываем идентификатор
 
                
return FMRES_IGNORED //Прекращаем дальшейнее выполнение функции
        }
 
        
new Float:fNOrigin[3], Float:fPOrigin[3//Сюда запишем координаты NPC и игрока
        new Float:fDistance //Сюда запишем расстяние между ними
    
        pev
(iEntitypev_originfNOrigin//Получаем координаты NPC
        pev(iPlayer_IDpev_originfPOrigin//Получаем координаты игрока
    
        fDistance 
get_distance_f(fNOriginfPOrigin//Получаем дистанцию между ними
 
        
if(fDistance <= floatget_pcvar_numg_Cvar[3] ) )) //Если дистация межде указанной
        {
                client_print(iPlayer_IDprint_center"[NPC]I caught up with you"//Чисто для прикола выводим, что NPC догнал нас
 
                
if(pev(iEntitypev_sequence) != 1//Если анимация npc установлена не стоячая
                {
                        entity_set_int(iEntityEV_INT_sequence1//Задаем анимацию бега
                        entity_set_float(iEntityEV_FL_animtimeget_gametime()) //Задаем время анимации
                        entity_set_float(iEntityEV_FL_framerate1.0//Задаем скорость анимации
                        entity_set_float(iEntityEV_FL_frame0.0//Задаем начальный кадр
                }
        }else{
                if(pev(iEntitypev_sequence) != 4//Если анимация npc установлена не бега
                {
                        entity_set_int(iEntityEV_INT_sequence4//Задаем анимацию бега
                        entity_set_float(iEntityEV_FL_animtimeget_gametime()) //Задаем время анимации
                        entity_set_float(iEntityEV_FL_framerate1.0//Задаем скорость анимации
                        entity_set_float(iEntityEV_FL_frame0.0//Задаем начальный кадр
                }
 
                
new Float:fAngles[3//Сюда запишем координаты, куда должен будет смотреть NPC
                new Float:fVelocity[3//Сюда запишем координаты, куда будет бежать NPC
 
                entity_get_vector
(iEntityEV_VEC_anglesfAngles//Получаем
 
                
new Float:fX fPOrigin[0] - fNOrigin[0//Расчитываем координаты x
                new Float:fZ fPOrigin[1] - fNOrigin[1//Расчитываем координаты z
 
                
new Float:fRadian
                fRadian 
floatatan(fZ/fXradian//Получаем угол
 
                fAngles
[1] = fRadian * (180 3.14//Приваиваем координаты
 
                
if(fPOrigin[0] < fNOrigin[0]) //Если координаты игрока относительно x меньше NPC`овскивх
                {
                        fAngles[1] = fAngles[1] - 180.0 //Разворачиваем его
                }else{
                        fAngles[1] = fRadian * (180 3.14//Записываем координаты
                }
 
                
new Float:fSpeed fDistance floatget_pcvar_numg_Cvar[2] ) ) //Задаем скорость
                
                
//Записываем координаты куда бежать
                fVelocity[0] = (fPOrigin[0] - fNOrigin[0]) / fSpeed
                fVelocity
[1] = (fPOrigin[1] - fNOrigin[1]) / fSpeed
                fVelocity
[2] = (fPOrigin[2] - fNOrigin[2]) / fSpeed
 
                entity_set_vector
(iEntityEV_VEC_anglesfAngles//Присваиваем новые координаты куда смотреть
                entity_set_vector(iEntityEV_VEC_velocityfVelocity//Присваиваем новые координаты куда бежать
        }
        entity_set_float(iEntityEV_FL_nextthinkhalflife_time() + 0.01//Повторяем
        return FMRES_HANDLED

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

Ну и последнее, что мы сделаем - это его смерть.

Код: Выделить всё
public NPCKillediEntity )
{
        new iEntity2 create_entity("info_target"//Создаем нового, тот пропал
 
        
if(pev_validiEntity2 )) //Проверяем, создан ли объект
        {
                client_print(iPlayer_IDprint_chat"[NPC]Create Dead create"//Если да, пишем, что создан
        }else{
                client_print(iPlayer_IDprint_chat"[NPC]Error create"//Иначе выводим
                return PLUGIN_HANDLED //Прекращаем дальшейнее выполнение функции
        }
 
        
new Float:fOrigin[3], Float:fAngles[3//Запишем, как стоял старый NPC
    
        pev
(iEntitypev_originfOrigin//Получаем координаты
        pev(iEntitypev_anglesfAngles//Получаем куда смотрит
    
        entity_set_origin
(iEntity2fOrigin//Присваиваем
        entity_set_vector(iEntity2EV_VEC_anglesfAngles//Присваиваем
    
        entity_set_model
(iEntity2gModel//Задаем модель
    
        entity_set_size
(iNPC_IDFloat:{-16.0, -16.0, -36.0}, Float:{16.016.036.0}) //Задаем размеры( не путать с размером модели )
 
        entity_set_int
(iEntity2EV_INT_sequence108//Задаем анимацию смерти
        entity_set_float(iEntity2EV_FL_animtimeget_gametime()) //Задаем время анимации
        entity_set_float(iEntity2EV_FL_framerate1.0//Задаем скорость анимации
        entity_set_float(iEntity2EV_FL_frame0.0//Задаем начальный кадр
 
        set_task
(10.0"GibsNPC"iEntity2//Разорвем на куски npc через 10 сек и уничтожим его. 
        return PLUGIN_HANDLED //конец
}
 
public GibsNPCiEntity )
{
        new Float:fOrigin[3//Куда запишем
        pev(iEntitypev_originfOrigin//Получаем координаты
 
        
for(new isizeof gModelGibsi++) //Разбрасываем кости
        {
                message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
                write_byte(TE_MODEL)
                engfunc(EngFunc_WriteCoordfOrigin[0])
                engfunc(EngFunc_WriteCoordfOrigin[1])
                engfunc(EngFunc_WriteCoordfOrigin[2])
                write_coord(random_num(100400))
                write_coord(random_num(100400))
                write_coord(random_num(100400))
                write_angle(random361 ))
                write_short(gModelGibs[i])
                write_byte(1)
                write_byte(125)
                message_end()
        }
 
        
//Создаем кровь
        message_begin(MSG_BROADCASTSVC_TEMPENTITY
        write_byte(TE_BLOODSPRITE)
        engfunc(EngFunc_WriteCoordfOrigin[0])
        engfunc(EngFunc_WriteCoordfOrigin[1])
        engfunc(EngFunc_WriteCoordfOrigin[2])
        write_short(gSpriteBlood)
        write_short(gSpriteBlood)
        write_byte(250)
        write_byte(20)
        message_end()
 
        remove_entity
iEntity //Уничтожаем его нахер
        client_print(iPlayer_IDprint_chat"[NPC]Terminated"//Выводим сообщение что ли

Ну вот и всё. Я чет устал писать, но думаю я делал это не зря. На форуме уже 3 человека попросили статью про npc - получите.

Полный исходный код выглядит так:

Код: Выделить всё
#include <amxmodx>
#include <engine>
#include <fakemeta>
#include <hamsandwich>
 
#define PLUGIN  "TestNPC"
#define VERSION         "1.0"
#define AUTHOR  "CrAsH"
 
new g_Cvar[5//квары
 
new const gModel[] = "models/player/vip/vip.mdl" //Модель NPC
new const gClassname[] = "TestNPC" //Класснейм NPC
 
//Флагменты костей(разрыв npc на части хД)
enum _:GIBS
{
        HEAD,
        LEG,
        BONE,
        LUNG,
        GIB
}
 
new gModelGibs[GIBS//Прекаши костей
new gSpriteBlood //прекаш спрайта
 
new iNPC_ID //Идентификатор созданного NPC
new iPlayer_ID //Идентификатор игрока, который создал NPC
 
new Float:fNPCOrigin[3//Координаты точки появление NPC
 
public plugin_init()
{
        register_plugin(PLUGINVERSIONAUTHOR//Ну думаю тут ясно
    
        register_think
(gClassname"NPCThink"//Событие действий NPC
 
        g_Cvar
[1] = register_cvar("testnpc_health""100"//жизни npc
        g_Cvar[2] = register_cvar("testnpc_speed""100"//Скорость noc
        g_Cvar[3] = register_cvar("testnpc_distance""100"//Минимальная дистанция при которой он побежит за вами
 
        register_clcmd
("say /npc_origin""NPCOrigin"//Команда создание координат появление
        register_clcmd("say /npc_create""NPCCreate"//Команда непосредственного создания
}
 
public plugin_precache()
{
        precache_modelgModel //Прекаш модели NPC
 
        
//Костей
        gModelGibs[HEAD] = precache_model("models/gib_skull.mdl")
        gModelGibs[LEG] = precache_model("models/gib_legbone.mdl")
        gModelGibs[BONE] = precache_model("models/gib_b_bone.mdl")
        gModelGibs[LUNG] = precache_model("models/gib_lung.mdl")
        gModelGibs[GIB] = precache_model("models/gib_b_gib.mdl")
 
        
//Крови
        gSpriteBlood precache_model("sprites/blood.spr")
 
}
 
public NPCOrigin(id)
{
        entity_get_vector(idEV_VEC_originfNPCOrigin)
        client_print(idprint_chat"[NPC]Origin create")
}
 
public NPCCreate(id)
  
        iPlayer_ID 
id //Записываем идентификатор игрока, запустившего создание NPC
 
        
if(iNPC_ID//Если npc уже был создан
        {
                remove_entity(iNPC_ID//Убираем его
                iNPC_ID //Сбрасываем идентификатор
        }
 
        iNPC_ID 
create_entity("info_target"//Создаем объект
 
        
if(pev_validiNPC_ID )) //Проверяем, создан ли объект
        {
                client_print(idprint_chat"[NPC]Create"//Если да, пишем, что создан
        }else{
                client_print(idprint_chat"[NPC]Error create"//Иначе выводим
                return PLUGIN_HANDLED //Прекращаем дальшейнее выполнение функции
        }
 
        entity_set_origin
(iNPC_IDfNPCOrigin//Ставим на координаты, созданные нами ранее
 
        entity_set_float
(iNPC_IDEV_FL_takedamage,1.0//Делаем смертным
 
        
new Float:fHealth floatget_pcvar_numg_Cvar[1] )) //Получаем значение квара и конвертируем в дробное число
        entity_set_float(iNPC_IDEV_FL_healthfHealth//Присваиваем количество жизней
 
        entity_set_model
(iNPC_IDgModel//Присваем модель
        entity_set_string(iNPC_IDEV_SZ_classnamegClassname//Присваиваем класс
    
        entity_set_int
(iNPC_IDEV_INT_solidSOLID_BBOX//Делаем его материальным
        entity_set_int(iNPC_IDEV_INT_movetypeMOVETYPE_PUSHSTEP//NPC может передвигаться по карте
 
        entity_set_size
(iNPC_IDFloat:{-16.0, -16.0, -36.0}, Float:{16.016.036.0}) //Задаем размеры( не путать с размером модели )
 
        entity_set_float
(iNPC_IDEV_FL_nextthinkhalflife_time() + 0.01//Заводим think
 
        
//Задаем свойства
        set_pev(iNPC_IDpev_enemy0)
        entity_set_int(iNPC_IDEV_INT_gamestate,1)
 
        entity_set_int
(iNPC_IDEV_INT_sequence1//Задаем начальную анимацию
        entity_set_float(iNPC_IDEV_FL_animtimeget_gametime()) //Задаем время анимации
        entity_set_float(iNPC_IDEV_FL_framerate 1.0//Задаем скорость анимации
        entity_set_float(iNPC_IDEV_FL_frame0.0//Задаем начальный кадр
 
        RegisterHamFromEntity
(Ham_KillediNPC_ID"NPCKilled"//Задаем событие смерти
 
        
//Создаем в руках оружие
        new iWeapon create_entity("info_target")
 
        entity_set_int
(iWeaponEV_INT_solidSOLID_NOT//Не задаем никаких физичиских свойств
        entity_set_int(iWeaponEV_INT_movetypeMOVETYPE_FOLLOW//Задаем свойство следования объекта за игроком
        entity_set_edict(iWeaponEV_ENT_aimentiNPC_ID//Непосредственно прикрепление объекта к NPC
        entity_set_model(iWeapon"models/p_ak47.mdl"//Задаем модель( можете хоть гранатомет ему давать )
 
        
return PLUGIN_HANDLED //конец
}
 
public NPCThinkiEntity )
{
        if(!is_valid_entiEntity )) //Если NPC не существует
                return FMRES_IGNORED //Прекращаем дальшейнее выполнение функции
 
        
if(!is_user_aliveiPlayer_ID ) || !is_user_connectediPlayer_ID )) //Если игрок мертв или отсоеденился
        {
                remove_entityiEntity //Убираем NPC
                iNPC_ID //Сбрасываем идентификатор
 
                
return FMRES_IGNORED //Прекращаем дальшейнее выполнение функции
        }
 
        
new Float:fNOrigin[3], Float:fPOrigin[3//Сюда запишем координаты NPC и игрока
        new Float:fDistance //Сюда запишем расстяние между ними
    
        pev
(iEntitypev_originfNOrigin//Получаем координаты NPC
        pev(iPlayer_IDpev_originfPOrigin//Получаем координаты игрока
    
        fDistance 
get_distance_f(fNOriginfPOrigin//Получаем дистанцию между ними
 
        
if(fDistance <= floatget_pcvar_numg_Cvar[3] ) )) //Если дистация межде указанной
        {
                client_print(iPlayer_IDprint_center"[NPC]I caught up with you"//Чисто для прикола выводим, что NPC догнал нас
 
                
if(pev(iEntitypev_sequence) != 1//Если анимация npc установлена не стоячая
                {
                        entity_set_int(iEntityEV_INT_sequence1//Задаем анимацию стоячую
                        entity_set_float(iEntityEV_FL_animtimeget_gametime()) //Задаем время анимации
                        entity_set_float(iEntityEV_FL_framerate1.0//Задаем скорость анимации
                        entity_set_float(iEntityEV_FL_frame0.0//Задаем начальный кадр
                }
        }else{
                if(pev(iEntitypev_sequence) != 4//Если анимация npc установлена не бега
                {
                        entity_set_int(iEntityEV_INT_sequence4//Задаем анимацию бега
                        entity_set_float(iEntityEV_FL_animtimeget_gametime()) //Задаем время анимации
                        entity_set_float(iEntityEV_FL_framerate1.0//Задаем скорость анимации
                        entity_set_float(iEntityEV_FL_frame0.0//Задаем начальный кадр
                }
 
                
new Float:fAngles[3//Сюда запишем координаты, куда должен будет смотреть NPC
                new Float:fVelocity[3//Сюда запишем координаты, куда будет бежать NPC
 
                entity_get_vector
(iEntityEV_VEC_anglesfAngles//Получаем
 
                
new Float:fX fPOrigin[0] - fNOrigin[0//Расчитываем координаты x
                new Float:fZ fPOrigin[1] - fNOrigin[1//Расчитываем координаты z
 
                
new Float:fRadian
                fRadian 
floatatan(fZ/fXradian//Получаем угол
 
                fAngles
[1] = fRadian * (180 3.14//Приваиваем координаты
 
                
if(fPOrigin[0] < fNOrigin[0]) //Если координаты игрока относительно x меньше NPC`овскивх
                {
                        fAngles[1] = fAngles[1] - 180.0 //Разворачиваем его
                }else{
                        fAngles[1] = fRadian * (180 3.14//Записываем координаты
                }
 
                
new Float:fSpeed fDistance floatget_pcvar_numg_Cvar[2] ) ) //Задаем скорость
                
                
//Записываем координаты куда бежать
                fVelocity[0] = (fPOrigin[0] - fNOrigin[0]) / fSpeed
                fVelocity
[1] = (fPOrigin[1] - fNOrigin[1]) / fSpeed
                fVelocity
[2] = (fPOrigin[2] - fNOrigin[2]) / fSpeed
 
                entity_set_vector
(iEntityEV_VEC_anglesfAngles//Присваиваем новые координаты куда смотреть
                entity_set_vector(iEntityEV_VEC_velocityfVelocity//Присваиваем новые координаты куда бежать
        }
        entity_set_float(iEntityEV_FL_nextthinkhalflife_time() + 0.01//Повторяем
        return FMRES_HANDLED
}
 
public NPCKillediEntity )
{
        new iEntity2 create_entity("info_target"//Создаем нового, тот пропал
 
        
if(pev_validiEntity2 )) //Проверяем, создан ли объект
        {
                client_print(iPlayer_IDprint_chat"[NPC]Create Dead create"//Если да, пишем, что создан
        }else{
                client_print(iPlayer_IDprint_chat"[NPC]Error create"//Иначе выводим
                return PLUGIN_HANDLED //Прекращаем дальшейнее выполнение функции
        }
 
        
new Float:fOrigin[3], Float:fAngles[3//Запишем, как стоял старый NPC
    
        pev
(iEntitypev_originfOrigin//Получаем координаты
        pev(iEntitypev_anglesfAngles//Получаем куда смотрит
    
        entity_set_origin
(iEntity2fOrigin//Присваиваем
        entity_set_vector(iEntity2EV_VEC_anglesfAngles//Присваиваем
    
        entity_set_model
(iEntity2gModel//Задаем модель
    
        entity_set_size
(iNPC_IDFloat:{-16.0, -16.0, -36.0}, Float:{16.016.036.0}) //Задаем размеры( не путать с размером модели )
 
        entity_set_int
(iEntity2EV_INT_sequence108//Задаем анимацию смерти
        entity_set_float(iEntity2EV_FL_animtimeget_gametime()) //Задаем время анимации
        entity_set_float(iEntity2EV_FL_framerate1.0//Задаем скорость анимации
        entity_set_float(iEntity2EV_FL_frame0.0//Задаем начальный кадр
 
        set_task
(10.0"GibsNPC"iEntity2//Разорвем на куски npc через 10 сек и уничтожим его. 
        return PLUGIN_HANDLED //конец
}
 
public GibsNPCiEntity )
{
        new Float:fOrigin[3//Куда запишем
        pev(iEntitypev_originfOrigin//Получаем координаты
 
        
for(new isizeof gModelGibsi++) //Разбрасываем кости
        {
                message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
                write_byte(TE_MODEL)
                engfunc(EngFunc_WriteCoordfOrigin[0])
                engfunc(EngFunc_WriteCoordfOrigin[1])
                engfunc(EngFunc_WriteCoordfOrigin[2])
                write_coord(random_num(100400))
                write_coord(random_num(100400))
                write_coord(random_num(100400))
                write_angle(random361 ))
                write_short(gModelGibs[i])
                write_byte(1)
                write_byte(125)
                message_end()
        }
 
        
//Создаем кровь
        message_begin(MSG_BROADCASTSVC_TEMPENTITY
        write_byte(TE_BLOODSPRITE)
        engfunc(EngFunc_WriteCoordfOrigin[0])
        engfunc(EngFunc_WriteCoordfOrigin[1])
        engfunc(EngFunc_WriteCoordfOrigin[2])
        write_short(gSpriteBlood)
        write_short(gSpriteBlood)
        write_byte(250)
        write_byte(20)
        message_end()
 
        remove_entity
iEntity //Уничтожаем его нахер
        client_print(iPlayer_IDprint_chat"[NPC]Terminated"//Выводим сообщение что ли

Видео демонстрация:


У кого есть идеи, предложения, замечания - прошу высказывать. Всё будет учтено в продолжении статьи в скором времени

При копировании материала активная ссылка на amx-x.ru и указания автора обязательно
Аватара пользователя
crash94
 
Сообщения: 683
Зарегистрирован: 25 фев 2010, 16:34
Забанен
Благодарил (а): 80 раз.
Поблагодарили: 317 раз.

Re: Создание продвинутого NPC

Сообщение Opo4 » 14 авг 2013, 19:12

Сделать что-бы он мог прыгать и стрелять

P.S Идея
Аватара пользователя
Opo4
 
Сообщения: 674
Зарегистрирован: 21 апр 2012, 21:56
Забанен
Благодарил (а): 51 раз.
Поблагодарили: 65 раз.
Опыт программирования: Около года
Языки программирования: Counter-Strike 1.6
Valve Hammer Editor

Re: Создание продвинутого NPC

Сообщение emel-maks-va » 14 авг 2013, 19:18

недавно мне 1 человек говорил что что то вроде этого стоит около 2000 рублей :crazy:
Мод не продаю, заказы не принимаю, плагины не пишу, в кс не играю.
Аватара пользователя
emel-maks-va
 
Сообщения: 373
Зарегистрирован: 18 сен 2012, 21:32
Благодарил (а): 105 раз.
Поблагодарили: 88 раз.
Опыт программирования: Около 6 месяцев
Языки программирования: Counter-Strike 1.6
HTML
PHP
CSS

Re: Создание продвинутого NPC

Сообщение Ruslan4ik0 » 14 авг 2013, 19:41

crash94, а этот бот занимает слот?Если да,то как он будет вызываться если сервер полный?Будет 2/1?
Статус:свободен
Заказы:принимаю

Skype:ruslansklar
Аватара пользователя
Ruslan4ik0
 
Сообщения: 694
Зарегистрирован: 24 июл 2013, 09:47
Забанен
Благодарил (а): 20 раз.
Поблагодарили: 108 раз.
Опыт программирования: Около года
Языки программирования: Counter-Strike 1.6

Re: Создание продвинутого NPC

Сообщение Mistrick » 14 авг 2013, 20:03

Ruslan4ik0, там создают энтити, а не fakeclient. таких можно сотню наспавнить, главное чтобы сервер и клиент выдержал
Аватара пользователя
Mistrick
Скриптер
 
Сообщения: 2940
Зарегистрирован: 04 ноя 2012, 18:15
Благодарил (а): 43 раз.
Поблагодарили: 1247 раз.
Языки программирования: PAWN
С/С++(few above zero)

Re: Создание продвинутого NPC

Сообщение crash94 » 14 авг 2013, 20:38

emel-maks-va писал(а):недавно мне 1 человек говорил что что то вроде этого стоит около 2000 рублей :crazy:

Я бы не стал оценивать такой код в 2000р, но учитывая положение вещей - данная статья была подготовлена в целью написания плагина для 1 человек с форума, но я решил, что научить его будет куда ценее заказа. Да и несколько человек просили данную статью

Добавлено спустя 42 секунды:
Opo4 писал(а):Сделать что-бы он мог прыгать и стрелять

P.S Идея

Подготовлю #2 в включу твою идею

Добавлено спустя 46 секунд:
LYlink писал(а):Ruslan4ik0, там создают энтити, а не fakeclient. таких можно сотню наспавнить, главное чтобы сервер и клиент выдержал

Всё верно. Можно создать до 1000 ботов одновременно, но ни 1 карта не поддержит место на карте для такого кол-во точек
Аватара пользователя
crash94
 
Сообщения: 683
Зарегистрирован: 25 фев 2010, 16:34
Забанен
Благодарил (а): 80 раз.
Поблагодарили: 317 раз.

Re: Создание продвинутого NPC

Сообщение TurangaLeela » 14 авг 2013, 21:03

crash94 писал(а):Можно создать до 1000 ботов одновременно, но ни 1 карта не поддержит место на карте для такого кол-во точек

Точек ? мб обьектов ? Но в любом случае такую можно найти, а лимит 1к вовсе не проблема т.к. есть параметр запуска сервера, регламентирующий максимальное кол-во эдиктов (по умолчанию 4092).

Код: Выделить всё
register_think(gClassname"NPCThink"//Событие действий NPC 

Лучше регать по фактическому классу, в данном случае "info_target", ибо этот хук ловит абсолютно все финки и проверяет класснайм ...

Код: Выделить всё
RegisterHamFromEntity(Ham_KillediNPC_ID"NPCKilled"//Задаем событие смерти 

подобную регистрацию стоит делать лиш 1н раз для каждого нового типа, да, именно типа, по тому как отлов идет именно по типу обьекта а не индексу. Код желательно обновить

Код: Выделить всё
static iKilledReg 1;
if(
iKilledReg) {
iKilledReg 0;
RegisterHamFromEntity(Ham_KillediNPC_ID"NPCKilled"); //Задаем событие смерти

Код: Выделить всё
set_task(10.0"GibsNPC"iEntity2)
public 
GibsNPCiEntity 

Сомнительный код, особенно если учесть тот факт что игровое окружение могут меняь и другие плагины .. мб проверочку на валид + класс ? т.к. валидность индекса еще не о чем не говорит

PS
кстати, это примитивный npc
Аватара пользователя
TurangaLeela
 
Сообщения: 930
Зарегистрирован: 24 авг 2010, 11:19
Откуда: Некрополь у Кремлёвской стены
Благодарил (а): 10 раз.
Поблагодарили: 266 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Half-Life
Valve Hammer Editor 3.5
C | C++ | Java

Re: Создание продвинутого NPC

Сообщение Asmodai » 14 авг 2013, 21:11

А в чем тут продвинутость заключается? Стволы в хлсдк и то продвинутей.
Аватара пользователя
Asmodai
Адмирал
 
Сообщения: 466
Зарегистрирован: 24 фев 2011, 20:48
Благодарил (а): 0 раз.
Поблагодарили: 393 раз.
Языки программирования: Counter-Strike 1.6

Re: Создание продвинутого NPC

Сообщение trololost » 14 авг 2013, 21:15

TurangaLeela писал(а):PS
кстати, это примитивный npc

последние статьи что добавлялись - вообще детские, эта же мало-мальски свеженькая.
и если есть что дополнить - напиши статью для продвинутого npc
[Не принимаю заказы]
Аватара пользователя
trololost
 
Сообщения: 923
Зарегистрирован: 05 ноя 2011, 02:25
Благодарил (а): 104 раз.
Поблагодарили: 358 раз.

Re: Создание продвинутого NPC

Сообщение TurangaLeela » 14 авг 2013, 21:19

trololost писал(а):и если есть что дополнить - напиши статью для продвинутого npc

Дополнить есть чем - уже дополнил, а полноценную статью писать не буду, смысла нету - ее мало кто поймет, а кто поймет - и без этой статьи сделает все сам
Аватара пользователя
TurangaLeela
 
Сообщения: 930
Зарегистрирован: 24 авг 2010, 11:19
Откуда: Некрополь у Кремлёвской стены
Благодарил (а): 10 раз.
Поблагодарили: 266 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Half-Life
Valve Hammer Editor 3.5
C | C++ | Java

След.

Вернуться в Статьи / фрагменты кода

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10