Ответ

Имя:
E-mail:
Тема:
Иконка:

Вложение:
(Удалить вложение)
(Добавить ещё)
Ограничения: максимум вложений в сообщении — 4, максимальный размер всех файлов — 192 Кбайт, максимальный размер одного файла — 128 Кбайт
Визуальная проверка:
Наберите символы, которые изображены на картинке
Прослушать / Запросить другое изображение

Наберите символы, которые изображены на картинке:
О какой игре форум? (три буквы заглавные):
Сколько будет (5*5 + 2) ответ цифрой.:

подсказка: нажмите alt+s для отправки или alt+p для предварительного просмотра сообщения


Сообщения в этой теме

Автор: kenking
« : Июль 09, 2019, 08:27:14 am »

Код: C++
  1. #include "plugin.h"
  2. #include "CMessages.h"
  3. #include "CWorld.h"
  4. #include "extensions\ScriptCommands.h"
  5. #include "eScriptCommands.h"
  6. #include "extensions\KeyCheck.h"
  7.  
  8. using namespace plugin;
  9.  
  10. class Test {
  11. public:
  12.     Test() {
  13.  
  14.         Events::gameProcessEvent += [] {
  15.             CPed *player = FindPlayerPed();
  16.             if (player) {
  17.                 CVector point = { 241.6f, -1283.0f, 10.9f };
  18.                 if (Command<COMMAND_LOCATE_PLAYER_ANY_MEANS_3D>(CWorld::PlayerInFocus, point.x, point.y, point.z, 2.0, 2.0, 2.0))
  19.                     CMessages::AddMessageJumpQ(L"Yes", 1000, 1);
  20.                 //
  21.                 static int sphere;
  22.                 KeyCheck::Update();
  23.                 if (KeyCheck::CheckWithDelay('M', 2000)) {
  24.                     CVector pos = FindPlayerPed()->TransformFromObjectSpace(CVector(0.0f, 5.0f, 0.0f));
  25.                     Command<COMMAND_ADD_SPHERE>(pos.x, pos.y, pos.z, 2.0, &sphere);
  26.                     CMessages::AddMessageJumpQ(L"Create", 2000, 1);
  27.                 }
  28.                 if (KeyCheck::CheckWithDelay('N', 2000)) {
  29.                     Command<COMMAND_REMOVE_SPHERE>(sphere);
  30.                     CMessages::AddMessageJumpQ(L"Delete", 2000, 1);
  31.                 }
  32.             }
  33.         };
  34.     }
  35. } test;
Автор: egor230
« : Июль 08, 2019, 11:36:51 pm »

Здравствуйте, уважаемый kenking, Спасибо вам большое, что уделили мне время.
 классный код, Вы четко и грамотно пиши код, Вы очень помогли. реализовал выдачу оружие педу

 У меня получилось сделать, чтобы клавиша срабатывала один раз, нажал, отпустил- действие, это помогает избежать залипание клавиш.
Код: Text
  1. //Нажать на клавишу один раз.
  2.  
  3. bool wait(unsigned int key) {
  4.         if (!KeyCheck::CheckWithDelay(key, 200)) { return true; }
  5.         else { return false; }
  6. }
  7.  
  8. class Message {//имя класса
  9. public:
  10.         Message() {
  11.                 Events::gameProcessEvent += [] {//обработчик событий игры
  12.                         CPed* player = FindPlayerPed();// найти игрока
  13.                         if (!player) return;// проверка найден игрок
  14.                         KeyCheck::Update();
  15.                         if (KeyCheck::CheckWithDelay('N', 200)) {//если N нажата
  16.                                 if (wait('N')) return; {//если м нажата
  17.                                 CMessages::AddMessageJumpQ(L"message", 2000, false);
  18.                                 }
  19.                         }
  20.                 };
  21.         }
  22. } message;
  23.  
  24.  

потом решил создать сферу и удалить ее, но тут встретился интересный нюанс, когда сферу создаешь первый раз, она через секунду удаляется. второй раз создается и удаляется, как было задумано. это какой-то глюк. Специально записал на видео этот глюк автоматическое
удаление сферы при первом ее создании. https://www.youtube.com/watch?v=BAoS1yaKakk&feature=youtu.be
может я что-то не так делаю?
Код: Text
  1. class Sphere1 {//имя класса
  2. public:
  3.         Sphere1() {
  4.                 static  int sphere;
  5.                 Events::gameProcessEvent += [] {//обработчик событий игры
  6.                         KeyCheck::Update();
  7.                         CPed* player = FindPlayerPed();// найти игрока
  8.                         if (!player) return; {
  9.                                 if (KeyCheck::CheckWithDelay('B', 1900)) {// проверка найден игрок
  10.                                         CMessages::AddMessageJumpQ(L"Create", 2000, 1);//выводит сообщение на экран
  11.                                         CVector* pos = worldcoord(player, 1.0, 10.0); //Нахождения координат на 10 от взгляда томми.
  12.                                         Command<COMMAND_ADD_SPHERE>(pos->x, pos->y, pos->z, 2.0, &sphere);
  13.                                 }
  14.                                 if (KeyCheck::CheckWithDelay('N', 1900)) { // (KeyCheck::CheckWithDelay('B', 200)) //если м нажата
  15.                                         CMessages::AddMessageJumpQ(L"delete", 2000, 1);  //выводит сообщение на экран.  
  16.                                         Command<COMMAND_REMOVE_SPHERE>(sphere);// удалить сферу.  
  17.                                 }
  18.                         }
  19.                 };
  20.         }
  21. } sphere1;
  22.  

Стараюсь разобраться со скриптовой командой, проверкой на нахождения в заданных координатах, вроде передаю параметры правильно.
Код: Text
  1. Создать маркер сферу и проверка на координаты.
  2.  
  3. class Message {//имя класса
  4. public:
  5.         Message() {
  6.  Events::gameProcessEvent += [] {//обработчик событий игры
  7. CVector* pos;
  8. static  int sphere;
  9.          KeyCheck::Update();
  10.          CPed* player = FindPlayerPed();// найти игрока
  11.          if (!player) return; {
  12.                  if (KeyCheck::CheckWithDelay('B', 1900)) {// проверка найден игрок
  13.                          CMessages::AddMessageJumpQ(L"Create", 2000, 1);//выводит сообщение на экран
  14.                          pos = worldcoord(player, 1.0, 10.0); //Нахождения координат на 10 от взгляда томми.
  15.                          Command<COMMAND_ADD_SPHERE>(pos->x, pos->y, pos->z, 2.0, &sphere);    
  16.                          //double x = pos->x;
  17.                          //double z = pos->y;
  18.                          //double z = pos->z;
  19.                  }
  20.          if (Command<COMMAND_LOCATE_PLAYER_ANY_MEANS_3D>(CWorld::PlayerInFocus, true, pos->x, pos->y, pos->z, 2.0, 2.0, 2.0))
  21.          { CMessages::AddMessageJumpQ(L"delete", 2000, 1); }     //выводит сообщение на экран.  
  22.           }
  23.          };
  24.   }
  25. } message;             
  26.  
  27.  
  28.  


