Автор Тема: LuaLoader - как MoonLoader, только для GTA VC, на основе Plugin SDK от DK  (Прочитано 8508 раз)

Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 183
  • Репутация: +7/-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.  

« Последнее редактирование: Февраль 03, 2020, 05:06:50 pm от Shagg_E »

Оффлайн Shagg_E

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

Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 183
  • Репутация: +7/-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

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

Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 183
  • Репутация: +7/-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

  • Новичок
  • **
  • Сообщений: 237
  • Репутация: +16/-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

  • Новичок
  • **
  • Сообщений: 183
  • Репутация: +7/-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

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

Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 183
  • Репутация: +7/-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

  • Новичок
  • **
  • Сообщений: 237
  • Репутация: +16/-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;

Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 183
  • Репутация: +7/-0
    • Просмотр профиля
    • Mr
Re: lualoader как modloader, только для GTA vc на основе SDK Plugin DK
« Ответ #10 : Декабрь 08, 2019, 09:41:45 pm »
kenking спасибо большое за Ваш ответ.
насчет работы с patch::Set и patch::Get, пытался установить бомбу в авто, на CLEO это так.

 
Код: Text
  1. / Установить тип бомбы 0@ (car handle) 1@ (bomb stage)    
  2. gosub @text
  3. 05E7: 0@ = car 0@ struct
  4. 0@ += 0x1FE  // car bomb offset
  5. 05E0: 2@ = read_memory 0@ size 1 virtual_protect 0  // store previous value
  6. 05F9: 1@ = 1@ AND 7  // keep only the first three bits from input param
  7. 05F9: 2@ = 2@ AND 0xF8  // exclude the first three bits in stored value
  8. 05FA: 2@ = 2@ OR 1@  // replace the first three bits of stored value with input param
  9. 05DF: write_memory 0@ size 1 value 2@ virtual_protect 0  // set to new value
  10. 05F6: ret 0
  11.  
  12.  
Немного проект забуксовал, виной я, мало опыта, добавил несколько функций.

 
Код: Text
  1.  show_text_gtx() вывести игровой текст.
  2.  camera_at_point()переместить камеру в координатах.
  3.  restore_camera() восстановить камеру.
  4.  is_wanted_level() проверить уровень розыска.
  5.  set_camera_position() уст камеру в координатах.
  6.  flash_hud() Мигание элементов HUD.
  7.  set_radio() уст радио.                
  8.  set_car_tires() проколоть шину.
  9.  
  10.   [/ccp]
  11. хотел немного изменить камеру, путем перемещения ее в цикле. не могу развернуть если томми повернулся.  [url]https://www.youtube.com/watch?v=3i_KD9zfKog[/url] работа с камерой очень нужна, для создания сцен миссии.
  12. сколько не бился, никак не получилось создать специального актера через скриптовые команды.
  13.  
  14. постоянно сталкиваюсь с кучей проблем, как сделать лучше то или другое, все часто хромает. когда всё постоянно идёт с большим трудностями, это психологически давит. Хочется хочется видеть результат больше, чем он есть на самом деле. Думаю, как сделать плагин более удобным, изобретаю костыли с велосипедами))))
  15. стараюсь найти способ смены скина педа.
  16.  
  17. все это время изучал новые методы SDK.
  18.         ped->BeingDraggedFromCar();     // вроде анимация выхода из авто.
  19. //ped->SetObjective(OBJECTIVE_GUARD_SPOT, pos); //охранное место  пед непонятно как охраняет.
  20.  
  21. Буду очень всем рад, кто напишет функции с описанием  их работы, добавляю  их в плагин.  Например, починка шин.

Оффлайн kenking

  • Новичок
  • **
  • Сообщений: 237
  • Репутация: +16/-0
    • Просмотр профиля
