Автор Тема: lualoader как modloader, только для GTA vc на основе SDK Plugin DK  (Прочитано 158 раз)

Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 161
  • Репутация: +6/-0
    • Просмотр профиля
    • Mr
Начал играть в GTA Vice City в 14, очень  понравилась сама  атмосфера. Всегда хотелось, что-то добавить свое в игру, как миссии, новые возможности.  Попробовал CLEO, написал пару десятков скриптов.  Но CLEO не является полноценным языком программирования. Узнал о MoonLoader - это lua плагин для игры GTA San Andreas, на нем  очень удобно и быстро можно писать скрипты,  лучше чем  на CLEO. Больше года назад,  узнал, что  можно писать плагины для VC  на C++ используя SDK Plugin DK. Изучил  основы с++, потом стал писать примитивные плагины. Тут возникла идея, что если написать свой аналог MoonLoader для VC на основе  SDK Plugin DK, приступил к изучению api lua c++ это было очень тяжело из-за отсутствие подробной информации по ней в интернете. взял за привязку LuaBridge, кому интересно весь исходной код здесь https://pastebin.com/VatypnLb Есть гитхаб https://github.com/egor230/lualoader

Нужно поместить  все файлы с расширением lua в папку lualoader, которую нужно создать в корневой папке игры. Остальные файлы в корень игры. Если не работает, ошибка запишется в лог, в папке lualoader.
вот ссылка https://github.com/egor230/lualoader
Рассмотрим как работает пара функций. Установим уровень здоровье для Томми 200.
 Как устроено на стороне C++/
Код: Javascript
  1. int findplayer(lua_State* L) {// получить указатель на игрока.
  2.         CPed* player = FindPlayerPed();// найти Томми.
  3.         Stack<CPed*>::push(L, player);// отправить в стек указатель на игрока.
  4.         return 1;
  5. };
  6. int setpedhealth(lua_State* L) {// установить здоровье педу.
  7.         try {
  8.                 if (LUA_TUSERDATA == lua_type(L, -2)) {// указатель на игрока.
  9.                         if (LUA_TNUMBER == lua_type(L, -1)) {
  10.                                 CPed* player = (CPed*)Userdata::get<CPed>(L, 1, false);// получить указатель на игрока.
  11.                                 float health = Stack<float>::get(L, 2);// если число.
  12.                                 health += 0.99f; player->m_fHealth = health; return 0;
  13.                         }// установить здоровье игрока.
  14.                         else { throw "bad argument in function setpedhealth option health"; }
  15.                 }
  16.                 else { throw "bad argument in function setpedhealth option of the player"; }
  17.         }
  18.         catch (const char* x) { writelog(x); }
  19.         return 0;
  20. };
  21.  

на lua это выглядит так.
Код: Javascript
  1. require("lualoader/mod")-- функции упрощающие написания скрипта.
  2. function main()
  3. while lualoader == nil do
  4.  wait()-- задержка.
  5.  player = findplayer()-- получить игрока
  6.  setpedhealth(player,200)-- уст 200 здоровье педу.
  7. end
  8. end
  9.  
  10.  

Мы загружаем модуль "mod" там куча вспомогательных функций, чтобы меньше писать код.
Функция main запускается всегда первой, как в MoonLoader.
Почему while lualoader == nil, а не while true? Чтобы выполнять перезагрузку скрипта по нажатию "ctrl". Другого способа пока не нашёл.

вот более полезный скрипт, который по нажатию клавиши "H" Устанавливает 200 здоровье, дает оружие, создает авто.