У нас есть много условно говоря функций(методов разных классов), с++ можно использовать как библиотеку классов и  функций, а lua их выполняет, то есть их реализовывает.
вот действия скрипта.
по нажатию клавиши “G”, создать пед, который побежит к девушке на маркере, клавишей “K” откроет огонь по ней.
видео   https://www.youtube.com/watch?v=0eIs4lqNRxI&feature=youtu.be
теперь код, он прост.
Код: Text
  1. require("lualoader/mod")
  2. --model = VICE8
  3. function main()
  4. while lualoader == nil do
  5.  wait()
  6.  player = findplayer()-- получить игрока
  7.  if Keypress(VK_G)
  8.  then     x,y,z = getworldcoordped(player,1.0,4)-- получить координаты на 4 м впереди от томми.
  9.  man = Createped("BMODK",x,y,z)-- создать педа(убийцу).
  10.  Giveweaponped(man,m4,100)-- дать педу оружие.
  11.  mar = create_marker_actor(man) -- создать маркер педа.
  12.  x,y,z = getworldcoordped(man,0.1,30)-- получить координаты на 30 м впереди от педа.
  13.  woman = Createped("HFYPR",x,y,z)-- создать педа(жертву).
  14.   sp = create_sphere(x,y,z, 1.5)-- создать сферу, последний параметр радиус.
  15.   x,y,z = getworldcoordped(woman,0.1,-4)-- получить координаты на 4 м сзади от жертвы.
  16.  ped_sprint_to_point(man, x,y,z)-- в эту точку делает спринт убийца.
  17.  wait(3000)-- задержка.
  18.  ped_aim_at_ped(man, woman)-- пед целиться в педа.
  19. --printmessage("created by the killer and victim", 2500, 3)
  20. end
  21.  if Keypress(VK_K)
  22.  then Kill_ped_on_foot(man, woman)-- пед хочет убить другого педа.
  23. removemarker(mar)-- удалить маркер над педом.
  24. remove_sphere(sp) -- удалить сферу.
  25.  end
  26. end
  27. end
  28.  

видите легко реализовать свои задумки на lua.
Автор: kenking
« : Июль 04, 2019, 01:17:35 pm »

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

Цитировать
Мне нужна именно функция таймер, например, передаешь 1000 мс, получаешь задержку в 1 сек, пробовал через рекурсии не выходит.
Задержку по времени между выполнением действий в теме была показана ранее на примере нажатия клавиши. Вот такой пример. Загрузка модели и создание педа вынесены в отдельные функции.
Код: C++
  1. #include "plugin.h"
  2. #include "CMessages.h"
  3. #include "CWorld.h"
  4. #include "CStreaming.h"
  5. #include "CTimer.h"
  6. #include "ePedModel.h"
  7. #include "ePedType.h"
  8. #include "CCivilianPed.h"
  9.  
  10. using namespace plugin;
  11.  
  12. class Test {
  13. public:
  14.     static bool LoadModel(int model) {
  15.         unsigned char oldFlags = CStreaming::ms_aInfoForModel[model].m_nFlags;
  16.         CStreaming::RequestModel(model, GAME_REQUIRED);
  17.         CStreaming::LoadAllRequestedModels(false);
  18.         if (CStreaming::ms_aInfoForModel[model].m_nLoadState == LOADSTATE_LOADED) {
  19.             if (!(oldFlags & GAME_REQUIRED)) {
  20.                 CStreaming::SetModelIsDeletable(model);
  21.                 CStreaming::SetModelTxdIsDeletable(model);
  22.             }
  23.             return true;
  24.         }
  25.         return false;
  26.     }
  27.  
  28.     static CPed *CreatePed(ePedType pedType, unsigned int modelIndex) {
  29.         CPed *ped = nullptr;
  30.         if (LoadModel(modelIndex)) {
  31.             ped = new CCivilianPed(pedType, modelIndex);
  32.             if (ped) {
  33.                 ped->SetPosition(FindPlayerPed()->TransformFromObjectSpace(CVector(0.0f, 2.0f, 0.0f)));
  34.                 CWorld::Add(ped);
  35.             }
  36.         }
  37.         return ped;
  38.     }
  39.  
  40.     Test() {
  41.         static int keyPressTime = 0;
  42.  
  43.         Events::gameProcessEvent += [] {
  44.             CPed *player = FindPlayerPed();
  45.             if (player) {
  46.                 if (KeyPressed('M') && CTimer::m_snTimeInMilliseconds > (keyPressTime + 5000)) {
  47.                     keyPressTime = CTimer::m_snTimeInMilliseconds;
  48.                     CPed *ped = CreatePed(PEDTYPE_CIVFEMALE, MODEL_HFYST);
  49.                     if (ped)
  50.                         CMessages::AddMessageJumpQ(L"CreatePed", 1000, 0);;
  51.                 }
  52.             }
  53.         };
  54.     }
  55. } test;

Как я уже писал ранее, по работе с lua ничего подсказать не могу.
Зачем ты смешиваешь код lua и плагин? Что такого можно сделать в lua, чего нельзя сделать в плагине? Хотя в lua я не разбираюсь, может чего и можно.
Автор: egor230
« : Июль 03, 2019, 03:34:34 pm »

Здравствуйте, уважаемый kenking за Ваш ответ. Написал функции определения типов педа и оружие(конечно, буду дорабатывать).
Все хорошо с lua плагином, но есть одно но. Пытаюсь сделать функцию таймер.

Обычно таймер делается так.
Код: C++
  1.         static unsigned int time = 0;// обнулить таймер.
  2.         if (CTimer::m_snTimeInMilliseconds - time > 500) {
  3.                 time = 0; // обнулить таймер
  4.  
  5.  

Мне нужна именно функция таймер, например, передаешь 1000 мс, получаешь задержку в 1 сек, пробовал через рекурсии не выходит.
Код: C++
  1. CVector* worldcoord(CPed* ped, float x = 1.0, float y = 1.0) {
  2.                 CVector& pos1 = ped->m_placement.pos + ped->m_placement.right * x + ped->m_placement.up * y;
  3.                 CVector* pos = &pos1;
  4.                 return pos;
  5. };
  6. CPed* create(int modelID, CVector *pos) {// создать pedа
  7.         char reference = 2;// чтобы удалился потом.
  8.     CStreaming::RequestModel(modelID, 0); // ANGEL 166 ModelID
  9.         CStreaming::LoadAllRequestedModels(false);// модель загружена.
  10.         CPed* ped = new CCivilianPed(PEDTYPE_COP, modelID);
  11.  
  12.         ped->m_nState = 4;// флаг
  13.         //ped->m_placement.SetRotate(0, 0, 3.5f);// смещение от координат игрока
  14.         ped->m_placement.pos.x = pos->x;
  15.         ped->m_placement.pos.y = pos->y;
  16.         ped->m_placement.pos.z = pos->z;
  17.         CWorld::Add(ped);// добавить в мир педа.
  18.         return ped;
  19. }
  20.  
  21. int delay(unsigned int &time, int delaytime) {
  22.         if (CTimer::m_snTimeInMilliseconds - time > delaytime) {
  23.                 time = 0;// обнулить таймер
  24.                 CMessages::AddMessageJumpQ(L"Stop timer ", 5000, 3);//выводит сообщение на экран
  25.                 }
  26.         else {
  27.                 for (int i = 0; i < 10000; i++) {
  28.                         int a = 0;
  29.                 };
  30.                 delay(time, delaytime);
  31.         }
  32. };
  33.  
  34. class Message {//имя класса
  35. public:
  36.         Message() {
  37.                 Events::gameProcessEvent += [] {//обработчик событий игры
  38.                         CPed* player = FindPlayerPed();// найти игрока
  39.                         if (!player) return;// проверка найден игрок
  40.                         KeyCheck::Update();
  41.  
  42.                         if (KeyCheck::CheckWithDelay('N', 200)) {//если м нажата
  43.                                 static unsigned int time = 0;// обнулить таймер.
  44.                                 delay(time, 1000);
  45.                                 CVector* pos = worldcoord(player, 1.0, 10.0); //Нахождени координат на 10 от взгляда томми.
  46.                                 CPed* v = create(MODEL_COP, pos); // Спавним копа, передаем коор на 10 м вперед от томми.
  47.                                        
  48.                         }
  49.                 };
  50.         }
  51. } message;
  52.  

Чтобы в lua реализовать это.

Код: C++
  1. function Createped(m,x,y,z)
  2.  local list = { COP = {1,6}, SWAT = {2,6}, FBI = {3,6}, ARMY = {4,6}, MEDIC = {5,16}, FIREMAN = {6,17},
  3.              HFYST = {9,5}, HFOST = {10,5}, HMYST = {11,4}, HFOST = {12,4}, HFYRI = {13,5}, HFORI = {14,5},
  4.              HMYRI = {15,4},HMORI = {16,4},HFYBE = {17,5},HFOBE = {18,5},HMYBE = {19,4},HMOBE = {20,4},
  5.              HFYBU = {21,5},HFYMD = {22,5},HFYCG = {23,5},HFYPR = {24,5},HFOTR = {25,5},HMOTR = {26,4},
  6.              HMYAP = {27,4},HMOCA = {28,4},BMODK = {29,4},BMYCR = {30,4},BFYST = {31,5},BFOST = {32,5},
  7.              BMYST = {33,4},BMOST = {34,4},BFYRI = {35,5},BFORI = {36,5},BMYRI = {37,4},BFYBE = {38,5},
  8.              BMYBE = {39,4},BFOBE = {40,5},BMOBE = {41,4},BMYBU = {42,4},BFYPR = {43,5},BFOTR = {44,5},
  9.              BMOTR = {45,4},BMYPI = {46,4},BMYBB = {47,4},WMYCR = {48,4},WFYST = {49,5},WFOST = {50,5},
  10.              WMYST = {51,4},WMOST = {52,4},WFYRI = {53, 5},WFORI = {54, 5}, WMYRI = {55,4}, WMORI = {56,4 },
  11.              WFYBE = {57,5}, WMYBE = {58,4}, WFOBE = {59,5}, WMOBE = {60,4}, WMYCW = {61,4}, WMYGO = {62,4},
  12.              WFOGO = {63,5}, WMOGO = {64,4}, WFYLG = {65, 5}, WMYLG = {66, 4}, WFYBU = {67,5}, WMYBU = {68, 4},
  13.              WMOBU = {69,4}, WFYPR = {70,5}, WFOTR = {71,5}, WMOTR = {72,4}, WMYPI = {73,4}, WMOCA = {74, 4},
  14.              WFYJG = {75, 5}, WMYJG = {76,4}, WFYSK = {77,5}, WMYSK = {78,4}, WFYSH = {79,5}, WFOSH = {80,5 },
  15.              JFOTO = {81, 5}, JMOTO = {82, 4}, CBA = {83,7}, CBB = {84,7}, HNA = {85,8}, HNB = {86,8},
  16.              SGA = {87,9}, SGB = {88,9}, CLA = {89,10}, CLB ={90,10}, GDA = {91,11}, GDB = {92,11},
  17.              BKA = {93, 12}, BKB = {94,12}, PGA = {95,13}, PGB = {96,13}, VICE1 = {97,18}, VICE2 = {98,18},
  18.              VICE3 = {99,18}, VICE4 = {100,18}, VICE5 = {101,18}, VICE6 = {102,18}, VICE7 = {103,18},
  19.              VICE8 = {104,18},WFYG1 = {105,5}, WFYG2 = {106,6}}
  20.    for k,v in pairs(list) do
  21.         if m == k
  22.         then m1 = v[1] -- модель педа.
  23.             t1 =v[2] -- тип педа
  24.         end end
  25.     m = m1--модель.
  26.     t = t1-- тип.
  27.        
  28.  loadmodel(m)
  29. while not availablemodel(m) do  delay(100) end
  30. ped= createped(m,t, x,y,z)
  31. releasemodel(m)
  32. return ped
  33. end
  34.  

Вообще таймеров много, чем они отличаются? 
Код: C++
  1.     SUPPORTED_10EN_11EN_STEAM static int &m_snTimeInMillisecondsPauseMode;
  2.     SUPPORTED_10EN_11EN_STEAM static int &m_snTimeInMilliseconds;
  3.     SUPPORTED_10EN_11EN_STEAM static float &ms_fTimeStepNonClipped;
  4.     SUPPORTED_10EN_11EN_STEAM static float &ms_fTimeStep;
  5.     SUPPORTED_10EN_11EN_STEAM static int &m_snPreviousTimeInMilliseconds;
  6.     SUPPORTED_10EN_11EN_STEAM static float &ms_fTimeScale;
  7.     SUPPORTED_10EN_11EN_STEAM static int &m_snTimeInMillisecondsNonClipped;
  8.  
Автор: kenking
« : Июнь 18, 2019, 02:27:30 pm »

Цитировать
Скажите, пожалуйста, у вас есть список типа для каждого педа
\GTA Vice City\data\default.ide раздел peds Default pedtype

в sdk есть enum ePedType
https://github.com/DK22Pac/plugin-sdk/blob/master/plugin_vc/game_vc/ePedType.h
Автор: egor230
« : Июнь 18, 2019, 03:36:46 am »

kenking рад, искреннему ответу, удалось реализовать отключение lua скриптов через триггер, также несколько новых функций.
 Есть список моделей машин и педов,  можно в lua создавать  авто car = createcar(model, x,y,z)- создает машину на координатах.
 Но при создание педов,  нужно указать его тип
ped = createped(model, 4, x, y, z) – создает педа на координатах, принимает модель, тип пед, координаты.

Скажите, пожалуйста, у вас есть список типа для каждого педа, хочу с помощью массива, определять  тип пед  автоматический.

в moonloader делал так.
Код: Text
  1.  
  2. function mymod.createped(m,x,y,z) -- создать педа
  3. list = {["BMYBE"]= {4,18}, ["HMYDRUG"]= {18,30}, ["SWMOCD"]= {4,234}, ["WMYLG"]= {4,97}, ["OMORI"]= {4,57}, ["HMYBE"]= {4,45}, ["WFYBU"]= {5,150},
  4. ["DWMOLC1"]= {4,32}, ["WFYCLOT"]= {5,211}, ["OMYKARA"]= {4,203}, ["WMYBE"]= {4,154}, ["WMYGOL1"]= {4,36}, ["CWFOFR"]= {5,196}, ["BFYBU"]= {5,148},
  5. ["BMORI"]= {4,14}, ["BMYDRUG"]= {18,28}, ["WMYKARA"]= {4,204}, ["SBMYST"]= {4,142}, ["SWMOST"]= {4,236}, ["BMYPIMP"]= {4,249}, ["FAM3"]= {8,107},
  6. ["MAFFA"]= {18,111}, ["ARMY"]= {6,287}, ["WFYRO"]= {5,92}, ["SBMYTR3"]= {4,136}, ["DNFYLC"]= {5,131}, ["VWFYWA2"]= {5,263}, ["SWMYRI"]= {4,240},
  7. ["DNFOLC2"]= {5,130}, ["WMOMIB"]= {4,165}, ["SOFOST"]= {5,225}, ["SOFORI"]= {5,224}, ["BMYPOL2"]= {4,67}, ["LSV3"]= {9,110}, ["MECGRL3"]= {5,192},
  8. ["SFFD1"]= {17,279}, ["SFR1"]= {10,173}, ["HFOST"]= {5,39}, ["OFOST"]= {5,54}, ["SWMOTR2"]= {4,135}, ["OMONOOD"]= {4,209}, ["WFOST"]= {5,89},
  9. ["BMYMIB"]= {4,166}, ["SWMYST"]= {4,188}, ["WMORI"]= {4,94}, ["BALLAS2"]= {7,103}, ["SWMYCR"]= {4,250}, ["VWMOTR2"]= {4,213}, ["WMYVA"]= {4,189},
  10. ["BMYCG"]= {18,144}, ["VHMYELV"]= {4,82}, ["WMYCLOT"]= {4,217}, ["SWMOTR3"]= {4,137}, ["VLA3"]= {14,116}, ["WMYCH"]= {4,255}, ["WMYVA2"]= {4,252},
  11. ["LSV2"]= {9,109}, ["SPECIAL03"]= {4,292}, ["WFYBURG"]= {5,205}, ["BMOCD"]= {4,262}, ["SBFYRI"]= {5,219}, ["WMYPLT"]= {4,61}, ["WMYRO"]= {4,99},
  12. ["VMAFF2"]= {12,125}, ["SPECIAL09"]= {4,298}, ["SBFYSTR"]= {5,256}, ["VWMYCD"]= {4,206}, ["VWMYBJD"]= {4,171}, ["DWFOLC"]= {5,31}, ["WMYJG"]= {4,96},
  13. ["MAFFB"]= {18,112}, ["SBMORI"]= {4,221}, ["TRIADB"]= {13,118}, ["SWFYSTR"]= {5,257}, ["BMYMOUN"]= {4,51}, ["DWFYLC1"]= {5,151}, ["OMOST"]= {4,58},
  14. ["TRIADA"]= {13,117}, ["BIKERB"]= {4,248}, ["SBMYRI"]= {4,185}, ["WFYST"]= {5,93}, ["HMOST"]= {4,44}, ["WMYCON"]= {4,27}, ["SOMORI"]= {4,228},
  15. ["BMYDJ"]= {4,19}, ["CWFYHB"]= {5,157}, ["SPECIAL02"]= {4,291}, ["WMOST"]= {4,95}, ["DWMYLC2"]= {4,202}, ["SWFYRI"]= {5,216}, ["DNFOLC1"]= {5,129},
  16. ["BFYST"]= {5,13}, ["SPECIAL10"]= {4,299}, ["BALLAS3"]= {7,104}, ["VIMYELV"]= {4,84}, ["CWMOHB1"]= {4,159}, ["WFYLG"]= {5,251}, ["OFYST"]= {5,56},
  17. ["DNMOLC2"]= {4,133}, ["BMOST"]= {4,15}, ["SHMYCR"]= {18,223}, ["HFYST"]= {5,41}, ["MALE01"]= {4,7}, ["LAFD1"]= {17,277}, ["SOMYBU"]= {4,187},
  18. ["WFORI"]= {5,88}, ["HECK1"]= {4,258}, ["SBMOTR2"]= {4,134}, ["SOFYBU"]= {5,141}, ["HFYBE"]= {5,140}, ["OFORI"]= {5,53}, ["VBMYCR"]= {18,183},
  19. ["WMYBOUN"]= {4,164}, ["WMOICE"]= {4,264}, ["BMYAP"]= {4,16}, ["HFORI"]= {5,38}, ["BFORI"]= {5,9}, ["BFYBE"]= {5,139}, ["SBFYST"]= {5,69},
  20. ["SOMOST"]= {4,229}, ["WFYBE"]= {5,138}, ["BIKDRUG"]= {4,254}, ["GUNGRL3"]= {5,191}, ["MAFBOSS"]= {18,113}, ["DNMOLC1"]= {4,132}, ["SOFYST"]= {5,226},
  21. ["FBI"]= {6,286}, ["DSHER"]= {6,288}, ["VBFYCRP"]= {5,11}, ["WMOPJ"]= {4,62}, ["CWFYFR1"]= {5,198}, ["VMAFF1"]= {12,124}, ["SWFOST"]= {5,232},
  22. ["CWMYHB2"]= {4,200}, ["DNB1"]= {11,121}, ["DWMOLC2"]= {4,33}, ["CSHER"]= {6,283}, ["DWFYLC2"]= {5,201}, ["SWFORI"]= {5,231}, ["VWMYBOX"]= {4,81},
  23. ["WMYBP"]= {4,26}, ["VWFYST1"]= {5,87}, ["FAM1"]= {8,105}, ["BMYBU"]= {4,17}, ["WMOTR1"]= {4,78}, ["DNMYLC"]= {4,128}, ["WFYSTEW"]= {5,76},
  24. ["COPGRL3"]= {5,190}, ["VHMYCR"]= {18,184}, ["VWMYCR"]= {18,181}, ["SBMYCR"]= {18,143}, ["BMYBOUN"]= {4,163}, ["WMYDRUG"]= {18,29}, ["BMYCR"]= {18,21},
  25. ["WMYCONB"]= {4,153}, ["LVFD1"]= {17,278}, ["SFEMT1"]= {16,276}, ["SWMOTR1"]= {4,77}, ["VWMOTR1"]= {4,212}, ["LAEMT1"]= {16,274}, ["LVEMT1"]= {16,275},
  26. ["BFOST"]= {5,10}, ["SWMORI"]= {4,235}, ["VLA1"]= {14,114}, ["TRIBOSS"]= {13,120}, ["VWFYWAI"]= {5,214}, ["SBFOST"]= {5,218}, ["VMAFF4"]= {12,127},
  27. ["HMYRI"]= {4,46}, ["BMYCON"]= {4,260}, ["WMYPIZZ"]= {4,155}, ["SPECIAL05"]= {4,294}, ["WMOPREA"]= {4,68}, ["DNB3"]= {11,123}, ["WMYGOL2"]= {4,37},
  28. ["OMYRI"]= {4,59}, ["BMOTR1"]= {4,79}, ["DNB2"]= {11,122}, ["VHFYST3"]= {5,246}, ["SBMOCD"]= {4,220}, ["GANGRL3"]= {5,195}, ["SFR3"]= {10,175},
  29. ["SFR2"]= {10,174}, ["WMYRI"]= {4,98}, ["LSV1"]= {9,108}, ["FAM2"]= {8,106}, ["SBFORI"]= {5,215}, ["WFYJG"]= {5,90}, ["SWAT"]= {6,285},
  30. ["LAPDM1"]= {6,284}, ["LVPD1"]= {6,282}, ["SPECIAL07"]= {4,296}, ["WBDYG1"]= {4,24}, ["NURGRL3"]= {5,193}, ["LAPD1"]= {6,280}, ["SPECIAL08"]= {4,297},
  31. ["HMYST"]= {4,48}, ["SOMOBU"]= {4,227}, ["SWMYHP1"]= {4,72}, ["WMYCD1"]= {4,261}, ["VMAFF3"]= {12,126}, ["HECK2"]= {4,259}, ["BMOSEC"]= {4,253},
  32. ["BIKERA"]= {4,247}, ["SMYST2"]= {4,242}, ["OFYRI"]= {5,55}, ["SBMOST"]= {4,222}, ["SWMOTR4"]= {4,239}, ["WMYMECH"]= {4,50}, ["VLA2"]= {14,115},
  33. ["OMYST"]= {4,60}, ["SWMOTR5"]= {4,230}, ["HFYRI"]= {5,40}, ["SPECIAL04"]= {4,293}, ["SMYST"]= {4,241}, ["BALLAS1"]= {7,102}, ["SOMYRI"]= {4,186},
  34. ["CROGRL3"]= {5,194}, ["VBMOCD"]= {4,182}, ["HMYCR"]= {4,47}, ["BMYTATT"]= {4,180}, ["BMOBAR"]= {4,156}, ["WMYAMMO"]= {4,179}, ["WMYBAR"]= {4,177},
  35. ["BMYPOL1"]= {4,66}, ["BMYBAR"]= {4,176}, ["BMYRI"]= {4,20}, ["SOMYST"]= {4,170}, ["BMOCHIL"]= {4,168}, ["WFYRI"]= {5,91}, ["WMYBELL"]= {4,167},
  36. ["BMYST"]= {4,22}, ["WMYCR"]= {18,100}, ["WMYST"]= {4,101}, ["CWMYFR"]= {4,161}, ["CWMOHB2"]= {4,160}, ["CWMOFR"]= {4,158}, ["WMYBU"]= {4,147},
  37. ["SPECIAL06"]= {4,295}, ["CWMYHB1"]= {4,162}, ["WFYSEX"]= {5,178}, ["VBMYELV"]= {4,83}, ["CWFOHB"]= {5,197}, ["VBMYBOX"]= {4,80}, ["WMYMOUN"]= {4,52},
  38. ["SPECIAL01"]= {4,290}, ["WMYSGRD"]= {4,71}, ["OMOBOAT"]= {4,210}, ["SWMYHP2"]= {4,73}, ["WFYCRK"]= {5,145}, ["BFYRI"]= {5,12}, ["SOFYRI"]= {5,169},
  39. ["OMOKUNG"]= {4,49}, ["HMYCM"]= {4,146}, ["HMORI"]= {4,43}, ["HMOGAR"]= {4,35}, ["DWMYLC1"]= {4,34}, ["SFPD1"]= {6,281}, ["WMYBMX"]= {4,23},
  40. ["VBFYST2"]= {5,244}, ["SWFYST"]= {5,233},["CWFYFR2"]= {5,199}, ["VWFYCRP"]= {5,172}, ["WMOSCI"]= {4,70}}
  41. for k,v in pairs(list) do
  42. if m == k
  43. then t = v[1] -- тип педа
  44.      m1 =v[2] -- модель педа
  45. end end
  46. m = m1
  47. requestModel(m) -- запрос модели
  48. while not isModelAvailable(v) do wait(0) end-- проверка на загруженность модели
  49. ped = createChar(t, m, x,y,z) -- 009A: 2@ = create_actor_playerPedtype 4 model #MALE01 at 0.0 0.0 0.0
  50. return ped
  51. end
  52.  

это упрощало создания педов, вот lua плагин https://vk.com/gtabuilder?w=wall-56513456_510

очень помогли скриптовые команды.

Автор: kenking
« : Июнь 15, 2019, 08:13:12 am »

К сожалению, по работе с lua скриптами ничего подсказать не могу.
Автор: egor230
« : Июнь 14, 2019, 04:11:12 pm »


 kenking, Бесконечно Вам благодарен. Потихоньку начинаю понимать, как это устроено.  Есть тестовой плагин, где экспериментирую.  Выходит маркер имеет свой id.
 Спасибо,  что Вы показали  как работает скриптовая комманда,  бывает привычнее использовать их, они похожи на опкоды cleo.
 Очень признательный, что вы  показали  как выводить целые числа на экран.

 Всегда хотел, написать плагин, позволяющий запускать lua скрипты для vc.
sdk имеет свой основный поток, который является  бесконечным циклом,  В каком-то роде. Если  там поставить задержу, например,  10 секунд, то на это время остановится игра.  Поэтому  запускаем  новый Независимый поток с флагом, для того,  чтобы  он был один.
Ищем  все lua файлы в папке,  запускаем в новом потоке с новым lua состоянием. Потоки и lua состояния  добавляются в вектора.
 Идет проверка на ошибки, счетчик запущенных скриптов увеличивается,  запускаем скрипт,  получаем в стек функцию main,  запускаем её.

В lua  находится функция main. она  имеет бесконечный цикл.  Всё работает, но есть одно но.  Как сделать перезагрузку всех скриптов?
 Нажимаем ctrl, проходим циклом for  вектор  c lua  состояниями,  снимаем со стека  функции, закрываем lua состоянием.
  Но к сожалению,  всё зависает.  Подскажите пожалуйста,  как правильно написать реализацию перезагрузке скриптов.
Код: C++
  1. void second(bool& reload) {
  2. vector<thread>t;//вектор для lua потоков.
  3. vector<lua_State*>luastate;// вектор для lua состояний.
  4.         for (auto const& de : fs::recursive_directory_iterator{ fs::current_path() / "lualoader" }) { // папка для поиска
  5.                 if (de.path().extension() == ".lua" || de.path().extension() == ".LUA") {
  6.                         string res = de.path().string();// перевод имя файла в строку.
  7.                         t.push_back(move((std::thread(search, res, std::ref(luastate)))));// добавить поток в вектор.
  8.                 }
  9.         };
  10.        
  11.         while (true) {
  12.                 if (KeyPressed(VK_CONTROL)) {// перезагрузка скрипта        
  13.                         this_thread::sleep_for(chrono::milliseconds(1));
  14.                         static unsigned int time = 0;// обнулить таймер.
  15.                         if (CTimer::m_snTimeInMilliseconds - time > 500) {
  16.                                 time = 0;// обнулить таймер
  17.         for (auto L : luastate) { lua_pop(L, lua_gettop(L));// снять со стека функцию main.
  18.         counts--;// уменьшить счетчик.
  19.                 lua_close(L);// закрыть состояние.
  20. };
  21.                                 for (auto& i : t) {
  22.                                         i.detach(); // все потоки независимы.
  23.                                 };
  24.                                 break;
  25.  
  26.                         };
  27.                 };
  28.         };
  29.  
  30.         if (counts == 0){// если нет запущенных скриптов.
  31.                 reload = false; // флаг, что можно запускать новый поток.
  32.  
  33.         };                     
  34. };
  35.  
  36. class Message {//имя класса
  37. public: Message() {
  38.         Events::gameProcessEvent += [] {//обработчик событий игры
  39.                 CPed* player = FindPlayerPed();// найти игрока
  40.                 if (!player) return;// проверка найден игрок
  41.                 if (reload == false) {  reload = true;// флаг, что уже запущен поток.
  42.                         thread th(second, std::ref(reload)); th.detach();// независимый поток.         
  43.                 }
  44.         };
  45. }
  46. } message;
  47.  
  48.  
Автор: kenking
« : Июнь 08, 2019, 08:25:44 pm »

Цитировать
Не думал, что маркер, это int.  Предполагал,  что мы должны передать  структуру.
Это ID маркера.

Цитировать
Конечно, как всегда столкнулся с трудностями,  как использовать скриптовую команду в качестве проверки?
Цитировать
Так же интересная ситуация с выводом целых чисел на экран, они не выводится.
Цитировать
Разобрался с проверками.
Цитировать
Только не получается дать оружие игроку через скриптовую команду.
Код: C++
  1. #include "plugin.h"
  2. #include "extensions\KeyCheck.h"
  3. #include "CMessages.h"
  4. #include "extensions\ScriptCommands.h"
  5. #include "eScriptCommands.h"
  6. #include "CWorld.h"
  7. #include "eWeaponModel.h"
  8. #include "eWeaponType.h"
  9. #include "CStreaming.h"
  10.  
  11. using namespace plugin;
  12.  
  13. class Test {
  14. public:
  15.     static int m_test;
  16.  
  17.     Test() {
  18.         Events::gameProcessEvent += [] {
  19.             CPed *player = FindPlayerPed();
  20.             KeyCheck::Update();
  21.             if (KeyCheck::CheckWithDelay('B', 1000)) {
  22.                 static char message[256];
  23.                 snprintf(message, 256, "test = %d", m_test);
  24.                 CMessages::AddMessageJumpQ(message, 1000, false);
  25.             }
  26.             if (player) {
  27.                 if (KeyCheck::CheckWithDelay('N', 1000)) {
  28.                     //if (player->m_bInVehicle)
  29.                     if (Command<COMMAND_IS_PLAYER_IN_ANY_CAR>(CWorld::PlayerInFocus))
  30.                         CMessages::AddMessageJumpQ(L"in car", 1000, 0);
  31.                     else
  32.                         CMessages::AddMessageJumpQ(L"not in car", 1000, 0);
  33.                 }
  34.                 if (KeyCheck::CheckWithDelay('M', 1000)) {
  35.                     //CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 1000;
  36.                     Command <COMMAND_ADD_SCORE>(CWorld::PlayerInFocus, 1000);
  37.  
  38.                     /*CStreaming::RequestModel(MODEL_COLT45, 2);
  39.                     CStreaming::LoadAllRequestedModels(false);
  40.                     player->GiveWeapon(WEAPONTYPE_PISTOL, 100, true);
  41.                     player->SetCurrentWeapon(WEAPONTYPE_PISTOL);
  42.                     CStreaming::SetModelIsDeletable(MODEL_COLT45);*/
  43.                     Command<COMMAND_REQUEST_MODEL>(MODEL_COLT45, 2);
  44.                     Command<COMMAND_LOAD_ALL_MODELS_NOW>(false);
  45.                     if (Command<COMMAND_HAS_MODEL_LOADED>(MODEL_COLT45)) {
  46.                         Command<COMMAND_GIVE_WEAPON_TO_PLAYER>(CWorld::PlayerInFocus, WEAPONTYPE_PISTOL, 100, true);
  47.                         Command<COMMAND_SET_CURRENT_PLAYER_WEAPON>(CWorld::PlayerInFocus, WEAPONTYPE_PISTOL);
  48.                         Command<COMMAND_MARK_MODEL_AS_NO_LONGER_NEEDED>(MODEL_COLT45);
  49.                     }
  50.                 }
  51.             }
  52.         };
  53.     }
  54. } test;
  55.  
  56. int Test::m_test = 3;

Цитировать
Это очень удобно использовать скриптовые команды.
Скриптовые команды надо использовать в случае отсутствия в sdk нужных функций и классов (ну для тестов ещё, чтобы поучиться). В остальном надо писать код с  разобранными функциями. В примере такой альтернативный код закомментирован.
Пример с оружием есть в sdk, ты же уже про это спрашивал.
Автор: egor230
« : Июнь 08, 2019, 01:51:01 pm »

 Спасибо большое уважаемый kenking за ваш ответ. Это очень удобно использовать скриптовые команды. Благодаря им наметился  определенный прогресс, что радует.
Не думал, что маркер, это int.  Предполагал,  что мы должны передать  структуру.
Вот примеры, может кому-то облегчать путь.
Код: C++
  1. Command<COMMAND_ADD_BLIP_FOR_CHAR>(CPools::GetPedRef(ped), &blip);// стрелка над педом.
  2. Command <COMMAND_SET_CHAR_MONEY>(CPools::GetPedRef(ped), 1000);// дать денег педу, но почему-то выходит 1006, может это прибавка?.
  3.  

 Конечно, как всегда столкнулся с трудностями,  как использовать скриптовую команду в качестве проверки?
 Пробовал разные варианты, получал  только вылет.
Код: C++
  1.         bool mod;
  2. class Test {//имя класса
  3. public:
  4.  
  5.         Test() {
  6.                 Events::gameProcessEvent += [] {
  7.                         CPed* player = FindPlayerPed();
  8.                         KeyCheck::Update();
  9.  
  10.                         if (KeyCheck::CheckWithDelay('M', 1000)){
  11.                        
  12.                         Command<COMMAND_IS_PLAYER_IN_ANY_CAR>(CPools::GetPedRef(player), mod);
  13.                         if(mod == true){ CMessages::AddMessageJumpQ(L"in car", 1000, 0);
  14.                         }
  15.                         }
  16.                 };
  17.         }
  18. } test;
  19.  
  20.  

 Так же интересная ситуация с выводом целых чисел на экран, они не выводится.
Код: C++
  1. class Test {//имя класса
  2. public:
  3.  
  4.         Test() {
  5.                 Events::gameProcessEvent += [] {
  6.                         CPed* player = FindPlayerPed();
  7.                         KeyCheck::Update();
  8.  
  9.                         if (KeyCheck::CheckWithDelay('M', 300)){
  10.                                 int numb = 3;
  11.                                 static char x[256];
  12.                                 snprintf(x, 256, "x = %.d", numb);
  13.  
  14.                         }
  15.                 };
  16.         }
  17. } test;
  18.  

Все сделал по правилам форматирования сделал в с++, может, что-то упустил? Подскажите, пожалуйста.

Разобрался с проверками.
Код: C++
  1.  
  2.                         mod = Command<COMMAND_IS_PLAYER_IN_ANY_CAR>();
  3.                         if(mod== true){
  4.                         CMessages::AddMessageJumpQ(L"in car", 1000, 0);
  5.                 }
  6.                         else{
  7.                                 CMessages::AddMessageJumpQ(L"not in car", 1000, 0);
  8.                         }
  9.                 }
  10.  

