Автор Тема: Написание плагина. Настройка проекта  (Прочитано 30777 раз)

Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 146
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr
Re: Написание плагина. Настройка проекта
« Ответ #255 : Март 12, 2019, 04:04:50 pm »
спасибо Вам огромное kenking за ответ. у меня пед выходит из машины с помощью    p->SetObjective(OBJECTIVE_LEAVE_CAR). чем отличается SetExitCar(car, 15)? 15 отвечает за выход педа, а какие числа еще есть, за что они отвечают? Скажите, пожалуйста, очень интересно.

Оффлайн kenking

  • Новичок
  • **
  • Сообщений: 213
  • Репутация: +13/-0
    • Просмотр профиля
Re: Написание плагина. Настройка проекта
« Ответ #256 : Март 12, 2019, 05:48:29 pm »
15 - это компонент  CAR_DOOR_LF (водитель выходит через левую переднюю дверь)
16 - CAR_DOOR_LR
11 - CAR_DOOR_RF
12 - CAR_DOOR_RR

Смотри eCarNodes

Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 146
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr
Re: Написание плагина. Настройка проекта
« Ответ #257 : Март 12, 2019, 05:52:27 pm »
спасибо большое

Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 146
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr
Re: Написание плагина. Настройка проекта
« Ответ #258 : Март 17, 2019, 01:17:21 pm »
Пытаюсь разобраться с функциями в sdk plugin,  с классом CPed, помогите, понять за что отвечают эти функции?
Код: C++
  1.                                 //ped->AttachPedToEntity();//?
  2.                                 //ped->DriveVehicle();//?
  3.                                 //ped->Duck();//?
  4.                                 //ped->BuyIceCream();// ?
  5.                                 //ped->Add();//?
  6.                                 //ped->BuildPedLists();//?
  7.                                 //ped->LookForInterestingNodes();//?
  8.                                 //ped->Dress();//пед дергается?
  9.                                 //ped->LoadFightData();//?
  10.                                 //ped->Idle();//??
  11.                                 //ped->Avoid();// избегает пед.
  12.                                 //ped->Flee();//?
  13.                                 //ped->Attack();//?
  14.                                 //ped->Fall();//пед падает
  15.                                 //ePedAction атака = 17;
  16.  

В некоторых функция есть параметр CEntity, что это за класс? Он использует в этой функции
 CEntity* AttachPedToEntity(CEntity* entity, CVector offset, unsigned short position, float angle, eWeaponType weaponType);

Очень хочу научиться писать плагины для gta vc.   

Оффлайн xanser

  • Главный Модератор
  • Постоялец
  • *****
  • Сообщений: 558
  • Репутация: +78/-0
  • Есть такая профессия - на работе сидеть
    • Просмотр профиля
Re: Написание плагина. Настройка проекта
« Ответ #259 : Март 18, 2019, 05:02:43 am »
Класс CEntity - это основа для всех сущностей игры: зданий, объектов, машин, людей, оружия и др, имеющих общие свойства, например идентификатор, матрицу поворота, флаги коллизии и прочее. От этого класса происходят остальные классы CVehicle, CPed и т.д. Функция AttachPedToEntity означает крепление педа к сущности, обычно к транспорту, как в некоторых миссиях, где пед стреляет с машины. Но можно крепить и к другим объектам, к карусели какой-нибудь, поэтому и используется общий класс CEntity.
Параметры функции:
entity - машина или другой объект, к которой происходит крепление педа
offset - точка крепления
position - от 0 до 3 - это сторона, в которую смотрит пед
angle - угол, на который может вращаться пед при стрельбе
weaponType - тип оружия

С остальными функциями надо разбираться, обычно из названия понятно, что они делают, дальше внутри смотри и ищи ссылки, откуда они вызываются. Например Ped->Dress() может переодеть педа. Если описать ее так, то можно менять скин игроку:

Код: C++
  1. void CPed::Dress(char * name) {
  2.         ((void(__thiscall *)(CPed *, char *))0x4EF030)(this, name);
  3.         ((void(__cdecl *)(bool _))0x40B5F0)(0);
  4.         ((void(__thiscall *)(CPed *))0x4EEFD0)(this);
  5. }
  6.  
  7. PlayerPed->Dress("player2");