Код: Javascript
  1. require("lualoader/mod")-- функции упрощающие написания скрипта.
  2. function main()
  3. while lualoader == nil do
  4.  wait()-- задержка.
  5.  player = findplayer()-- получить игрока
  6.  if Keypress(VK_H) -- если клавиша H.
  7. then  
  8.  Giveweaponped(player,300,"ingramsl")-- дать педу оружие.  
  9.  setpedhealth(player,200)-- уст 200 здоровье педу
  10.  setarmour(player,200)-- уст 200 броню педу
  11.  x,y,z =getcoordinates_on_y(player,10)-- получить координаты на 10 м впереди от игрока.
  12.  mycar = Createcar(MODEL_SENTXS,x,y,z) -- создать авто на 10 м впереди.
  13. end
  14. end
  15.  
  16. end
  17.  

« Последнее редактирование: Ноябрь 08, 2019, 09:08:54 pm от Shagg_E »

Оффлайн Shagg_E

  • Главный Модератор
  • Постоялец
  • *****
  • Сообщений: 614
  • Репутация: +20/-0
  • Изобретательный Рукожопъ
    • Просмотр профиля
    • NewRockstar
Пофиксил картинку в посте. Удачи в разработке!
Сам не интересуюсь lua скриптингом, но идея может найти отклик при большой базе функций. Чем больше у модмейкеров разных инструментов - тем лучше! Надеюсь, проект не постигнет участь Vice Lua...
Как я уже предлагал ранее - советую создать также тему на gtaforums, это должно поспособствовать развитию проекта.

Оффлайн egor230

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

 Спасибо Вам за поддержку уважаемый Shagg_E. может кого-нибудь это заинтересует. устал от ограниченности CLEO.
Буду рад, если кому-то поможет моя разработка. не знаю как выставить изображения в сообщение на сайт.

Помню как-то хотел на CLEO написать гонку, но в скрипте нужно было писать много строк кода. Легко можно было ошибиться.
Как это обстоит на lua.
Сначала нам нужно записать координаты чекпоинтов в файл.

Когда находимся в нужной координате, нажимаем клавишу "L". Благодаря скрипту координата записывается в текстовой файл.

Код: Javascript
  1. require("lualoader/mod")
  2.  
  3. function main()
  4. while lualoader == nil do
  5.  wait()
  6.  player = findplayer()-- получить игрока
  7.  if Keypress(VK_L)
  8.  then x,y,z = getpedcoordes(player)
  9.  x = tonumber(string.format("%.1f", x))
  10.  y = tonumber(string.format("%.1f", y))
  11.  z = tonumber(string.format("%.1f", z))
  12.  cord = tostring(x)..", "..tostring(y)..", " .. tostring(z)..", "
  13.   file = io.open('cordinat.txt', 'a') -- открыть файл для записи
  14.   file:write(cord)    
  15.   file:close()
  16.   printmessage("write cordinat", 3000, 1)
  17.  wait(600)
  18.  end  
  19.  end  
  20. end
  21.  
  22.  

Теперь копируем всё из файла cordinat.txt в таблицу road.
Функция follow_route_for_corona_for_playercar помещаем в бесконечный цикл. Она принимает автомобиль и массив пути следования.
возвращает true,когда автомобиль достигнул последний точки маршрута. Сама функция находится в модулем mod.

Код: Javascript
  1.  
  2. require("lualoader/mod")-- функции упрощающие написания скрипта.
  3. local road = {480.0, -198.1, 10.3, --1
  4.  446.3, -372.3, 9.6, --2
  5.  363.4, -450.0, 9.4, --3
  6.  }
  7.  
  8. function main()
  9. while lualoader == nil do
  10.  wait()
  11.  player = findplayer()-- получить игрока
  12.  if Keypress(VK_H)
  13. then
  14.  x,y,z =getcoordinates_on_y(player,10)-- получить координаты на 5 м впереди от игрока.
  15.   mycar = Createcar(MODEL_SENTXS,x,y,z) -- создать авто на 5 впереди.
  16. putincar(player, mycar)-- переместить педа в авто
  17. wait(600)
  18.    while lualoader == nil do  wait()
  19.    if follow_route_for_corona_for_playercar(mycar, road)
  20.     then miss(100) -- дать 100$
  21.     break
  22.      end
  23.  
  24.  end
  25.  end
  26.  end
  27.  end
  28.  