Re: lualoader как modloader, только для GTA vc на основе SDK Plugin DK
« Ответ #11 : Декабрь 09, 2019, 10:45:10 am »
Цитировать
сколько не бился, никак не получилось создать специального актера через скриптовые команды
Можно обойтись без скриптовых команд, все нужные для этого функции в sdk есть. Только обрати внимание, что в отличие от опкода, здесь надо использовать специальный слот на 1 меньше при том же ID спецактёра
Код: C++
  1. #include "plugin.h"
  2. #include "extensions\KeyCheck.h"
  3. #include "CStreaming.h"
  4. #include "CCivilianPed.h"
  5. #include "CWorld.h"
  6.  
  7. using namespace plugin;
  8.  
  9. class Test {
  10. public:
  11.     Test() {
  12.         Events::gameProcessEvent += [] {
  13.             KeyCheck::Update();
  14.             if (KeyCheck::CheckWithDelay('M', 2000)) {
  15.                 CStreaming::RequestSpecialChar(20, "SAM", 6); // 023C: load_special_actor 21 'SAM'
  16.                 if (CStreaming::HasSpecialCharLoaded(20)) {   // 023D: special_actor 21 loaded
  17.                     CPed *ped = new CCivilianPed(PEDTYPE_CIVMALE, 129);
  18.                     if (ped) {
  19.                         ped->SetPosition(FindPlayerPed()->TransformFromObjectSpace(CVector(0.0f, 2.0f, 0.0f)));
  20.                         CWorld::Add(ped);
  21.                     }
  22.                     CStreaming::SetMissionDoesntRequireSpecialChar(20); // 0296: unload_special_actor 21
  23.                 }
  24.             }
  25.         };
  26.     }
  27. } test;

Цитировать
Например, починка шин.
Код: C++
  1. #include "plugin.h"
  2. #include "extensions\KeyCheck.h"
  3. #include "CMessages.h"
  4.  
  5. using namespace plugin;
  6.  
  7. class Test {
  8. public:
  9.     Test() {
  10.         Events::gameProcessEvent += [] {
  11.             KeyCheck::Update();
  12.             if (KeyCheck::CheckWithDelay('N', 2000)) {
  13.                 CVehicle *vehicle = FindPlayerVehicle();
  14.                 if (vehicle && vehicle->m_nVehicleClass == VEHICLE_AUTOMOBILE) {
  15.                     CAutomobile *automobile = reinterpret_cast<CAutomobile *>(vehicle);
  16.                     if (!automobile->m_carDamage.GetWheelStatus(0)) {
  17.                         automobile->m_carDamage.SetWheelStatus(0, 1);
  18.                         CMessages::AddMessageJumpQ(L"damage", 2000, false);
  19.                     }
  20.                     else {
  21.                         automobile->m_carDamage.SetWheelStatus(0, 0);
  22.                         CMessages::AddMessageJumpQ(L"fix", 2000, false);
  23.                     }
  24.                 }
  25.             }
  26.         };
  27.     }
  28. } test;

Добавлено:
Цитировать
стараюсь найти способ смены скина педа.
Посмотрел опкоды, получается так:
Код: C++
  1. #include "plugin.h"
  2. #include "extensions\KeyCheck.h"
  3. #include "extensions\ScriptCommands.h"
  4. #include "eScriptCommands.h"
  5. #include "CStreaming.h"
  6. #include "CWorld.h"
  7.  
  8. using namespace plugin;
  9.  
  10. class Test {
  11. public:
  12.     Test() {
  13.         Events::gameProcessEvent += [] {
  14.             KeyCheck::Update();
  15.             if (KeyCheck::CheckWithDelay('N', 2000)) {
  16.                 CPed *player = FindPlayerPed();
  17.                 if (player) {
  18.                     //Command<COMMAND_UNDRESS_CHAR>(CPools::GetPedRef(player), "STRIPA");
  19.                     int modelIndex = player->m_nModelIndex;
  20.                     player->DeleteRwObject();
  21.                     if (player->IsPlayer())
  22.                         modelIndex = 0;
  23.                     CStreaming::RequestSpecialModel(modelIndex, "STRIPA", 6);
  24.                     CWorld::Remove(player);
  25.                     //Command<COMMAND_LOAD_ALL_MODELS_NOW>();
  26.                     CTimer::Stop();
  27.                     CStreaming::LoadAllRequestedModels(false);
  28.                     CTimer::Update();
  29.                     //Command<COMMAND_DRESS_CHAR>(CPools::GetPedRef(player));
  30.                     player->m_nModelIndex = -1;
  31.                     player->SetModelIndex(modelIndex);
  32.                     CWorld::Add(player);
  33.                 }
  34.             }
  35.         };
  36.     }
  37. } test;