А вообще не стоит все смешивать в одну кучу, вот зачем тебе все эти функции сразу, если непонятно их назначение. Выбери что-то конкретное и копай в этом направлении. Научиться писать плагины - это что-то слишком размытое. Ну напишешь ты 30 плагинов про все подряд, и что это будет? Лучше развивать конкретное направление, смотреть чего именно не хватает и собирать по кирпичику. Вообще эта тема зафлудилась.
« Последнее редактирование: Март 18, 2019, 05:07:39 am от xanser »

Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 146
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr
Re: Написание плагина. Настройка проекта
« Ответ #260 : Март 18, 2019, 10:30:26 pm »
Спасибо вам большое за ваш ответ  xanser. Выходит,Класс CEntity  является родительским классом, других классов, они от него  наследуются.

 Получается в некотором роде Функция AttachPedToEntity является аналогом 0464: put_actor 4@ into_turret_on_car 3@ at_car_offset 0.4242 -0.0679 1.1322 position 0 angle 360.0 with_weapon 30


 Хочется чтобы  всё было  максимально просто и понятно. значит  метод Ped->Dress(), мы можем переопределить сами.

согласен с вами,  лучше работать в одном направлении.  Есть  задача, чтобы ped нападал  на  игрока.
 Думал, сделать так, через функции не получилось.
Код: Text
  1. ped->Attack();
  2. ped->m_dwAction;
  3. ped->m_fAttachRot =17;
  4.  

пришлось, чтобы пед  атаковал игрока, использовать скриптовую команду.

Код: Text
  1. CPed *ped = randomfindped(player, 20.0);
  2. Command<COMMAND_SET_CHAR_OBJ_KILL_CHAR_ON_FOOT>(ped, player );
  3.  

Да, заработало, но не так хотел, нападают, при любом количестве нажатии на клавишу активации, максимум только 2.
как сделать это через функции, метода класса CPed?

Оффлайн kenking

  • Новичок
  • **
  • Сообщений: 213
  • Репутация: +13/-0
    • Просмотр профиля
Re: Написание плагина. Настройка проекта
« Ответ #261 : Март 19, 2019, 07:46:41 am »
Цитировать
Есть  задача, чтобы ped нападал  на  игрока.
Думал, сделать так, через функции не получилось.
пришлось, чтобы пед  атаковал игрока, использовать скриптовую команду.
Надо смотреть, как устроен соответствующий опкод в базе (я уже ранее писал про это). Опкоды:
01C9: actor $2324 kill_actor $2291
01CA: actor $853 kill_player $PLAYER_CHAR

в базе выглядят так:
Код: C++
  1. case SET_CHAR_OBJ_KILL_CHAR_ON_FOOT:
  2.       CRunningScript::CollectParameters(this, &this->m_nIp, 2);
  3.       CPed *ped_01C9 = CPool<CPed,CPlayerPed>::GetAt(CPools::ms_pPedPool, ScriptParams[0].m_nIntValue);
  4.       CPed *ped_01C9a = CPool<CPed,CPlayerPed>::GetAt(CPools::ms_pPedPool, ScriptParams[1].m_nIntValue);
  5.       ped_01C9->bfFlagsD &= 0x7F;
  6.       CPed::SetObjective(ped_01C9, OBJECTIVE_KILL_CHAR_ON_FOOT, ped_01C9a);
  7.       result = 0;
  8. break;
  9. case SET_CHAR_OBJ_KILL_PLAYER_ON_FOOT:
  10.       CRunningScript::CollectParameters(this, &this->m_nIp, 2);
  11.       CPed *ped_01CA = CPool<CPed,CPlayerPed>::GetAt(CPools::ms_pPedPool, ScriptParams[0].m_nIntValue);
  12.       id_01CA = ScriptParams[1].m_nIntValue;
  13.       ped_01CA->bfFlagsD &= 0x7F;
  14.       CPed::SetObjective(ped_01CA, OBJECTIVE_KILL_CHAR_ON_FOOT, CWorld::Players[id_01CA].m_pPed);
  15.       result = 0;
  16. break;

Значит в первом случае надо сделать так:
Код: C++
  1. pedOne->bfFlagsD &= 0x7F;
  2. CPed::SetObjective(pedOne, OBJECTIVE_KILL_CHAR_ON_FOOT, pedTwo);