Как работает функция putincar? Она принимает педа и авто, перемещая его в авто.

Код: Javascript
  1. int putincar(lua_State* L) {// переместить педа в авто.
  2.         try {
  3.                 if (LUA_TUSERDATA == lua_type(L, 2) && LUA_TUSERDATA == lua_type(L, -1)) {//число.
  4.  
  5.                         CPed* ped = (CPed*)Userdata::get<CPed>(L, 1, false);
  6.                         CVehicle* car = (CVehicle*)Userdata::get<CVehicle>(L, 2, false);
  7.  
  8.                         CPed* player = FindPlayerPed();// найти игрока  
  9.                         if (ped != player) {
  10.                                 Command<COMMAND_WARP_CHAR_INTO_CAR>(CPools::GetPedRef(ped), CPools::GetVehicleRef(car));
  11.                                 return 0;
  12.                         }
  13.                         else {
  14.                                 Command<COMMAND_WARP_PLAYER_INTO_CAR>(CWorld::PlayerInFocus, CPools::GetVehicleRef(car));
  15.                                 return 0;
  16.                         }
  17.                 }
  18.                 else { throw "bad argument in function putincar"; }
  19.         }
  20.         catch (const char* x) { writelog(x); }// записать ошибку в файл.
  21.         return 0;
  22. };
  23.  

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

Помогите мне понять как работает скриптовая команда Command<COMMAND_DISPLAY_ONSCREEN_TIMER_WITH_STRING>(0,"R_TIME", 1);
На CLEO использовал ее так.
Код: Javascript
  1. while true
  2. wait 0 ms  
  3. 03C3: set_timer_with_text_to 16@ type 0 text 'R_TIME'  // ˜pem¬ ?ohk?:
  4. jump @1
  5.  
скрипт exapmle 2
Вот видео https://www.youtube.com/watch?v=MXaVkJihJyg&feature=youtu.be

Оффлайн Prographer

  • Прохожий
  • *
  • Сообщений: 100
  • Репутация: +9/-0
  • Говнокодим, грабим, убиваем
    • Просмотр профиля
Круто!
Конечно, у Lua больше возможностей, чем у SCM, но я при предпочёл старый, добрый инструмент, потому что не вижу большого смысла писать на Lua, вдобавок поддерживать разработку плагина.
А в целом очень здорово. Удачи в разработке :)

Оффлайн egor230

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

Когда я прошел GTA Vice City, мне хотелось больше миссии, тогда денег не было на новые игры, а интернет был чем недосягаемым в 2003.
Мы часто обсуждаем, Какие новые миссии могли быть в игре. На CLEO их очень долго писать, бесило постоянные проверки, объём строк кода переваливал за 100.

Попробовал написать миссию для GTA San Andreas на moonloader

Код: Javascript
  1. [url]https://www.youtube.com/watch?v=0r0_bvHEWlc&featu=[/url]
  2. script_author("egor")
  3. require "lib.moonloader"
  4. func = require 'module'
  5. glob = require 'game.globals'
  6. model = require 'lib.game.models'
  7. local encoding = require 'encoding'
  8. encoding.default = 'CP1251'
  9. function step1()
  10. text = func.koder("езжай на маркер")
  11. printStringNow(text, 2000)— вывод текста
  12. wait(2000)
  13. while not locateCar3d(car, 2445.20,-1659.75,13.07, 6.0, 6.0, 3.0, true) do
  14. wait(0) end
  15. removeBlip(checkpoint)
  16. text = func.koder("убей неё")
  17. printStringNow(text, 2000)— вывод текста
  18. wait(500)
  19. ped = func.foe("VWFYWA2",28) — враг номер
  20. while not isCharDead(ped) do wait(0) end — пока жив пед пауза
  21. func.pass(100) — кол-во денег за победу
  22. end
  23.  
  24. function mission()
  25. car = createCar(model.CHEETAH, 2492.70, -1661.45, 13.10) — создать машину
  26. checkpoint = addBlipForCoord(2445.20,-1659.75,13.07) — 018A: 1@ = create_checkpoint_at 14@ 15@ 16@
  27. setCoordBlipAppearance(checkpoint, 2) — 08FB: set_checkpoint 1@ type_to 0
  28. step1()
  29. end
  30. function main()
  31. miss = 0
  32. creat = 0 — флаг создание сферы и иконки
  33. models = {model.CHEETAH,model.VWFYWA2,model.MICRO_UZI}— список моделей для миссии
  34. posx = 2497.49, posy = -1652.38, posz = 13.47 — координаты метки миссии
  35. icons = 40 — номер иконки миссии
  36. while true do
  37. wait(0)
  38. miss = func.check()
  39. if miss == 1
  40. then mission()
  41. end
  42. end
  43. end
  44.  
  45.  

