- 1
- 0
- Версия MoonLoader
- Другое
Здравствуйте. Совсем недавно начал изучать lua, это мой второй язык программирования, который я решил освоить. В первый день смотрел синтаксис и просто как устроен язык. Через неделю приступил к практике написания скриптов для SA:MP и решил написать бота трамвайщика для ARZ, и так как это был мой первый подобный опыт я написал его логику "в лоб", то есть просто через нажатия клавиш бот должен выполнять все требуемые действия, ну и как начал так и продолжил. Так вот, основа логики езды трамвая основана на координатах: 1) точек чекпоинтов, 2) точек когда нужно начать тормозить чтобы остановиться на точках чекпоинтов. Мой вопрос: работает ли данный метод на любом устройстве? Ведь, очевидно, пинг, фпс и т.п. у каждого будет различаться. Я ставил ограничение фпс и вроде трамвай ехал как надо, но я всё же хочу уточнить этот момент пока бот еще довольно сырой (он уже полностью работает и автоматизирован, но имеет свои баги и явно нуждается в доработках) и потом мне не пришлось переписывать чуть ли не всю основу кода. Также я прикрепил видео
для наглядности и полный код если вдруг кто заметит очевидно неверные подходы или просто не совсем рациональные решения в скрипте.
Заранее огромное спасибо!
Заранее огромное спасибо!
Lua:
-- Подключение необходимых библиотек
require("lib.moonloader")
require("lib.sampfuncs")
local encoding = require "encoding"
local imgui = require "imgui"
local samp_ev = require "lib.samp.events"
-- Глобальные переменные для управления состоянием бота
run = false
play = false
stage = 1
time_count = 0
forced_stop = false
adm_check = false
-- Структуры для хранения данных о диалоговых окнах и статистике
dialogw = {
dw_dialogId = nil,
dw_style = nil,
dw_title = nil,
dw_button1 = nil,
dw_button2 = nil,
dw_text = nil
}
stats = {
time_full = 0,
salary = 0,
route_count = 0
}
-- Координаты для взятия маршрута
spawn_point = {-2265.9475097656, 501.72549438477, 1487.6927490234}
take_point = {{-2263.2526855469, 513.08807373047, 1487.6917724609}}
restart_point = {
{-2261.638671875, 509.93923950195, 1487.7027587891},
{-2261.6967773438, 506.30764770508, 1487.7027587891},
{-2260.1748046875, 502.38452148438, 1487.6927490234}
}
restart_food = {
{-2261.3422851563, 512.25323486328, 1487.6927490234},
{-2258.9245605469, 515.13458251953, 1487.6927490234},
{-2257.9938964844, 511.3674621582, 1487.6927490234}
}
foot_coords = {
{-2263.0354003906, 502.57992553711, 1487.6927490234},
{-2262.5622558594, 502.96221923828, 1487.6927490234},
{-2262.4440917969, 504.65939331055, 1487.6927490234},
{-2262.9919433594, 507.09457397461, 1487.6927490234}
}
foot_coords1 = {
{-2261.4553222656, 503.47729492188, 1487.6917724609},
{-2261.2084960938, 503.5869140625, 1487.6917724609},
{-2260.0004882813, 504.40594482422, 1487.6917724609},
{-2258.7253417969, 505.50250244141, 1487.6917724609},
{-2258.1333007813, 506.90542602539, 1487.6917724609},
{-2257.9938964844, 511.75677490234, 1487.6917724609}
}
restart_p = {false, false}
-- Координаты остановок и торможения
main_coords = {
{-2264.9060058594, 781.74798583984, 49.841285705566},
{-2264.875, 1030.8063964844, 84.130714416504},
{-1988.6790771484, 1307.875, 7.4973087310791},
{-1641.5390625, 1254.5151367188, 7.4973087310791},
{-1538.7077636719, 967.39538574219, 7.4973087310791},
{-1741.2626953125, 921.125, 25.122308731079},
{-2001.625, 892.17053222656, 45.74730682373},
{-1874.95703125, 848.875, 35.49730682373},
{-1604.5676269531, 848.908203125, 7.9973087310791},
{-1626.8010253906, 728.75, 14.902610778809},
{-1865.2484130859, 603.25, 35.49730682373},
{-2006.5, 210.66424560547, 27.997308731079},
{-2006.5, 88.550201416016, 27.997308731079},
{-2166.625, -70.026824951172, 35.62230682373},
{-2251.5573730469, 149.05737304688, 35.62230682373},
{-2339.7514648438, 508.5, 30.301301956177},
}
brake_coords = {
{-2264.9506835938, 732.50493164063, 49.79679107666},
{-2264.875, 977.96145019531, 70.373799133301},
{-2042.9405517578, 1305.6669921875, 7.6223087310791},
{-1679.6846923828, 1292.7875976563, 7.4973087310791},
{-1573.2088623047, 1011.6076660156, 7.4973087310791},
{-1687.3196533203, 921.125, 25.122308731079},
{-1972.1208496094, 921, 44.641761779785},
{-1911.8176269531, 848.875, 35.49730682373},
{-1658.4816894531, 848.875, 19.5728931427},
{-1572.5378417969, 728.75, 7.6708054542542},
{-1809.8125976563, 603.25, 34.998847961426},
{-2004.6945800781, 265.88493652344, 31.753614425659},
{-2006.5, 115.27388916016, 27.997308731079},
{-2166.625, -48.292022705078, 35.62230682373},
{-2251.8759765625, 96.16723632813, 35.62230682373},
{-2361.2368164063, 483.1110534668, 30.597286224365}
}
function main()
-- Ожидание загрузки SA:MP
while not isSampAvailable() do wait(1000) end
-- ImGui
myImgui = {
windows = {status = {main = imgui.ImBool(false)}}
}
apply_custom_style()
print("{27AB0F}LOADED {FFFFFF}(/tramon)")
-- Регистрация команд для включения и выключения бота
sampRegisterChatCommand('tramon', function()
if not run then
run = true
stats.time_full = os.clock()
sampAddChatMessage('> {FFFFFF}Tram turned {27AB0F}[ENABLED]', 0xFF27ab0f)
lua_thread.create(thread_checks)
else
sampAddChatMessage('> {FFFFFF}Tram is already {E5FF00}[ENABLED]', 0xFFe5ff00)
end
end)
sampRegisterChatCommand('tramoff', function()
if run then
run = false
play = false
stage = 1
time_count = 0
stats.time_full = 0
dialogvalue = false
sampAddChatMessage('> {FFFFFF}Tram turned {AB0F0F}[DISABLED]', 0xFFab0f0f)
else
sampAddChatMessage('> {FFFFFF}Tram is already {E5FF00}[DISABLED]', 0xFFe5ff00)
end
end)
-- Основной цикл бота
while true do
wait(0)
-- Проверка нажатия клавиши для запуска бота
if wasKeyPressed(VK_1) and run and not play and not sampIsCursorActive() then
play = true
sampAddChatMessage('Bot started.', 0xFF27ab0f)
time_count = os.clock()
stats.time_full = os.clock()
if isCharInAnyCar(PLAYER_PED) then
stage = 2
else
stage = 1
end
end
-- Основная логика бота
if play then
if stage == 2 and isCharInAnyCar(PLAYER_PED) then
for i = 1, #brake_coords do
wait(300)
if not isCharInAnyCar(PLAYER_PED) and not forced_stop then
break
end
if not isCharInAnyCar(PLAYER_PED) and forced_stop then
while not isCharInAnyCar(PLAYER_PED) do
wait(0)
end
end
local tram = storeCarCharIsInNoSave(PLAYER_PED)
local xR, yR, zR = main_coords[i][1], main_coords[i][2], main_coords[i][3]
local xBr, yBr, zBr = brake_coords[i][1], brake_coords[i][2], brake_coords[i][3]
local xN, yN, zN = getCharCoordinates(PLAYER_PED)
local dist = getDistanceBetweenCoords3d(xR, yR, zR, xN, yN, zN)
local dist_brake = getDistanceBetweenCoords3d(xBr, yBr, zBr, xN, yN, zN)
local br_vel = 0.06
local braking = false
while dist > 3 or getCarSpeed(tram) > 0.1 do
wait(0)
if adm_check then
admin_check()
end
if isCharInAnyCar(PLAYER_PED) then
local xn, yn, zn = getCharCoordinates(PLAYER_PED)
dist = getDistanceBetweenCoords3d(xR, yR, zR, xn, yn, zn)
dist_brake = getDistanceBetweenCoords3d(xBr, yBr, zBr, xn, yn, zn)
if braking then
draw_line(xR, yR, zR, "db1d1d", 0, 0, 0)
printStringNow("Distance (No." .. i .."): ~r~~h~" .. math.floor(dist) .. "m~n~~w~Velocity: ~r~~h~" .. math.floor(getCarSpeed(tram) * 3.5))
else
draw_line(xR, yR, zR, "1ddb4f", xBr, yBr, zBr)
printStringNow("Distance (No." .. i .."): ~g~~h~" .. math.floor(dist) .. "m~n~~w~Velocity: ~g~~h~" .. math.floor(getCarSpeed(tram) * 3.5))
end
if (not braking and dist_brake < 1) or forced_stop then
braking = true
end
if not braking then
if getCarSpeed(tram) < 24 then
press_gas()
else
press_brake(braking)
end
else
if getCarSpeed(tram) > br_vel then
press_brake(braking)
else
if br_vel < 0.5 and not forced_stop then
br_vel = 1
end
press_gas()
end
if br_vel > 0.5 and dist <= 1 then
br_vel = 0.06
end
end
if wasKeyPressed(VK_3) then
sampAddChatMessage('playing paused.', -1)
while true do
wait(0)
if wasKeyPressed(VK_1) and not sampIsCursorActive() then
sampAddChatMessage('playing unpaused...', -1)
break
end
end
end
else
break
end
end
end
stage = 1
else
if restart_p[1] and not restart_p[2] then
local resX, resY, resZ = getCharCoordinates(PLAYER_PED)
if getDistanceBetweenCoords3d(spawn_point[1], spawn_point[2], spawn_point[3], resX, resY, resZ) > 2 then
take_route(restart_point)
else
take_route(foot_coords)
end
else
if os.clock() - time_count >= 2000 then
time_count = os.clock()
local notfood = take_route(foot_coords1)
if notfood then
take_route(restart_food)
else
take_route(take_point)
end
else
take_route(foot_coords)
end
end
end
end
if not play and run then
draw_line(0, 0, 0, "ca61ff", 0, 0, 0)
end
end
end
-- Функция для нажатия на газ
function press_gas()
if not sampIsCursorActive() then
writeMemory(0xB73458 + 0x20, 1, 255, false)
else
if not forced_stop then
admin_check()
end
end
end
-- Функция для нажатия на тормоз
function press_brake(braking)
if not sampIsCursorActive() or forced_stop then
if not braking then
writeMemory(0xB73458 + 0xC, 1, 64, false)
else
writeMemory(12006516, 1, 255, false)
end
else
admin_check()
end
end
-- Функция для установки позиции камеры
function set_camera_pos_unfix(posX, posY)
local cPosX, cPosY, cPosZ = getActiveCameraCoordinates()
setCameraPositionUnfixed(0.0, (getHeadingFromVector2d(posX - cPosX, posY - cPosY) - 90.0) / 57.2957795)
end
-- Функция для взятия маршрута
function take_route(coords)
if not restart_p[1] and not restart_p[2] then
timer(3000)
end
if not restart_p[1] and restart_p[2] then
restart_p = {false, false}
end
wait(10)
if not sampIsCursorActive() and not isCharInAnyCar(PLAYER_PED) then
sampAddChatMessage("Time to eat: " .. math.floor(os.clock() - time_count) .. " / 2000", -1)
local Xn, Yn, Zn = getCharCoordinates(PLAYER_PED)
local Xf, Yf, Zf = spawn_point[1], spawn_point[2], spawn_point[3]
if getDistanceBetweenCoords3d(Xn, Yn, Zn, Xf, Yf, Zf) > 100 then
sampAddChatMessage("Too big distance:", 0xFFd10f0f)
admin_check()
end
if restart_p[1] then
restart_p[2] = true
end
local coords_check = {}
local delay = 0
if coords == take_point or coords == foot_coords then
delay = 100
end
for i = 1, #coords do
if isCharInAnyCar(PLAYER_PED) then
admin_check()
break
end
if (restart_p[1] and not restart_p[2]) or (not restart_p[1] and restart_p[2]) then
break
end
local posX, posY, zF = coords[i][1], coords[i][2], coords[i][3]
local xN, yN, zN = getCharCoordinates(PLAYER_PED)
local dist = getDistanceBetweenCoords3d(posX, posY, zF, xN, yN, zN)
local close_dist = getDistanceBetweenCoords3d(Xf, Yf, Zf, xN, yN, zN)
local sprint = true
if i == #coords then
sprint = false
end
while dist > 1 do
wait(0)
if isCharInAnyCar(PLAYER_PED) then
break
end
if sampIsCursorActive() or adm_check then
admin_check()
end
local xn, yn, zn = getCharCoordinates(PLAYER_PED)
table.insert(coords_check, {xn, yn, zn})
if #coords_check >= 50 then
if delay == 0 then
local x_check1, y_check1, z_check1 = coords_check[1][1], coords_check[1][2], coords_check[1][3]
local x_check2, y_check2, z_check2 = coords_check[50][1], coords_check[50][2], coords_check[50][3]
if getDistanceBetweenCoords3d(x_check1, y_check1, z_check1, x_check2, y_check2, z_check2) < 0.1 then
if not restart_p[1] then
sampAddChatMessage("Stucked. restart...", -1)
restart_p[1] = true
else
admin_check()
restart_p = {false, true}
end
break
end
else
delay = delay - 1
end
table.remove(coords_check, 1)
end
dist = getDistanceBetweenCoords3d(posX, posY, zF, xn, yn, zn)
close_dist = getDistanceBetweenCoords3d(Xf, Yf, Zf, xn, yn, zn)
setGameKeyState(1, -128)
if sprint then
setGameKeyState(16, 255)
end
set_camera_pos_unfix(posX, posY)
draw_line(posX, posY, zF, "1d95db", 0, 0, 0)
if wasKeyPressed(VK_3) then
sampAddChatMessage('playing paused.', -1)
while true do
wait(0)
if wasKeyPressed(VK_1) and not sampIsCursorActive() then
sampAddChatMessage('playing unpaused...', -1)
break
end
end
end
end
end
wait(500)
if sampIsCursorActive() then
admin_check()
end
if not restart_p[1] and not restart_p[2] and not isCharInAnyCar(PLAYER_PED) then
printStringNow("~b~~h~Alt ~w~pressed", 300)
press_button(18)
wait(250)
if sampIsCursorActive() then
if dialogw.dw_dialogId == 4297 or dialogw.dw_dialogId == 185 then
wait(50)
printStringNow("~b~~h~Enter ~w~pressed", 300)
press_button(13)
end
clear_dw_data()
else
if coords == foot_coords1 then
if restart_p[1] and restart_p[2] then
restart_p = {false, false}
end
return true
end
end
end
if restart_p[1] and restart_p[2] then
restart_p = {false, false}
end
if coords ~= foot_coords1 and not restart_p[1] and not restart_p[2] and coords ~= restart_point and not isCharInAnyCar(PLAYER_PED) then
timer(3000)
wait(10)
while not sampIsCursorActive() do
wait(0)
if not isCharInAnyCar(PLAYER_PED) then
break
end
end
press_button(13)
end
stage = 2
else
if sampIsCursorActive() then
admin_check()
else
finish_route()
end
end
end
-- Функция для досрочного завершения маршрута если пропустил чекпоинт
function finish_route()
forced_stop = true
while not sampIsCursorActive() do
wait(0)
if not isCharInAnyCar(PLAYER_PED) then
break
end
timer(300)
press_button(70)
wait(300)
end
forced_stop = false
if sampIsCursorActive() then
if dialogw.dw_dialogId == 4295 then
press_button(13)
else
admin_check()
end
clear_dw_data()
end
end
-- Функция для рисования линии
function draw_line(posX, posY, posZ, col, dopX, dopY, dopZ)
local chPosX, chPosY, chPosZ = getCharCoordinates(PLAYER_PED)
local ang = 14
if not play then
chPosZ = chPosZ + 1
ang = 3
end
local wPosX, wPosY = convert3DCoordsToScreen(posX, posY, posZ)
local wPosX1, wPosY1 = convert3DCoordsToScreen(chPosX, chPosY, chPosZ)
if isPointOnScreen(posX, posY, posZ, 1) and play then
renderDrawLine(wPosX1, wPosY1, wPosX, wPosY, 2, "0xFF" .. col)
renderDrawPolygon(wPosX, wPosY, 10, 10, 4, 0, "0x7F" .. col)
end
if stage == 2 and dopX ~= 0 and dopY ~= 0 and dopZ ~= 0 then
local dPosX, dPosY = convert3DCoordsToScreen(dopX, dopY, dopZ)
if isPointOnScreen(dopX, dopY, dopZ, 1) then
renderDrawPolygon(dPosX, dPosY, 30, 30, 14, 0, "0x7Fdb1d1d")
end
end
renderDrawPolygon(wPosX1, wPosY1 , 15, 15, ang, 180, "0x9F" .. col)
end
-- Функция для краша при подозрении на админа
function admin_check()
adm_check = true
if sampIsCursorActive() then
timer(2000)
press_button(13)
wait(10)
sampAddChatMessage("(admin check): Dialog window closed.", -1)
end
local intime = 4
local t = os.clock()
local n = {0, true}
sampAddChatMessage("!!! The game will shutdown in " .. intime .. "s. Press 0 to cancel. !!!", 0xFFd10f0f)
timer(500)
wait(100)
press_button(84)
sampAddChatMessage("(admin check): Chat opened.", -1)
while os.clock() - t < intime do
wait(0)
printStringNow("~r~Shutdown in " .. intime - math.floor((os.clock() - t) * 10) / 10 .. "s")
if wasKeyPressed(VK_0) then
n[2] = false
adm_check = false
sampAddChatMessage("Canceled.", -1)
sampAddChatMessage('playing paused.', -1)
while true do
wait(0)
if wasKeyPressed(VK_1) and not sampIsCursorActive() then
sampAddChatMessage('playing unpaused...', -1)
break
end
end
break
end
end
if n[2] then
while n[2] do
if wasKeyPressed(VK_0) then
n[2] = false
end
end
end
wait(1000)
end
-- Функция для нажатия на кнопку
function press_button(id)
setVirtualKeyDown(id, true)
wait(50)
setVirtualKeyDown(id, false)
end
-- Функция таймера
function timer(time)
local t = os.clock()
while os.clock() - t < time / 1000 do
wait(0)
printStringNow("Wait: ~y~" .. time / 1000 - math.floor((os.clock() - t) * 10) / 10 .. "s" )
if wasKeyPressed(VK_3) then
sampAddChatMessage('playing paused.', -1)
local ps = time / 1000 - math.floor((os.clock() - t) * 10) / 10
while true do
wait(0)
printStringNow("Wait (paused): ~r~~h~~h~" .. ps .. "s" )
if wasKeyPressed(VK_1) and not sampIsCursorActive() then
sampAddChatMessage('playing unpaused...', -1)
t = os.clock()
time = ps * 1000
break
end
end
end
end
end
-- Функция для отображения окна статистики
function imgui.OnDrawFrame()
if myImgui.windows.status.main.v then
imgui.ShowCursor = false
local posX, posY = get_window_position(200, 100)
imgui.SetNextWindowPos(imgui.ImVec2(posX, posY), imgui.Cond.Appearing, imgui.ImVec2(0.0, 0.0))
imgui.SetNextWindowSize(imgui.ImVec2(200, 100), imgui.Cond.Appearing)
imgui.Begin("Stats", myImgui.windows.status.main, imgui.WindowFlags.NoResize + imgui.WindowFlags.NoTitleBar)
imgui.Text("Stats:\n> time: " .. get_time(os.clock(), stats.time_full) .. "\n> earned: " .. stats.salary .. "$\n> rounds: " .. stats.route_count)
imgui.End()
end
end
-- Функция для кастомизации окна статистики
function apply_custom_style()
imgui.SwitchContext()
imgui.GetIO().MouseDoubleClickTime = 0.1
local style = imgui.GetStyle()
local colors = style.Colors
local clr = imgui.Col
local ImVec4 = imgui.ImVec4
style.WindowRounding = 5.0
style.WindowTitleAlign = imgui.ImVec2(0.5, 0.84)
style.FrameRounding = 2.5
style.ItemSpacing = imgui.ImVec2(5.0, 4.0)
style.ScrollbarSize = 20
style.ScrollbarRounding = 5.0
style.GrabMinSize = 10.0
style.GrabRounding = 5.0
colors[clr.WindowBg] = imgui.ImVec4(0.02, 0.02, 0.02, 0.9)
colors[clr.ComboBg] = ImVec4(0.15, 0.15, 0.15, 1.00)
colors[clr.Border] = ImVec4(0.125, 0.125, 0.125, 0.50)
colors[clr.FrameBg] = ImVec4(0.11, 0.11, 0.11, 1.00)
colors[clr.TitleBg] = ImVec4(0.10, 0.10, 0.10, 1.00)
colors[clr.TitleBgActive] = ImVec4(0.10, 0.10, 0.10, 1.00)
colors[clr.TitleBgCollapsed] = ImVec4(0.10, 0.10, 0.10, 0.50)
colors[clr.Button] = ImVec4(0.15, 0.15, 0.15, 1.00)
colors[clr.ButtonHovered] = ImVec4(0.175, 0.175, 0.175, 1.00)
colors[clr.ButtonActive] = ImVec4(0.2, 0.2, 0.2, 1.00)
colors[clr.Header] = ImVec4(0.125, 0.125, 0.125, 1.00)
colors[clr.HeaderHovered] = ImVec4(0.15, 0.15, 0.15, 1.00)
colors[clr.HeaderActive] = ImVec4(0.175, 0.175, 0.175, 1.00)
colors[clr.ScrollbarBg] = ImVec4(0.1, 0.1, 0.1, 1.0)
colors[clr.ScrollbarGrab] = ImVec4(0.15, 0.15, 0.15, 1.00)
colors[clr.CheckMark] = ImVec4(0.75, 0.75, 0.75, 1.00)
colors[clr.SliderGrab] = ImVec4(0.15, 0.15, 0.15, 0.50)
colors[clr.ScrollbarGrabHovered] = ImVec4(0.175, 0.175, 0.175, 1.00)
colors[clr.ScrollbarGrabActive] = ImVec4(0.20, 0.20, 0.20, 1.00)
colors[clr.TextSelectedBg] = ImVec4(0.125, 0.125, 0.125, 1.00)
colors[clr.ResizeGrip] = ImVec4(0.125, 0.125, 0.125, 0.70)
colors[clr.ResizeGripHovered] = ImVec4(0.15, 0.15, 0.15, 1.00)
colors[clr.ResizeGripActive] = ImVec4(0.175, 0.175, 0.175, 1.00)
colors[clr.CloseButton] = ImVec4(0.15, 0.15, 0.15, 1.00)
colors[clr.CloseButtonHovered] = ImVec4(0.175, 0.175, 0.175, 1.00)
colors[clr.CloseButtonActive] = ImVec4(0.20, 0.20, 0.20, 1.00)
end
-- Получить позицию окна
function get_window_position(sizeX, sizeY)
local resX, resY = getScreenResolution()
local posX = resX - sizeX - 20
local posY = resY - sizeY - 20
return posX, posY
end
-- Функция для получения времени работы
function get_time(time_a, time_b)
local uptime = time_a - time_b
local gonetime = {math.floor(uptime / 3600), math.floor(uptime / 60) % 60, math.floor(uptime % 60)}
for i = 1, 3 do
if gonetime[i] < 10 then
gonetime[i] = "0" .. gonetime[i]
end
end
return gonetime[1] .. ":" .. gonetime[2] .. ":" .. gonetime[3]
end
-- Мониторинг сообщений
function samp_ev.onServerMessage(color, text)
if not adm_check and run then
if text:find("говорит:") or text:find("Администратор") then
print("{D10f0f}WARNING: {FFFFFF}" .. text)
if text:find(" tut") or text:find(" тут") or text:find(" здесь") or text:find(" monitora") or text:find(" монитора") then
local wrds = {" tut?", " тут?", " здесь?", " monitora?", " монитора?"}
local index
for i = 1, #wrds do
if text:find(wrds[i]) then
index = i
break
end
end
sampAddChatMessage("Text detected (" .. wrds[index] .. "): " .. text, 0xFFd10f0f)
adm_check = true
end
end
if text:find("Вы не переоделись в рабочую одежду") then
print("Error: not dressed up.")
adm_check = true
end
if text:find("Зачислено на банковский счёт") then
stats.salary = stats.salary + text:match("(%d+)")
stats.route_count = stats.route_count + 1
end
if text:find("У вас осталось 30 секунд") then
sampAddChatMessage("finish_route() by attention.", -1)
lua_thread.create(finish_route)
end
end
end
-- Мониторинг диалоговых окон
function samp_ev.onShowDialog(dialogId, style, title, button1, button2, text)
dialogw.dw_dialogId = dialogId
dialogw.dw_style = style
dialogw.dw_title = title
dialogw.dw_button1 = button1
dialogw.dw_button2 = button2
dialogw.dw_text = text
end
-- Функция для очистки данных диалогового окна
function clear_dw_data()
dialogw.dw_dialogId = nil
dialogw.dw_style = nil
dialogw.dw_title = nil
dialogw.dw_button1 = nil
dialogw.dw_button2 = nil
end
-- Поток для показа статистики
function thread_checks()
while true do
wait(0)
if run then
imgui.Process = myImgui.windows.status.main.v
if isKeyJustPressed(103) then
myImgui.windows.status.main.v = not myImgui.windows.status.main.v
end
else
break
end
end
end