Во втором случае с игроком так:
Код: C++
  1. ped->bfFlagsD &= 0x7F;
  2. CPed::SetObjective(ped, OBJECTIVE_KILL_CHAR_ON_FOOT, CWorld::Players[CWorld::PlayerInFocus].m_pPed);


Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 146
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr
Re: Написание плагина. Настройка проекта
« Ответ #262 : Март 20, 2019, 12:17:06 am »
Спасибо вам большое за вас ответ, kenking. сделал в цикле- находит людей, они начинают атаковать меня. Всё хорошо, но есть 2 но, враги  они становится медленнее находится чем на cleo, через пару минут  игра вылетает, Как решить данную проблему?

Код: Text
  1.  
  2. CPed* randomfindped(CPed *p, float radius) {CVehicle* v = NULL;
  3.  
  4.         if (p->m_bInVehicle && p->m_pVehicle != NULL) {// в авто игрок?
  5.                 CVehicle *v = p->m_pVehicle;    }// получить указатель на хенлд авто в котором сидит томии.
  6.         for (auto car : CPools::ms_pVehiclePool) {
  7.                 if (car != v && DistanceBetweenPoints(car->GetPosition(), p->GetPosition()) < radius && car->m_fHealth > 50) {
  8.                 car->CanPedExitCar(true);
  9.                 if (CPed*ped = car->m_pDriver) {if (ped != NULL && ped != p) {
  10.                         CMessages::AddMessageJumpQ("found ped", 1000, 0);//выводит сообщение на экран
  11.                                 return ped;     }}}}
  12.         for (auto ped : CPools::ms_pPedPool) {
  13.                 if (ped != p && DistanceBetweenPoints(ped->GetPosition(), p->GetPosition()) < radius && ped->m_fHealth > 50) {
  14.                         CMessages::AddMessageJumpQ("found ped", 1000, 0);//выводит сообщение на экран
  15.                         return ped;     }}
  16.        
  17.                  CMessages::AddMessageJumpQ("not found ped", 1000, 0);  
  18. };
  19. bool flag = false;
  20. class Message {//имя класса
  21. public:
  22.         Message() {
  23.                 Events::gameProcessEvent += [] {//обработчик событий игры
  24.                                 CPed *player = FindPlayerPed();// найти игрока
  25.                         KeyCheck::Update();
  26.                         if (KeyCheck::CheckWithDelay('M', 200)|| flag==true) {//если м нажата
  27.                                 flag=true;
  28.                                 if (!player) return;// проверка найден игрок
  29.                                 CPed *ped = randomfindped(player, 20.0);
  30.                                 //ped->bfFlagsD &= 0x7F;//это метода нет
  31.                                 ped->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, CWorld::Players[CWorld::PlayerInFocus].m_pPed);
  32.                         }};
  33.         }
  34. } message;
  35.  

все работает без проблем.

Код: Text
  1. CPed* randomfindped(CPed *p, float radius) {CVehicle* v = NULL;
  2.  
  3.         if (p->m_bInVehicle && p->m_pVehicle != NULL) {// в авто игрок?
  4.                 CVehicle *v = p->m_pVehicle;    }// получить указатель на хенлд авто в котором сидит томии.
  5.         for (auto car : CPools::ms_pVehiclePool) {
  6.                 if (car != v && DistanceBetweenPoints(car->GetPosition(), p->GetPosition()) < radius && car->m_fHealth > 50) {
  7.                 car->CanPedExitCar(true);// пед может выйти из авто
  8.                 if (car->m_pDriver != NULL && car->m_pDriver != p) {
  9.                         CMessages::AddMessageJumpQ("found ped", 1000, 0);//выводит сообщение на экран
  10.                         return car->m_pDriver;
  11.                 }
  12.  
  13.         }
  14. }
  15.         for (auto ped : CPools::ms_pPedPool) {
  16.                 if (ped != p && DistanceBetweenPoints(ped->GetPosition(), p->GetPosition()) < radius && ped->m_fHealth > 50) {
  17.                         CMessages::AddMessageJumpQ("found ped", 1000, 0);//выводит сообщение на экран
  18.                         return ped;     }
  19.        
  20.         }
  21.                  CMessages::AddMessageJumpQ("not found ped", 1000, 0);  
  22.                         return NULL;
  23. };
  24. bool flag = false;
  25. class Message {//имя класса
  26. public:
  27.         Message() {
  28.                 Events::gameProcessEvent += [] {//обработчик событий игры
  29.                                 CPed *player = FindPlayerPed();// найти игрока
  30.                         KeyCheck::Update();
  31.                         if (KeyCheck::CheckWithDelay('M', 200)|| flag==true) {//если м нажата
  32.                                 flag=true;
  33.                                 if (!player) return;// проверка найден игрок
  34.                                 CPed *ped = randomfindped(player, 20.0);
  35.  
  36.                                 if (ped == NULL) return;// проверка найден игрок
  37.                                 ped->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, CWorld::Players[CWorld::PlayerInFocus].m_pPed);
  38.                         }
  39.                 };
  40.         }
  41. } message;
  42.  