Меньший объем кода достигается за счёт многопоточности, где происходили проверки.

Попробовал сделать миссию на lua для GTA Vice City. Это по сути однопоточная система, реальной многопоточности, есть сопрограммы.
введите чит-код "mission4" и начнется миссия.
Код: Javascript
  1. require("lualoader/mod")
  2. local road = {239.2, -1338.6, 10.6, -- 1
  3. 296.1, -997.9, 10.6, -- 2
  4. 490.5, -545.5, 10.6, -- 3
  5. 520.0, -81.6, 10.2, -- 4
  6. 526.5, 1264.8, 15.8 -- 5
  7. } open_doors = coroutine.create(function(car)
  8. while lualoader == nil do
  9.   coroutine.yield()
  10.   local health = getcarhealth(car)
  11.  if health < 800 and status == nil
  12.  then printmessage("open doors car", 3500,1)
  13.  opendoorcar(car, DRL) opendoorcar(car, DRR)
  14.  status = 1
  15.  for i = 1, 30 do x,y,z = getcarcoordinates_on_y(car,-3)
  16.   wait(600)  z = z -0.9 create_money_pickup(2000, x,y,z)
  17.   coroutine.yield()
  18.  end
  19.   else  coroutine.yield()
  20.  end
  21.  end
  22.  end
  23.  )
  24.  exit_foel = coroutine.create(function(car,ped)
  25. while lualoader == nil do  coroutine.yield()  
  26.   local health = getcarhealth(car)-- получить здоровье авто.
  27.  if health < 500
  28.  then printmessage("~r~i kill you", 2500,1)
  29.    Giveweaponped(ped,600,"buddyshot")-- дать педу оружие.
  30.  exitcar(ped)-- выход педа из авто.
  31.  Kill_ped_on_foot(ped, player)-- пед хочет убить игрока.
  32.  break
  33.  end
  34.  end
  35.  end
  36.  )
  37.  
  38. function main()
  39. while lualoader == nil do wait()
  40.  player = findplayer()-- получить игрока.
  41.  if  star_mission(player,"mission4")-- чит-код для активации миссии.
  42.  then fade(0,200) -- затенение, 200 время.
  43.  showtext("collection car", 500,1)-- вывод названия миссии.
  44.    Giveweaponped(player,600,"uzi")-- дать педу оружие.
  45.    wait(1900)-- задержка.
  46.    setpedcoordes(player, -212.4, -1433.0, 8.1)-- переместить игрока в координаты.
  47.    setpedangle(player, 220.0)-- уст угол педа.
  48.  mycar = Createcar(MODEL_PCJ600, 97.1, -1520.8, 10.0) -- создать авто.
  49.   setcarangle(mycar, 169)-- уст угол авто игрока.
  50.   putincar(player, mycar)--  поместить педа в авто.
  51.  
  52.  car = Createcar(MODEL_SECURICA, 86.4, -1590.9, 10.0, 265) -- создать авто.
  53.   setcarangle(car, 270) -- уст угол авто педа.
  54.   m = create_marker_car(car)-- создать маркер над авто.
  55.   ped = set_ped_in_car(car, "WMYSK" )-- уст педа водителя авто.
  56.  setcarspeed(car, 45) setdrivingstyle(car, 2) setcarstrong(car, 1)
  57.  
  58.  
  59.   fade(1,2600) --просветления, 2600 время.
  60.   printmessage("~r~kill driver and car!",4000,1)
  61.   newthread(checkmission, player) -- в новом потоке, постоянная проверка жив ли игрок?
  62.  while true == getflagmission() do wait()
  63.  
  64.  if follow_route(car, road) -- ехать по маршруту.
  65.  then  end_mission("mission failed!")--миссия провалена.
  66.  break
  67.  end
  68.  if 0 == getcarhealth(car) and 0 == getpedhealth(ped)-- если враг убит и машина уничтожена.
  69.  then miss(100) -- миссия выполнена дать 100$
  70.  break
  71.  end
  72.   coroutine.resume(exit_foel, car, ped) -- потока выхода педа из авто.
  73.   coroutine.resume(open_doors, car)-- выпадения денег.
  74.  end
  75. destroy()-- удалить все объекты
  76. end end
  77. end
  78. [url]https://www.youtube.com/watch?v=uoWVNks1WGk&feature=youtu.be[/url]
  79.  
  80.  