« Последнее редактирование: Декабрь 09, 2019, 12:37:12 pm от kenking »

Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 183
  • Репутация: +7/-0
    • Просмотр профиля
    • Mr
Re: lualoader как modloader, только для GTA vc на основе SDK Plugin DK
« Ответ #12 : Декабрь 22, 2019, 05:05:02 pm »

  Благодарю вас kenking за  ответ,  ваши примеры смог перенести в плагин. Как всегда долго тупил.
 Вот как создавать специального актера.
Код: Text
  1.  
  2.  ped1 = Create_spec_ped("SAM", 1,x,y,z) --
  3.  
  4. Вот список имен спец актеров.
  5.  
  6. SPEC_PED_MODELS_AND_TYPES = {
  7.  BGA = {129,4,20}, BGB = {129,4,20}, BOUNCA = {129,4,20}, BURGER = {129,4,20}, CGONA = {129,4,20}, CGONB = {129,4,20}, CGONC = {129,4,20},
  8.  CHEF = {129,4,20}, CMRAMAN = {129,4,20}, COURIER = {129,4,20}, CREWA = {129,4,20}, CREWB = {129,4,20}, CSJUGGZ = {129,5,20},
  9.  DGOONA = {129,4,20}, DGOONB = {129,4,20}, DGOONC = {129,4,20}, FLOOZYA = {129,5,20}, FLOOZYB = {129,5,20}, FLOOZYC = {129,5,20},
  10.  FSFA = {129,4,20}, IGALSCB = {129,4,20}, IGBUDDY = {129,4,20}, IGBUDY2 = {129,4,20}, IGBUDY3 = {129,4,20}, IGCANDY = {129,5,20},
  11.  IGCOLON = {129,4,20}, IGDIAZ = {129,4,20}, IGDICK = {129,4,20}, IGGONZ = {129,4,20}, IGHLARY = {129,4,20}, IGHLRY2 = {129,4,20},
  12.  IGJEZZ = {129,4,20}, IGKEN = {129,4,20}, IGMERC = {129,5,20}, IGMIKE = {129,4,20}, IGMIKE2 = {129,4,20}, IGPERCY = {129,4,20},
  13.  IGPHIL = {129,4,20}, IGPHIL2 = {129,4,20}, IGPHIL3 = {129,4,20}, IGSONNY = {129,4,20}, IGMERC2 = {129,5,20}, MBA = {129,4,20},
  14.  MBB = {129,4,20}, MPORNA = {129,4,20}, MGOONA = {129,4,20}, MSERVER = {129,4,20}, MBA = {129,4,20}, MBB = {129,4,20}, MPORNA = {129,4,20},
  15.  MGOONA = {129,4,20}, MSERVER = {129,4,20}, PLAY10 = {129,4,20}, PLAY11 = {129,4,20}, PLAY12 = {129,4,20}, PLAYER2 = {129,4,20},
  16.  PLAYER3 = {129,4,20}, PLAYER4 = {129,4,20},  PLAYER5 = {129,4,20},  PLAYER6 = {129,4,20},   PLAYER7 = {129,4,20},
  17.  PLAYER8 = {129,4,20}, PLAYER9 = {129,4,20}, PRINTRA = {129,4,20},  PRINTRB = {129,4,20}, PRINTRC = {129,4,20}, PSYCHO = {129,4,20},
  18.  S_KEEP = {129,4,20}, SAM = {129,4,20}, SGC = {129,4,20}, SGOONA = {129,4,20}, SGOONB = {129,4,20}, SHOOTRA = {129,5,20},
  19.  SHOOTRB = {129,4,20}, SPANDXA = {129,5,20},SPANDXB = {129,5,20}, STRIPA = {129,5,20}
  20. }
  21.  
  22. Теперь рассмотрим функцию создания специального актёра.
  23.  
  24. function Create_spec_ped(m, slot, x,y,z)--создать спец пед.
  25. idmodel, t = model_and_type(m, SPEC_PED_MODELS_AND_TYPES)-- модель и тип.
  26. tipe = idmodel -108- slot
  27. create_spec_ped(m,idmodel,tipe, t ,slot, x,y,z)
  28.  return ped
  29. end
  30.  