« Последнее редактирование: Март 20, 2019, 01:39:29 am от egor230 »

Оффлайн kenking

  • Новичок
  • **
  • Сообщений: 213
  • Репутация: +13/-0
    • Просмотр профиля
Re: Написание плагина. Настройка проекта
« Ответ #263 : Март 20, 2019, 08:00:56 am »
Цитировать
//ped->bfFlagsD &= 0x7F;//это метода нет
Это установка флага. В базе и в sdk записи в данный момент не совпадают и не все флаги "обозначены" правильно.
Надо так:
Код: C++
  1. ped->m_nPedFlags.b32 = 0;

Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 146
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr
Re: Написание плагина. Настройка проекта
« Ответ #264 : Март 21, 2019, 03:59:08 am »
 Спасибо за ваш ответ kenking. Всё таки получилось создать педа. Но вопрос правильно ли?
Код: Text
  1. CPed * create(int modelID) {// создать pedа
  2.         char reference = 2;// чтобы удалился потом.
  3.         CPed *player = FindPlayerPed();
  4.         CVector position = player->m_placement.pos;
  5.         position += player->m_placement.up * 10.f; // Вектор оси прямо от игрока умножаем на 10 метров и прибавляем к позиции.
  6.         CStreaming::RequestModel(modelID, 0); // загрузим.
  7.         CStreaming::LoadAllRequestedModels(false);// модель загружена.
  8.         CPed *ped = new CCivilianPed(PEDTYPE_COP, modelID);
  9.                
  10.         ped->m_nState = 4;// флаг
  11.         ped->m_placement.SetRotate(0, 0, 3.5f);// смещение от координат игрока
  12.         ped->m_placement.pos.x = position.x;
  13.         ped->m_placement.pos.y = position.y;
  14.         ped->m_placement.pos.z = position.z;
  15.         CWorld::Add(ped);// добавить в мир педа.
  16.         return ped;    
  17. }
  18.  

за что отвечают эти функции?
Код: Text
  1.  //v->CollideWithPed(player);//??
  2. // v->HasAttractor();//??
  3. // v->Initialise();//?
  4.  

как заставить педа бежать к координатам? в некоторые функциях есть параметр CVector, что передаем в таком случае?

Оффлайн kenking

  • Новичок
  • **
  • Сообщений: 213
  • Репутация: +13/-0
    • Просмотр профиля
Re: Написание плагина. Настройка проекта
« Ответ #265 : Март 21, 2019, 10:01:02 am »
Цитировать
как заставить педа бежать к координатам?
В который раз объясняю, что надо смотреть в базе, как устроен соответствующий опкод, без этого не разберёшься.
Код: C++
  1. CPed *ped;
  2. CVector *point;
  3. ped->m_nPedFlags.b32 = 0;
  4. CPed::SetObjective(ped, OBJECTIVE_RUN_TO_AREA, point);

Цитировать
в некоторые функциях есть параметр CVector, что передаем в таком случае?
Вектор и передаём.

Цитировать
за что отвечают эти функции?
Переведи названия функций, смотри в базе, где они вызываются, может используются в каких-либо скриптовых командах (опкодах).

Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 146
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr
Re: Написание плагина. Настройка проекта
« Ответ #266 : Март 28, 2019, 07:56:34 pm »
благодарю Вас за помощь kenking. пытаюсь разобраться. Вы пишите- надо смотреть как устроен в базе.
хорошо, что нужно изучить?  Чтобы в ней разбираться.  Было бы здорово к каждой функции иметь  комментарий, для лучшего понимания.
 Не всегда название функции, помогают понять как они работают.
 Всё это время вникал в класс cped,  Вот, Может это кому-то облегчить путь.