Миссия достаточно простая, по комментариям разобраться можно.
периодическое вызывается функция которую мы поместили в newthread она проверяет жив или арестован игрок.
Как она устроена на стороне с++.
Код: Javascript
  1. int newthread(lua_State* L) {// новый поток.
  2.         try {
  3.                 if (LUA_TFUNCTION == lua_type(L, 1)) {
  4.                         int stacksize = lua_gettop(L);
  5.                         //lua_pushinteger(L, stacksize);
  6.                         return lua_yield(L, stacksize);
  7.                 }
  8.                 else { throw "bad argument in function newthread"; }
  9.         }
  10.         catch (const char* x) { writelog(x); }
  11.         return 0;
  12. };
  13.                        
  14.     lua_pcall(L, 0, 0, 0);// запуск файла.
  15.     lua_State* L1 = lua_newthread(L);// создать новый поток.
  16.      lua_getglobal(L, "main"); counts++;// увеличить счетчик запущенных скриптов на 1.
  17.         if (LUA_TFUNCTION == lua_type(L, -1)) {
  18.                 luastate.push_back(L);// добавить указатель на lua состояния в вектор.
  19.                 lua_resume(L, NULL, 0); //Основной поток
  20.                 int args = lua_gettop(L);// получить аргументы для второго потока.
  21.                 lua_xmove(L, L1, args);
  22.                 args--;
  23.                 reversestack(L1); //инвертировать содержимое стека.
  24.                 while (LUA_OK != lua_status(L)) {// Пока основной поток не закончен.
  25.                         this_thread::sleep_for(chrono::milliseconds(1)); // задержка.
  26.                         if (LUA_TFUNCTION == lua_type(L1, -1) && LUA_YIELD == lua_status(L)) {
  27.  
  28.                                 for (int i = 1; i <= args; i++) { lua_pushvalue(L1, i); }// расстановка аргументов для вызова.
  29.                                 lua_resume(L1, L, args);
  30.                         }
  31.                         if (LUA_YIELD == lua_status(L1)) {
  32.                                 lua_sethook(L, (lua_Hook)hookFunc, LUA_MASKCOUNT, 9000); //вызов функции с заданной паузой.
  33.                                 lua_resume(L, L1, 0);// возобновить основной поток.
  34.                         }
  35.                         if (LUA_OK == lua_status(L1)) {// если второй поток завершен.
  36.                                 lua_sethook(L, (lua_Hook)hookFunc, LUA_MASKCOUNT, 0);// отключить хук.
  37.                                 lua_resume(L, NULL, 0);
  38.                         }
  39.                 }
  40.  
  41.  
К сожалению можно запускать только один дополнительный поток, не нашел способ Как сделать лучше.

Prographer Спасибо вам большое за ваше мнения, скорее lua, инструмент, чтобы изучить возможности sdk plugin

Оффлайн kenking

  • Новичок
  • **
  • Сообщений: 225
  • Репутация: +14/-0
    • Просмотр профиля
Цитировать
как работает скриптовая команда Command<COMMAND_DISPLAY_ONSCREEN_TIMER_WITH_STRING>(0,"R_TIME", 1);
Посмотрел как устроен опкод и класс COnscreenTimer. Пример работы с таймерами:
Код: C++
  1. #include "plugin.h"
  2. #include "extensions\KeyCheck.h"
  3. #include "CUserDisplay.h"
  4.  
  5. int &var_$3402 = *(int *)0x8247A8;
  6.  
  7. using namespace plugin;
  8.  
  9. class Test {
  10. public:
  11.     static int timer;
  12.     enum eTimerState { STATE_ADD, STATE_CLEAR };
  13.     static eTimerState m_currentState;
  14.  
  15.     Test() {
  16.         Events::drawingEvent += [] {
  17.             gamefont::Print({
  18.                 Format("id %d", CUserDisplay::OnscnTimer.m_aClocks[0].m_nVarId),
  19.                 Format("direction %d", CUserDisplay::OnscnTimer.m_aClocks[0].m_nTimerDirection),
  20.                 Format("enabled %d", CUserDisplay::OnscnTimer.m_aClocks[0].m_bEnabled),
  21.                 Format("text %s", CUserDisplay::OnscnTimer.m_aClocks[0].m_acDisplayedText),
  22.                 Format("key %s", &CUserDisplay::OnscnTimer.m_aClocks[0].m_acDescriptionTextKey),
  23.                 Format("var $3402 %d", var_$3402)
  24.             }, 10, 10, 1, FONT_DEFAULT, 0.75f, 0.75f, color::White);
  25.  
  26.             KeyCheck::Update();
  27.             switch (m_currentState) {
  28.             case STATE_ADD:
  29.                 if (!CUserDisplay::OnscnTimer.m_aClocks[0].m_bEnabled) {
  30.                     if (KeyCheck::CheckWithDelay('M', 1000)) {
  31.                         var_$3402 = 120000; //in CLEO $3402 = 120000
  32.                         CUserDisplay::OnscnTimer.AddClock(timer, "R_TIME", 1); //03C3: set_timer_with_text_to $3402 type 1 text 'R_TIME'
  33.                         m_currentState = STATE_CLEAR;
  34.                     }
  35.                     if (KeyCheck::CheckWithDelay('U', 1000)) {
  36.                         CUserDisplay::OnscnTimer.AddClock(timer, "R_TIME", 0); //03C3: set_timer_with_text_to $3402 type 0 text 'R_TIME'
  37.                         m_currentState = STATE_CLEAR;
  38.                     }
  39.                 }
  40.                 break;
  41.             case STATE_CLEAR:
  42.                 if (KeyCheck::CheckWithDelay('N', 1000) || var_$3402 > 121000 || var_$3402 < 1) {
  43.                     CUserDisplay::OnscnTimer.ClearClock(timer); //014F: stop_timer $3402
  44.                     var_$3402 = 0; //$3402 = 0
  45.                     m_currentState = STATE_ADD;
  46.                 }
  47.                 break;
  48.             }
  49.         };
  50.     }
  51. } test;
  52.  
  53. int Test::timer = 13608;
  54. Test::eTimerState Test::m_currentState = STATE_ADD;

Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 161
  • Репутация: +6/-0
    • Просмотр профиля
    • Mr
kenking благодарю Вас, что помогли мне с таймером, старался перенести в lua.

Удалось реализовать 3 типа таймера
Код: Javascript
  1. 1.  timer_donw(60,"R_TIME",1) последний параметр отвечает за уменьшения или увеличения его со временем.
  2.  
  3. 2. t =turn_default_timer(true,"TIMER:")--  первый параметр  включает, второй  какую надпись выводит перед  таймером.
  4. функция устроена так
  5. t ={turn,str_timer,1267,270, 1,1, 2.0, 2.0, 101, 193, 244}--
  6. print_front(t)-- вкл\выкл таймер, координаты, размер, цвет.
  7.  
  8. 3. countdown(8) от какого числа начинать  обратный отчёт, когда достигает 0, возвращает false,  использовать в цикле.
  9.  

Код: Javascript
  1. require("lualoader/mod")
  2.  
  3. function main()
  4. while lualoader == nil do
  5.  wait()-- задержка.
  6.  player = findplayer()-- получить игрока
  7.  if Keypress(VK_T) -- если клавиша T.
  8.  then
  9.  timer_donw(60,"R_TIME",1)-- Таймер на уменьшения
  10.  end
  11.  
  12.  if Keypress(VK_U) -- если клавиша U.
  13.  then
  14.  stop_timer("R_TIME")-- удалить таймер.
  15.  end
  16.  if Keypress(VK_H) -- если клавиша H.
  17.  then x,y,z =getcoordinates_on_y(player,10)-- получить координаты на 10 м впереди.
  18.   z = z-1
  19.   obj = Create_obj(350, x,y,z) -- создать объект(бочка).
  20.   printmessage("the bomb is planted", 2000,1)
  21.  while countdown(8) do wait()-- таймер на 8 секунд.
  22.      
  23. end
  24.  create_explosion(3,x,y,z ) --Создать взрыв на координатах.
  25. remove_obj(obj)
  26. end
  27.  
  28.  if Keypress(VK_G) -- если клавиша G.
  29. then printmessage("star timer", 2000,1)
  30. t =turn_default_timer(true,"TIMER:")
  31. end
  32.  if Keypress(VK_N) -- если клавиша N.
  33. then printmessage("stop timer", 2000,1)
  34. turn_default_timer(false,t)
  35.  
  36. end  
  37. end
  38. end
  39.  

Видео https://www.youtube.com/watch?v=W-GEgnW9gHU&feature=youtu.be

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

 Думаю пока над новыми функциями,  как работа с памятью.

Оффлайн kenking

  • Новичок
  • **
  • Сообщений: 225
  • Репутация: +14/-0
    • Просмотр профиля
Цитировать
как в данной функции обойтись без использования скриптовой команды?
Код: C++
  1. CPed *ped; CVehicle *vehicle;
  2. ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, vehicle);
  3. ped->WarpPedIntoCar(vehicle);

Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 161
  • Репутация: +6/-0
    • Просмотр профиля
    • Mr
