Вопросы по Lua скриптингу

Общая тема для вопросов по разработке скриптов на языке программирования Lua, в частности под MoonLoader.
  • Задавая вопрос, убедитесь, что его нет в списке частых вопросов и что на него ещё не отвечали (воспользуйтесь поиском).
  • Поищите ответ в теме посвященной разработке Lua скриптов в MoonLoader
  • Отвечая, убедитесь, что ваш ответ корректен.
  • Старайтесь как можно точнее выразить мысль, а если проблема связана с кодом, то обязательно прикрепите его к сообщению, используя блок [code=lua]здесь мог бы быть ваш код[/code].
  • Если вопрос связан с MoonLoader-ом первым делом желательно поискать решение на wiki.

Частые вопросы

Как научиться писать скрипты? С чего начать?
Информация - Гайд - Всё о Lua скриптинге для MoonLoader(https://blast.hk/threads/22707/)
Как вывести текст на русском? Вместо русского текста у меня какие-то каракули.
Изменить кодировку файла скрипта на Windows-1251. В Atom: комбинация клавиш Ctrl+Shift+U, в Notepad++: меню Кодировки -> Кодировки -> Кириллица -> Windows-1251.
Как получить транспорт, в котором сидит игрок?
Lua:
local veh = storeCarCharIsInNoSave(PLAYER_PED)
Как получить свой id или id другого игрока?
Lua:
local _, id = sampGetPlayerIdByCharHandle(PLAYER_PED) -- получить свой ид
local _, id = sampGetPlayerIdByCharHandle(ped) -- получить ид другого игрока. ped - это хендл персонажа
Как проверить, что строка содержит какой-то текст?
Lua:
if string.find(str, 'текст', 1, true) then
-- строка str содержит "текст"
end
Как эмулировать нажатие игровой клавиши?
Lua:
local game_keys = require 'game.keys' -- где-нибудь в начале скрипта вне функции main

setGameKeyState(game_keys.player.FIREWEAPON, -1) -- будет сэмулировано нажатие клавиши атаки
Все иды клавиш находятся в файле moonloader/lib/game/keys.lua.
Подробнее о функции setGameKeyState здесь: lua - setgamekeystate | BlastHack — DEV_WIKI(https://www.blast.hk/wiki/lua:setgamekeystate)
Как получить id другого игрока, в которого целюсь я?
Lua:
local valid, ped = getCharPlayerIsTargeting(PLAYER_HANDLE) -- получить хендл персонажа, в которого целится игрок
if valid and doesCharExist(ped) then -- если цель есть и персонаж существует
  local result, id = sampGetPlayerIdByCharHandle(ped) -- получить samp-ид игрока по хендлу персонажа
  if result then -- проверить, прошло ли получение ида успешно
    -- здесь любые действия с полученным идом игрока
  end
end
Как зарегистрировать команду чата SAMP?
Lua:
-- До бесконечного цикла/задержки
sampRegisterChatCommand("mycommand", function (param)
     -- param будет содержать весь текст введенный после команды, чтобы разделить его на аргументы используйте string.match()
    sampAddChatMessage("MyCMD", -1)
end)
Крашит игру при вызове sampSendChat. Как это исправить?
Это происходит из-за бага в SAMPFUNCS, когда производится попытка отправки пакета определенными функциями изнутри события исходящих RPC и пакетов. Исправления для этого бага нет, но есть способ не провоцировать его. Вызов sampSendChat изнутри обработчика исходящих RPC/пакетов нужно обернуть в скриптовый поток с нулевой задержкой:
Lua:
function onSendRpc(id)
  -- крашит:
  -- sampSendChat('Send RPC: ' .. id)

  -- норм:
  lua_thread.create(function()
    wait(0)
    sampSendChat('Send RPC: ' .. id)
  end)
end
 
Последнее редактирование:
1,417
1,030
Заметил, что если скрипт выгружать с помощью этой функции - на n-й раз (обычно до 5) игра крашится.
[22:46:34] SAMPFUNCS v5.3.3 release #19 (SA-MP 0.3.7) caught an exception.
[22:46:34] Base address: 5F2F0000
[22:46:34] > Exception record:
[22:46:34] Exception at address: 763D08B2, Flags: 00000001
[22:46:34] Module: C:\Windows\System32\KERNELBASE.dll (762D0000)
[22:46:34] Cause: E06D7363
а зачем его выгружать n кол-во раз? Не легче использовать scr:reload()?
 
  • Нравится
Реакции: RTD

Garrus

Известный
159
20
а зачем его выгружать n кол-во раз? Не легче использовать scr:reload()?
К примеру, есть параметры, которые скрипт берет для работы при входе в игру на определенном сервере. На другом сервере, соответственно, без этих параметров, скрипт завершает работу через thisScript():unload(). Я занимаюсь другим скриптом и перезагружаю его при помощи скрипта reloadall. И вот, на n-й раз, игра падает. Выходит, тот скрипт, который нужно перезагрузить, нужно перезагружать с помощью scr:reload(). Не критично, но тем не менее)
 
1,417
1,030
К примеру, есть параметры, которые скрипт берет для работы при входе в игру на определенном сервере. На другом сервере, соответственно, без этих параметров, скрипт завершает работу через thisScript():unload(). Я занимаюсь другим скриптом и перезагружаю его при помощи скрипта reloadall. И вот, на n-й раз, игра падает. Выходит, тот скрипт, который нужно перезагрузить, нужно перезагружать с помощью scr:reload(). Не критично, но тем не менее)
Поставь Lua - AutoReboot(https://blast.hk/threads/15454/) и не перезагружай все скрипты, AutoReboot при обновлении файла сам перезагрузит нужный скрипт.
 

Bogach

Активный
558
27
Однако снова здравствуйте, снова нужна Ваша помощь.
Задача следующая:

Выбрав игрока правой кнопкой мыши, над ним появился конус, после чего нажимаю на кнопку "L" и открывается sampShowDialog.
Title должен выглядеть так:
"[Помощник] Действие с игрком - nick"

(Я не знаю как тут выводятся переменные, поэтому вот. Еще переменной nick нужно присвоить значение того кого я выбрал ПКМ, ну логично в принципе).
Вот. Возьми мой пример.
Lua:
local valid, ped = getCharPlayerIsTargeting(PLAYER_HANDLE) -- получить хендл персонажа, в которого целится игрок
    if valid and isKeyDown(VK_I) then
         result, id = sampGetPlayerIdByCharHandle(ped)
         if result then -- Проверить, прошло ли получение ида успешно
               TargetingNickName = sampGetPlayerNickname(id)
               tName,tFamily = string.match(TargetingNickName,"(%a+)_(%a+)")
                 sampShowDialog(1000, string.format("{4682B4}СТО{FFD700} [%s / %d]",TargetingNickName,id), "{FFE4B5}- {FFFFFF}Принять в СТО\n{FFE4B5}- {FFFFFF}Выдать премию", "Выбрать", "Закрыть", 2)
         end
    end -- [[ Закрывает условие "valid" ]]
 

_JeT_

Новичок
24
0
Как заменить эти клавиши? Я просто не понял что за код клавиш, т.к. которые через VK не подходят по номерам
if isKeyDown(18) and isKeyJustPressed(114) then
И есть ли в LUA функция вроде get_player_nickname как в CLEO?
 

Vlad Horii

Известный
Проверенный
310
171
Как заменить эти клавиши? Я просто не понял что за код клавиш, т.к. которые через VK не подходят по номерам
if isKeyDown(18) and isKeyJustPressed(114) then
И есть ли в LUA функция вроде get_player_nickname как в CLEO?
Функция есть.
Клавиши использовать либо по их коду, либо подключая библиотеку "keys" (что является намного удобнее).
 

f0Re3t

Poh production
Друг
876
808
есть некоторый код в майне, в нем проверки, если проверки не прошли, то скрипт должен выгрузиться, все хорошо работает, но после выгружения он кидает в чат краш и в консоли сф пишет ерроры:
Код:
[12:14:51] Warning(s007): Exception 0xC0000005 at 0x525235FF

[ML] (error) scr: cannot resume non-suspended coroutine
[ML] (error) scr: Script died due to error. (0A8DFD14)

выгружаю таким образом:
Lua:
local scr_name_id = thisScript() --  в начале скрипта

if 1 < 2 then -- где-то в мейне
    scr_name_id.unload()
    return
end
 

ZKelo

Известный
82
25
есть некоторый код в майне, в нем проверки, если проверки не прошли, то скрипт должен выгрузиться, все хорошо работает, но после выгружения он кидает в чат краш и в консоли сф пишет ерроры:
Код:
[12:14:51] Warning(s007): Exception 0xC0000005 at 0x525235FF

[ML] (error) scr: cannot resume non-suspended coroutine
[ML] (error) scr: Script died due to error. (0A8DFD14)

выгружаю таким образом:
Lua:
local scr_name_id = thisScript() --  в начале скрипта

if 1 < 2 then -- где-то в мейне
    scr_name_id.unload()
    return
end
Измени:
Lua:
scr_name_id.unload()
На это:
Lua:
scr_name_id:unload()
Ссылка.
 
  • Нравится
Реакции: f0Re3t
1,417
1,030
есть некоторый код в майне, в нем проверки, если проверки не прошли, то скрипт должен выгрузиться, все хорошо работает, но после выгружения он кидает в чат краш и в консоли сф пишет ерроры:
Код:
[12:14:51] Warning(s007): Exception 0xC0000005 at 0x525235FF

[ML] (error) scr: cannot resume non-suspended coroutine
[ML] (error) scr: Script died due to error. (0A8DFD14)

выгружаю таким образом:
Lua:
local scr_name_id = thisScript() --  в начале скрипта

if 1 < 2 then -- где-то в мейне
    scr_name_id.unload()
    return
end
Lua:
scr_name_id:unload()
попробуй
 
  • Нравится
Реакции: f0Re3t

Ken Block

Известный
432
31
CLEO:
// Скрипт: "Стробоскопы"
// Версия: 1.1 от 11/12/2017
// Описание: Модификация специально для гос. сотрудников (полиция, МЧС, ФБР), которая при включении сирены моргает фарами, что добавляет дополнительный реализм. 
// Активация/деактивация: автоматическая (при включении/выключении сирены)
// ----------------------------------
// Авторство: Xakkup™
// Связь с автором: vk.com/penlikamop
// Распространение без указания автора запрещено.
// ----------------------------------

{$CLEO .cs}

thread 'STROBOSCOPES'
0000: NOP


:START
wait 200
if
    Player.Defined($PLAYER_CHAR)
jf @START
goto @INIT_SIREN // Инициализируем


:INIT_SIREN
wait 500  // Частота обновления скрипта (500 ms - два раза в секунду)
if and
    00DF:     actor $PLAYER_ACTOR driving                        // Игрок в транспорте
    847A: not actor $PLAYER_ACTOR driving_bike                   // Не в байке
    84A7: not actor $PLAYER_ACTOR driving_boat                   // Не в лодке
    84C8: not actor $PLAYER_ACTOR driving_flying_vehicle         // Не в самолёте/вертолёте
    89AE: not actor $PLAYER_ACTOR driving_train                  // Не в поезде
    not Actor.DrivingVehicleType($PLAYER_ACTOR, #RHINO)          // Не в танке
jf @INIT_SIREN
03C0: 0@ = actor $PLAYER_ACTOR car  // Получаем авто игрока
if
    0ABD:   vehicle 0@ siren_on
jf @INIT_SIREN  // Если сирена выключена, то повторяем инициализацию
0A97: 1@ = car 0@ struct  // Получаем указатель структуры авто
1@ += 1440
goto @SIREN  // Начинаем мигать фарами

         
:SIREN                                
wait 250
0AA6: call_method 7086336 struct 1@ num_params 2 pop 0 1 0  // Выключить(1) левую(0) фару  
0AA6: call_method 7086336 struct 1@ num_params 2 pop 0 0 1  // Включить(0) правую(1) фару
wait 250
0AA6: call_method 7086336 struct 1@ num_params 2 pop 0 0 0  // Включить(0) левую(0) фару
0AA6: call_method 7086336 struct 1@ num_params 2 pop 0 1 1  // Выключить(1) правую(1) фару 
if
    0ABD: vehicle 0@ siren_on 
then
    goto @SIREN  // Если сирена включена, то опять мигаем фарами
else             // Иначе выключаем мигание
    0AA6: call_method 7086336 struct 1@ num_params 2 pop 0 0 0  // Включить(0) левую(0) фару
    0AA6: call_method 7086336 struct 1@ num_params 2 pop 0 0 1  // Включить(0) правую(1) фару
    Car.RemoveReferences(0@)  // Удалить из памяти скрипта машину
end
goto @INIT_SIREN  // Повторяем цикл
0A93: end_custom_thread


Как перевести это в lua ?

Lua:
local returnValue = callMethod(7086336, 1, 2, 0 1 1)

Выдаёт ошибку в Atom'e
 

imring

Ride the Lightning
Всефорумный модератор
2,356
2,524
Как узнать ID машины
bool result, int id = sampGetVehicleIdByCarHandle(Vehicle car) -- 0B2C

и её название ?
Lua:
local cars = {"Landstalker","Bravura","Buffalo","Linerunner","Perrenial","Sentinel","Dumper","Firetruck","Trashmaster","Stretch","Manana","Infernus","Voodoo","Pony","Mule","Cheetah","Ambulance","Leviathan","Moonbeam","Esperanto","Taxi","Washington","Bobcat","Whoopee","BFInjection","Hunter","Premier","Enforcer","Securicar","Banshee","Predator","Bus","Rhino","Barracks","Hotknife","Trailer","Previon","Coach","Cabbie","Stallion","Rumpo","RCBandit","Romero","Packer","Monster","Admiral","Squalo","Seasparrow","Pizzaboy","Tram","Trailer","Turismo","Speeder","Reefer","Tropic","Flatbed","Yankee","Caddy","Solair","Berkley'sRCVan","Skimmer","PCJ-600","Faggio","Freeway","RCBaron","RCRaider","Glendale","Oceanic","Sanchez","Sparrow","Patriot","Quad","Coastguard","Dinghy","Hermes","Sabre","Rustler","ZR-350","Walton","Regina","Comet","BMX","Burrito","Camper","Marquis","Baggage","Dozer","Maverick","NewsChopper","Rancher","FBIRancher","Virgo","Greenwood","Jetmax","Hotring","Sandking","BlistaCompact","PoliceMaverick","Boxvillde","Benson","Mesa","RCGoblin","HotringRacerA","HotringRacerB","BloodringBanger","Rancher","SuperGT","Elegant","Journey","Bike","MountainBike","Beagle","Cropduster","Stunt","Tanker","Roadtrain","Nebula","Majestic","Buccaneer","Shamal","hydra","FCR-900","NRG-500","HPV1000","CementTruck","TowTruck","Fortune","Cadrona","FBITruck","Willard","Forklift","Tractor","Combine","Feltzer","Remington","Slamvan","Blade","Freight","Streak","Vortex","Vincent","Bullet","Clover","Sadler","Firetruck","Hustler","Intruder","Primo","Cargobob","Tampa","Sunrise","Merit","Utility","Nevada","Yosemite","Windsor","Monster","Monster","Uranus","Jester","Sultan","Stratum","Elegy","Raindance","RCTiger","Flash","Tahoma","Savanna","Bandito","FreightFlat","StreakCarriage","Kart","Mower","Dune","Sweeper","Broadway","Tornado","AT-400","DFT-30","Huntley","Stafford","BF-400","NewsVan","Tug","Trailer","Emperor","Wayfarer","Euros","Hotdog","Club","FreightBox","Trailer","Andromada","Dodo","RCCam","Launch","PoliceCar","PoliceCar","PoliceCar","PoliceRanger","Picador","S.W.A.T","Alpha","Phoenix","GlendaleShit","SadlerShit","Luggage","Luggage","Stairs","Boxville","Tiller","UtilityTrailer"}

if isCharInAnyCar(playerPed) then
carh = storeCarCharIsInNoSave(playerPed)
cmdl = getCarModel(carh)
carname = cars[cmdl-399]
end

--carname будет содержать имя кара, к примеру infernus
 
  • Нравится
Реакции: Alkasch226 и Ken Block

_PGames_

Новичок
11
0
Добого времени, вопросец такой, возможно ли как то работать с буфером обмена через скрипт, т.е записать в него что-либо?
А так же, можно ли как то открыть ссылку в браузере через игру?
 

ZKelo

Известный
82
25
  • Нравится
Реакции: _PGames_