Код: C++
  1.  
  2.                                 // v->ClearInvestigateEvent();// пед уходит, опустить педа.
  3.                                 // v->ReactToAttack(player);// временно атакует
  4.                                 // CVector pla = player->m_placement.pos;
  5.                                 // CVector ped = v->m_placement.pos;
  6.                                  //v->FightHitPed(player,ped,pla,1);// как бы получает удар и теряет хп.
  7.  
  8.                                  
  9.                                  // чем отличается способы получение вектора?
  10.                                   CVector pos = player->GetPosition(); 
  11.                                    //CVector pos = player->m_placement.pos;                            
  12.  
  13.                                   // телепорт чем отличает 2 функции телепорта?                                                                                     
  14.                                  //player->m_placement.SetTranslate(pos.x, pos.y, pos.z + 13.0f);
  15.                                  //player->m_placement.SetTranslateOnly(pos.x, pos.y, pos.z + 13.0f);
  16.                                  
  17.                                  //v->m_placement.RotateX(45.0);// перемещение, поворот.
  18.                                  //player->m_placement.SetRotate(pos.x, pos.y, pos.z + 13.0f);// телепорт.
  19.                                  //player->m_placement.Rotate(pos.x, pos.y, pos.z + 13.0f);// телепорт в разные места.
  20.                
  21.                                  // v->CanPedJumpThis(player, pos.x);//?? прыжок?.
  22.                                 //v->Mug();//?
  23.                                  //v->DeadPedMakesTyresBloody();//?? может быть кровавые следы педа.
  24.  
  25.                                   //v->SetObjective(player, OBJECTIVE_RUN_TO_AREA, &pos);//не получается заставить идти педа в координаты.
  26.  

Оффлайн kenking

  • Новичок
  • **
  • Сообщений: 213
  • Репутация: +13/-0
    • Просмотр профиля
Re: Написание плагина. Настройка проекта
« Ответ #267 : Март 29, 2019, 12:39:32 pm »
Цитировать
Вы пишите- надо смотреть как устроен в базе.
хорошо, что нужно изучить?  Чтобы в ней разбираться.
Отрыть базу в IDA. Взять простой опкод или простую функцию и попытаться понять, разобрать как он  устроен (как работает функция). Мне легче разбирать в псевдокоде (F5).

Цитировать
Не всегда название функции, помогают понять как они работают.
Поэтому я и написал, что надо смотреть в базе, где вызываются эти функции.

Цитировать
// чем отличается способы получение вектора?
CVector pos = player->GetPosition(); 
//CVector pos = player->m_placement.pos;
Ничем.
Код: C++
  1. inline CVector &GetPosition() {
  2.     return m_placement.pos;
  3. }

Цитировать
// телепорт чем отличает 2 функции телепорта?
Если в названии функции есть приставка Only, то при вращении (например, компонента транспорта) не придётся сохранять координаты позиции компонента, компонент просто повернётся на указанный градус и останется в той же позиции. Если использовать "похожую" функцию без этой приставки в названии, то надо перед вращением считывать координаты позиции компонента, после вращения их восстанавливать, так как координаты сбросятся в ноль после вращения. Аналогично для функций перемещения, только для значений углов поворота.

 
Цитировать
// v->CanPedJumpThis(player, pos.x);//?? прыжок?.
Это проверка может ли сделать прыжок. Смотри в базе, где вызывается
Код: C++
  1. if ( CPed::CanPedJumpThis(ped, pedTwo, &ped->physical.m_vecCollisionPower) )
  2.     CPed::SetJump(ped);
Обращай внимание на параметры.

Цитировать
//v->SetObjective(player, OBJECTIVE_RUN_TO_AREA, &pos);//не получается заставить идти педа в координаты.
Код: C++
  1. CVector offset = { 0.0f, 20.0f, 0.0f };
  2. CVector point = player->m_placement * offset;
  3. player->m_nPedFlags.bHasObjectiveCompleted = 0;
  4. player->SetObjective(OBJECTIVE_RUN_TO_AREA, point);

Что касается других функций. Сделай какой-нибудь простой плагин для тестов, например, так.
Код: C++
  1. #include "plugin.h"
  2. #include "CPed.h"
  3. #include "extensions\KeyCheck.h"
  4.  
  5. using namespace plugin;
  6.  
  7. class Test {
  8. public:
  9.     static CPed *GetRandomPed(CVector const &posn, float radius) {
  10.         std::vector<CPed *> peds;
  11.         for (auto ped : CPools::ms_pPedPool) {
  12.             if (DistanceBetweenPoints(ped->GetPosition(), posn) <= radius)
  13.                 peds.push_back(ped);
  14.         }
  15.         return peds.empty() ? nullptr : peds[plugin::Random(0, peds.size() - 1)];
  16.     }
  17.    
  18.     Test() {
  19.         Events::gameProcessEvent += [] {
  20.             KeyCheck::Update();
  21.             if (KeyCheck::CheckWithDelay('M', 500)) {
  22.                 CPed *player = FindPlayerPed();
  23.                 if (player) {
  24.                     CPed *ped = GetRandomPed(player->GetPosition(), 15.0f);
  25.                     if (ped) {
  26.                         CVector offset = { 0.0f, 2.0f, 0.0f };
  27.                         CVector point = player->m_placement * offset;
  28.                         ped->m_nPedFlags.bHasObjectiveCompleted = 0;
  29.                         ped->SetObjective(OBJECTIVE_RUN_TO_AREA, point);
  30.                     }
  31.                 }
  32.             }
  33.         };
  34.     }
  35. } test;

и проверяй нужные тебе функции (не забывай про правильную передачу параметров).



Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 146
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr
Re: Написание плагина. Настройка проекта
« Ответ #268 : Май 29, 2019, 09:52:23 am »
Здравствуйте, уважаемый kenking.   Спасибо большое я ваш  ответ. сделал плагин для тестов,  изучаю  Assembler  идёт очень тяжело.

 Пытаюсь разобрать функции  в псевдокоде, иногда псевкод простой функции отражается так.  Может, он не так должен отображается?

  Благодарю благодарю Вас за объяснения функций телепорта,  буду изучать как это работает на практике.
 Выходит это проверка сделан ли прыжок.
 Насчёт функции player->SetObjective(OBJECTIVE_RUN_TO_AREA, point);// заставить педа бежать в точку.  А функция ped->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, point);// пед идет.

 Вообще  функция SetObjective  имеет 5  перегрузки.
    void SetObjective(eObjective objective);// emun.
    void SetObjective(eObjective objective, CVector arg1);// emun и вектор.
    void SetObjective(eObjective objective, float arg1, CVector const& arg2);// emun, float, вектор.
    void SetObjective(eObjective objective, short arg1, short arg2);// emun, int, int.
    void SetObjective(eObjective objective, void* arg1);// emun, функция.

 Это понятно,  теперь  допустим берём emun OBJECTIVE_SOLICIT_VEHICLE,  какие параметры передать в функцию SetObjective. Поймите меня правильно,  Очень хочу разобраться в этом.  Например, более- менее  понимаю в api lua,  вот написал  небольшую  подсказку новичкам
код https://pastebin.com/8f9UH56W

 Мне бы хотелось в будущем  написать  статьи,  Как создавать плагины.
 Посоветуйте пожалуйста,  какую литературу прочитать,  чтобы  понимать основы работы движка игры?
« Последнее редактирование: Май 29, 2019, 09:59:31 am от egor230 »

Оффлайн kenking

  • Новичок
  • **
  • Сообщений: 213
  • Репутация: +13/-0
    • Просмотр профиля
Re: Написание плагина. Настройка проекта
« Ответ #269 : Май 29, 2019, 08:12:16 pm »
Цитировать
теперь  допустим берём emun OBJECTIVE_SOLICIT_VEHICLE,  какие параметры передать в функцию SetObjective.
Код: C++
  1. CPed *ped;
  2. CVehicle *vehicle;
  3. ped->SetObjective(OBJECTIVE_SOLICIT_VEHICLE, vehicle);

Цитировать
Пытаюсь разобрать функции  в псевдокоде, иногда псевкод простой функции отражается так.  Может, он не так должен отображается?
Учиться разбирать надо с маленьких функций.
Возьмём для примера функцию CPed::SetObjectiveTimer
Нажимаем F5 и получаем такой псевдокод:
Код: C++
  1. unsigned int __thiscall CPed::SetObjectiveTimer(int this, int a2)
  2. {
  3.   unsigned int result; // eax@2
  4.  
  5.   if ( a2 )
  6.   {
  7.     result = *(_DWORD *)(this + 1360);
  8.     if ( CTimer::m_snTimeInMilliseconds > result )
  9.     {
  10.       result = CTimer::m_snTimeInMilliseconds + a2;
  11.       *(_DWORD *)(this + 1360) = CTimer::m_snTimeInMilliseconds + a2;
  12.     }
  13.   }
  14.   else
  15.   {
  16.     *(_DWORD *)(this + 1360) = 0;
  17.   }
  18.   return result;
  19. }