Новые функции.
Код: Javascript
  1. .addCFunction("ped_attack_car", ped_attack_car) // пед атакует авто.
  2.  
  3. .addCFunction("ped_frozen", ped_frozen)  // заморозить игpока.
  4. .addCFunction("hold_cellphone", hold_cellphone) // поднять телефон.
  5. .addCFunction("car_lastweapondamage", car_lastweapondamage)// номер оружие, которое нанесло урон авто.
  6. .addCFunction("car_currentgear", car_currentgear) // текущая передача авто.
  7.  
  8. .addCFunction("getcar_model", getcar_model) // получить модель авто.
  9. .addCFunction("setcarsiren", setcarsiren) // установить сирену для авто.
  10. .addCFunction("ped_car_as_driver", ped_car_as_driver) // пед садится в авто как водитель.
  11. .addCFunction("ped_car_as_passenger", ped_car_as_passenger) // пед садится в авто как пассажир.
  12.  
  13.  

нажмите клавишу "H" томми позвонить по телефону, появиться авто и 2 педа, они садят в авто 
вот сам скрипт.

Код: Javascript
  1. require("lualoader/mod")
  2.  
  3. function main()
  4. while lualoader == nil do
  5.  wait()-- задержка.
  6.  player = findplayer()-- получить игрока
  7.   if Keypress(VK_H) -- если клавиша H.
  8.  then   x,y,z =getcoordinates_on_y(player,5)-- получить координаты на 5 м впереди.
  9. Giveweaponped(player,600,"uzi")-- дать педу оружие.
  10. Hold_cellphone(player, 1)-- понять телефон.
  11. wait(1300)
  12. show_text_styled("BNK1_4",1000,2)
  13. play_voice("BNK1_4")
  14. Hold_cellphone(player, 0)-- положить телефон.
  15. mycar = Createcar(MODEL_INFERNUS,x,y,z) -- создать авто на 5 впереди.
  16.  
  17.  wait(12)-- задержка.
  18.   x,y,z =getcoordinates_on_y(player,10)-- получить координаты на 10 м впереди.
  19.  ped = Createped("HMYST",x,y,z)
  20. ped_car_as_driver(ped, mycar)-- пед садится в авто как водитель.
  21.  wait(12)-- задержка.
  22.   x,y,z =getcoordinates_on_y(player,15)-- получить координаты на 15 м впереди.
  23.  ped1 = Createped("HFOBE",x,y,z)
  24.  ped_car_as_passenger(ped1, mycar)-- пед садится в авто как пассажир.
  25.  
  26. wait(5300)
  27.  destroy()
  28.  end  
  29.  end
  30. end
  31.  
  32.  
