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

Тема в разделе "Lua", создана пользователем FYP, 8 авг 2016.

  1. FYP

    FYP
    not-set

    Регистрация:
    9 мар 2013
    Сообщения:
    1.684
    Симпатии:
    4.639
    Общая тема для вопросов по разработке скриптов на языке программирования 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.
    Как получить транспорт, в котором сидит игрок?
    
    local veh = storeCarCharIsInNoSave(PLAYER_PED)
    
    Как получить свой id или id другого игрока?
    
    local _, id = sampGetPlayerIdByCharHandle(PLAYER_PED) -- получить свой ид
    local _, id = sampGetPlayerIdByCharHandle(ped) -- получить ид другого игрока. ped - это хендл персонажа
    
    Как проверить, что строка содержит какой-то текст?
    
    if string.find(str, 'текст', 1, true) then
    -- строка str содержит "текст"
    end
    
    Как эмулировать нажатие игровой клавиши?
    
    local game_keys = require 'game.keys' -- где-нибудь в начале скрипта вне функции main
    
    setGameKeyState(game_keys.player.FIREWEAPON, -1) -- будет сэмулировано нажатие клавиши атаки
    
    Все иды клавиш находятся в файле moonloader/lib/game/keys.lua.
    Подробнее о функции setGameKeyState здесь: lua - setgamekeystate | BlastHack — DEV_WIKI(http://blast.hk/wiki/lua:setgamekeystate)
    Как получить id другого игрока, в которого целюсь я?
    
    local valid, ped = getCharPlayerIsTargeting(PLAYER_HANDLE) -- получить хендл персонажа, в которого целится игрок
    if valid and doesCharExist(ped) then -- если цель есть и персонаж существует
      local result, id = sampGetPlayerIdByCharHandle(ped) -- получить samp-ид игрока по хендлу персонажа
      if result then -- проверить, прошло ли получение ида успешно
        -- здесь любые действия с полученным идом игрока
      end
    end
    
    Как зарегистрировать команду чата SAMP?
    
    -- До бесконечного цикла/задержки
    sampRegisterChatCommand("mycommand", function (param)
         -- param будет содержать весь текст введенный после команды, чтобы разделить его на аргументы используйте string.match()
        sampAddChatMessage("MyCMD", -1)
    end)
    
     
    #1 FYP, 8 авг 2016
    Последнее редактирование: 14 июл 2018
    Magnum Opus, Byblik, Maklilli и 8 другим нравится это.
  2. mac

    mac HEY DARLING

    Регистрация:
    6 сен 2014
    Сообщения:
    1.390
    Симпатии:
    985
    От делать нехуй решил попробовать работу с диалогами. list в стиле диалогов почему-то принимается за msgbox. Скрин
    Хз, вот сурс на всякий случай. Мб чего не помню, в клео такую херню делал года полтора-два назад, в луа первый день :/
    
    function openmenu()
        s = string.format("Player \nVehicle \nOther Huinya")
        sampShowDialog(17, "Mactawish Mod Menu", s, "Ok", "Exit", "DIALOG_STYLE_LIST")
    end
     
  3. legend2360

    legend2360 Up to June 2019
    not-set

    Регистрация:
    23 мар 2013
    Сообщения:
    2.614
    Симпатии:
    1.612
    тип должен быть int, а не string
    константы подключи
     
    mac нравится это.
  4. mac

    mac HEY DARLING

    Регистрация:
    6 сен 2014
    Сообщения:
    1.390
    Симпатии:
    985
    Я понимаю, что я уебан, но все-таки, в этом луа первый день. Скрипт сразу крашается, в логах ничего необычного. При релоаде скриптов виснет игра :/
    Без того, что в while true в main работает спокойно. Не оч понял просто
    
    function main()
        while not isSampfuncsLoaded() do
            wait(1000)
        end
        sampAddChatMessage("Mod Menu by Mactawish loaded. Version: 0.0000001", -1)
        sampRegisterChatCommand("menu", openmenu)
        while true do
            local result, button, list, input = sampHasDialogRespond(17)
            if result == true then
                sampAddChatMessage("Была нажата кнопка " .. button, -1)
            end
            if button == 1 then
                sampAddChatMessage("Типа выбран элемент под номером " .. list, -1);
            end
        end
    end
    
    function openmenu()
        s = string.format("Other Players \nSelf \nVehicle")
        sampShowDialog(17, "Mactawish Mod Menu", s, "Ok", "Exit", 2)
    end
     
    #4 mac, 9 авг 2016
    Последнее редактирование: 9 авг 2016
  5. FYP

    FYP
    not-set

    Регистрация:
    9 мар 2013
    Сообщения:
    1.684
    Симпатии:
    4.639
    @[Mactawish] ты используешь бесконечный цикл без задержки. не надо так.
     
    kewa.opcode1, 4el0ve4ik, AWRage и 2 другим нравится это.
  6. WhyExtern

    WhyExtern Постоянный участник

    Регистрация:
    10 авг 2016
    Сообщения:
    73
    Симпатии:
    11
    После: while true do
    Добавь: wait (0)
     
  7. WhyExtern

    WhyExtern Постоянный участник

    Регистрация:
    10 авг 2016
    Сообщения:
    73
    Симпатии:
    11
    Как при нажатии клавиши задействовать команду которая сразу отправится в чат как сообщение?
    Написал скрипт чтобы при нажатии на Y автоматически вводилась команда /mm и открывалось меню сервера
    Не пашет
    script_name("Ymm")
    script_author("WhyExtern")
    script_description("Y")
    script_version_number(1)
    
    require "lib.moonloader"
    require "lib.sampfuncs"
    
    function main()
       while true
       wait(0)
       if isKeyDown(VK_Y) then
       sampAddChatMessage "/mm"
       while isKeyDown(VK_1) do
       wait(100) end
        end
      end
    end
    Вот что пишет sampfuncs в консоль
     
    #7 WhyExtern, 10 авг 2016
    Последнее редактирование: 10 авг 2016
  8. MelomanCool

    Проверенный

    Регистрация:
    19 мар 2013
    Сообщения:
    65
    Симпатии:
    60
    while true do
    Учите синтаксис.
     
  9. 4el0ve4ik

    4el0ve4ik Всефорумный модератор
    Друг

    Регистрация:
    12 ноя 2015
    Сообщения:
    1.452
    Симпатии:
    955
    Через sampAddChatMessage можно вывести текст и он никому кроме тебя не будет виден, для ввода команды используй sampSendChat(string text)
     
    CAPTA!N нравится это.
  10. 4el0ve4ik

    4el0ve4ik Всефорумный модератор
    Друг

    Регистрация:
    12 ноя 2015
    Сообщения:
    1.452
    Симпатии:
    955
    Знаю, я долбоеб который ничего не смыслит, но все же. Такой вопрос: как сделать что бы работало вот это
    if handle = getCharPlayerIsTargeting(int player) and isKeyDown(VK_1) then
    ......
    Если пишу так как представил выше, то выбивает ошибку 'then' expected near '='.
     
    CAPTA!N и loremi735 нравится это.
  11. loremi735

    loremi735 Участник

    Регистрация:
    26 июл 2016
    Сообщения:
    11
    Симпатии:
    17
    Во-первых, getCharPlayerIsTargeting() возвращает два значения, а это значит, что нужно сперва сохранить эти значения (или только одно нужное) в какую-нибудь переменную, чтобы затем использовать в if:
    
    local result, target = getCharPlayerIsTargeting(playerHandle) -- нижнее подчеркивание (_) позволяет игнорировать возвращаемый результат, поэтому можешь написать _ вместо result, если не будешь использовать result. вот так:
    local _, target = getCharPlayerIsTargeting(playerHandle)
    if handle == target and isKeyDown(VK_1) then
    ......
    
    Во-вторых, чтобы сравнить два значения, нужно использовать оператор ==, а не = (это присваивание).

    В-третьих, не нужно указывать тип аргумента при вызове функции.

    Можешь смотреть возвращаемые значения, тип аргументов и названия функций здесь: https://gist.github.com/THE-FYP/abc6f8bea87f4cb42331fc6dd7a84576
     
    #11 loremi735, 10 авг 2016
    Последнее редактирование: 10 авг 2016
    FYP и 4el0ve4ik нравится это.
  12. 4el0ve4ik

    4el0ve4ik Всефорумный модератор
    Друг

    Регистрация:
    12 ноя 2015
    Сообщения:
    1.452
    Симпатии:
    955
    про сравнивание не шло и речи, мне нужно что бы при прицеливании на игрока и нажатии n-ой клавиши выполнялось действие.
     
    CAPTA!N нравится это.
  13. loremi735

    loremi735 Участник

    Регистрация:
    26 июл 2016
    Сообщения:
    11
    Симпатии:
    17
    ну, тогда нужно проверить result на true:
    
    local result, target = getCharPlayerIsTargeting(playerHandle)
    if result and isKeyDown(VK_1) then
    ....
    
    result здесь означает, удалось ли получить другого игрока, в которого целится играющий.
    target - это игрок, в которого целится играющий.

    про сравнивание я написал, потому что многие путают = и ==, и не вдавался в подробности кода
     
  14. 4el0ve4ik

    4el0ve4ik Всефорумный модератор
    Друг

    Регистрация:
    12 ноя 2015
    Сообщения:
    1.452
    Симпатии:
    955
    каким образом можно заменить опкод
    0ad3: format_stirng [email protected] = "Первый пункт%cВторой пункт%cТретий пункт" 0xA 0xA
    я прост нуб))
     
    CAPTA!N нравится это.
  15. DarkP1xel

    BH Team

    Регистрация:
    17 июн 2013
    Сообщения:
    3.106
    Симпатии:
    3.565
    string.format
     
    EdikDen03 нравится это.
  16. 4el0ve4ik

    4el0ve4ik Всефорумный модератор
    Друг

    Регистрация:
    12 ноя 2015
    Сообщения:
    1.452
    Симпатии:
    955
    Да понял я что string.format, как вывести переменную с данными строки, мне для локального диалога, так бы не спрашивал
     
    CAPTA!N нравится это.
  17. legend2360

    legend2360 Up to June 2019
    not-set

    Регистрация:
    23 мар 2013
    Сообщения:
    2.614
    Симпатии:
    1.612
    Просто берешь и подставляешь форматированную строку
     
  18. mac

    mac HEY DARLING

    Регистрация:
    6 сен 2014
    Сообщения:
    1.390
    Симпатии:
    985
    Банальный пример, хотя можно и легче
     s = string.format("Other Players \nSelf \nVehicle")
        sampShowDialog(17, "Mactawish Mod Menu", s, "Ok", "Exit", 2)
     
    4el0ve4ik нравится это.
  19. legend2360

    legend2360 Up to June 2019
    not-set

    Регистрация:
    23 мар 2013
    Сообщения:
    2.614
    Симпатии:
    1.612
    Ну если вам не хочется ставить \n, то юзайте так:
    local content = [[Other players
    Self
    Vehicle
    ]]
    -- showDialog
    
    
    UPD: мда, над починить синтаксис
     
    4leniksFransy и loremi735 нравится это.
  20. 4el0ve4ik

    4el0ve4ik Всефорумный модератор
    Друг

    Регистрация:
    12 ноя 2015
    Сообщения:
    1.452
    Симпатии:
    955
    пол дня ебусь, ебусь, а толку 0...
    menu = string.format("первый \nвторой \nтретий")
    dialog = sampShowDialog(17, "парапа",  menu, "Ok", "Exit", 2)
    re  = sampIsDialogActive()
    if re then
    res, button, list, input = sampHasDialogRespond(17)
    if res then
    
    
    if list  == 0 then
        sampAddChatMessage("1", 0xcc0000)
    end
    
    if list == 1 then
      sampaddchatmessage("2", 0xcc0000)
    end
    
    if list == 2 then
     sampAddChatMessage("3", 0xcc0000)
    end
    
    какой пункт не выбери в диалоге, все равно нихуя не выходит, как ни еб*лся с ними
     
    CAPTA!N нравится это.
  21. hnnssy

    hnnssy knowname
    Друг

    Регистрация:
    23 мар 2013
    Сообщения:
    2.283
    Симпатии:
    1.786
    sampHasDialogRespond() в цикле юзать надо

    можно просто
    sampShowDialog(17, "Mactawish Mod Menu", string.format("Other Players \nSelf \nVehicle"), "Ok", "Exit", 2)
    наверн
     
    #21 hnnssy, 11 авг 2016
    Последнее редактирование модератором: 11 авг 2016
  22. 4el0ve4ik

    4el0ve4ik Всефорумный модератор
    Друг

    Регистрация:
    12 ноя 2015
    Сообщения:
    1.452
    Симпатии:
    955
    можно, проверил)
     
    CAPTA!N нравится это.
  23. 4el0ve4ik

    4el0ve4ik Всефорумный модератор
    Друг

    Регистрация:
    12 ноя 2015
    Сообщения:
    1.452
    Симпатии:
    955
    В общем получилось, но не так как хотелось бы, когда выбираешь пункт и что бы надпись появилась нужно еще раз открыть диалог,
    как сделать что бы отправлялась сразу после закрытия диалога?
    menu = string.format("1 \n2")
    dia = sampShowDialog(17, "парапа", menu, "OK", "Close", 2)
    re, button, list, input = sampHasDialogRespond(17)
    while not re do
      wait(10)
    end
    if list == 0 then
      sampAddChatMessage("1")
    end
    if list == 1 then
      sampAddChatMessage("2")
    end
     
  24. hnnssy

    hnnssy knowname
    Друг

    Регистрация:
    23 мар 2013
    Сообщения:
    2.283
    Симпатии:
    1.786
     
  25. 4el0ve4ik

    4el0ve4ik Всефорумный модератор
    Друг

    Регистрация:
    12 ноя 2015
    Сообщения:
    1.452
    Симпатии:
    955
    напиши пожалуйста цикл с sampHasDialogRespond(), а то я криворукий и только по примерам че то смогу выучить -_-
     
  26. hnnssy

    hnnssy knowname
    Друг

    Регистрация:
    23 мар 2013
    Сообщения:
    2.283
    Симпатии:
    1.786
    
    dia = sampShowDialog(17, "парапа", string.format("1 \n2"), "OK", "Close", 2)
    repeat
      wait(0)
      result, button, list, input = sampHasDialogRespond(17)
    until result
    if list == 0 then
      sampAddChatMessage("1")
    end
    if list == 1 then
      sampAddChatMessage("2")
    end
    
     
  27. 4el0ve4ik

    4el0ve4ik Всефорумный модератор
    Друг

    Регистрация:
    12 ноя 2015
    Сообщения:
    1.452
    Симпатии:
    955
    подскажите как сделать что бы диалог закрывался на кнопку "Exit",
    sampShowDialog(17, "Mactawish Mod Menu", string.format("Other Players \nSelf \nVehicle"), "Ok", "Exit", 2)
    как я понял делаеться это с помощью данного
    sampCloseCurrentDialogWithButton(--[[int]] button)
    Но как не пытался ничего у меня не получилось:(
     
    EazyBoost нравится это.
  28. DarkP1xel

    BH Team

    Регистрация:
    17 июн 2013
    Сообщения:
    3.106
    Симпатии:
    3.565
    ID какой пишешь?
     
  29. 4el0ve4ik

    4el0ve4ik Всефорумный модератор
    Друг

    Регистрация:
    12 ноя 2015
    Сообщения:
    1.452
    Симпатии:
    955
    я пишу так
    sampCloseCurrentDialogWithButton(2)
    или нужно так?
    sampCloseCurrentDialogWithButton(button2)
     
    Barry_Bradley нравится это.
  30. DarkP1xel

    BH Team

    Регистрация:
    17 июн 2013
    Сообщения:
    3.106
    Симпатии:
    3.565
    Просто цифру.
     
  31. 4el0ve4ik

    4el0ve4ik Всефорумный модератор
    Друг

    Регистрация:
    12 ноя 2015
    Сообщения:
    1.452
    Симпатии:
    955
    как сделать что бы открывался файл ини, который лежит в папке со скриптом, у каждого пользователя путь к гта разный я подумал использовать так:
      dir = script.directory
      ini_test = io.openfile(dir"test.ini", "r")
    ну или подскажите как усобачить путь по другому.
     
  32. legend2360

    legend2360 Up to June 2019
    not-set

    Регистрация:
    23 мар 2013
    Сообщения:
    2.614
    Симпатии:
    1.612
    local file = io.open("moonloader/file.txt", "r")
    if file ~= nil then
        --local first_line = file:read()
        print(file:read())
        file:close()
    end
    
    Кстати, если ты там пишешь свои костыли, то лучше заюзай библиотеку, по типу LIP: https://github.com/Dynodzzo/Lua_INI_Parser
    Не хуже будет.
     
    #32 legend2360, 12 авг 2016
    Последнее редактирование: 12 авг 2016
    Garrus, loremi735 и 4el0ve4ik нравится это.
  33. iTz_WEEZY

    iTz_WEEZY Свой человек

    Регистрация:
    14 мар 2016
    Сообщения:
    300
    Симпатии:
    88
    как правильно указать инт Актера?
     
  34. 4el0ve4ik

    4el0ve4ik Всефорумный модератор
    Друг

    Регистрация:
    12 ноя 2015
    Сообщения:
    1.452
    Симпатии:
    955
    function prost()
      menurp = string.format("1 \n2")
      dia = sampShowDialog(25, "qq", menurp, "OK", "Close", 2)
      sampSetCurrentDialogListItem(0)
      repeat
        wait(0)
        re, button, listr, input = sampHasDialogRespond(25)
      until re
      if button == 0 then
        _ = sampCloseCurrentDialogWithButton()
      else
        if listr == 0 then
            dia = sampShowDialog(26, "prp", "hz", "OK", "Close", 1)
            repeat
              wait(0)
               re, button, _, number = sampHasDialogRespond(26) -- вот тут
            until re
            if button == 0 then
              _ = sampCloseCurrentDialogWithButton()
            end
          end
        if listrpsms == 1 then
          sampAddChatMessage("%d", number, 0xcc0000) 
        end
    Как можно сохранить переменную number до полной перезагрузки скрипта или покуда не введу другое число?
     
  35. legend2360

    legend2360 Up to June 2019
    not-set

    Регистрация:
    23 мар 2013
    Сообщения:
    2.614
    Симпатии:
    1.612
    В начале скрипта объяви(вне функций)
     
    4el0ve4ik нравится это.