Это метод класса CPed, значит первым параметром передаётся указатель на этот класс.
Ставим курсор мышки на this, нажимаем Y и вводим вместо int CPed* (или можно нажать правую клавишу мыши и в контекстном меню выбрать Convert to struct* и выбрать из списка имеющихся в базе структур CPed)
Получается так:
Код: C++
  1. unsigned int __thiscall CPed::SetObjectiveTimer(CPed *this, int a2)
Смотрим тип второго аргумента, там должен быть unsigned int, а у нас int, исправляем (курсор мыши на a2, нажимаем Y и добавляем unsigned перед int):
Код: C++
  1. unsigned int __thiscall CPed::SetObjectiveTimer(CPed *this, unsigned int a2)
Переменную a2 переименуем в time, курсор мыши на a2, нажимаем N и вводим time:
Код: C++
  1. unsigned int __thiscall CPed::SetObjectiveTimer(CPed *this, unsigned int time)
Смотрим в тех функциях, где вызывается эта функция есть ли возвращаемое значение (клавиша X и переход в место, где эта функция вызывается).
В данном случае возвращаемого значения нет. Меняем тип возвращаемого значения на void, курсор на названии функции и Y, воодим void вместо unsigned int:
Код: C++
  1. void __thiscall CPed::SetObjectiveTimer(CPed *this, unsigned int time)

Можно было все вышеперечисленные правки сделать в этом последнем действии (Y на названии функции и ввод нужных данных и изменение названий переменных), показал отдельно для наглядности.
В итоге получилось так:
Код: C++
  1. void __thiscall CPed::SetObjectiveTimer(CPed *this, unsigned int time)
  2. {
  3.   if ( time )
  4.   {
  5.     if ( CTimer::m_snTimeInMilliseconds > this->m_nObjectiveTimer )
  6.       this->m_nObjectiveTimer = CTimer::m_snTimeInMilliseconds + time;
  7.   }
  8.   else
  9.   {
  10.     this->m_nObjectiveTimer = 0;
  11.   }
  12. }

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


Возьмём для второго примера ещё одну небольшую функцию CPed::Teleport
Нажимаем F5 и получаем такой псевдокод:
Код: C++
  1. char __thiscall CPed::Teleport(CEntity *this, float a2, int a3, int a4)
  2. {
  3.   CEntity *v4; // ebx@1
  4.  
  5.   v4 = this;
  6.   CWorld::Remove(this);
  7.   v4->m_placement.m_matrix.pos.x = a2;
  8.   v4->m_placement.m_matrix.pos.y = *(float *)&a3;
  9.   v4->m_placement.m_matrix.pos.z = *(float *)&a4;
  10.   LOBYTE(v4[3].m_placement.m_matrix.pad1) &= 0xFEu;
  11.   v4[5].m_pRwObject = 0;
  12.   v4[5].m_placement.m_matrix.pAttached = 0;
  13.   v4[5].m_placement.m_matrix.bDeleteOnDetach = 0;
  14.   v4[2].m_placement.m_matrix.pad4 = 0;
  15.   return CWorld::Add((CPhysical *)v4);
  16. }

Это метод класса CPed, но сейчас в псевдокоде почему-то класс CEntity, вместо второго параметра CVector одна переменная типа float и две типа int, возвращаемое значение стоит char, хотя функция ничего не должна возвращать. Будем исправлять.
Нажимаем Y на названии функции и водим нужные данные:
Код: C++
  1. void __thiscall CPed__Teleport(CPed *this, CVector point)
Переименовываем переменную v2 в ped.
Получаем такой псевдокод:
Код: C++
  1. void __thiscall CPed::Teleport(CPed *this, CVector point)
  2. {
  3.   CPed *ped; // ebx@1
  4.  
  5.   ped = this;
  6.   CWorld::Remove(&this->physical.entity);
  7.   ped->physical.entity.m_placement.matrix.pos = point;
  8.   ped->bfFlagsA &= 0xFEu;
  9.   ped->m_nActionTimer = 0;
  10.   ped->fActionX = 0;
  11.   ped->fActionY = 0;
  12.   ped->physical.m_pPhysColliding = 0;
  13.   CWorld::Add(&ped->physical);
  14. }

Ну тут тоже всё стало понятно (за исключением установки какого-то флага, но это отдельная история, не все флаги названы).
Изменения надо сохранить в базе (нажать на иконку сохранения).