Вопросы по 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
 
Последнее редактирование:

mOdest

Участник
13
3
Lua:
local hook = require 'lib.samp.events'

function hook.onCreate3DText(i, clr, pos, distance, ignoreWalls, playerId, vehicleId, textd)
-- code
end

как вывести pos?
 
U

user390868

Гость
Lua:
local hook = require 'lib.samp.events'

function hook.onCreate3DText(i, clr, pos, distance, ignoreWalls, playerId, vehicleId, textd)
-- code
end

как вывести pos?
Там позиция в 3д векторе. Три точки, x, y, z Выводи через точку. position.x и тд. с алгеброй и геометрией у меня не очень. в векторах не очень разбираюсь. но как вывести я написал
 
  • Нравится
Реакции: mOdest

Eugene Crabs

Активный
544
30
Ребят, подскажите два скрипта.
Первый - показывает работающие сейчас lua файлы
Второй - выводит moonloade.log в окно в samp'e
 

Eugene Crabs

Активный
544
30
не разу не было такого чтобы скрипты все после него не работали
Я создал функцию. Функция очень большая, но простая по логике. Ошибок внутри неё быть не может, ибо я проводил тесты по часу-два за одну сессию и она работала прекрасно. Но если я перезагружу все скрипты после её выполнения - они все вылетят.

Вот я и думаю в чем может заключаться ошибка. Быть может, происходит утечка данных (или как там эта хрень называется), из-за которой reload_all сложно все перезагрузить (Там несколько потоков, кол-во которых контролируется).
 

thebestsupreme

Участник
170
12
ERORR:
[ML] (error) ATools: C:\GTA SHINOBI by JOHNYSTAR\moonloader\SAMP ATOOLS.lua:60: attempt to index upvalue 'report' (a boolean value)
stack traceback:
    C:\GTA SHINOBI by JOHNYSTAR\moonloader\SAMP ATOOLS.lua:60: in function 'callback'



CODE:
function sampev.onServerMessage(color, text)
   if report.v and text:find('Репорт от (.+)%[(%d+)%]: (.+)') and not reportmenu == true then
      lua_thread.create(function()
         txtreport = text:match(": (.+)")
         nickreport = text:match("от (.*)%:")
         reportid = text:match("%[(%d+)%]:")
         wait(1000)
         ReportText.v = (u8(''..txtreport))
         ReportTextOtvet.v = (u8(''))
         reportmenu = true
      end)
   end
end


ребят подскажите почему у меня ошибка
 

SurnikSur

Активный
284
40
Можно как-то сделать что бы скрипт чекал територии гетто и мог писать сколько тер у кого?
 

EclipsedFlow

Известный
Проверенный
1,040
459
Добавить fAwesome5 в скрипт, все по инструкции и получаю такое -
1614336684877.png
Как исправить?
 

Vintik

Мечтатель
Проверенный
1,411
851
Можно как-то сделать что бы скрипт чекал територии гетто и мог писать сколько тер у кого?
Можно, но только с помощью SAMP.Lua
Код:
INCOMING_RPCS[RPC.GANGZONECREATE]             = {'onCreateGangZone', {zoneId = 'int16'}, {squareStart = 'vector2d'}, {squareEnd = 'vector2d'}, {color = 'int32'}}
INCOMING_RPCS[RPC.GANGZONEDESTROY]            = {'onGangZoneDestroy', {zoneId = 'int16'}}
INCOMING_RPCS[RPC.GANGZONEFLASH]              = {'onGangZoneFlash', {zoneId = 'int16'}, {color = 'int32'}}
INCOMING_RPCS[RPC.GANGZONESTOPFLASH]          = {'onGangZoneStopFlash', {zoneId = 'int16'}}
Например, при появлении территории гетто вывести в чат текст можно вот так:
Lua:
local sampev = require 'lib.samp.events' -- подключаем модуль

function sampev.onCreateGangZone(zoneId, squareStart, squareEnd, color)
  sampAddChatMessage('На карте появилась гетто территория цвета: ' .. tostring(color), -1)
end
Тебе нужно узнать цвет территорий всех банд гетто. Также создать переменную, хранящую кол-во терр для каждой банды ("копилку"). Затем просто в коде, написанном выше, сравнивать цвет появившейся территории со цветом каждой из банд, и если они одинаковые – добавлять в "копилку" банд +1 терру.

UPD: полный код будет иметь такой вид. тебе в нём осталось лишь добавить цвета терр для каждой банды (4 строка кода), потому что у серверов они могут быть разными.
Lua:
local sampev = require 'lib.samp.events' -- подключаем модуль

local gang_names = { 'Grove'; 'Ballas'; 'Vagos'; 'Aztec'; 'Rifa' }
local gang_colors = { -1778336996; -1761670701; -1778331930; -1766081792; -1426098880 } -- цвета терр банд
local gang_terrs = { 0; 0; 0; 0; 0 } -- кол-во терр у банд соответственно

local zoneid = {} -- массив id добавленных терр
local zonegang = {} -- соответствующий массив банд, которым добавлены терры

function sampev.onCreateGangZone(zoneId, squareStart, squareEnd, color)
  for i, clr in ipairs(gang_colors) do -- обходим все банды
    if color == clr then -- если цвет равен
      zoneid[#zoneid + 1] = zoneId
      zonegang[#zonegang + 1] = i
      gang_terrs[i] = gang_terrs[i] + 1 -- +1 терра к банде
      break
    end
  end
end

function sampev.onGangZoneDestroy(zoneId)
  for i, zid in ipairs(zoneid) do
    if zid == zoneId then
      local gang = zonegang[i] -- узнаём какой банде шла эта терра при добавлении
      gang_terrs[gang] = gang_terrs[gang] - 1 -- -1 терра от банды (т. к. гангзона удалена)
      table.remove(zoneid, i)
      table.remove(zonegang, i)
      break
    end
  end
end

function main()
  if not isSampLoaded() or not isSampfuncsLoaded() then return end
  while not isSampAvailable() do wait(0) end
  sampRegisterChatCommand('checkghetto', checkghetto) -- активация по команде /checkghetto
  wait(-1)
end

function checkghetto()
  local allZones = 0
  for i, gang in ipairs(gang_names) do
    sampAddChatMessage(gang .. ' имеет ' .. tostring(gang_terrs[i]) .. ' территорий', 0xc43737)
    allZones = allZones + gang_terrs[i]
  end
  sampAddChatMessage('Всего ' .. allZones .. ' территорий', 0xc43737)
end
 
Последнее редактирование: