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

Оффлайн egor230

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

  • Новичок
  • **
  • Сообщений: 215
  • Репутация: +14/-0
    • Просмотр профиля
Re: Написание плагина. Настройка проекта
« Ответ #271 : Июнь 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

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

Оффлайн kenking

  • Новичок
  • **
  • Сообщений: 215
  • Репутация: +14/-0
    • Просмотр профиля
Re: Написание плагина. Настройка проекта
« Ответ #273 : Июнь 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

  • Новичок
  • **
  • Сообщений: 148
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr
Re: Написание плагина. Настройка проекта
« Ответ #274 : Июнь 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.  

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

Оффлайн kenking

  • Новичок
  • **
  • Сообщений: 215
  • Репутация: +14/-0
    • Просмотр профиля
Re: Написание плагина. Настройка проекта
« Ответ #275 : Июнь 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

  • Новичок
  • **
  • Сообщений: 148
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr
Re: Написание плагина. Настройка проекта
« Ответ #276 : Июнь 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

  • Новичок
  • **
  • Сообщений: 215
  • Репутация: +14/-0
    • Просмотр профиля
Re: Написание плагина. Настройка проекта
« Ответ #277 : Июнь 15, 2019, 08:13:12 am »
К сожалению, по работе с lua скриптами ничего подсказать не могу.

Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 148
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr
Re: Написание плагина. Настройка проекта
« Ответ #278 : Июнь 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

  • Новичок
  • **
  • Сообщений: 215
  • Репутация: +14/-0
    • Просмотр профиля
Re: Написание плагина. Настройка проекта
« Ответ #279 : Июнь 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

  • Новичок
  • **
  • Сообщений: 148
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr
Re: Написание плагина. Настройка проекта
« Ответ #280 : Июль 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

  • Новичок
  • **
  • Сообщений: 215
  • Репутация: +14/-0
    • Просмотр профиля
Re: Написание плагина. Настройка проекта
« Ответ #281 : Июль 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

  • Новичок
  • **
  • Сообщений: 148
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr
Re: Написание плагина. Настройка проекта
« Ответ #282 : Июль 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

  • Новичок
  • **
  • Сообщений: 215
  • Репутация: +14/-0
    • Просмотр профиля
Re: Написание плагина. Настройка проекта
« Ответ #283 : Июль 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

  • Новичок
  • **
  • Сообщений: 148
  • Репутация: +5/-0
    • Просмотр профиля
    • Mr
Re: Написание плагина. Настройка проекта
« Ответ #284 : Июль 26, 2019, 07:42:58 pm »
спасибо большое за Ваш ответ уважаемый kenking. много работал над многопоточности, удалось ее реализовать через костыл.
потому не lanes и effil не удалось собрать. все работает.
По нажатию клавиши “G” запускается функция
newthread(funs,"BMYBB","remove ped")
первый параметр, названия функцией запущенной в отдельном потоке, модель педа, текст надписи на экране.
Вот сама функция.
Код: C++
  1. require("lualoader/mod")
  2. function funs(ped, text)
  3.  player = findplayer()-- получить игрока
  4.  x,y,z =getcoordinates_on_y(player,5)-- получить координаты на 5 м впереди.
  5.  man = Createped(ped,x,y,z) -- создать педа.
  6.  mar = create_marker_actor(man) -- создать маркер педа.
  7. while true do
  8.  if 0 == gethealth(man)-- проверить его здоровье.
  9.  then  
  10.  printmessage(text, 1500,1)
  11.  remove_ped(man)-- удалить педа.
  12.  removemarker(mar)-- удалить маркер над педом.
  13.  break
  14.  end
  15. end
  16. end
  17. function main()
  18. while lualoader == nil do
  19.  wait()
  20.  player = findplayer()-- получить игрока
  21.  if Keypress(VK_G)
  22.  then
  23.  newthread(funs,"BMYBB","remove ped")-- функция, модель пед, текст надписи.
  24.  end
  25.  
  26.  end  
  27.  end
  28.  

теперь есть желание написать простую миссию, пытаюсь понять как получить и установить флаг миссии.
пробовал вот так не получается.
Код: C++
  1.                 if (KeyCheck::CheckWithDelay('M', 1000)) {
  2.                                 //      Command<COMMAND_DECLARE_MISSION_FLAG>(true);
  3.                                         if(Command <COMMAND_CAN_PLAYER_START_MISSION>(CWorld::PlayerInFocus)){
  4.                                         //CRunningScript script;
  5.                                     //if(script.m_bIsMission) {
  6.                                                 CMessages::AddMessageJumpQ(L"on", 2000, 1);}
  7.  
  8.                                         else {  CMessages::AddMessageJumpQ(L"mission", 2000, 1);
  9.                                         }
  10.        
  11.                                 }
  12.  

помогите, пожалуйста, Ваши советом, как проверить флаг миссии? И установить его, что миссия запущена.