Видео демонстрация https://www.youtube.com/watch?v=yoV30HMnZY4&feature=youtu.be

Также есть пара функций
set_wheel_status)// уст состояния шин авто.         
/*
первый указатель на авто.
второй параметр номер колесо.
третий  статус, 0 = починка.
*/
set_skin // уст скин педа.
remove_spec_ped // удалить спец педа.
[/code]




Оффлайн egor230

  • Новичок
  • **
  • Сообщений: 183
  • Репутация: +7/-0
    • Просмотр профиля
    • Mr
Re: lualoader как modloader, только для GTA vc на основе SDK Plugin DK
« Ответ #13 : Январь 28, 2020, 10:09:24 pm »
Здравствуйте, всем. Была задержка в разработке.  Написал миссию.
Теперь спец актеры, это обычный пед с измененным скином, меньше мороки.
Код: Javascript
  1. Новые функции.
  2. ped = create_spec_ped("IGHLARY", 0.0,0.0,0.0) – Создать спец актер.
  3.    go_to_route(car, road)- авто следует по маршруту, принимает указатель на авто, таблицу с координатами.
  4. Теперь, чтобы создать корону чекпойнта, не нужно ставить ее в цикл.
  5.  local t = {true, 4.5, 6, 0, 255, 0, 0, x,y,z}
  6.   draw_corona(t) -- вкл корону
  7.   then  sound_coordinate(7, 0.0,0.0,0.0)
  8. local t = {false, 4.5, 6, 0, 255, 0, 0, x,y,z}
  9.   draw_corona(t) -- выкл корону
  10.  
Новая миссия  “ driver”. Для активации введите чит-код “mission4”.
Вот видео  https://www.youtube.com/watch?v=GTIX6V4P1Vk&feature=youtu.be

Хотел у Вас спросить почему в игре некоторые части карты, имеют не полностью загруженные текстурами, на видео эти глюки есть если убрать только все asi плагины( а не только мой) то все текстуры прогружаются хорошо, у меня студия 19.
Скажите, пожалуйста,  как заставить актера – сидеть, лежать и т.д. где можно посмотреть полный список анимации? есть ли проверка, что пед удален?
« Последнее редактирование: Январь 29, 2020, 01:19:13 am от egor230 »

Оффлайн xanser

  • Главный Модератор
  • Постоялец
  • *****
  • Сообщений: 598
  • Репутация: +92/-0
  • Есть такая профессия - на работе сидеть
    • Просмотр профиля
Re: lualoader как modloader, только для GTA vc на основе SDK Plugin DK
« Ответ #14 : Январь 29, 2020, 11:30:17 am »
На видео текстуры не пропадают, там лоды, которые не успевают меняться на нормальные модели из-за увеличенной нагрузки модами. Попробуй увеличить Streaming memory. Анимацию персонажей можно задавать функцией 0x405640 CAnimManager::BlendAnimation. Во вложении коды анимаций, которые я себе выписал. Например 14 код - падение вперед, CAnimManager::BlendAnimation(PlayerPed->rwObject, 0, 14, 10000.0f);