Создать машину.
Код: C++
  1.                         if (KeyCheck::CheckWithDelay('M', 300)){
  2.                                 Command<COMMAND_REQUEST_MODEL>(MODEL_COMET);
  3.                                 bool f = Command<COMMAND_HAS_MODEL_LOADED>(MODEL_COMET);
  4.                         if ( f== true) {
  5.                                 CVector pos = player->GetPosition();
  6.                                 CVehicle* v = nullptr;
  7.                                 Command<COMMAND_CREATE_CAR>(MODEL_COMET, pos.x, pos.y+10, pos.z, &v);
  8.                 }
  9. }
  10.                 };
  11.  


Только не получается дать оружие игроку через скриптовую команду.

Код: Text
  1.                         if (KeyCheck::CheckWithDelay('M', 300)){
  2.                        
  3.                                 Command<COMMAND_REQUEST_MODEL>(MODEL_COLT45);
  4.                         if (Command<COMMAND_HAS_MODEL_LOADED>(MODEL_COLT45)) {
  5.                                
  6.                                 CMessages::AddMessageJumpQ(L"model load", 1000, 0);
  7. Command<COMMAND_GIVE_WEAPON_TO_PLAYER>(CPools::GetPedRef(player), WEAPONTYPE_PISTOL, 100);
  8.                 }
  9.  

Автор: kenking
« : Июнь 03, 2019, 09:37:28 am »

Цитировать
Как использовать эту скриптовую команду?
Скриптовая команда - это опкод, смотришь в eScriptCommands какому номеру опкода соответствует эта команда. Открываешь поиск опкодов в SB, находишь нужный опкод: 0162: tie_marker $2344 to_actor $2320 4 2
Смотришь параметры этого опкода.
Код: C++
  1. #include "plugin.h"
  2. #include "extensions\KeyCheck.h"
  3. #include "extensions\ScriptCommands.h"
  4. #include "eScriptCommands.h"
  5.  
  6. using namespace plugin;
  7.  
  8. class Test {
  9. public:
  10.     static int blip;
  11.    
  12.     Test() {
  13.         Events::gameProcessEvent += [] {
  14.             CPed *player = FindPlayerPed();
  15.             KeyCheck::Update();
  16.             if (player && KeyCheck::CheckWithDelay('M', 1000))
  17.                 Command<COMMAND_ADD_BLIP_FOR_CHAR_OLD>(CPools::GetPedRef(player), 4, 2, &blip);
  18.             if (player && KeyCheck::CheckWithDelay('N', 1000))
  19.                 Command<COMMAND_REMOVE_BLIP>(blip);
  20.         };
  21.     }
  22. } test;
  23.  
  24. int Test::blip;
Автор: egor230
« : Июнь 02, 2019, 12:41:45 am »

 Здравствуйте уважаемый kenking. Был  уверен,  что вы досконально знаете все функции в sdk. Вы же понимаете хочется всё и сразу.
Пока непонятно как это задержка работает.
Несколько лет это долго.
Советы и подсказки от других людей это конечно хорошо, в час по чайной ложке, а желание всё горит внутри. Например, учил с++ - посмотрел видеокурсы, переписал код, с ним поэкспериментировал, прочитал несколько книг, так учебный процесс прошел быстро.
А тут прямо буксую. Сегодня нашел вот что
Код: C++
  1. ped->SetObjective(OBJECTIVE_HASSLE_CHAR, player); // пед идет к игроку.
  2. ped->SetAttack(player);//пед бьет
  3. ped->Attack();// правой рукой.
  4.  
  5.  
Спасибо большое за ваше объяснение. Очень не хочется,чтобы такой гениальный проект забросили.

Как использовать эту скриптовую команду?
Код: C++
  1.  
  2.                                         CPed* ped = randomfindped(player, 30.0);
  3.                                         CObject *p;
  4.                                         Command<COMMAND_ADD_BLIP_FOR_CHAR_OLD>(CPools::GetPedRef(ped), p);
  5.  
Автор: kenking
« : Июнь 01, 2019, 09:40:13 am »

Цитировать
Иногда явного  эффекта от функции нет.  Например, что даёт  функция
ped->SetObjectiveTimer(60000);
 Да это таймер,  но никакой задержка  вы действиях педа не наблюдается.
Задержки и не должно быть. По-идеи это установка максимального времени на какое-то действие педа (как я это понимаю).

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

Цитировать
Допустим, CLEO которая является хуком  знаю,  где посмотреть ее исходник на с++. Может  это поможет разобраться?  Посоветуйте, пожалуйста, книгу,  которая помогла вам стать  таким крутым специалистом??
Я учусь разбираться в классах игры также, как и ты и крутым специалистом себя не считаю. В некоторых случаях, чтобы ответить на твой вопрос, мне приходится самому его сначала разобрать. Никакой такой книги я не знаю. Мне помогли подсказки и советы DK и других пользователей, которые они писали в этой теме, в целом на этом форуме и других форумах.

Вот немного пояснений, которые я для себя сохранил:
Цитировать
Если есть IDA и idb-база, то для "распутывания ниточек" можно использовать такие приёмы:

Как определить, откуда вызывается данная функция?
1.Открываем код функции в основной вкладке.
2.Далее выбираем в меню пункт View - Open Subviews - Function calls - список Caller.

Как определить, откуда происходит обращение к данному адресу?
1.Вставляем курсор между буквами названия адреса. Например здесь
Code:

.data:00B7CB84 _currentTime dd ? ; DATA XREF: _sub_406E50r

вставляем курсор между любыми буквами _currentTime.
2.Жмём X. Открывается список ссылок на данный адрес.


Очень часто случается такое, что декомпилятор (hex-rays) выдаёт ошибку "switch analysis failed".
Случается это в функциях, где используется конструкция switch.
Случается это потому что (моё предположение) разные версии декомпилятора по-разному работают с этой
конструкцией.
В официальных доках рекомендуют вручную настроить эту конструкцию, но есть более простое решение:
пересобрать функцию.
Для этого надо преобразовать функцию в обычные данные, преобразовать данные в код, и создать функцию.

1. Нажимаем U на названии функции (Undefine function).
2. Нажимаем C на первом байте (Code)
3. Нажимаем P (Create function).

В exe есть 2 основных типа адресов - data и text (есть и другие типы). Если проводить аналогию со
скриптами, то адреса типа data можно сравнить с глобальными переменными - в них хранятся различные
значения (например, 0xB7CB84 - [dword] Глобальный таймер в ms, 0x8D2530 - [float] Плотность движения
пешеходов). В ходе игры отдельные процедуры exe читают эти значения или записывают в эти адреса новые
значения. Эти адреса (не все) можно читать/перезаписывать и в скрипте с помощью опкодов 0A8C/0A8D.
Назначение некоторых часто употребляемых data-адресов, а также смещений в структурах можно найти тут:
http://gtamodding.ru...еса_Памяти_(SA)
Что касается адресов типа text, то в них записаны отдельные команды, из которых в свою очередь
состоят процедуры exe. Сами по себе значения этих адресов во время игры не меняются, но их, как и
адреса data, можно (не все) менять скриптом - в этом случае в опкодах 0A8C/0A8D следует ставить
значение параметра virtual protect, равное 1. Понятно, что в случае изменения значения text-адреса,
процедура, которой он принадлежит, станет работать уже по новому алгоритму.
Для поиска нужных адресов и процедур незаменима idb-база от listener. Открыть её можно с помощью
IDA 5. В окне программы есть несколько вкладок, которые представляют код exe в различном виде.
Основные из них: "IDA View-A" - основной вид. Если текущий участок exe состоит из адресов типа data,
то они отображаются в виде списка, а если текущий участок является какой-то
процедурой (text-адреса), то она отобразится в виде блок-схемы. "Hex View-A" - побайтовое отображение
кода. Многие data-адреса и процедуры в базе проименованы, при активной вкладке "IDA View-A" можно
осуществлять их поиск по названию (Search - Text).
Есть ещё полезная вкладка Functions - список всех процедур exe. Если эта вкладка активна, то можно
осуществить поиск процедуры по названию (Search). Например, осуществив поиск по слову train, можно
найти процедуры, имеющие отношение к поездам. При щелчке по названию процедуры, активируется вкладка
"IDA View-A" и появится блок-схема этой процедуры, по которой можно исследовать, как она
работает (какие процедуры вызывает, со значениями каких адресов оперирует и т.д.).


Автор: egor230
« : Май 31, 2019, 08:46:39 pm »

Спасибо вам огромное уважаемый kenking за исключительно подробный ответ. Вы столько времени на него потратили. за это я вам очень благодарен. Примерно, понимаю какие параметры передавать в  функцию.  Вот нашел список  https://zredix.com/index.php?title=GTA_VC_Functions(1.0)

  Долго копался тестировал, может кому поможет.

Код: Text
  1. //ped->SetObjective(OBJECTIVE_KILL_CHAR_ANY_MEANS, player);// пед хочет убить игрока.
  2. //ped->SetObjective(OBJECTIVE_SPRINT_TO_AREA, point);// пед делает спринт к точке.
  3. //CMessages::AddMessage(L"ok", 2000, 0);// 0 текст белого цвета.
  4. //CMessages::AddBigMessage(L"ok", 2000, 0);/*0 большими, розовые как миссии пройдена, 1 надпись как названия миссии, 2 зеленым большими,
  5. // в правом нижним углу, 3 синим в центре, 4 зеленным в центре.*/
  6. //ped->SetObjective(OBJECTIVE_SOLICIT_VEHICLE, v);// ЦЕЛЬ.ПРОСИТЬ.ТРАНСПОРТ пед подходит к авто.
  7. //ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, v);// пед садится как пассажир.
  8. //ped->SetObjective(OBJECTIVE_DESTROY_CAR, v);// пед ударит авто.
  9. ped->SetDead();// как будь-то пед умер под ним кровь.
  10.  
  11.                                         Проверка пед не в воздухе, а на земле.
  12.                                         if(!ped->CheckIfInTheAir()){
  13.  
  14.                                                 CMessages::AddMessageJumpQ(L"ped not in air", 1000, 0);
  15.                                         }
  16.  
  17.  

 Иногда явного  эффекта от функции нет.  Например, что даёт  функция
ped->SetObjectiveTimer(60000);

 Да это таймер,  но никакой задержка  вы действиях педа не наблюдается.
или Idle(). псевкоду что-то перерисовывает.

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

 Допустим, CLEO которая является хуком  знаю,  где посмотреть ее исходник на с++. Может  это поможет разобраться?  Посоветуйте, пожалуйста, книгу,  которая помогла вам стать  таким крутым специалистом??
Автор: kenking
« : Май 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. }

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