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

Оффлайн egor230

  • Новичек
  • **
  • Сообщений: 140
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr
Спасибо вам огромное уважаемый 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

  • Новичек
  • **
  • Сообщений: 202
  • Репутация: +13/-0
    • Просмотр профиля
Цитировать
Иногда явного  эффекта от функции нет.  Например, что даёт  функция
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

  • Новичек
  • **
  • Сообщений: 140
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr
 Здравствуйте уважаемый 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.  
« Последнее редактирование: Июнь 02, 2019, 09:45:47 pm от egor230 »

Оффлайн kenking

  • Новичек
  • **
  • Сообщений: 202
  • Репутация: +13/-0
    • Просмотр профиля
Цитировать
Как использовать эту скриптовую команду?
Скриптовая команда - это опкод, смотришь в 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

  • Новичек
  • **
  • Сообщений: 140
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr
 Спасибо большое уважаемый 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.  

« Последнее редактирование: Июнь 08, 2019, 06:10:32 pm от egor230 »

Оффлайн kenking

  • Новичек
  • **
  • Сообщений: 202
  • Репутация: +13/-0
    • Просмотр профиля
Цитировать
Не думал, что маркер, это 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

  • Новичек
  • **
  • Сообщений: 140
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr

 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

  • Новичек
  • **
  • Сообщений: 202
  • Репутация: +13/-0
    • Просмотр профиля
К сожалению, по работе с lua скриптами ничего подсказать не могу.

Оффлайн egor230

  • Новичек
  • **
  • Сообщений: 140
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr
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

  • Новичек
  • **
  • Сообщений: 202
  • Репутация: +13/-0
    • Просмотр профиля
Цитировать
Скажите, пожалуйста, у вас есть список типа для каждого педа
\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