видео https://www.youtube.com/watch?v=UvUD6oaJB-w&feature=youtu.be

добавлю новый функционал.
спасибо за ответ kenking, поправил, все работает. копаюсь в базе, разбираю функции,   всё идёт крайне медленно, занимает много времени.
Я сам недоволен  как работает lua в плагине, хочется лучше.  Вот бы посмотреть исходники moonloader.   Чтобы улучшить, у самого  маленькой опыт в программирование.  Например,  не знаю как выводить gtx записи. пед охраняет зону ped->SetObjective(OBJECTIVE_GUARD_SPOT, pos); //охранное место 0194
А на деле стоит на месте. ищу аналоги 0A8C: write_memory 0xC0BC15 size 1 value 1 virtual_protect 0 и 0A8D: $result = read_memory 1@ size 4 virtual_protect 0
 чтобы поработать с памятью, не могу актировать бомбу в машине, хотя делал все правильно.

      car->ActivateBombWhenEntered();
      car->ActivateBomb();*/


Оффлайн kenking

  • Новичок
  • **
  • Сообщений: 225
  • Репутация: +14/-0
    • Просмотр профиля
Цитировать
не знаю как выводить gtx записи
Класс CText пока в sdk не добавлен. Пока можно скриптовыми командами:
Код: C++
  1. #include "plugin.h"
  2. #include "eScriptCommands.h"
  3. #include "extensions\ScriptCommands.h"
  4. #include "extensions\KeyCheck.h"
  5.  
  6. using namespace plugin;
  7.  
  8. class Test {
  9. public:
  10.     Test() {
  11.         Events::gameProcessEvent += [] {
  12.             KeyCheck::Update();
  13.             if (KeyCheck::CheckWithDelay('M', 2000)) {
  14.                 Command<COMMAND_LOAD_MISSION_TEXT>("GENERA1");
  15.                 Command<COMMAND_PRINT_NOW>("GEN1_A", 2000, 1);
  16.             }
  17.         };
  18.     }
  19. } test;

Цитировать
ищу аналоги 0A8C: write_memory 0xC0BC15 size 1 value 1 virtual_protect 0
и 0A8D: $result = read_memory 1@ size 4 virtual_protect 0
чтобы поработать с памятью
Для этого есть patch::Set и patch::Get
Но можно просто работать через свою переменную, например, как показал выше в примере с таймерами.
Код: C++
  1. int &var_$3402 = *(int *)0x8247A8;